Skip to content

Commit 15bac21

Browse files
authored
Merge branch 'main' into hypeship/go-1.27
2 parents debb054 + 8a21ef1 commit 15bac21

22 files changed

Lines changed: 692 additions & 238 deletions

‎README.md‎

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,8 +1009,12 @@ Destinations are the OTLP/HTTP endpoints sessions export to. They belong to the
10091009
### Browser Playwright
10101010

10111011
- `kernel browsers playwright execute <id> [code]` - Execute Playwright/TypeScript code against the browser
1012+
- `--executor <name>` - Executor to run the call in. Calls on different executors run concurrently in separate tabs of the same browser; calls on one executor run one at a time. Omit to use the always-present `default` executor bound to the active tab. Any other name creates a named executor on first use that owns a background tab `page` is bound to. At most 8 named executors per browser (409 when exceeded)
10121013
- `--timeout <seconds>` - Maximum execution time in seconds (defaults server-side)
10131014
- If `[code]` is omitted, code is read from stdin
1015+
- `kernel browsers playwright executors list <id>` - List the browser's Playwright executors (default first) with busy state, timestamps, and the tab each named executor owns
1016+
- `kernel browsers playwright executors delete <id> <executor>` - Delete a Playwright executor. Deleting `default` restarts it instead of removing it
1017+
- `--close-tab` - Close the tab owned by the executor (default: true)
10141018

10151019
### Browser REPL
10161020

@@ -1131,7 +1135,7 @@ anywhere a project ID does.
11311135
- `--output json`, `-o json` - Output raw JSON object
11321136

11331137
- `--name <name>` - Proxy configuration name (required)
1134-
- `--type <type>` - Proxy type: datacenter, isp, residential, mobile, custom (required)
1138+
- `--type <type>` - Proxy type: isp, residential, mobile, custom (required)
11351139
- `--protocol <http|https>` - Protocol to use (default: https)
11361140
- `--country <code>` - ISO 3166 country code or "EU" (location-based types)
11371141
- `--city <name>` - City name (no spaces, e.g. sanfrancisco) (residential, mobile; requires `--country`)
@@ -1524,6 +1528,15 @@ TS
15241528
# With a timeout in seconds
15251529
kernel browsers playwright execute my-browser --timeout 30 'await (await context.newPage()).goto("https://example.com")'
15261530

1531+
# Drive two tabs in parallel with named executors (each owns its own tab)
1532+
kernel browsers playwright execute my-browser --executor docs 'await page.goto("https://example.com/docs"); return await page.title();' &
1533+
kernel browsers playwright execute my-browser --executor pricing 'await page.goto("https://example.com/pricing"); return await page.title();' &
1534+
wait
1535+
1536+
# List executors and delete one (closes its tab unless --close-tab=false)
1537+
kernel browsers playwright executors list my-browser
1538+
kernel browsers playwright executors delete my-browser docs
1539+
15271540
# Mini CDP connection load test (10s)
15281541
cat <<'TS' | kernel browsers playwright execute my-browser
15291542
const start = Date.now();
@@ -1589,11 +1602,11 @@ kernel browsers extensions upload my-browser ./extension1 ./extension2
15891602
# List proxy configurations
15901603
kernel proxies list
15911604

1592-
# Create a datacenter proxy
1593-
kernel proxies create --type datacenter --country US --name "US Datacenter"
1605+
# Create an ISP proxy
1606+
kernel proxies create --type isp --country US --name "US ISP"
15941607

1595-
# Create a datacenter proxy using HTTP protocol
1596-
kernel proxies create --type datacenter --country US --protocol http --name "US DC (HTTP)"
1608+
# Create an ISP proxy using HTTP protocol
1609+
kernel proxies create --type isp --country US --protocol http --name "US ISP (HTTP)"
15971610

15981611
# Create a custom proxy
15991612
kernel proxies create --type custom --host proxy.example.com --port 8080 --username myuser --password mypass --name "My Custom Proxy"

‎cmd/browsers.go‎

Lines changed: 12 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,6 @@ type BrowserLogService interface {
9090
StreamStreaming(ctx context.Context, idOrName string, query kernel.BrowserLogStreamParams, opts ...option.RequestOption) (stream *ssestream.Stream[shared.LogEvent])
9191
}
9292

93-
// BrowserPlaywrightService defines the subset we use for Playwright execution.
94-
type BrowserPlaywrightService interface {
95-
Execute(ctx context.Context, idOrName string, body kernel.BrowserPlaywrightExecuteParams, opts ...option.RequestOption) (res *kernel.BrowserPlaywrightExecuteResponse, err error)
96-
}
97-
9893
// BrowserComputerService defines the subset we use for OS-level mouse & screen.
9994
type BrowserComputerService interface {
10095
Batch(ctx context.Context, idOrName string, body kernel.BrowserComputerBatchParams, opts ...option.RequestOption) (err error)
@@ -517,16 +512,17 @@ type BrowsersUpdateInput struct {
517512

518513
// BrowsersCmd is a cobra-independent command handler for browsers operations.
519514
type BrowsersCmd struct {
520-
browsers BrowsersService
521-
replays BrowserReplaysService
522-
fs BrowserFSService
523-
fsWatch BrowserFWatchService
524-
process BrowserProcessService
525-
logs BrowserLogService
526-
computer BrowserComputerService
527-
playwright BrowserPlaywrightService
528-
telemetry BrowserTelemetryService
529-
webmcp BrowserWebMCPService
515+
browsers BrowsersService
516+
replays BrowserReplaysService
517+
fs BrowserFSService
518+
fsWatch BrowserFWatchService
519+
process BrowserProcessService
520+
logs BrowserLogService
521+
computer BrowserComputerService
522+
playwright BrowserPlaywrightService
523+
playwrightExecutors BrowserPlaywrightExecutorService
524+
telemetry BrowserTelemetryService
525+
webmcp BrowserWebMCPService
530526
}
531527

532528
type BrowsersListInput struct {
@@ -1836,64 +1832,6 @@ type BrowsersFSWatchEventsInput struct {
18361832
WatchID string
18371833
}
18381834

1839-
// Playwright
1840-
type BrowsersPlaywrightExecuteInput struct {
1841-
Identifier string
1842-
Code string
1843-
Timeout int64
1844-
Output string
1845-
}
1846-
1847-
func (b BrowsersCmd) PlaywrightExecute(ctx context.Context, in BrowsersPlaywrightExecuteInput) error {
1848-
if err := validateJSONOutput(in.Output); err != nil {
1849-
return err
1850-
}
1851-
1852-
if b.playwright == nil {
1853-
pterm.Error.Println("playwright service not available")
1854-
return nil
1855-
}
1856-
br, err := b.browsers.Get(ctx, in.Identifier, kernel.BrowserGetParams{})
1857-
if err != nil {
1858-
return util.CleanedUpSdkError{Err: err}
1859-
}
1860-
params := kernel.BrowserPlaywrightExecuteParams{Code: in.Code}
1861-
if in.Timeout > 0 {
1862-
params.TimeoutSec = kernel.Opt(in.Timeout)
1863-
}
1864-
res, err := b.playwright.Execute(ctx, br.SessionID, params)
1865-
if err != nil {
1866-
return util.CleanedUpSdkError{Err: err}
1867-
}
1868-
1869-
if in.Output == "json" {
1870-
return util.PrintPrettyJSON(res)
1871-
}
1872-
1873-
rows := pterm.TableData{{"Property", "Value"}, {"Success", fmt.Sprintf("%t", res.Success)}}
1874-
PrintTableNoPad(rows, true)
1875-
1876-
if res.Stdout != "" {
1877-
pterm.Info.Println("stdout:")
1878-
fmt.Println(res.Stdout)
1879-
}
1880-
if res.Stderr != "" {
1881-
pterm.Info.Println("stderr:")
1882-
fmt.Fprintln(os.Stderr, res.Stderr)
1883-
}
1884-
if res.Result != nil {
1885-
bs, err := json.MarshalIndent(res.Result, "", " ")
1886-
if err == nil {
1887-
pterm.Info.Println("result:")
1888-
fmt.Println(string(bs))
1889-
}
1890-
}
1891-
if !res.Success && res.Error != "" {
1892-
pterm.Error.Printf("error: %s\n", res.Error)
1893-
}
1894-
return nil
1895-
}
1896-
18971835
// REPL
18981836
type BrowsersReplInput struct {
18991837
Identifier string
@@ -3201,13 +3139,7 @@ func init() {
32013139
computerRoot.AddCommand(computerClick, computerMove, computerScreenshot, computerType, computerPressKey, computerScroll, computerDrag, computerSetCursor, computerGetMousePosition, computerBatch, computerReadClipboard, computerWriteClipboard)
32023140
browsersCmd.AddCommand(computerRoot)
32033141

3204-
// playwright
3205-
playwrightRoot := &cobra.Command{Use: "playwright", Short: "Playwright operations"}
3206-
playwrightExecute := &cobra.Command{Use: "execute <id> [code]", Short: "Execute Playwright/TypeScript code against the browser", Args: cobra.MinimumNArgs(1), RunE: runBrowsersPlaywrightExecute}
3207-
playwrightExecute.Flags().Int64("timeout", 0, "Maximum execution time in seconds (default per server)")
3208-
addJSONOutputFlag(playwrightExecute)
3209-
playwrightRoot.AddCommand(playwrightExecute)
3210-
browsersCmd.AddCommand(playwrightRoot)
3142+
browsersCmd.AddCommand(newBrowsersPlaywrightCommand())
32113143

32123144
// repl
32133145
replCmd := &cobra.Command{
@@ -3828,33 +3760,6 @@ func runBrowsersFSWatchEvents(cmd *cobra.Command, args []string) error {
38283760
return b.FSWatchEvents(cmd.Context(), BrowsersFSWatchEventsInput{Identifier: args[0], WatchID: args[1]})
38293761
}
38303762

3831-
func runBrowsersPlaywrightExecute(cmd *cobra.Command, args []string) error {
3832-
client := getKernelClient(cmd)
3833-
svc := client.Browsers
3834-
3835-
var code string
3836-
if len(args) >= 2 {
3837-
code = strings.Join(args[1:], " ")
3838-
} else {
3839-
// Read code from stdin
3840-
stat, _ := os.Stdin.Stat()
3841-
if (stat.Mode() & os.ModeCharDevice) != 0 {
3842-
pterm.Error.Println("no code provided. Provide code as an argument or pipe via stdin")
3843-
return nil
3844-
}
3845-
data, err := io.ReadAll(os.Stdin)
3846-
if err != nil {
3847-
pterm.Error.Printf("failed to read stdin: %v\n", err)
3848-
return nil
3849-
}
3850-
code = string(data)
3851-
}
3852-
timeout, _ := cmd.Flags().GetInt64("timeout")
3853-
output, _ := cmd.Flags().GetString("output")
3854-
b := BrowsersCmd{browsers: &svc, playwright: &svc.Playwright}
3855-
return b.PlaywrightExecute(cmd.Context(), BrowsersPlaywrightExecuteInput{Identifier: args[0], Code: strings.TrimSpace(code), Timeout: timeout, Output: output})
3856-
}
3857-
38583763
func runBrowsersRepl(cmd *cobra.Command, args []string) error {
38593764
client := getKernelClient(cmd)
38603765
svc := client.Browsers

0 commit comments

Comments
 (0)