From 6e6a0e470df89434dda60508cd86a557af9a1448 Mon Sep 17 00:00:00 2001 From: Steven Miller Date: Fri, 16 Jan 2026 13:52:53 -0500 Subject: [PATCH 1/2] Support swapping proxies --- cmd/browsers.go | 86 ++++++++++++++++++++++++++++++++++++++++++++ cmd/browsers_test.go | 8 +++++ go.mod | 2 +- go.sum | 4 +-- 4 files changed, 97 insertions(+), 3 deletions(-) diff --git a/cmd/browsers.go b/cmd/browsers.go index 4db20f5..d81cb6c 100644 --- a/cmd/browsers.go +++ b/cmd/browsers.go @@ -32,6 +32,7 @@ type BrowsersService interface { Get(ctx context.Context, id string, opts ...option.RequestOption) (res *kernel.BrowserGetResponse, err error) List(ctx context.Context, query kernel.BrowserListParams, opts ...option.RequestOption) (res *pagination.OffsetPagination[kernel.BrowserListResponse], err error) New(ctx context.Context, body kernel.BrowserNewParams, opts ...option.RequestOption) (res *kernel.BrowserNewResponse, err error) + Update(ctx context.Context, id string, body kernel.BrowserUpdateParams, opts ...option.RequestOption) (res *kernel.BrowserUpdateResponse, err error) Delete(ctx context.Context, body kernel.BrowserDeleteParams, opts ...option.RequestOption) (err error) DeleteByID(ctx context.Context, id string, opts ...option.RequestOption) (err error) LoadExtensions(ctx context.Context, id string, body kernel.BrowserLoadExtensionsParams, opts ...option.RequestOption) (err error) @@ -181,6 +182,13 @@ type BrowsersGetInput struct { Output string } +type BrowsersUpdateInput struct { + Identifier string + ProxyID string + ClearProxy bool + Output string +} + // BrowsersCmd is a cobra-independent command handler for browsers operations. type BrowsersCmd struct { browsers BrowsersService @@ -537,6 +545,54 @@ func (b BrowsersCmd) Get(ctx context.Context, in BrowsersGetInput) error { return nil } +func (b BrowsersCmd) Update(ctx context.Context, in BrowsersUpdateInput) error { + if in.Output != "" && in.Output != "json" { + return fmt.Errorf("unsupported --output value: use 'json'") + } + + // Validate that at least one update option is provided + if in.ProxyID == "" && !in.ClearProxy { + return fmt.Errorf("must specify --proxy-id or --clear-proxy") + } + + // Cannot specify both --proxy-id and --clear-proxy + if in.ProxyID != "" && in.ClearProxy { + return fmt.Errorf("cannot specify both --proxy-id and --clear-proxy") + } + + params := kernel.BrowserUpdateParams{} + if in.ClearProxy { + // Set to empty string to remove proxy + params.ProxyID = kernel.Opt("") + } else if in.ProxyID != "" { + params.ProxyID = kernel.Opt(in.ProxyID) + } + + if in.Output != "json" { + if in.ClearProxy { + pterm.Info.Printf("Removing proxy from browser %s...\n", in.Identifier) + } else { + pterm.Info.Printf("Updating browser %s with proxy %s...\n", in.Identifier, in.ProxyID) + } + } + + browser, err := b.browsers.Update(ctx, in.Identifier, params) + if err != nil { + return util.CleanedUpSdkError{Err: err} + } + + if in.Output == "json" { + return util.PrintPrettyJSON(browser) + } + + if in.ClearProxy { + pterm.Success.Printf("Removed proxy from browser %s\n", browser.SessionID) + } else { + pterm.Success.Printf("Updated browser %s with proxy %s\n", browser.SessionID, browser.ProxyID) + } + return nil +} + // Logs type BrowsersLogsStreamInput struct { Identifier string @@ -1833,6 +1889,14 @@ var browsersGetCmd = &cobra.Command{ RunE: runBrowsersGet, } +var browsersUpdateCmd = &cobra.Command{ + Use: "update ", + Short: "Update a browser session", + Long: "Update a running browser session. Currently supports changing or removing the proxy.", + Args: cobra.ExactArgs(1), + RunE: runBrowsersUpdate, +} + func init() { // list flags browsersListCmd.Flags().StringP("output", "o", "", "Output format: json for raw API response") @@ -1846,11 +1910,17 @@ func init() { // view flags browsersViewCmd.Flags().StringP("output", "o", "", "Output format: json for raw API response") + // update flags + browsersUpdateCmd.Flags().StringP("output", "o", "", "Output format: json for raw API response") + browsersUpdateCmd.Flags().String("proxy-id", "", "ID of the proxy to use for the browser session") + browsersUpdateCmd.Flags().Bool("clear-proxy", false, "Remove the proxy from the browser session") + browsersCmd.AddCommand(browsersListCmd) browsersCmd.AddCommand(browsersCreateCmd) browsersCmd.AddCommand(browsersDeleteCmd) browsersCmd.AddCommand(browsersViewCmd) browsersCmd.AddCommand(browsersGetCmd) + browsersCmd.AddCommand(browsersUpdateCmd) // logs logsRoot := &cobra.Command{Use: "logs", Short: "Browser logs operations"} @@ -2264,6 +2334,22 @@ func runBrowsersGet(cmd *cobra.Command, args []string) error { }) } +func runBrowsersUpdate(cmd *cobra.Command, args []string) error { + client := getKernelClient(cmd) + out, _ := cmd.Flags().GetString("output") + proxyID, _ := cmd.Flags().GetString("proxy-id") + clearProxy, _ := cmd.Flags().GetBool("clear-proxy") + + svc := client.Browsers + b := BrowsersCmd{browsers: &svc} + return b.Update(cmd.Context(), BrowsersUpdateInput{ + Identifier: args[0], + ProxyID: proxyID, + ClearProxy: clearProxy, + Output: out, + }) +} + func runBrowsersLogsStream(cmd *cobra.Command, args []string) error { client := getKernelClient(cmd) svc := client.Browsers diff --git a/cmd/browsers_test.go b/cmd/browsers_test.go index e2a9eab..7fcb120 100644 --- a/cmd/browsers_test.go +++ b/cmd/browsers_test.go @@ -57,6 +57,7 @@ type FakeBrowsersService struct { GetFunc func(ctx context.Context, id string, opts ...option.RequestOption) (*kernel.BrowserGetResponse, error) ListFunc func(ctx context.Context, query kernel.BrowserListParams, opts ...option.RequestOption) (*pagination.OffsetPagination[kernel.BrowserListResponse], error) NewFunc func(ctx context.Context, body kernel.BrowserNewParams, opts ...option.RequestOption) (*kernel.BrowserNewResponse, error) + UpdateFunc func(ctx context.Context, id string, body kernel.BrowserUpdateParams, opts ...option.RequestOption) (*kernel.BrowserUpdateResponse, error) DeleteFunc func(ctx context.Context, body kernel.BrowserDeleteParams, opts ...option.RequestOption) error DeleteByIDFunc func(ctx context.Context, id string, opts ...option.RequestOption) error LoadExtensionsFunc func(ctx context.Context, id string, body kernel.BrowserLoadExtensionsParams, opts ...option.RequestOption) error @@ -83,6 +84,13 @@ func (f *FakeBrowsersService) New(ctx context.Context, body kernel.BrowserNewPar return &kernel.BrowserNewResponse{}, nil } +func (f *FakeBrowsersService) Update(ctx context.Context, id string, body kernel.BrowserUpdateParams, opts ...option.RequestOption) (*kernel.BrowserUpdateResponse, error) { + if f.UpdateFunc != nil { + return f.UpdateFunc(ctx, id, body, opts...) + } + return &kernel.BrowserUpdateResponse{}, nil +} + func (f *FakeBrowsersService) Delete(ctx context.Context, body kernel.BrowserDeleteParams, opts ...option.RequestOption) error { if f.DeleteFunc != nil { return f.DeleteFunc(ctx, body, opts...) diff --git a/go.mod b/go.mod index 0042473..ff373fe 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/charmbracelet/lipgloss/v2 v2.0.0-beta.1 github.com/golang-jwt/jwt/v5 v5.2.2 github.com/joho/godotenv v1.5.1 - github.com/kernel/kernel-go-sdk v0.25.0 + github.com/kernel/kernel-go-sdk v0.26.0 github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c github.com/pterm/pterm v0.12.80 github.com/samber/lo v1.51.0 diff --git a/go.sum b/go.sum index 847e196..02041b3 100644 --- a/go.sum +++ b/go.sum @@ -64,8 +64,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -github.com/kernel/kernel-go-sdk v0.25.0 h1:I6EpQKcOasiuVi6gX8HcqEIxK9dAs6xMGSnlUW7AxXY= -github.com/kernel/kernel-go-sdk v0.25.0/go.mod h1:EeZzSuHZVeHKxKCPUzxou2bovNGhXaz0RXrSqKNf1AQ= +github.com/kernel/kernel-go-sdk v0.26.0 h1:IBiEohSSZN5MEZjmnfqseT3tEip6+xg7Zxr79vJYMBA= +github.com/kernel/kernel-go-sdk v0.26.0/go.mod h1:EeZzSuHZVeHKxKCPUzxou2bovNGhXaz0RXrSqKNf1AQ= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.10/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= From 00b3107d3966bf87d93fffc852359b0a8f44a970 Mon Sep 17 00:00:00 2001 From: Steven Miller Date: Fri, 16 Jan 2026 13:56:30 -0500 Subject: [PATCH 2/2] Improve error message --- cmd/browsers.go | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/cmd/browsers.go b/cmd/browsers.go index d81cb6c..dc661de 100644 --- a/cmd/browsers.go +++ b/cmd/browsers.go @@ -1893,8 +1893,16 @@ var browsersUpdateCmd = &cobra.Command{ Use: "update ", Short: "Update a browser session", Long: "Update a running browser session. Currently supports changing or removing the proxy.", - Args: cobra.ExactArgs(1), - RunE: runBrowsersUpdate, + Args: func(cmd *cobra.Command, args []string) error { + if len(args) == 0 { + return fmt.Errorf("missing required argument: browser ID\n\nUsage: kernel browsers update [flags]") + } + if len(args) > 1 { + return fmt.Errorf("expected 1 argument (browser ID), got %d", len(args)) + } + return nil + }, + RunE: runBrowsersUpdate, } func init() {