diff --git a/cmd/browsers.go b/cmd/browsers.go index 7e56255..aee09f7 100644 --- a/cmd/browsers.go +++ b/cmd/browsers.go @@ -86,6 +86,7 @@ type BrowserComputerService interface { MoveMouse(ctx context.Context, id string, body kernel.BrowserComputerMoveMouseParams, opts ...option.RequestOption) (err error) PressKey(ctx context.Context, id string, body kernel.BrowserComputerPressKeyParams, opts ...option.RequestOption) (err error) Scroll(ctx context.Context, id string, body kernel.BrowserComputerScrollParams, opts ...option.RequestOption) (err error) + SetCursorVisibility(ctx context.Context, id string, body kernel.BrowserComputerSetCursorVisibilityParams, opts ...option.RequestOption) (res *kernel.BrowserComputerSetCursorVisibilityResponse, err error) TypeText(ctx context.Context, id string, body kernel.BrowserComputerTypeTextParams, opts ...option.RequestOption) (err error) } @@ -567,6 +568,11 @@ type BrowsersComputerDragMouseInput struct { HoldKeys []string } +type BrowsersComputerSetCursorInput struct { + Identifier string + Hidden bool +} + func (b BrowsersCmd) ComputerClickMouse(ctx context.Context, in BrowsersComputerClickMouseInput) error { if b.computer == nil { pterm.Error.Println("computer service not available") @@ -789,6 +795,32 @@ func (b BrowsersCmd) ComputerDragMouse(ctx context.Context, in BrowsersComputerD return nil } +func (b BrowsersCmd) ComputerSetCursor(ctx context.Context, in BrowsersComputerSetCursorInput) error { + if b.computer == nil { + pterm.Error.Println("computer service not available") + return nil + } + br, err := b.resolveBrowserByIdentifier(ctx, in.Identifier) + if err != nil { + return util.CleanedUpSdkError{Err: err} + } + if br == nil { + pterm.Error.Printf("Browser '%s' not found\n", in.Identifier) + return nil + } + body := kernel.BrowserComputerSetCursorVisibilityParams{Hidden: in.Hidden} + _, err = b.computer.SetCursorVisibility(ctx, br.SessionID, body) + if err != nil { + return util.CleanedUpSdkError{Err: err} + } + if in.Hidden { + pterm.Success.Println("Cursor hidden") + } else { + pterm.Success.Println("Cursor shown") + } + return nil +} + // Replays type BrowsersReplaysListInput struct { Identifier string @@ -1955,7 +1987,12 @@ func init() { computerDrag.Flags().String("button", "left", "Mouse button: left,middle,right") computerDrag.Flags().StringSlice("hold-key", []string{}, "Modifier keys to hold (repeatable)") - computerRoot.AddCommand(computerClick, computerMove, computerScreenshot, computerType, computerPressKey, computerScroll, computerDrag) + // computer set-cursor + computerSetCursor := &cobra.Command{Use: "set-cursor ", Short: "Hide or show the cursor", Args: cobra.ExactArgs(1), RunE: runBrowsersComputerSetCursor} + computerSetCursor.Flags().String("hidden", "", "Whether to hide the cursor: true or false") + _ = computerSetCursor.MarkFlagRequired("hidden") + + computerRoot.AddCommand(computerClick, computerMove, computerScreenshot, computerType, computerPressKey, computerScroll, computerDrag, computerSetCursor) browsersCmd.AddCommand(computerRoot) // playwright @@ -2462,6 +2499,26 @@ func runBrowsersComputerDragMouse(cmd *cobra.Command, args []string) error { return b.ComputerDragMouse(cmd.Context(), BrowsersComputerDragMouseInput{Identifier: args[0], Path: path, Delay: delay, StepDelayMs: stepDelayMs, StepsPerSegment: stepsPerSegment, Button: button, HoldKeys: holdKeys}) } +func runBrowsersComputerSetCursor(cmd *cobra.Command, args []string) error { + client := getKernelClient(cmd) + svc := client.Browsers + hiddenStr, _ := cmd.Flags().GetString("hidden") + + var hidden bool + switch strings.ToLower(hiddenStr) { + case "true", "1", "yes": + hidden = true + case "false", "0", "no": + hidden = false + default: + pterm.Error.Printf("Invalid value for --hidden: %s (expected true or false)\n", hiddenStr) + return nil + } + + b := BrowsersCmd{browsers: &svc, computer: &svc.Computer} + return b.ComputerSetCursor(cmd.Context(), BrowsersComputerSetCursorInput{Identifier: args[0], Hidden: hidden}) +} + func truncateURL(url string, maxLen int) string { if len(url) <= maxLen { return url diff --git a/cmd/browsers_test.go b/cmd/browsers_test.go index d68e9b8..44e5719 100644 --- a/cmd/browsers_test.go +++ b/cmd/browsers_test.go @@ -533,6 +533,7 @@ type FakeComputerService struct { ScrollFunc func(ctx context.Context, id string, body kernel.BrowserComputerScrollParams, opts ...option.RequestOption) error DragMouseFunc func(ctx context.Context, id string, body kernel.BrowserComputerDragMouseParams, opts ...option.RequestOption) error TypeTextFunc func(ctx context.Context, id string, body kernel.BrowserComputerTypeTextParams, opts ...option.RequestOption) error + SetCursorVisibilityFunc func(ctx context.Context, id string, body kernel.BrowserComputerSetCursorVisibilityParams, opts ...option.RequestOption) (*kernel.BrowserComputerSetCursorVisibilityResponse, error) } func (f *FakeComputerService) ClickMouse(ctx context.Context, id string, body kernel.BrowserComputerClickMouseParams, opts ...option.RequestOption) error { @@ -578,6 +579,12 @@ func (f *FakeComputerService) TypeText(ctx context.Context, id string, body kern } return nil } +func (f *FakeComputerService) SetCursorVisibility(ctx context.Context, id string, body kernel.BrowserComputerSetCursorVisibilityParams, opts ...option.RequestOption) (*kernel.BrowserComputerSetCursorVisibilityResponse, error) { + if f.SetCursorVisibilityFunc != nil { + return f.SetCursorVisibilityFunc(ctx, id, body, opts...) + } + return &kernel.BrowserComputerSetCursorVisibilityResponse{}, nil +} // --- Tests for Logs --- diff --git a/go.mod b/go.mod index d4596f0..6fe8743 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/charmbracelet/fang v0.2.0 github.com/golang-jwt/jwt/v5 v5.2.2 github.com/joho/godotenv v1.5.1 - github.com/onkernel/kernel-go-sdk v0.18.0 + github.com/onkernel/kernel-go-sdk v0.19.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 366a3af..a69902e 100644 --- a/go.sum +++ b/go.sum @@ -91,8 +91,8 @@ github.com/muesli/mango-pflag v0.1.0 h1:UADqbYgpUyRoBja3g6LUL+3LErjpsOwaC9ywvBWe github.com/muesli/mango-pflag v0.1.0/go.mod h1:YEQomTxaCUp8PrbhFh10UfbhbQrM/xJ4i2PB8VTLLW0= github.com/muesli/roff v0.1.0 h1:YD0lalCotmYuF5HhZliKWlIx7IEhiXeSfq7hNjFqGF8= github.com/muesli/roff v0.1.0/go.mod h1:pjAHQM9hdUUwm/krAfrLGgJkXJ+YuhtsfZ42kieB2Ig= -github.com/onkernel/kernel-go-sdk v0.18.0 h1:hlBqxL2sEUto6h449b93C0YkAQeRdxrhn5cAScbhjaQ= -github.com/onkernel/kernel-go-sdk v0.18.0/go.mod h1:MjUR92i8UPqjrmneyVykae6GuB3GGSmnQtnjf1v74Dc= +github.com/onkernel/kernel-go-sdk v0.19.0 h1:kfLHmcye/zEF9INP3zIXffmVLGFVZiZNFs4NeVAgya0= +github.com/onkernel/kernel-go-sdk v0.19.0/go.mod h1:t80buN1uCA/hwvm4D2SpjTJzZWcV7bWOFo9d7qdXD8M= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=