Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
245 commits
Select commit Hold shift + click to select a range
3573f61
Add agent-task command with OAuth token validation
BagToad Aug 27, 2025
2128a29
Show help on agent-task command execution
BagToad Aug 27, 2025
1bc2710
Refactor test to use require.Empty assertion
BagToad Aug 27, 2025
b939188
Refactor agent task tests into table-driven format
BagToad Aug 27, 2025
09be17e
Merge pull request #11600 from cli/kw/997-gh-agent-task-responds-and-…
BagToad Aug 27, 2025
dd424d8
Add agent task listing command and CAPI client
BagToad Aug 27, 2025
0de5cf2
Fix import alias for shared package in agent-task list
BagToad Aug 29, 2025
0a5b78a
Refactor session filtering in listRun function
BagToad Aug 29, 2025
7b71b5f
Refactor agent-task list command client initialization
BagToad Aug 29, 2025
4801206
Remove commented-out fields from sessionPullRequest
BagToad Aug 29, 2025
13c293f
Refactor variable names in ListSessionsForViewer
BagToad Aug 29, 2025
bc1d306
Update API query name for session PR fetch
BagToad Aug 29, 2025
5281be4
Refactor error handling in generatePullRequestNodeID
BagToad Aug 29, 2025
ea9dfae
Optimize session pull request hydration logic
BagToad Aug 29, 2025
4fd6ae6
Refactor session state color logic to shared package
BagToad Aug 29, 2025
c10ac8a
Merge pull request #11606 from cli/kw/1001-gh-agent-task-list-respond…
BagToad Aug 29, 2025
e750e71
Add repo-scoped agent session listing support
BagToad Aug 29, 2025
a49994d
Add limit flag to agent-task list command
BagToad Aug 29, 2025
83c597f
Show default limit in agent-task list flag help
BagToad Aug 29, 2025
a2d75d1
Add --web flag to agent-task list command
BagToad Aug 30, 2025
3197193
Handle repo resolution errors gracefully in agent-task list
BagToad Aug 30, 2025
ffc8792
Merge branch 'kw/1002-gh-agent-task-list-respects-cwd-repo-and---repo…
BagToad Aug 30, 2025
61c8b5e
Merge branch 'kw/1003-gh-agent-task-list-respects--l--limit' into kw/…
BagToad Aug 30, 2025
97da7fc
Simplify BaseRepo assignment in list command
BagToad Sep 2, 2025
4a07cdf
Simplify time calculation in listRun test
BagToad Sep 2, 2025
227f0bd
Add comment explaining error handling in listRun
BagToad Sep 2, 2025
163eb7e
Return NoResultsError when no agent tasks found
BagToad Sep 2, 2025
51aa033
Add test case for negative limit in list command
BagToad Sep 2, 2025
93f7e98
Add comment on web dashboard filtering limitation
BagToad Sep 2, 2025
c4c0ddc
Add test for web mode with repo flag in listRun
BagToad Sep 2, 2025
c5f7be9
Replace panic with require.FailNow in test
BagToad Sep 2, 2025
0dcf0c6
Merge pull request #11619 from cli/kw/1002-gh-agent-task-list-respect…
BagToad Sep 2, 2025
68af5cc
Merge pull request #11620 from cli/kw/1003-gh-agent-task-list-respect…
BagToad Sep 2, 2025
fca5e0c
Merge pull request #11621 from cli/kw/1004-gh-agent-task-list-respect…
BagToad Sep 2, 2025
2a99dcd
Add pager support to agent-task list output
BagToad Sep 2, 2025
3574ee9
Add agent task creation command and job API
BagToad Sep 2, 2025
d39c8c2
Merge pull request #11651 from cli/kw/agent-task-list-pager
babakks Sep 3, 2025
a3fa830
Update agent-task create command argument handling
BagToad Sep 3, 2025
a81cff3
Update command usage for agent task creation
BagToad Sep 3, 2025
3a7465e
Remove redundant 'error:' prefix from repo error
BagToad Sep 3, 2025
2bec2bc
Update error message in createRun test
BagToad Sep 3, 2025
3d8d5f3
Update test to expect 500 error response
BagToad Sep 3, 2025
c3bbd37
Remove nil check for job in agentSessionWebURL
BagToad Sep 3, 2025
33d1196
Escape URL path segments in agent session links
BagToad Sep 3, 2025
b890f88
Escape owner and repo in job creation URL
BagToad Sep 3, 2025
9ec10a4
Escape URL path parameters in GetJob request
BagToad Sep 3, 2025
5472fcf
Use Job struct in request
BagToad Sep 3, 2025
32bf915
Improve job error handling and update tests
BagToad Sep 3, 2025
44e81b0
Simplify stdout assertion in createRun test
BagToad Sep 3, 2025
21ccabc
Simplify error handling in CreateJob response
BagToad Sep 3, 2025
a821b40
Update error messages and test repo handling in agent-task create
BagToad Sep 3, 2025
6a50ecb
Merge pull request #11653 from cli/1013-gh-agent-task-create-creates-…
BagToad Sep 3, 2025
b94ffe9
Add file input support to agent-task create command
BagToad Sep 3, 2025
9dfe89f
Increase backoff timing for agent task creation
BagToad Sep 3, 2025
8af1787
Support reading task description from stdin
BagToad Sep 3, 2025
b2f506f
Add base branch option to agent task creation
BagToad Sep 3, 2025
3c3b566
Refactor test case struct in create_test.go
BagToad Sep 3, 2025
fdc74cd
Merge pull request #11658 from cli/kw/1016-gh-agent-task-create-respe…
babakks Sep 4, 2025
90cb805
Merge pull request #11657 from cli/kw/1015-gh-agent-task-create-respe…
babakks Sep 4, 2025
28a7dae
Improve agent-task create command help text
BagToad Sep 4, 2025
ad79b90
Merge pull request #11665 from cli/kw/11657-11658-pr-feedback
BagToad Sep 4, 2025
107edc3
fix(agent-task/shared): add `CapiClientFunc` helper
babakks Sep 3, 2025
f3c3797
refactor(agent-task list): use shared `CapiClientFunc`
babakks Sep 3, 2025
0138bf3
refactor(agent-task/capi): improve pagination
babakks Sep 4, 2025
77bb72c
fix(agent-task/capi): improve returned errs
babakks Sep 4, 2025
0f5fd6e
fix(agent-task/capi): handle non-JSON error response
babakks Sep 4, 2025
79602d3
test(agent-task/capi): add tests for session-related methods
babakks Sep 4, 2025
be8e6f6
test(agent-task/capi): add tests for job-related methods
babakks Sep 4, 2025
ab99ee5
test(agent-task/capi): add `go:generate` directive to gen mock
babakks Sep 4, 2025
585b639
test(agent-task/capi): add `CapiClientMock`
babakks Sep 4, 2025
19e17c5
refactor(agent-task/capi): drop embedding of unexported struct
babakks Sep 4, 2025
27d9a0d
test(agent-task list): update `TestNewCmdList`
babakks Sep 4, 2025
c708e58
test(agent-task list): use `CapiClientMock`
babakks Sep 4, 2025
3762d97
test(agent-task list): apply test args anyway
babakks Sep 4, 2025
b0ac06e
fix(agent-task create): allow no positional arg
babakks Sep 4, 2025
d17fdb3
test(agent-task list): update `TestNewCmdCreate`
babakks Sep 4, 2025
28bb0f6
fix(agent-task create): simplify command initialisation
babakks Sep 4, 2025
07ec8c6
test(agent-task create): use `CapiClientMock`
babakks Sep 4, 2025
844c0ab
refactor(agent-task create): remove redundant `if`
babakks Sep 4, 2025
7824b43
refactor(agent-task list): simplify cmd initialisation
babakks Sep 4, 2025
004be9d
test(agent-task create): quote file paths to pass CI on Windows
babakks Sep 5, 2025
1e36e9f
refactor(agent-task/capi): hydrate user data
babakks Sep 5, 2025
4e1fcf1
refactor(agent-task/capi): populate PRs `IsDraft`
babakks Sep 5, 2025
dcadeb7
feat(agent-task/capi): add `GetSession` method
babakks Sep 5, 2025
ee8fc06
test(agent-task/capi): add tests for `GetSession`
babakks Sep 5, 2025
87b772d
feat(agent-task/capi): add `GetSession` method to `CapiClient` interface
babakks Sep 5, 2025
476b636
test(agent-task list): remove unused `stubs`
babakks Sep 5, 2025
92c7a56
feat(agent-task view): add `view` command
babakks Sep 5, 2025
d3fa0a7
test(agent-task view): add tests for the `view` command
babakks Sep 5, 2025
a1dbafe
Merge pull request #11668 from cli/babakks/refactor-agent-task-tests
BagToad Sep 5, 2025
a6dd9c1
feat(agent-task/capi): add `ListSessionsByResourceID`
babakks Sep 5, 2025
9b2ecf4
feat(agent-task/capi): add `ListSessionsByResourceID` method to `Capi…
babakks Sep 5, 2025
fd11b1e
fix(pr/shared): add `ParseFullReference` func
babakks Sep 5, 2025
a769175
test(pr/shared): add test for `ParseFullReference`
babakks Sep 5, 2025
5f6189b
fix(agent-task/shared): add `IsSessionID`
babakks Sep 5, 2025
09e1f25
test(agent-task/shared): add test for `IsSessionID`
babakks Sep 5, 2025
e68e28d
fix(agent-task/shared): add `SessionSymbol` func
babakks Sep 5, 2025
8482e3d
feat(agent-task view): support PR arg
babakks Sep 5, 2025
d80b25f
test(agent-task/capi): add tests for `GetSessionByResourceID`
babakks Sep 8, 2025
f57114a
feat(agent-task/capi): add `GetPullRequestDatabaseID` method
babakks Sep 8, 2025
abd2d8a
test(agent-task/capi): add tests for `GetPullRequestDatabaseID`
babakks Sep 8, 2025
f8f7b0e
fix(agent-task/capi): add `GetPullRequestDatabaseID` to `CapiClient` …
babakks Sep 8, 2025
c1beeb5
fix(agent-task view): use `CapiClient.GetPullRequestDatabaseID`
babakks Sep 8, 2025
d06d026
fix(agent-task view): use lower limit for fetching sessions
babakks Sep 8, 2025
6e78b8d
test(agent-task view): update tests
babakks Sep 8, 2025
9228433
docs(agent-task/shared): add godoc to `SessionStateString`
babakks Sep 9, 2025
d52502b
fix(agent-task/capi): skip unpopulated resource ID when hydrating
babakks Sep 9, 2025
0a9a4a4
test(agent-task/capi): fix test case args
babakks Sep 9, 2025
8b1f722
docs(agent-task/capi): remove redundant comment
babakks Sep 9, 2025
751af8a
Merge pull request #11670 from cli/babakks/add-agent-task-view-cmd
babakks Sep 9, 2025
f8ff42a
docs(agent-task view): explain when condition is met
babakks Sep 9, 2025
ec8f412
docs(agent-task view): explain test case rationale
babakks Sep 9, 2025
f9617d9
Merge pull request #11674 from cli/babakks/add-pr-number-arg-support-…
BagToad Sep 9, 2025
bbf7586
Show session name instead of ID in agent-task list
BagToad Sep 9, 2025
52b85a1
Merge pull request #11699 from cli/kw/use-agent-session-name
BagToad Sep 9, 2025
1f107ce
Fix default value in session selection prompt
BagToad Sep 9, 2025
24fc5df
Merge pull request #11701 from cli/kw/agent-task-view-improper-default
BagToad Sep 9, 2025
5638093
Add interactive prompt for task description in agent-task create
BagToad Sep 9, 2025
6945fc0
Still prompt for task desc with -F
BagToad Sep 9, 2025
6b29c29
fix(agent-task/capi): also return PR URL from `GetPullRequestDatabaseID`
babakks Sep 10, 2025
ab7e403
refactor: move Copilot Agents home URL to capi
babakks Sep 10, 2025
57d9f1f
feat(agent-task view): add `--web` mode
babakks Sep 10, 2025
ecbad7e
test(agent-task view): add `--web` mode tests
babakks Sep 10, 2025
b3b8697
test(agent-task view): enhance naming and stubs
babakks Sep 10, 2025
88e2d0d
fix(agent-task view): stop progress indicator before opening browser
babakks Sep 10, 2025
b463395
fix(agent-task create): only prompt for problem statement if not prov…
babakks Sep 10, 2025
4cebd35
refactor(agent-task create): assign `Config` at instantiation
babakks Sep 10, 2025
6a54813
docs(agent-task view): improve `--help` docs
babakks Sep 10, 2025
7763060
Merge pull request #11700 from cli/kw/1017-gh-agent-task-create-promp…
BagToad Sep 10, 2025
20c8904
Merge pull request #11704 from cli/babakks/add-web-flag-to-view-cmd
BagToad Sep 10, 2025
78b09e5
fix(pr/shared): add rest return value to `ParseURL`
babakks Sep 10, 2025
7e21837
fix(agent-task/shared): add `ParsePullRequestAgentSessionURL`
babakks Sep 10, 2025
3798d98
feat(agent-task view): support PR `/agent-sessions/*` URL as argument
babakks Sep 10, 2025
6b87292
refactor(agent-task view): rename `resourceID` to `prID`
babakks Sep 10, 2025
b079ea8
refactor(agent-task/shared): extract uuid pattern
babakks Sep 10, 2025
2311a04
fix(pr/shared): ensure `ParseURL` regexp is backward-compatible
babakks Sep 10, 2025
c0a5b9a
Refactor agent-task create to improve file input handling
BagToad Sep 11, 2025
deee0c6
Update command examples for agent-task create
BagToad Sep 11, 2025
1c37ab9
refactor(agent-task/shared): enhance symbol names
babakks Sep 11, 2025
10e4abc
refactor(pr/shared): rename `rest` to `tail`
babakks Sep 11, 2025
bfa0975
Merge pull request #11707 from cli/babakks/accept-agent-sessions-url-…
babakks Sep 11, 2025
872cf49
Refactor create command tests and add base branch case
BagToad Sep 11, 2025
666f557
Remove unused stdin field from create command tests
BagToad Sep 11, 2025
f22dc92
Update test to use edited task description
BagToad Sep 11, 2025
1dbb694
Add test for non-interactive problem statement input
BagToad Sep 11, 2025
3831380
Add error type assertion to createRun tests
BagToad Sep 11, 2025
48cf448
Merge pull request #11708 from cli/kw/edit-file-and-prompt-for-confir…
BagToad Sep 11, 2025
fbcdeed
feat(agent-task/capi): add `GetSessionLogs` method
babakks Sep 11, 2025
05e609c
fix(agent-task/shared): add log renderer
babakks Sep 12, 2025
1ccbb0a
feat(agent-task view): add `--log` and `--follow` flags
babakks Sep 12, 2025
1155e83
feat(agent-task view): add `--log` and `--follow` flags
babakks Sep 12, 2025
0fb10fc
Various log rendering improvements
BagToad Sep 12, 2025
9e16a82
Refactor JSON content rendering in log entries
BagToad Sep 12, 2025
ec3fce0
Improve log rendering and tool call handling
BagToad Sep 12, 2025
718c462
Refactor markdown rendering helper function names
BagToad Sep 15, 2025
3829cff
Rename relativePath to relativeFilePath in log rendering
BagToad Sep 15, 2025
282a25f
Rename renderToolCall to renderToolCallTitle
BagToad Sep 15, 2025
6bbb5c4
Update log test expectation files
BagToad Sep 15, 2025
e5e7bc8
Add and improve function documentation in log.go
BagToad Sep 15, 2025
ab796c8
Fix comment for GetSessionLogs method
BagToad Sep 15, 2025
0b5a049
Make log tests OS-agnostic by normalizing line endings
BagToad Sep 15, 2025
87d8d83
Add note for updating testdata files in log tests
BagToad Sep 15, 2025
62d7a75
Fix line ending conversion in tests
BagToad Sep 15, 2025
f33ef42
Normalize line endings in log testdata files too
BagToad Sep 15, 2025
2c68168
Rename testdata log files for clarity
BagToad Sep 15, 2025
887e842
Enable Bash session tool handling in log rendering
BagToad Sep 15, 2025
77509fc
Update comment for reasoning text formatting
BagToad Sep 15, 2025
f779a3d
Add TODO for bash-related tool call details
BagToad Sep 15, 2025
a0696dd
Merge pull request #11743 from cli/kw-bs/1012-gh-agent-task-view-resp…
babakks Sep 16, 2025
134ae31
refactor(agent-task create): extract session URL polling into a func
babakks Sep 16, 2025
4f7d577
feat(agent-task create): add `--follow` flag
babakks Sep 16, 2025
f5ed563
docs(agent-task create): add example for `--follow` flag
babakks Sep 16, 2025
dab285c
test(agent-task create): add test for `--follow`
babakks Sep 16, 2025
4d9038a
Add pager support to log output in printLogs
BagToad Sep 16, 2025
37d8e0a
Refactor generic tool call titles map to package scope
BagToad Sep 16, 2025
d636f4c
Clarify comment on CRLF normalization in tests
BagToad Sep 16, 2025
97d3253
Prefix rendered shell commands with '$ ' in logs
BagToad Sep 16, 2025
65b45ad
Improve log rendering error handling and test coverage
BagToad Sep 16, 2025
c0a2648
Use filepath.Ext to detect file extension in markdown renderer
BagToad Sep 16, 2025
b3401ff
Refactor stripDiffFormat guard clause logic
BagToad Sep 16, 2025
c55003b
Merge pull request #11746 from cli/babakks/add-follow-option-to-agent…
BagToad Sep 17, 2025
6eafe96
Merge pull request #11752 from cli/kw/run-view-pr-feedback
babakks Sep 17, 2025
5b9d6ae
fix(pr/shared): add `DisableProgress` field to `FindOptions`
babakks Sep 17, 2025
1f5cbc5
test(pr/shared): assert `FindOptions.DisableProgress` is respected
babakks Sep 17, 2025
897c2b1
fix(agent-task view): disable PR finder progress indicator
babakks Sep 17, 2025
87b310a
fix(agent-task view): display completed sessions as "Ready for review"
babakks Sep 17, 2025
49ba21a
fix(agent-task view): display session duration
babakks Sep 17, 2025
fe95cd8
fix(agent-task/capi): add `PremiumRequests` field to `Session`
babakks Sep 17, 2025
99a6161
fix(agent-task view): display premium requests used
babakks Sep 17, 2025
661817d
fix(agent-task view): omit session overview in log mode
babakks Sep 17, 2025
f6b4985
Remove obsolete log-3 test data files
BagToad Sep 17, 2025
25c0d0c
Refactor comments in stripDiffFormat function
BagToad Sep 17, 2025
0c3171c
Merge pull request #11756 from cli/kw/pr-feedback-for-11752
BagToad Sep 17, 2025
40a5907
Enhance agent-task command help and usage info
BagToad Sep 18, 2025
562efc9
Update pkg/cmd/agent-task/agent_task.go
BagToad Sep 18, 2025
7d2dfd3
Update pkg/cmd/agent-task/agent_task.go
BagToad Sep 18, 2025
6927d64
fix(agent-task/shared): make capitalised status names consistent
babakks Sep 18, 2025
f0a0c4b
fix(agent-task view): display zero premium requests
babakks Sep 18, 2025
6f69840
docs(pr/shared): add a `TODO` on decoupling PR finder from IO
babakks Sep 18, 2025
151b971
Merge pull request #11755 from cli/babakks/polish-agent-task-view
babakks Sep 18, 2025
a7c8fa4
docs(agent-task): use `heredoc.Doc`
babakks Sep 18, 2025
c02a8d8
Merge pull request #11760 from cli/kw/update-gh-agent-root-cmd-help
babakks Sep 18, 2025
680ebad
Remove repo-scoped session listing and related code
BagToad Sep 17, 2025
08bc1a8
Fix session deduplication and add test for paging
BagToad Sep 18, 2025
6ec4324
docs(agent-task/capi): fix test case explanation
babakks Sep 18, 2025
5f73d3b
refactor(agent-task list): remove unused `BaseRepo` from `ListOptions`
babakks Sep 18, 2025
c68d1a3
fix(agent-task/capi): keep sessions with no resource attached
babakks Sep 18, 2025
6235c33
test(agent-task/capi): assert session with zero resource ID are kept
babakks Sep 18, 2025
169f45d
chore(agent-task/shared): regenerate `LogRenderer` mock
babakks Sep 18, 2025
7d163ea
docs(agent-task list): add "(preview)" note to cmd docs
babakks Sep 18, 2025
7643768
fix(agent-task/shared): fix session state value
babakks Sep 18, 2025
4a0c32e
fix(agent-task list): show capitalised session state
babakks Sep 18, 2025
2116327
Merge pull request #11758 from cli/kw/agent-list-polish
babakks Sep 18, 2025
cb9808f
fix(agent-task create): avoid prompting when problem statement is pro…
babakks Sep 18, 2025
c7a811e
fix(agent-task create): use pager when following logs
babakks Sep 18, 2025
863329b
fix(agent-task create): block empty problem statement arg
babakks Sep 18, 2025
3ed9034
fix(agent-task/capi): add `Error` field to `Session`
babakks Sep 18, 2025
b6816ad
refactor(agent-task/capi): remove unused slice
babakks Sep 18, 2025
e5739cc
fix(agent-task/capi): add `WorkflowRunID` field to `Session`
babakks Sep 18, 2025
beba8f6
fix(agent-task view): display session error
babakks Sep 18, 2025
123c9ea
fix(agent-task view): improve session error
babakks Sep 18, 2025
03f4b77
Merge pull request #11762 from cli/babakks/remove-prompt-from-agent-t…
BagToad Sep 18, 2025
185e36c
update agents resource route
mntlty Sep 18, 2025
546ab1c
refactor(agent-task/capi): keep `resource` private
babakks Sep 19, 2025
9148f41
fix(agent-task/capi): handle unpopulated resource session `LastUpdate…
babakks Sep 19, 2025
a108b4e
fix(agent-task/capi): fetch viewer when resource session user id is zero
babakks Sep 19, 2025
2fe60d9
docs(agent-task/capi): add TODO note for dropping local ID generation
babakks Sep 19, 2025
eba3134
test(agent-tassk/capi): update `ListSessionsByResourceID` tests
babakks Sep 19, 2025
597cdaf
fix(agent-task/capi): remove fallback to viewer when user id is zero
babakks Sep 19, 2025
bba12f8
Merge pull request #11770 from cli/mntlty/update-session
babakks Sep 19, 2025
3091c21
fix(agent-task view): re-fetch session to get all pieces of data
babakks Sep 19, 2025
3e43a98
refactor(agent-task view): merge empty println calls with next
babakks Sep 19, 2025
ecfbb67
fix(agent-task view): improve session overview
babakks Sep 19, 2025
eb3c842
test(agent-task view): populate `Session.Name` in all test cases
babakks Sep 19, 2025
002ba54
Merge pull request #11763 from cli/babakks/display-session-error
babakks Sep 22, 2025
6fc5742
fix(agent-task/capi): return proper error message when resp is not a …
babakks Sep 22, 2025
ecb236b
Merge pull request #11783 from cli/babakks/display-proper-error-in-ag…
babakks Sep 22, 2025
3ba03e3
add initiator_type for attestations
ejahnGithub Sep 23, 2025
9e54a62
Update pkg/cmd/attestation/api/client.go
ejahnGithub Sep 23, 2025
8d701dc
update the test
ejahnGithub Sep 23, 2025
8818c0d
chore: update third-party licenses
babakks Sep 23, 2025
e673dfe
Add TODO for better integer handling in GetPullRequestDatabaseID
BagToad Sep 23, 2025
8c75079
Add math package import to sessions.go
BagToad Sep 23, 2025
4b02071
Merge pull request #11796 from cli/eugeene/release_filter_initiator_type
ejahnGithub Sep 23, 2025
7ff84cf
Merge pull request #11797 from cli/github-cli-epic-990
BagToad Sep 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions api/queries_pr.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ type PullRequest struct {
MergedBy *Author
HeadRepositoryOwner Owner
HeadRepository *PRRepository
Repository *PRRepository
IsCrossRepository bool
IsDraft bool
MaintainerCanModify bool
Expand Down Expand Up @@ -251,8 +252,9 @@ type Workflow struct {
}

type PRRepository struct {
ID string `json:"id"`
Name string `json:"name"`
ID string `json:"id"`
Name string `json:"name"`
NameWithOwner string `json:"nameWithOwner"`
}

type AutoMergeRequest struct {
Expand Down
7 changes: 4 additions & 3 deletions api/queries_repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,10 @@ type RepositoryOwner struct {
}

type GitHubUser struct {
ID string `json:"id"`
Login string `json:"login"`
Name string `json:"name"`
ID string `json:"id"`
Login string `json:"login"`
Name string `json:"name"`
DatabaseID int64 `json:"databaseId"`
}

// Actor is a superset of User and Bot, among others.
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ require (
github.com/spf13/pflag v1.0.7
github.com/stretchr/testify v1.11.0
github.com/theupdateframework/go-tuf/v2 v2.1.1
github.com/vmihailenco/msgpack/v5 v5.4.1
github.com/yuin/goldmark v1.7.13
github.com/zalando/go-keyring v0.2.6
golang.org/x/crypto v0.41.0
Expand Down Expand Up @@ -205,6 +206,7 @@ require (
github.com/transparency-dev/merkle v0.0.2 // indirect
github.com/transparency-dev/tessera v0.2.1-0.20250610150926-8ee4e93b2823 // indirect
github.com/vbatts/tar-split v0.12.1 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
github.com/yuin/goldmark-emoji v1.0.6 // indirect
github.com/zeebo/errs v1.4.0 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1417,6 +1417,10 @@ github.com/transparency-dev/tessera v0.2.1-0.20250610150926-8ee4e93b2823 h1:s3p7
github.com/transparency-dev/tessera v0.2.1-0.20250610150926-8ee4e93b2823/go.mod h1:Jv2IDwG1q8QNXZTaI1X6QX8s96WlJn73ka2hT1n4N5c=
github.com/vbatts/tar-split v0.12.1 h1:CqKoORW7BUWBe7UL/iqTVvkTBOF8UvOMKOIZykxnnbo=
github.com/vbatts/tar-split v0.12.1/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA=
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
100 changes: 100 additions & 0 deletions pkg/cmd/agent-task/agent_task.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package agent

import (
"errors"
"fmt"
"strings"

"github.com/MakeNowJust/heredoc"
cmdCreate "github.com/cli/cli/v2/pkg/cmd/agent-task/create"
cmdList "github.com/cli/cli/v2/pkg/cmd/agent-task/list"
cmdView "github.com/cli/cli/v2/pkg/cmd/agent-task/view"
"github.com/cli/cli/v2/pkg/cmdutil"
"github.com/cli/go-gh/v2/pkg/auth"
"github.com/spf13/cobra"
)

// NewCmdAgentTask creates the base `agent-task` command.
func NewCmdAgentTask(f *cmdutil.Factory) *cobra.Command {
cmd := &cobra.Command{
Use: "agent-task <command>",
Aliases: []string{"agent-tasks", "agent", "agents"},
Short: "Work with agent tasks (preview)",
Long: heredoc.Doc(`
Working with agent tasks in the GitHub CLI is in preview and
subject to change without notice.
`),
Annotations: map[string]string{
"help:arguments": heredoc.Doc(`
A task can be identified as argument in any of the following formats:
- by pull request number, e.g. "123"; or
- by session ID, e.g. "12345abc-12345-12345-12345-12345abc"; or
- by URL, e.g. "https://github.com/OWNER/REPO/pull/123/agent-sessions/12345abc-12345-12345-12345-12345abc";

Identifying tasks by pull request is not recommended for non-interactive use cases as
there may be multiple tasks for a given pull request that require disambiguation.
`),
},
Example: heredoc.Doc(`
# List your most recent agent tasks
$ gh agent-task list

# Create a new agent task on the current repository
$ gh agent-task create "Improve the performance of the data processing pipeline"

# View details about agent tasks associated with a pull request
$ gh agent-task view 123

# View details about a specific agent task
$ gh agent-task view 12345abc-12345-12345-12345-12345abc
`),
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
return requireOAuthToken(f)
},
// This is required to run this root command. We want to
// run it to test PersistentPreRunE behavior.
RunE: func(cmd *cobra.Command, args []string) error {
return cmd.Help()
},
}

// register subcommands
cmd.AddCommand(cmdList.NewCmdList(f, nil))
cmd.AddCommand(cmdCreate.NewCmdCreate(f, nil))
cmd.AddCommand(cmdView.NewCmdView(f, nil))

return cmd
}

// requireOAuthToken ensures an OAuth (device flow) token is present and valid.
// agent-task subcommands inherit this check via PersistentPreRunE.
func requireOAuthToken(f *cmdutil.Factory) error {
cfg, err := f.Config()
if err != nil {
return err
}

authCfg := cfg.Authentication()
host, _ := authCfg.DefaultHost()
if host == "" {
return errors.New("no default host configured; run 'gh auth login'")
}

if auth.IsEnterprise(host) {
return errors.New("agent tasks are not supported on this host")
}

token, source := authCfg.ActiveToken(host)

// Tokens from sources "oauth_token" and "keyring" are likely
// minted through our device flow.
tokenSourceIsDeviceFlow := source == "oauth_token" || source == "keyring"
// Tokens with "gho_" prefix are OAuth tokens.
tokenIsOAuth := strings.HasPrefix(token, "gho_")

// Reject if the token is not from a device flow source or is not an OAuth token
if !tokenSourceIsDeviceFlow || !tokenIsOAuth {
return fmt.Errorf("this command requires an OAuth token. Re-authenticate with: gh auth login")
}
return nil
}
149 changes: 149 additions & 0 deletions pkg/cmd/agent-task/agent_task_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
package agent

import (
"testing"

"github.com/cli/cli/v2/internal/config"
"github.com/cli/cli/v2/internal/gh"
ghmock "github.com/cli/cli/v2/internal/gh/mock"
"github.com/cli/cli/v2/pkg/cmdutil"
"github.com/cli/cli/v2/pkg/iostreams"
"github.com/stretchr/testify/require"
)

// setupMockOAuthConfig configures a blank config with a default host and optional token behavior.
func setupMockOAuthConfig(t *testing.T, tokenSource string) gh.Config {
t.Helper()
c := config.NewBlankConfig()
switch tokenSource {
case "oauth_token":
// valid OAuth device flow token stored in config
c.Set("github.com", "oauth_token", "gho_OAUTH123")
case "keyring":
// valid OAuth device flow token stored in keyring
c.Set("github.com", "oauth_token", "gho_OAUTH123")
case "GH_TOKEN":
// classic style token stored in config (will fail prefix check)
c.Set("github.com", "oauth_token", "ghp_CLASSIC123")
case "GH_ENTERPRISE_TOKEN":
// enterprise style token stored in config (will fail prefix check)
c.Set("something.ghes.com", "oauth_token", "ghe_ENTERPRISE123")
}
return c
}

func TestNewCmdAgentTask(t *testing.T) {
tests := []struct {
name string
tokenSource string
customConfig func() (gh.Config, error)
wantErr bool
wantErrContains string
wantStdout string
}{
{
name: "oauth token is accepted",
tokenSource: "oauth_token",
wantErr: false,
wantStdout: "",
},
{
name: "keyring oauth token is accepted",
tokenSource: "keyring",
wantErr: false,
wantStdout: "",
},
{
name: "env var token is rejected",
tokenSource: "GH_TOKEN",
wantErr: true,
wantErrContains: "requires an OAuth token",
},
{
name: "enterprise token alone is ignored and rejected",
tokenSource: "GH_ENTERPRISE_TOKEN",
wantErr: true,
},
{
name: "github.com oauth is accepted and enterprise token ignored",
customConfig: func() (gh.Config, error) {
c := config.NewBlankConfig()
c.Set("something.ghes.com", "oauth_token", "ghe_ENTERPRISE123")
c.Set("github.com", "oauth_token", "gho_OAUTH123")
return c, nil
},
wantErr: false,
wantStdout: "",
},
{
name: "enterprise host is rejected",
customConfig: func() (gh.Config, error) {
return &ghmock.ConfigMock{
AuthenticationFunc: func() gh.AuthConfig {
c := &config.AuthConfig{}
c.SetDefaultHost("something.ghes.com", "GH_HOST")
return c
},
}, nil
},
wantErr: true,
wantErrContains: "not supported on this host",
},
{
name: "empty host is rejected",
customConfig: func() (gh.Config, error) {
return &ghmock.ConfigMock{
AuthenticationFunc: func() gh.AuthConfig {
c := &config.AuthConfig{}
c.SetDefaultHost("", "GH_HOST")
return c
},
}, nil
},
wantErr: true,
wantErrContains: "no default host configured",
},
{
name: "no auth is rejected",
tokenSource: "",
wantErr: true,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
f := &cmdutil.Factory{}
ios, _, stdout, _ := iostreams.Test()
f.IOStreams = ios
if tt.customConfig != nil {
f.Config = tt.customConfig
} else {
f.Config = func() (gh.Config, error) { return setupMockOAuthConfig(t, tt.tokenSource), nil }
}

cmd := NewCmdAgentTask(f)
err := cmd.Execute()

if tt.wantErr {
require.Error(t, err)
if tt.wantErrContains != "" {
require.Contains(t, err.Error(), tt.wantErrContains)
}
} else {
require.NoError(t, err)
require.Equal(t, tt.wantStdout, stdout.String())
}
})
}
}

func TestAliasAreSet(t *testing.T) {
f := &cmdutil.Factory{}
ios, _, _, _ := iostreams.Test()
f.IOStreams = ios
f.Config = func() (gh.Config, error) { return setupMockOAuthConfig(t, "oauth_token"), nil }

cmd := NewCmdAgentTask(f)

require.ElementsMatch(t, []string{"agent-tasks", "agent", "agents"}, cmd.Aliases)
}
72 changes: 72 additions & 0 deletions pkg/cmd/agent-task/capi/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package capi

import (
"context"
"net/http"

"github.com/cli/cli/v2/internal/gh"
)

//go:generate moq -rm -out client_mock.go . CapiClient

const baseCAPIURL = "https://api.githubcopilot.com"
const capiHost = "api.githubcopilot.com"

// CapiClient defines the methods used by the caller. Implementations
// may be replaced with test doubles in unit tests.
type CapiClient interface {
ListLatestSessionsForViewer(ctx context.Context, limit int) ([]*Session, error)
CreateJob(ctx context.Context, owner, repo, problemStatement, baseBranch string) (*Job, error)
GetJob(ctx context.Context, owner, repo, jobID string) (*Job, error)
GetSession(ctx context.Context, id string) (*Session, error)
GetSessionLogs(ctx context.Context, id string) ([]byte, error)
ListSessionsByResourceID(ctx context.Context, resourceType string, resourceID int64, limit int) ([]*Session, error)
GetPullRequestDatabaseID(ctx context.Context, hostname string, owner string, repo string, number int) (int64, string, error)
}

// CAPIClient is a client for interacting with the Copilot API
type CAPIClient struct {
httpClient *http.Client
authCfg gh.AuthConfig
}

// NewCAPIClient creates a new CAPI client. Provide a token and an HTTP client which
// will be used as the base transport for CAPI requests.
//
// The provided HTTP client will be mutated for use with CAPI, so it should not
// be reused elsewhere.
func NewCAPIClient(httpClient *http.Client, authCfg gh.AuthConfig) *CAPIClient {
host, _ := authCfg.DefaultHost()
token, _ := authCfg.ActiveToken(host)

httpClient.Transport = newCAPITransport(token, httpClient.Transport)
return &CAPIClient{
httpClient: httpClient,
authCfg: authCfg,
}
}

// capiTransport adds the Copilot auth headers
type capiTransport struct {
rp http.RoundTripper
token string
}

func newCAPITransport(token string, rp http.RoundTripper) *capiTransport {
return &capiTransport{
rp: rp,
token: token,
}
}

func (ct *capiTransport) RoundTrip(req *http.Request) (*http.Response, error) {
req.Header.Set("Authorization", "Bearer "+ct.token)

// Since this RoundTrip is reused for both Copilot API and
// GitHub API requests, we conditionally add the integration
// ID only when performing requests to the Copilot API.
if req.URL.Host == capiHost {
req.Header.Add("Copilot-Integration-Id", "copilot-4-cli")
}
return ct.rp.RoundTrip(req)
}
Loading
Loading