Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
82 changes: 81 additions & 1 deletion cmd/browsers.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,11 @@ type BrowserComputerService interface {
GetMousePosition(ctx context.Context, id string, opts ...option.RequestOption) (res *kernel.BrowserComputerGetMousePositionResponse, err error)
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)
ReadClipboard(ctx context.Context, id string, opts ...option.RequestOption) (res *kernel.BrowserComputerReadClipboardResponse, 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)
WriteClipboard(ctx context.Context, id string, body kernel.BrowserComputerWriteClipboardParams, opts ...option.RequestOption) (err error)
}

// BoolFlag captures whether a boolean flag was set explicitly and its value.
Expand Down Expand Up @@ -784,6 +786,16 @@ type BrowsersComputerBatchInput struct {
ActionsJSON string
}

type BrowsersComputerReadClipboardInput struct {
Identifier string
Output string
}

type BrowsersComputerWriteClipboardInput struct {
Identifier string
Text string
}

func (b BrowsersCmd) ComputerClickMouse(ctx context.Context, in BrowsersComputerClickMouseInput) error {
if b.computer == nil {
pterm.Error.Println("computer service not available")
Expand Down Expand Up @@ -1063,6 +1075,47 @@ func (b BrowsersCmd) ComputerBatch(ctx context.Context, in BrowsersComputerBatch
return nil
}

func (b BrowsersCmd) ComputerReadClipboard(ctx context.Context, in BrowsersComputerReadClipboardInput) error {
if in.Output != "" && in.Output != "json" {
return fmt.Errorf("unsupported --output value: use 'json'")
}
if b.computer == nil {
pterm.Error.Println("computer service not available")
return nil
}
br, err := b.browsers.Get(ctx, in.Identifier, kernel.BrowserGetParams{})
if err != nil {
return util.CleanedUpSdkError{Err: err}
}
res, err := b.computer.ReadClipboard(ctx, br.SessionID)
if err != nil {
return util.CleanedUpSdkError{Err: err}
}
if in.Output == "json" {
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
return enc.Encode(res)
}
fmt.Println(res.Text)
return nil
}

func (b BrowsersCmd) ComputerWriteClipboard(ctx context.Context, in BrowsersComputerWriteClipboardInput) error {
if b.computer == nil {
pterm.Error.Println("computer service not available")
return nil
}
br, err := b.browsers.Get(ctx, in.Identifier, kernel.BrowserGetParams{})
if err != nil {
return util.CleanedUpSdkError{Err: err}
}
if err := b.computer.WriteClipboard(ctx, br.SessionID, kernel.BrowserComputerWriteClipboardParams{Text: in.Text}); err != nil {
return util.CleanedUpSdkError{Err: err}
}
pterm.Success.Println("Text written to clipboard")
return nil
}

// Replays
type BrowsersReplaysListInput struct {
Identifier string
Expand Down Expand Up @@ -2415,7 +2468,16 @@ func init() {
computerBatch.Flags().String("actions", "", "JSON object with actions array (e.g., {\"actions\":[{\"type\":\"click_mouse\",...}]})")
_ = computerBatch.MarkFlagRequired("actions")

computerRoot.AddCommand(computerClick, computerMove, computerScreenshot, computerType, computerPressKey, computerScroll, computerDrag, computerSetCursor, computerGetMousePosition, computerBatch)
// computer read-clipboard
computerReadClipboard := &cobra.Command{Use: "read-clipboard <id>", Short: "Read text from the browser clipboard", Args: cobra.ExactArgs(1), RunE: runBrowsersComputerReadClipboard}
computerReadClipboard.Flags().StringP("output", "o", "", "Output format: json for raw API response")

// computer write-clipboard
computerWriteClipboard := &cobra.Command{Use: "write-clipboard <id>", Short: "Write text to the browser clipboard", Args: cobra.ExactArgs(1), RunE: runBrowsersComputerWriteClipboard}
computerWriteClipboard.Flags().String("text", "", "Text to write to the clipboard")
_ = computerWriteClipboard.MarkFlagRequired("text")

computerRoot.AddCommand(computerClick, computerMove, computerScreenshot, computerType, computerPressKey, computerScroll, computerDrag, computerSetCursor, computerGetMousePosition, computerBatch, computerReadClipboard, computerWriteClipboard)
browsersCmd.AddCommand(computerRoot)

// playwright
Expand Down Expand Up @@ -3159,6 +3221,24 @@ func runBrowsersComputerBatch(cmd *cobra.Command, args []string) error {
return b.ComputerBatch(cmd.Context(), BrowsersComputerBatchInput{Identifier: args[0], ActionsJSON: actionsJSON})
}

func runBrowsersComputerReadClipboard(cmd *cobra.Command, args []string) error {
client := getKernelClient(cmd)
svc := client.Browsers
output, _ := cmd.Flags().GetString("output")

b := BrowsersCmd{browsers: &svc, computer: &svc.Computer}
return b.ComputerReadClipboard(cmd.Context(), BrowsersComputerReadClipboardInput{Identifier: args[0], Output: output})
}

func runBrowsersComputerWriteClipboard(cmd *cobra.Command, args []string) error {
client := getKernelClient(cmd)
svc := client.Browsers
text, _ := cmd.Flags().GetString("text")

b := BrowsersCmd{browsers: &svc, computer: &svc.Computer}
return b.ComputerWriteClipboard(cmd.Context(), BrowsersComputerWriteClipboardInput{Identifier: args[0], Text: text})
}

func truncateURL(url string, maxLen int) string {
if len(url) <= maxLen {
return url
Expand Down
14 changes: 14 additions & 0 deletions cmd/browsers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,8 @@ type FakeComputerService struct {
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)
ReadClipboardFunc func(ctx context.Context, id string, opts ...option.RequestOption) (*kernel.BrowserComputerReadClipboardResponse, error)
WriteClipboardFunc func(ctx context.Context, id string, body kernel.BrowserComputerWriteClipboardParams, opts ...option.RequestOption) error
}

func (f *FakeComputerService) Batch(ctx context.Context, id string, body kernel.BrowserComputerBatchParams, opts ...option.RequestOption) error {
Expand Down Expand Up @@ -764,6 +766,18 @@ func (f *FakeComputerService) SetCursorVisibility(ctx context.Context, id string
}
return &kernel.BrowserComputerSetCursorVisibilityResponse{}, nil
}
func (f *FakeComputerService) ReadClipboard(ctx context.Context, id string, opts ...option.RequestOption) (*kernel.BrowserComputerReadClipboardResponse, error) {
if f.ReadClipboardFunc != nil {
return f.ReadClipboardFunc(ctx, id, opts...)
}
return &kernel.BrowserComputerReadClipboardResponse{}, nil
}
func (f *FakeComputerService) WriteClipboard(ctx context.Context, id string, body kernel.BrowserComputerWriteClipboardParams, opts ...option.RequestOption) error {
if f.WriteClipboardFunc != nil {
return f.WriteClipboardFunc(ctx, id, body, opts...)
}
return nil
}

// --- Tests for Logs ---

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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.43.0
github.com/kernel/kernel-go-sdk v0.44.0
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
github.com/pterm/pterm v0.12.80
github.com/samber/lo v1.51.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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.43.0 h1:sbvOy5rHomG+0GQfQ6Qeoli1ZXr8jl61bTporsBIzKk=
github.com/kernel/kernel-go-sdk v0.43.0/go.mod h1:EeZzSuHZVeHKxKCPUzxou2bovNGhXaz0RXrSqKNf1AQ=
github.com/kernel/kernel-go-sdk v0.44.0 h1:GQKq4UAcI4WBgl2dTXBuuiEBZE3WCSTxe1S96MDru6w=
github.com/kernel/kernel-go-sdk v0.44.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=
Expand Down
Loading