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>
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>
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>
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>
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>
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>
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>
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.
Fixesgithub/cli#1111
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add comment headers to group examples by concern (title/body, labels,
reviewers, assignees, projects/milestones), matching the style used by
other commands like pr review and repo create. Also adds examples for
--body-file and re-requesting review via --add-reviewer.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The --add-reviewer flag on pr edit already supports re-requesting
reviews from reviewers who have already submitted their review,
but this wasn't documented in the help text.
Ref #12489
Ref #2053
Wire up MultiSelectWithSearch for assignees in MetadataSurvey, replacing
the static MultiSelect that required bulk fetching all assignable actors.
This applies to both gh pr create and gh issue create interactive flows
when selecting assignees via the 'Add metadata' prompt.
Changes:
- Add assigneeSearchFunc parameter to MetadataSurvey
- Skip assignee bulk fetch when search func is available
- New SearchRepoAssignableActors API function for repo-level search
(create flows have no issue/PR node ID yet)
- New RepoAssigneeSearchFunc in shared editable.go
- Refactor actorsToSearchResult helper shared by both search functions
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add AssigneeSearchFunc to gh issue edit interactive flow, matching
the pattern already used in gh pr edit. This eliminates the bulk
RepositoryAssignableActors fetch for interactive assignee selection,
using dynamic SuggestedAssignableActors search instead.
Also clean up pr edit assigneeSearchFunc signature to remove the
unused editable parameter (no longer needed after removing the
actor accumulation hack).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The assigneeSearchFunc previously accumulated actors into
editable.Metadata.AssignableActors so that MembersToIDs could
later resolve logins to node IDs. Now that the edit flow uses
AssigneeLogins + ReplaceActorsForAssignableByLogin on github.com,
this accumulation is no longer needed.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When ActorAssignees is true (github.com), the --add-assignee and
--remove-assignee flag flows now pass logins directly to
ReplaceActorsForAssignableByLogin instead of bulk fetching all
assignable actors and resolving logins to node IDs.
Changes:
- New AssigneeLogins() method on Editable that computes the final
login set (defaults + add - remove) without ID resolution
- UpdateIssue: call AssigneeLogins + ByLogin when ActorAssignees is true
- EditableOptionsFetch: skip assignee bulk fetch for flag flows on
github.com (only fetch on GHES where ID resolution is needed)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When ActorAssignees is true (github.com), pass assignee logins directly
to the ReplaceActorsForAssignable mutation instead of resolving logins
to node IDs. This eliminates the need to bulk fetch all assignable
users/actors and fixes a bug where providing assignees via CLI flag
and then interactively adding metadata would fail with 'not found'
because the cached MetadataResult had no assignee data.
Changes:
- Set state.ActorAssignees = true in pr create (was missing)
- AddMetadataToIssueParams: pass assigneeLogins when ActorAssignees
is true, skip fetch and ID resolution entirely
- CreatePullRequest/IssueCreate: call ReplaceActorsForAssignableByLogin
after creation to assign via logins
- Consolidate replaceActorsForAssignable mutation into api/ package
(ReplaceActorsForAssignableByLogin + ReplaceActorsForAssignableByID)
- Remove duplicate replaceActorAssigneesForEditable from editable_http.go
- Add TODO replaceActorsByLoginCleanup markers on edit paths
Fixescli/cli#13000
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(agent-task): resolve Copilot API URL dynamically
Query viewer.copilotEndpoints.api to get the correct Copilot API URL
for the user's host instead of hardcoding api.githubcopilot.com. This
fixes 401 errors for ghe.com tenancy users whose Copilot API lives at
a different endpoint.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
- reorder if checks: validate --enable-squash-merge is set before
checking the value, and error when --enable-squash-merge=false
- use validSquashMsgValues directly in interactive prompt instead of
duplicating the slice
- use slices.Contains in validateSquashMergeCommitMsg
- interpolate const values in Long description instead of hardcoding
- add default clause in transformSquashMergeOpts to avoid mutating
title/message on unknown input
- move optionDiscussions to end of const block with TODO comment
- add test for unknown input and --enable-squash-merge=false case
Add a single --squash-merge-commit-message flag that maps to both
squash_merge_commit_title and squash_merge_commit_message API fields.
Supported values:
- default: COMMIT_OR_PR_TITLE + COMMIT_MESSAGES
- pr-title: PR_TITLE + BLANK
- pr-title-commits: PR_TITLE + COMMIT_MESSAGES
- pr-title-description: PR_TITLE + PR_BODY
The flag requires --enable-squash-merge to be set alongside it. In
interactive mode, the squash merge commit message prompt appears when
squash merging is selected.
Closes#10092
Only the destination repo ID is needed for issue transfer. Switch from
GitHubRepo to IssueRepoInfo to use minimal fields appropriate for issues.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Update test mocks to match the renamed GraphQL query used by
IssueRepoInfo, and switch to StubIssueRepoInfoResponse helper.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Switch issue create from GitHubRepo to IssueRepoInfo so that
gh issue create works with fine-grained PATs that only have
Issues:Write and Metadata:Read permissions.
Fixescli/cli#12798
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add a new IssueRepoInfo function that fetches only the fields needed
for issue creation (id, name, owner, hasIssuesEnabled, viewerPermission),
avoiding defaultBranchRef and other fields that require Contents:Read.
Also add StubIssueRepoInfoResponse helper to httpmock for testing.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Apply DisplayName() to author and assignee display in issue view,
consistent with the pr view changes.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace copilotDisplayName with actorDisplayName(typeName, login, name)
which handles all actor types: known bots get friendly names (e.g.
Copilot → 'Copilot (AI)'), regular bots return login, users with
names return 'login (Name)', others return login.
All DisplayName() methods on Author, CommentAuthor, GitHubUser,
AssignableUser, AssignableBot, RequestedReviewer, and ReviewerBot
now delegate to actorDisplayName with their available fields.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add CopilotDisplayName helper that translates known Copilot bot
logins (copilot-pull-request-reviewer, copilot-swe-agent) to the
friendly 'Copilot (AI)' display name. Applied to:
- PullRequestReview.AuthorLogin() — review comment author
- Comment.AuthorLogin() — PR/issue comment author
- parseReviewers() in pr view — reviewer list display
This ensures gh pr view shows 'Copilot (AI)' instead of the raw
'copilot-pull-request-reviewer' login for both the reviewer status
line and any review comments left by Copilot.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- add usage examples to --help output
- use path.Match instead of filepath.Match for OS-consistent behavior
- rename patterns to excludePatterns for clarity
- simplify splitDiffSections using strings.Split
Add a new --exclude (-e) flag to gh pr diff that allows users to exclude
files matching glob patterns from the diff output. This is useful for
filtering out auto-generated files, vendor directories, or other noise
when reviewing pull requests.
Supports standard glob patterns and can be specified multiple times.
Patterns match against both the full path and basename.
Closes#8739
Use DefaultLogins instead of Default display names when calling
MultiSelectWithSearch for reviewers. The dedup logic in the
prompter compares keys (logins) against defaults, so passing
display names like 'mxie (Melissa Xie)' prevented deduplication
against search result keys like 'mxie'.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Wire CopilotReviewerReplacer into NewIssueState so that
`gh pr create --reviewer @copilot` correctly resolves to the
copilot-pull-request-reviewer bot login, matching the behavior
already implemented in gh pr edit.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Mark the GHES ID-resolution branch in AddMetadataToIssueParams
for cleanup once GHES supports requestReviewsByLogin.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Team reviewers must be provided as fully qualified org/teamname.
Remove the /slug shorthand that auto-prefixed the repo owner,
as this format is not supported.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Mark the legacy static MultiSelect reviewer path for cleanup once
GHES supports requestReviewsByLogin and search-based selection can
be used universally.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Gate search-based reviewer selection on both state.ActorReviewers
and the search function being available, consistent with the
ActorAssignees pattern used for assignees.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Consolidate duplicated INSUFFICIENT_SCOPES error handling into a single
implementation. The project queries package now calls
api.GenerateScopeErrorForGQL instead of reimplementing the same logic.
Removes duplicated requiredScopesFromServerMessage, scopesRE, and the
associated test (already covered by api/client_test.go).
Fixes#12823