Skip to content

Add --search-type flag for semantic and hybrid issue search - #14006

Merged
babakks merged 3 commits into
cli:trunkfrom
michaeljacholke:mj/semantic-search-issues
Aug 13, 2026
Merged

Add --search-type flag for semantic and hybrid issue search#14006
babakks merged 3 commits into
cli:trunkfrom
michaeljacholke:mj/semantic-search-issues

Conversation

@michaeljacholke

Copy link
Copy Markdown
Contributor

Adds a --search-type <lexical|semantic|hybrid> flag to gh search issues, defaulting to lexical so existing behavior is unchanged. When set to semantic or hybrid, the command sends the REST search_type query parameter.

Behavior

  • Semantic/hybrid are scoped to issues, so --include-prs cannot be combined with them, --sort / --order are rejected (results are relevance-ranked), and --web is rejected (the web search UI cannot carry search_type).
  • Unknown values are rejected client-side, since the API silently ignores them.
  • Support is feature-detected via the existing SearchType enum introspection (ISSUE_SEMANTIC / ISSUE_HYBRID), present on github.com and ghe.com, absent on single-tenant GHES, where the command fails with a clear "not supported on this host" error.
  • Semantic/hybrid use a separate, smaller rate-limit bucket, so fetching is bounded to a single page.

Testing

  • Unit tests cover query encoding, the searcher request (param present for semantic/hybrid, absent for lexical, single-page bound, and the unsupported-host error), feature detection, and flag validation.
  • Manually verified on github.com that --search-type semantic|hybrid sends the parameter and that no flag sends none.

Notes

  • search_type is independent of advanced_search=true.
  • Semantic ranking applies to keyword queries, quoted exact phrase queries are handled as lexical by the backend.

@github-actions github-actions Bot added external pull request originating outside of the CLI core team needs-triage needs to be reviewed labels Jul 29, 2026
@github-actions github-actions Bot removed the needs-triage needs to be reviewed label Jul 30, 2026
@babakks
babakks self-requested a review July 30, 2026 09:53

@babakks babakks left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the PR, @michaeljacholke! 🙏

The PR looks good. I added some comments but most of them are not substantial. I haven't approved it yet, as I need to go through some smoke tests too. That's for the second pass.

Two main points:

  1. We need to simplify the feature detection as it's getting more complicated as it was before and maintaining it over time could be a problem, especially when me and the rest of the team won't remember the context.
  2. Seems like your base branch was a bit stale. Since last release we've made some changes to URL construction. So, you should just rebase it on top of the current trunk.

Comment thread pkg/cmd/search/issues/issues.go Outdated
Comment thread pkg/cmd/search/issues/issues.go Outdated
Comment thread pkg/cmd/search/issues/issues.go Outdated
Comment thread pkg/cmd/search/issues/issues.go Outdated
Comment thread pkg/cmd/search/issues/issues.go
Comment thread pkg/cmd/search/issues/issues.go
Comment thread internal/featuredetection/feature_detection_test.go Outdated
Comment thread pkg/search/query.go Outdated
Copilot AI balanced review requested due to automatic review settings August 12, 2026 12:34
@michaeljacholke
michaeljacholke force-pushed the mj/semantic-search-issues branch from 2bc87a1 to 1d0cb0c Compare August 12, 2026 12:34

Copilot AI 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.

Pull request overview

Adds semantic and hybrid issue search modes while preserving lexical search as the default.

Changes:

  • Adds and validates the --search-type flag.
  • Sends search_type and limits semantic/hybrid searches to one page.
  • Detects host support and adds unit coverage.
Show a summary per file
File Description
pkg/search/searcher.go Handles backend selection and pagination.
pkg/search/searcher_test.go Tests requests, errors, and page limits.
pkg/search/query.go Adds the search type field.
pkg/cmd/search/issues/issues.go Adds the flag, help, and validation.
pkg/cmd/search/issues/issues_test.go Tests flag parsing and conflicts.
internal/featuredetection/feature_detection.go Detects semantic and hybrid support.
internal/featuredetection/feature_detection_test.go Tests host capability detection.
internal/featuredetection/detector_mock.go Adds feature-detector test fixtures.

Review details

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Suppressed comments (5)

pkg/search/searcher_test.go:1324

  • 🛑 Requirement: Use require.NoError here.

AGENTS.md:112 requires require, rather than assert, for error checks so this test halts before inspecting a result from a failed request. Add the corresponding import as part of the change.

	assert.NoError(t, err)

pkg/search/searcher.go:248

  • 🛑 Requirement: Use the request URL's query setter here.

qs is not declared in this function, so the hybrid branch also fails to compile. Use the same u.SetQuery API as the other REST parameters.

			qs.Set("search_type", query.SearchType)

pkg/search/searcher.go:245

  • 🛑 Requirement: Add a cleanup marker immediately above this feature gate.

AGENTS.md:163 requires feature-detection conditionals to have a directly preceding TODO cleanup identifier for linter compliance.

			if !features.HybridSearch {

pkg/cmd/search/issues/issues.go:99

  • 🛑 Requirement: Report the search type the user actually selected.

For --search-type hybrid --include-prs, this message incorrectly identifies the request as semantic search. Use searchType so the error describes the invalid invocation.

				return cmdutil.FlagErrorf("semantic search is scoped to issues and cannot be combined with `--include-prs`")

pkg/cmd/search/issues/issues.go:102

  • 🛑 Requirement: Report the search type the user actually selected.

The hybrid mode reaches this branch too, but the resulting error says semantic search. Interpolate searchType to keep the message correct for both modes.

				return cmdutil.FlagErrorf("`--sort` and `--order` are not supported with semantic search")
  • Files reviewed: 8/8 changed files
  • Comments generated: 4
  • Review effort level: Balanced

Comment thread pkg/search/searcher_test.go Outdated
Comment thread pkg/search/searcher.go Outdated
Comment thread pkg/search/searcher.go

switch query.SearchType {
case "semantic":
if !features.SemanticSearch {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No. This is not like other features that would eventually be supported on all supported hosts. Currently, there's no plan for GHES to support the semantic search, so this check may live here indefinitely.

On the other hand, although this is a github.com/GHEC only feature, it's still best to have explicit boolean feature fields for them, to provide a user-friendly error message when someone on GHES tries to use them. Note that, we already do a schema inspection anyway, so it's not an additional cost.

Comment thread pkg/cmd/search/issues/issues.go Outdated
@michaeljacholke

Copy link
Copy Markdown
Contributor Author

Thanks for the review and suggestions @babakks!

Pushed the changes and addressed the feedback/questions

@babakks babakks left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM! Thanks for the changes, @michaeljacholke! 🙏

Just a minor comment.

Comment thread pkg/search/searcher.go Outdated

switch query.IssueSearchType {
case "semantic":
// TODO semanticSearchCleanup

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I know this is due to the :copilot: review, but I think it doesn't apply here.

As a bit of context, most feature detection checks come with a mindset that at some point we're going to scrap them as they're no longer needed (i.e. older GHES version will eventually go out of support).

But, for the semantic search, we know it's not supported on GHES and it's a gihtub.com/GHEC only feature. So, a future cleanup doesn't make sense. Also, if we ever decided to add them to GHES, gh will already have everything in place to provide the experience to the user.

So, let's remove the cleanup comments here (this and the other down below).

@babakks babakks left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

suggestion: you can also introduce the semantic/hybrid search in the gh's skill file (in skills/gh/SKILL.md). There's an entry for search issues. I think you can add a simple sentence to it surfacing the new flags and a quick guide on when should the agent use them.

@babakks
babakks marked this pull request as ready for review August 13, 2026 12:00
@babakks
babakks requested a review from a team as a code owner August 13, 2026 12:00
@babakks
babakks requested review from sergiou87 and removed request for sergiou87 August 13, 2026 12:00
@github-actions

This comment was marked as resolved.

@michaeljacholke

Copy link
Copy Markdown
Contributor Author

Great catch and additional suggestion @babakks! Implemented the changes here - b892e92

@babakks
babakks enabled auto-merge August 13, 2026 13:06
@babakks
babakks merged commit a7059d5 into cli:trunk Aug 13, 2026
11 checks passed
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Aug 21, 2026
This MR contains the following updates:

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

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.98.0`](https://github.com/cli/cli/releases/tag/v2.98.0): GitHub CLI 2.98.0

[Compare Source](cli/cli@v2.97.0...v2.98.0)

#### Security

A security vulnerability has been identified, and fixed, that binds the local forwarded port to all available network interfaces by default.

Users of `gh codespace ports forward` are advised to update `gh` to version `v2.98.0` as soon as possible.

For more information see: <GHSA-vfhh-p7hm-pxfh>

#### Support worktrees in `pr checkout`

Users can now checkout a pull request into a git worktree by using the new `--worktree PATH` flag in `gh pr checkout`:

```shell
gh pr checkout 12 --worktree ../wt-feature
```

#### Add semantic search to `search issues`

The `gh search issues` command now supports semantic search for issues. Users can select the search type by passing the `--search-type` flag:

```shell
gh search issues --search-type semantic ...

gh search issues --search-type hybrid ...
```

For more information about semantic search see: ["Improved Search for github issues is now generally available"](https://github.blog/changelog/2026-04-02-improved-search-for-github-issues-is-now-generally-available/).

#### What's Changed

##### ✨ Features

- Add --worktree flag to gh pr checkout by [@&#8203;tidy-dev](https://github.com/tidy-dev) in [#&#8203;13946](cli/cli#13946)
- Set GH\_EXTENSION=1 when gh invokes an extension by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14072](cli/cli#14072)
- Add --search-type flag for semantic and hybrid issue search by [@&#8203;michaeljacholke](https://github.com/michaeljacholke) in [#&#8203;14006](cli/cli#14006)

##### 🐛 Fixes

- Fix `RESTWithNext` error type, repairing `gh status` and attestation retries by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;13988](cli/cli#13988)
- Trim spaces when parsing X-Oauth-Scopes in `gh release create` by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14065](cli/cli#14065)
- Fix project item-add output for non-TTY by [@&#8203;zwick](https://github.com/zwick) in [#&#8203;14056](cli/cli#14056)

##### 📚 Docs & Chores

- Slim down dependabot triage comments by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14019](cli/cli#14019)
- Require explicit MR review ownership by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14028](cli/cli#14028)
- Collapse spam triage into the agentic issue-triage workflow by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14027](cli/cli#14027)
- Run Dependabot triage every hour by [@&#8203;sergiou87](https://github.com/sergiou87) in [#&#8203;14030](cli/cli#14030)
- Route deploy key requests through api.Client by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;13989](cli/cli#13989)
- Route ssh key requests through api.Client by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;13994](cli/cli#13994)
- Route gpg key requests through api.Client by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;13997](cli/cli#13997)
- Route autolink requests through api.Client by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14013](cli/cli#14013)
- Route extension requests through api.Client by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14059](cli/cli#14059)
- Route release creation through api.Client by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14062](cli/cli#14062)
- Tell agents to use the MR template in AGENTS.md by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14074](cli/cli#14074)
- Make Dependabot triage cheaper and more decisive by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14079](cli/cli#14079)
- Route release deletions through api.Client by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14077](cli/cli#14077)
- Give Dependabot triage a real reachability check by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14087](cli/cli#14087)
- Restore automatic spam issue closure by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14088](cli/cli#14088)
- Add a scheduled tech debt burndown skill by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14095](cli/cli#14095)
- Use reflect.Pointer instead of deprecated reflect.Ptr by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14098](cli/cli#14098)
- Clarify what belongs in the MR template's testing section by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14103](cli/cli#14103)
- Rename cli-code-reviewer skill to code-review by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;14116](cli/cli#14116)
- Add aw-actions group to dependabot configuration by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;14123](cli/cli#14123)
- Isolate tests from local machine's auth and git configuration by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;14128](cli/cli#14128)
- Don't ask for feature detection cleanup comments when not needed by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;14139](cli/cli#14139)
- Accept pre-release tags in deployment validation by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;14193](cli/cli#14193)
- ci: add temporary step to verify Linux repo signing keys by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;14202](cli/cli#14202)
- Revert "ci: add temporary step to verify Linux repo signing keys" by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;14203](cli/cli#14203)
- Fix issue triage action compatibility \[skip changelog] by [@&#8203;tidy-dev](https://github.com/tidy-dev) in [#&#8203;14207](cli/cli#14207)

##### :dependabot: Dependencies

- chore(deps): bump github.com/sigstore/sigstore-go from 1.2.2 to 1.3.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14047](cli/cli#14047)
- chore(deps): bump the codeql-actions group across 1 directory with 3 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14049](cli/cli#14049)
- chore(deps): bump google.golang.org/grpc from 1.82.1 to 1.83.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14048](cli/cli#14048)
- chore(deps): bump github.com/google/go-containerregistry from 0.21.7 to 0.21.8 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14066](cli/cli#14066)
- chore(deps): bump actions/attest from 4.2.1 to 4.2.2 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14100](cli/cli#14100)
- chore(deps): bump azure/login from 3.0.0 to 3.0.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14101](cli/cli#14101)
- chore(deps): bump the codeql-actions group across 1 directory with 3 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14091](cli/cli#14091)
- chore(deps): bump github/gh-aw-actions/setup-cli from 0.83.4 to 0.85.4 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14068](cli/cli#14068)
- chore(deps): bump github.com/google/go-containerregistry from 0.21.8 to 0.21.9 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14119](cli/cli#14119)
- chore(deps): bump github.com/klauspost/compress from 1.19.1 to 1.19.2 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14120](cli/cli#14120)
- chore(deps): bump the aw-actions group with 2 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14147](cli/cli#14147)
- chore: sign APT repository with both keys by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;13271](cli/cli#13271)
- chore(deps): bump github.com/yuin/goldmark from 1.8.4 to 1.8.5 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14029](cli/cli#14029)
- chore(deps): bump actions/attest from 4.2.0 to 4.2.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14050](cli/cli#14050)
- Bump golangci-lint in CI to v2.12.2 by [@&#8203;williammartin](https://github.com/williammartin) in [#&#8203;14102](cli/cli#14102)
- chore(deps): bump the aw-actions group with 2 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14124](cli/cli#14124)
- chore(deps): bump google.golang.org/protobuf from 1.36.11 to 1.36.12 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14140](cli/cli#14140)
- Upgrade gh-aw workflows to v0.85.4 by [@&#8203;tidy-dev](https://github.com/tidy-dev) in [#&#8203;14141](cli/cli#14141)
- Bump Go to 1.26.6 by [@&#8203;github-actions](https://github.com/github-actions)\[bot] in [#&#8203;14143](cli/cli#14143)
- chore: bump go to 1.26.7 by [@&#8203;babakks](https://github.com/babakks) in [#&#8203;14205](cli/cli#14205)
- chore(deps): bump github.com/stretchr/testify from 1.11.1 to 1.12.1 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14204](cli/cli#14204)
- chore(deps): bump the codeql-actions group across 1 directory with 3 updates by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14169](cli/cli#14169)
- chore(deps): bump golang.org/x/crypto from 0.54.0 to 0.55.0 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14164](cli/cli#14164)
- chore(deps): bump charm.land/lipgloss/v2 from 2.0.5 to 2.0.6 by [@&#8203;dependabot](https://github.com/dependabot)\[bot] in [#&#8203;14166](cli/cli#14166)
- Bump gh-aw-actions to v0.87.1 and recompile agentic workflows by [@&#8203;BagToad](https://github.com/BagToad) in [#&#8203;14210](cli/cli#14210)

#### New Contributors

- [@&#8203;sergiou87](https://github.com/sergiou87) made their first contribution in [#&#8203;14030](cli/cli#14030)
- [@&#8203;michaeljacholke](https://github.com/michaeljacholke) made their first contribution in [#&#8203;14006](cli/cli#14006)

**Full Changelog**: <cli/cli@v2.97.0...v2.98.0>

</details>

---

### Configuration

📅 **Schedule**: (UTC)

- 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 [Mend Renovate](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yODguMCIsInVwZGF0ZWRJblZlciI6IjQzLjI4OC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiLCJhdXRvbWF0aW9uOmJvdC1hdXRob3JlZCIsImRlcGVuZGVuY3ktdHlwZTo6bWlub3IiXX0=-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

external pull request originating outside of the CLI core team ready-for-review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants