Skip to content

Commit 73816ee

Browse files
committed
playwright code exec
1 parent c3ec0bb commit 73816ee

3 files changed

Lines changed: 102 additions & 8 deletions

File tree

‎cmd/browsers.go‎

Lines changed: 98 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ type BrowserLogService interface {
7373
StreamStreaming(ctx context.Context, id string, query kernel.BrowserLogStreamParams, opts ...option.RequestOption) (stream *ssestream.Stream[shared.LogEvent])
7474
}
7575

76+
// BrowserPlaywrightService defines the subset we use for Playwright execution.
77+
type BrowserPlaywrightService interface {
78+
Execute(ctx context.Context, id string, body kernel.BrowserPlaywrightExecuteParams, opts ...option.RequestOption) (res *kernel.BrowserPlaywrightExecuteResponse, err error)
79+
}
80+
7681
// BrowserComputerService defines the subset we use for OS-level mouse & screen.
7782
type BrowserComputerService interface {
7883
CaptureScreenshot(ctx context.Context, id string, body kernel.BrowserComputerCaptureScreenshotParams, opts ...option.RequestOption) (res *http.Response, err error)
@@ -166,12 +171,13 @@ type BrowsersViewInput struct {
166171

167172
// BrowsersCmd is a cobra-independent command handler for browsers operations.
168173
type BrowsersCmd struct {
169-
browsers BrowsersService
170-
replays BrowserReplaysService
171-
fs BrowserFSService
172-
process BrowserProcessService
173-
logs BrowserLogService
174-
computer BrowserComputerService
174+
browsers BrowsersService
175+
replays BrowserReplaysService
176+
fs BrowserFSService
177+
process BrowserProcessService
178+
logs BrowserLogService
179+
computer BrowserComputerService
180+
playwright BrowserPlaywrightService
175181
}
176182

177183
type BrowsersListInput struct {
@@ -940,6 +946,59 @@ type BrowsersProcessStdoutStreamInput struct {
940946
ProcessID string
941947
}
942948

949+
// Playwright
950+
type BrowsersPlaywrightExecuteInput struct {
951+
Identifier string
952+
Code string
953+
Timeout int64
954+
}
955+
956+
func (b BrowsersCmd) PlaywrightExecute(ctx context.Context, in BrowsersPlaywrightExecuteInput) error {
957+
if b.playwright == nil {
958+
pterm.Error.Println("playwright service not available")
959+
return nil
960+
}
961+
br, err := b.resolveBrowserByIdentifier(ctx, in.Identifier)
962+
if err != nil {
963+
return util.CleanedUpSdkError{Err: err}
964+
}
965+
if br == nil {
966+
pterm.Error.Printf("Browser '%s' not found\n", in.Identifier)
967+
return nil
968+
}
969+
params := kernel.BrowserPlaywrightExecuteParams{Code: in.Code}
970+
if in.Timeout > 0 {
971+
params.TimeoutSec = kernel.Opt(in.Timeout)
972+
}
973+
res, err := b.playwright.Execute(ctx, br.SessionID, params)
974+
if err != nil {
975+
return util.CleanedUpSdkError{Err: err}
976+
}
977+
978+
rows := pterm.TableData{{"Property", "Value"}, {"Success", fmt.Sprintf("%t", res.Success)}}
979+
PrintTableNoPad(rows, true)
980+
981+
if res.Stdout != "" {
982+
pterm.Info.Println("stdout:")
983+
fmt.Println(res.Stdout)
984+
}
985+
if res.Stderr != "" {
986+
pterm.Info.Println("stderr:")
987+
fmt.Fprintln(os.Stderr, res.Stderr)
988+
}
989+
if res.Result != nil {
990+
bs, err := json.MarshalIndent(res.Result, "", " ")
991+
if err == nil {
992+
pterm.Info.Println("result:")
993+
fmt.Println(string(bs))
994+
}
995+
}
996+
if !res.Success && res.Error != "" {
997+
pterm.Error.Printf("error: %s\n", res.Error)
998+
}
999+
return nil
1000+
}
1001+
9431002
func (b BrowsersCmd) ProcessExec(ctx context.Context, in BrowsersProcessExecInput) error {
9441003
if b.process == nil {
9451004
pterm.Error.Println("process service not available")
@@ -1898,6 +1957,13 @@ func init() {
18981957
computerRoot.AddCommand(computerClick, computerMove, computerScreenshot, computerType, computerPressKey, computerScroll, computerDrag)
18991958
browsersCmd.AddCommand(computerRoot)
19001959

1960+
// playwright
1961+
playwrightRoot := &cobra.Command{Use: "playwright", Short: "Playwright operations"}
1962+
playwrightExecute := &cobra.Command{Use: "execute <id|persistent-id> [code]", Short: "Execute Playwright/TypeScript code against the browser", Args: cobra.MinimumNArgs(1), RunE: runBrowsersPlaywrightExecute}
1963+
playwrightExecute.Flags().Int64("timeout", 0, "Maximum execution time in seconds (default per server)")
1964+
playwrightRoot.AddCommand(playwrightExecute)
1965+
browsersCmd.AddCommand(playwrightRoot)
1966+
19011967
// Add flags for create command
19021968
browsersCreateCmd.Flags().StringP("persistent-id", "p", "", "Unique identifier for browser session persistence")
19031969
browsersCreateCmd.Flags().BoolP("stealth", "s", false, "Launch browser in stealth mode to avoid detection")
@@ -2120,6 +2186,32 @@ func runBrowsersProcessStdoutStream(cmd *cobra.Command, args []string) error {
21202186
return b.ProcessStdoutStream(cmd.Context(), BrowsersProcessStdoutStreamInput{Identifier: args[0], ProcessID: args[1]})
21212187
}
21222188

2189+
func runBrowsersPlaywrightExecute(cmd *cobra.Command, args []string) error {
2190+
client := getKernelClient(cmd)
2191+
svc := client.Browsers
2192+
2193+
var code string
2194+
if len(args) >= 2 {
2195+
code = strings.Join(args[1:], " ")
2196+
} else {
2197+
// Read code from stdin
2198+
stat, _ := os.Stdin.Stat()
2199+
if (stat.Mode() & os.ModeCharDevice) != 0 {
2200+
pterm.Error.Println("no code provided. Provide code as an argument or pipe via stdin")
2201+
return nil
2202+
}
2203+
data, err := io.ReadAll(os.Stdin)
2204+
if err != nil {
2205+
pterm.Error.Printf("failed to read stdin: %v\n", err)
2206+
return nil
2207+
}
2208+
code = string(data)
2209+
}
2210+
timeout, _ := cmd.Flags().GetInt64("timeout")
2211+
b := BrowsersCmd{browsers: &svc, playwright: &svc.Playwright}
2212+
return b.PlaywrightExecute(cmd.Context(), BrowsersPlaywrightExecuteInput{Identifier: args[0], Code: strings.TrimSpace(code), Timeout: timeout})
2213+
}
2214+
21232215
func runBrowsersFSNewDirectory(cmd *cobra.Command, args []string) error {
21242216
client := getKernelClient(cmd)
21252217
svc := client.Browsers

‎go.mod‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,5 @@ require (
5858
golang.org/x/text v0.24.0 // indirect
5959
gopkg.in/yaml.v3 v3.0.1 // indirect
6060
)
61+
62+
replace github.com/onkernel/kernel-go-sdk => github.com/stainless-sdks/kernel-go v0.0.0-20251023003520-8596b55f4eda

‎go.sum‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,6 @@ github.com/muesli/mango-pflag v0.1.0 h1:UADqbYgpUyRoBja3g6LUL+3LErjpsOwaC9ywvBWe
9191
github.com/muesli/mango-pflag v0.1.0/go.mod h1:YEQomTxaCUp8PrbhFh10UfbhbQrM/xJ4i2PB8VTLLW0=
9292
github.com/muesli/roff v0.1.0 h1:YD0lalCotmYuF5HhZliKWlIx7IEhiXeSfq7hNjFqGF8=
9393
github.com/muesli/roff v0.1.0/go.mod h1:pjAHQM9hdUUwm/krAfrLGgJkXJ+YuhtsfZ42kieB2Ig=
94-
github.com/onkernel/kernel-go-sdk v0.15.0 h1:gLeZixS9bhOy1WuEk/eFogHUBjG6UJKN2l+OJNNdE+4=
95-
github.com/onkernel/kernel-go-sdk v0.15.0/go.mod h1:MjUR92i8UPqjrmneyVykae6GuB3GGSmnQtnjf1v74Dc=
9694
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
9795
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
9896
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -118,6 +116,8 @@ github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
118116
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
119117
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
120118
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
119+
github.com/stainless-sdks/kernel-go v0.0.0-20251023003520-8596b55f4eda h1:B4l9L34CCyUSwdHgNwRncNVi1kGaLxQBdeg08Nq49lg=
120+
github.com/stainless-sdks/kernel-go v0.0.0-20251023003520-8596b55f4eda/go.mod h1:MjUR92i8UPqjrmneyVykae6GuB3GGSmnQtnjf1v74Dc=
121121
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
122122
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
123123
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=

0 commit comments

Comments
 (0)