Commit graph

11039 commits

Author SHA1 Message Date
Sebastiaan van Stijn
6868d273ec
replace github.com/golang/snappy with klauspost/compress/snappy
The github.com/golang/snappy repository was archived and is no longer
maintained. klauspost/compress provides a drop-in replacement, which
is actively maintained, and the klauspost/compress module is already
an existing (indirect) dependency.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
2026-03-26 22:58:08 +01:00
William Martin
b62671151b
Merge pull request #12859 from cli/kw/experimental-huh-prompter
Add experimental huh-only prompter gated by GH_EXPERIMENTAL_PROMPTER
2026-03-26 14:38:19 +01:00
William Martin
cb2b50576f Ensure huh prompter cleans up 2026-03-26 14:26:57 +01:00
Kynan Ware
84a3ba83e4 fix(huh prompter): remove unused fields and imports
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 14:26:57 +01:00
Kynan Ware
f92fab6124 go mod tidy 2026-03-26 14:26:56 +01:00
Kynan Ware
13e47d0078 feat(huh prompter): clear search input after submitting query
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 14:26:17 +01:00
Kynan Ware
cfb2224176 refactor(huh prompter): custom Field for MultiSelectWithSearch
Replace the OptionsFunc-based MultiSelectWithSearch with a custom huh
Field implementation. huh's OptionsFunc runs in a goroutine, causing
data races with selection state and stale cache issues that made
selections disappear on toggle or search changes.

The custom field (multiSelectSearchField) combines a text input and
multi-select list in a single field with full control over the update
loop. Search runs asynchronously via tea.Cmd when the user presses
Enter, with a themed spinner during loading. Selections are stored in
a simple map — no goroutine races, no Eval cache, no syncAccessor.

Also adds defensive validation for mismatched Keys/Labels slices from
searchFunc.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 14:26:17 +01:00
Kynan Ware
f38abbe1ca feat(huh prompter): add placeholder to search input
Add 'Type to search, Ctrl+U to clear' placeholder to the
MultiSelectWithSearch search input. Set WithWidth(80) in the test
harness to prevent textinput placeholder rendering panics when
there is no terminal.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 14:26:17 +01:00
Kynan Ware
38e10d5ebf fix(huh prompter): use synchronized accessors to eliminate data race
Replace Value() pointer bindings with syncAccessor in
MultiSelectWithSearch. huh's OptionsFunc runs in a goroutine while
the main event loop writes field values, causing a data race on
shared variables. syncAccessor implements huh's Accessor interface
with a shared mutex, ensuring all reads and writes are synchronized.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 14:26:17 +01:00
Kynan Ware
95a59f4431 fix(accessible prompter): update test expectations for huh v2
Fix accessible prompter tests that broke with the huh v2 upgrade:
- Replace 'Input a number' with 'Enter a number' (huh v2 changed text)
- Remove trailing CRLF from ExpectString calls that now fail due to
  ANSI color codes wrapping the title text
- Allow ANSI escape codes in password masking regex assertions

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 14:26:16 +01:00
Kynan Ware
4d74e057f2 refactor(huh prompter): pipe-based test harness with full coverage
Replace manual model updates with an io.Pipe-based test harness that
drives forms through bubbletea's real event loop. Interaction helpers
(tab(), toggle(), typeKeys(), enter(), etc.) send raw terminal bytes
through io.Pipe to form.Run() in a goroutine.

Add tests for AuthToken, ConfirmDeletion, and InputHostname including
validation rejection paths. Add MultiSelectWithSearch coverage for
persistent options and empty search results.

30 tests, ~1s, all build*Form methods at 94-100% coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 14:26:16 +01:00
Kynan Ware
86d876fd34 test(huh prompter): add table-driven tests for all prompt types
Extract build*Form() methods from each huhPrompter method, separating
form construction from form.Run(). This enables testing the real form
construction code by driving it with direct model updates, adapted
from huh's own test patterns.

Tests cover Input, Select, MultiSelect, Confirm, Password,
MarkdownEditor, and MultiSelectWithSearch including a persistence
test that verifies selections survive across search query changes.

Also fixes a search cache initialization bug where the first
buildOptions("") call would skip the searchFunc due to
cachedSearchQuery defaulting to "".

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 14:26:16 +01:00
Kynan Ware
f294831e7d Upgrade to huh/v2 and fix selection persistence in MultiSelectWithSearch
Migrate from github.com/charmbracelet/huh v1 to charm.land/huh/v2,
updating ThemeBase16 to the new ThemeFunc API.

Fix selected options being lost across searches in the huhPrompter's
MultiSelectWithSearch. The root cause was huh's internal Eval cache:
when the user returned to a previously-seen search query, cached
options with stale .selected state overwrote the current selections
via updateValue(). The fix includes selectedValues in the OptionsFunc
binding hash (via searchOptionsBinding) so the cache key changes
whenever selections change, preventing stale cache hits. A local
searchFunc result cache avoids redundant API calls when only the
selection state (not the query) has changed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 14:26:15 +01:00
Kynan Ware
4661c05ed0 Fix gofmt alignment for prompter-enabled fields in IOStreams
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 14:24:56 +01:00
Kynan Ware
726714d1a7 Use LayoutStack for huhPrompter MultiSelectWithSearch
Implement a huh-native MultiSelectWithSearch that renders the search
input and multi-select list simultaneously using LayoutStack. The
search input is in Group 0 and the multi-select in Group 1, with
OptionsFunc bound to the search query so results update when the
user presses Enter to advance focus. Users can Shift+Tab back to
refine their search, and selections persist across queries.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 14:24:56 +01:00
Kynan Ware
87426ee236 Add experimental huh-only prompter gated by GH_EXPERIMENTAL_PROMPTER
Introduce a new Prompter implementation (huhPrompter) that uses the
charmbracelet/huh library in its standard interactive mode, as an
alternative to the survey-based default prompter. The new implementation
is gated behind the GH_EXPERIMENTAL_PROMPTER environment variable,
following the same truthy/falsey pattern as GH_ACCESSIBLE_PROMPTER.

Key differences from the accessible prompter:
- No WithAccessible(true) flag (full interactive TUI)
- Uses EchoModePassword (masked with *) instead of EchoModeNone
- No default value annotations appended to prompt text

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-26 14:24:56 +01:00
William Martin
afe0adf7ed
Merge pull request #12951 from cli/dependabot/github_actions/azure/login-3.0.0
chore(deps): bump azure/login from 2.3.0 to 3.0.0
2026-03-26 14:09:45 +01:00
William Martin
c61b1600c2
Merge pull request #13004 from cli/dependabot/github_actions/mislav/bump-homebrew-formula-action-4.1
chore(deps): bump mislav/bump-homebrew-formula-action from 3.6 to 4.1
2026-03-26 14:09:33 +01:00
William Martin
3460080d27
Merge pull request #13005 from cli/dependabot/github_actions/microsoft/setup-msbuild-3.0.0
chore(deps): bump microsoft/setup-msbuild from 2.0.0 to 3.0.0
2026-03-26 14:09:19 +01:00
William Martin
39407e65e3
Merge pull request #13037 from cli/kw/acceptance-test-git-config
Fix acceptance test failures: git identity, headRepository JSON, obsolete traversal test
2026-03-26 13:32:29 +01:00
William Martin
971be976b3 Add nameWithOwner to necessary tests 2026-03-26 13:23:43 +01:00
Kynan Ware
5ed8cf0faa fix(pr view): fetch nameWithOwner in headRepository GraphQL query
Commit dd424d85f added NameWithOwner to PRRepository for agent-task
listings but didn't update the headRepository GraphQL query to fetch it.
This caused gh pr view --json headRepository to emit an empty
"nameWithOwner":"" field, breaking the pr-create-respects-simple-
pushdefault acceptance test.

Fetch nameWithOwner in the query and update the test assertion to expect
it.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 12:47:45 -06:00
Kynan Ware
be4960a255 test(acceptance): remove run-download-traversal test
GitHub's Artifact API now rejects artifact names like '..' server-side
with a 400 Bad Request, making it impossible to create artifacts with
path traversal names. This means the scenario this test was verifying
(that gh run download catches traversal names) can no longer be
reproduced through normal artifact creation.

The client-side traversal check in gh run download remains in place as a
defense-in-depth measure.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 12:47:45 -06:00
Kynan Ware
6666850871 fix(acceptance): set git identity in testscript sandbox
The sandbox overrides HOME so git cannot find the user's global config,
causing 'Author identity unknown' errors when acceptance test scripts
make commits. Write a minimal .gitconfig with user.name and user.email
into the sandbox working directory during sharedSetup.

Co-Authored-By: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-25 12:47:44 -06:00
Kynan Ware
a32d004d9d
Merge pull request #13030 from cli/cleanup-outdated-triage-doc
Align triage.md with current triage process
2026-03-25 11:59:27 -06:00
Kynan Ware
8f7d20855e
Merge pull request #13025 from cli/kw/refactor/reviewer-assignee-actor-symmetry
Consolidate actor-mode signals into ApiActorsSupported
2026-03-25 11:43:18 -06:00
William Martin
9b4a989d35
Merge pull request #13033 from Lslightly/13001-fix-err-data-race-and-heap-alloc
define err in go func instead of use err defined in outer scope
2026-03-25 18:13:38 +01:00
Qingwei Li
e53e360d5b
internal/codespaces/portforwarder: define err in go func instead of use err defined in outer scope
Fixes #13001
2026-03-26 00:31:56 +08:00
William Martin
d81c9bbdd3
Merge pull request #13031 from cli/dependabot/go_modules/github.com/zalando/go-keyring-0.2.8
chore(deps): bump github.com/zalando/go-keyring from 0.2.6 to 0.2.8
2026-03-25 15:55:00 +01:00
dependabot[bot]
c3fe99fc2a
chore(deps): bump github.com/zalando/go-keyring from 0.2.6 to 0.2.8
Bumps [github.com/zalando/go-keyring](https://github.com/zalando/go-keyring) from 0.2.6 to 0.2.8.
- [Release notes](https://github.com/zalando/go-keyring/releases)
- [Commits](https://github.com/zalando/go-keyring/compare/v0.2.6...v0.2.8)

---
updated-dependencies:
- dependency-name: github.com/zalando/go-keyring
  dependency-version: 0.2.8
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-25 14:40:34 +00:00
William Martin
69d89a6590
Merge pull request #12884 from cli/babakks/use-min-discovery-fields-for-issue-create
fix(issue): avoid fetching unnecessary fields for discovery
2026-03-25 15:39:40 +01:00
William Martin
7ef7d7fb69
Merge pull request #12962 from cli/dependabot/go_modules/github.com/google/go-containerregistry-0.21.3
chore(deps): bump github.com/google/go-containerregistry from 0.20.7 to 0.21.3
2026-03-25 15:38:07 +01:00
William Martin
52850321b4
Merge pull request #12725 from realMelTuc/fix-readme-typo
Fix typo: remove extra space in README.md link
2026-03-25 15:25:11 +01:00
tidy-dev
5477387fa5
Update docs/triage.md
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-25 06:57:10 -07:00
tidy-dev
e6680adaaa
Update docs/triage.md
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-03-25 06:56:19 -07:00
tidy-dev
c82177c702 Align triage.md with unified triage process 2026-03-25 09:45:59 -04:00
MelTuc
bbbfe9b8ca Fix typo: remove extra space in README.md link 2026-03-25 14:31:31 +01:00
Kynan Ware
391e6616d5 fix(survey): use useReviewerSearch consistently in prompt path
The reviewer prompt branch checked reviewerSearchFunc != nil directly
instead of useReviewerSearch, making the fetch and prompt decisions
inconsistent. This mirrors how the assignee path already uses
useAssigneeSearch at both the fetch and prompt gates.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-24 23:28:26 -06:00
Kynan Ware
bff468bafe fix(pr create): wire up @copilot assignee replacement and [bot] suffix
Two bugs introduced in #13009 found during acceptance testing:

1. `pr create --assignee @copilot` sent the literal `@copilot` to the
   API because NewIssueState only ran MeReplacer on assignees, not
   CopilotReplacer. Fixed by switching to SpecialAssigneeReplacer (which
   handles both @me and @copilot) like issue create already does.

2. The replaceActorsForAssignable mutation requires the [bot] suffix on
   bot actor logins (e.g. `copilot-swe-agent[bot]`), unlike
   requestReviewsByLogin which has a separate botLogins field. Added the
   suffix in ReplaceActorsForAssignableByLogin for CopilotAssigneeLogin.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-24 23:26:28 -06:00
Kynan Ware
6a68ebc1c9 refactor(survey): simplify ApiActorsSupported in RepoMetadataInput
The expression was redundantly re-checking whether assignees or
reviewers were chosen. RepoMetadata already gates on
input.Assignees || input.Reviewers before consulting
ApiActorsSupported, so passing state.ApiActorsSupported directly
is sufficient.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-24 21:37:58 -06:00
Kynan Ware
92f205e54b docs(featuredetection): document GHES removal criteria for ApiActorsSupported
Expand the ApiActorsSupported doc comment to explain the two API
generations (legacy AssignableUser vs actor-based AssignableActor),
what each returns, and the specific GraphQL schema additions to
check for when evaluating GHES support.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-24 21:15:39 -06:00
Kynan Ware
ae5e857c2e refactor(featuredetection): rename ActorIsAssignable to ApiActorsSupported
Aligns the feature detector field name with the downstream
ApiActorsSupported flag introduced in the previous commit, so the
signal has one consistent name from detection through to consumption.

Also consolidates leftover TODO tags (actorIsAssignableCleanup,
requestReviewsByLoginCleanup) under the single // TODO ApiActorsSupported
tag so there's exactly one thing to grep for.

Pure rename with no logic changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-24 21:09:04 -06:00
Kynan Ware
3c00ffdade refactor(pr shared): consolidate ActorAssignees and ActorReviewers into ApiActorsSupported
The CLI had two per-entity flags (ActorAssignees on EditableAssignees and
IssueMetadataState, ActorReviewers on IssueMetadataState) threaded through
different layers of the stack to distinguish github.com from GHES. Both
flags were always set from the same source (issueFeatures.ActorIsAssignable)
and never had different values, but they were carried independently on
different structs. This led to a confusing asymmetry where:

- EditableAssignees had ActorAssignees but EditableReviewers had nothing
- The PR edit flow piggybacked on editable.Assignees.ActorAssignees to
  make reviewer mutation decisions, which was misleading
- RepoMetadataInput only had ActorAssignees with no reviewer equivalent

This commit replaces all per-entity flags with a single ApiActorsSupported
bool hoisted to the shared level on Editable, IssueMetadataState, and
RepoMetadataInput. Both assignees and reviewers now key off the same signal.

Every branch site is marked with // TODO ApiActorsSupported so we can grep
for cleanup sites when GHES eventually supports the actor-based mutations
(replaceActorsForAssignable, requestReviewsByLogin).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-24 21:04:41 -06:00
Kynan Ware
1df6f84d70
Merge pull request #13009 from cli/fix/pr-create-assignee-metadata-13000
Use login-based assignee mutation on github.com
2026-03-24 20:29:11 -06:00
Kynan Ware
4e6bc78e04 refactor(pr shared): extract SpecialAssigneeReplacer for @me and Copilot expansion
The inline replaceSpecialAssigneeNames closures in AssigneeIds and
AssigneeLogins were duplicated. Extract them into an exported
SpecialAssigneeReplacer type that consolidates MeReplacer and
CopilotReplacer into a single ReplaceSlice call, parameterised by
actorAssignees and copilotUseLogin.

Adopt the new type in the issue create flow as well, replacing the
manual MeReplacer + conditional CopilotReplacer sequence.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-24 18:59:21 -06:00
dependabot[bot]
b99ee4c092
chore(deps): bump github.com/google/go-containerregistry
Bumps [github.com/google/go-containerregistry](https://github.com/google/go-containerregistry) from 0.20.7 to 0.21.3.
- [Release notes](https://github.com/google/go-containerregistry/releases)
- [Commits](https://github.com/google/go-containerregistry/compare/v0.20.7...v0.21.3)

---
updated-dependencies:
- dependency-name: github.com/google/go-containerregistry
  dependency-version: 0.21.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-24 19:32:54 +00:00
William Martin
bdc0413774
Merge pull request #12963 from cli/dependabot/go_modules/google.golang.org/grpc-1.79.3
chore(deps): bump google.golang.org/grpc from 1.79.2 to 1.79.3
2026-03-24 20:31:35 +01:00
William Martin
dedb2287be
Merge pull request #13024 from cli/agents-md
Add AGENTS.md
2026-03-24 20:28:41 +01:00
William Martin
1ea2952566
Merge pull request #13023 from cli/agent-in-header
Record agentic invocations in User-Agent header
2026-03-24 20:28:32 +01:00
William Martin
c51769c977 Record agentic invocations in User-Agent header
Detect which AI coding agent is invoking gh by checking well-known
environment variables and include the agent name in the User-Agent
header sent to GitHub APIs.

Supported agents: Codex, Gemini CLI, Copilot CLI, OpenCode,
Claude Code, and Amp. Generic AI_AGENT env var is also supported
with validation to prevent header injection.

Fixes github/cli#1111

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-24 19:58:37 +01:00