Add --web flag to agent-task list command

Introduces a --web flag to the agent-task list command, allowing users to open the agent tasks page in their browser. Updates tests to cover the new flag and browser interaction.
This commit is contained in:
Kynan Ware 2025-08-29 18:21:47 -06:00
parent 83c597ff53
commit a2d75d12f6
2 changed files with 71 additions and 16 deletions

View file

@ -5,9 +5,11 @@ import (
"fmt"
"time"
"github.com/cli/cli/v2/internal/browser"
"github.com/cli/cli/v2/internal/gh"
"github.com/cli/cli/v2/internal/ghrepo"
"github.com/cli/cli/v2/internal/tableprinter"
"github.com/cli/cli/v2/internal/text"
"github.com/cli/cli/v2/pkg/cmd/agent-task/capi"
"github.com/cli/cli/v2/pkg/cmd/agent-task/shared"
prShared "github.com/cli/cli/v2/pkg/cmd/pr/shared"
@ -25,14 +27,17 @@ type ListOptions struct {
Limit int
CapiClient func() (*capi.CAPIClient, error)
BaseRepo func() (ghrepo.Interface, error)
Web bool
Browser browser.Browser
}
// NewCmdList creates the list command
func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Command {
opts := &ListOptions{
IO: f.IOStreams,
Config: f.Config,
Limit: defaultLimit,
IO: f.IOStreams,
Config: f.Config,
Limit: defaultLimit,
Browser: f.Browser,
}
cmd := &cobra.Command{
@ -59,6 +64,7 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman
}
cmd.Flags().IntVarP(&opts.Limit, "limit", "L", defaultLimit, fmt.Sprintf("Maximum number of agent tasks to fetch (default %d)", defaultLimit))
cmd.Flags().BoolVarP(&opts.Web, "web", "w", false, "Open agent tasks in the browser")
opts.CapiClient = func() (*capi.CAPIClient, error) {
cfg, err := opts.Config()
@ -77,6 +83,14 @@ func NewCmdList(f *cmdutil.Factory, runF func(*ListOptions) error) *cobra.Comman
}
func listRun(opts *ListOptions) error {
if opts.Web {
const webURL = "https://github.com/copilot/agents"
if opts.IO.IsStdoutTTY() {
fmt.Fprintf(opts.IO.ErrOut, "Opening %s in your browser.\n", text.DisplayURL(webURL))
}
return opts.Browser.Browse(webURL)
}
if opts.Limit <= 0 {
opts.Limit = defaultLimit
}

View file

@ -8,6 +8,7 @@ import (
"time"
"github.com/MakeNowJust/heredoc"
"github.com/cli/cli/v2/internal/browser"
"github.com/cli/cli/v2/internal/config"
"github.com/cli/cli/v2/internal/gh"
"github.com/cli/cli/v2/internal/ghrepo"
@ -44,6 +45,14 @@ func TestNewCmdList(t *testing.T) {
args: "--limit 0",
wantErr: "invalid limit: 0",
},
{
name: "web flag",
args: "--web",
wantOpts: ListOptions{
Limit: defaultLimit,
Web: true,
},
},
}
for _, tt := range tests {
@ -62,6 +71,7 @@ func TestNewCmdList(t *testing.T) {
}
require.NoError(t, err)
assert.Equal(t, tt.wantOpts.Limit, gotOpts.Limit)
assert.Equal(t, tt.wantOpts.Web, gotOpts.Web)
})
}
}
@ -72,14 +82,17 @@ func Test_listRun(t *testing.T) {
createdAt := sixHoursAgo.Format(time.RFC3339)
tests := []struct {
name string
tty bool
stubs func(*httpmock.Registry)
baseRepo ghrepo.Interface
baseRepoErr error
limit int
wantOut string
wantErr error
name string
tty bool
stubs func(*httpmock.Registry)
baseRepo ghrepo.Interface
baseRepoErr error
limit int
web bool
wantOut string
wantErr error
wantStderr string
wantBrowserURL string
}{
{
name: "no sessions",
@ -166,6 +179,14 @@ func Test_listRun(t *testing.T) {
r6 #306 OWNER/REPO mystery about 6 hours ago
`),
},
{
name: "web mode",
tty: true,
web: true,
wantOut: "",
wantStderr: "Opening https://github.com/copilot/agents in your browser.\n",
wantBrowserURL: "https://github.com/copilot/agents",
},
}
for _, tt := range tests {
@ -179,16 +200,28 @@ func Test_listRun(t *testing.T) {
cfg.Set("github.com", "oauth_token", "OTOKEN")
authCfg := cfg.Authentication()
ios, _, stdout, _ := iostreams.Test()
ios, _, stdout, stderr := iostreams.Test()
ios.SetStdoutTTY(tt.tty)
var br *browser.Stub
if tt.web {
br = &browser.Stub{}
}
httpClient := &http.Client{Transport: reg}
capiClient := capi.NewCAPIClient(httpClient, authCfg)
opts := &ListOptions{
IO: ios,
Config: func() (gh.Config, error) { return cfg, nil },
Limit: tt.limit,
CapiClient: func() (*capi.CAPIClient, error) { return capiClient, nil },
IO: ios,
Config: func() (gh.Config, error) { return cfg, nil },
Limit: tt.limit,
Web: tt.web,
Browser: br,
CapiClient: func() (*capi.CAPIClient, error) {
if tt.web {
panic("CapiClient should not be invoked when --web is set")
}
return capiClient, nil
},
}
if tt.baseRepo != nil || tt.baseRepoErr != nil {
baseRepo := tt.baseRepo
@ -205,6 +238,14 @@ func Test_listRun(t *testing.T) {
}
got := stdout.String()
require.Equal(t, tt.wantOut, got)
if tt.wantStderr != "" {
require.Equal(t, tt.wantStderr, stderr.String())
} else {
require.Equal(t, "", stderr.String())
}
if tt.web {
br.Verify(t, tt.wantBrowserURL)
}
reg.Verify(t)
})
}