Skip to content

Commit ed7a71f

Browse files
committed
Add start URL browser flags
1 parent 8d26914 commit ed7a71f

6 files changed

Lines changed: 67 additions & 10 deletions

File tree

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ Commands with JSON output support:
208208
- `-s, --stealth` - Launch browser in stealth mode to avoid detection
209209
- `-H, --headless` - Launch browser without GUI access
210210
- `--kiosk` - Launch browser in kiosk mode
211+
- `--start-url <url>` - Initial page to open on launch
211212
- `--pool-id <id>` - Acquire a browser from the specified pool (mutually exclusive with --pool-name; ignores other session flags)
212213
- `--pool-name <name>` - Acquire a browser from the pool name (mutually exclusive with --pool-id; ignores other session flags)
213214
- `--output json`, `-o json` - Output raw JSON object
@@ -242,12 +243,12 @@ Commands with JSON output support:
242243
- `--fill-rate <n>` - Percentage of the pool to fill per minute
243244
- `--timeout <seconds>` - Idle timeout for browsers acquired from the pool
244245
- `--stealth`, `--headless`, `--kiosk` - Default pool configuration
245-
- `--profile-id`, `--profile-name`, `--save-changes`, `--proxy-id`, `--extension`, `--viewport` - Same semantics as `kernel browsers create`
246+
- `--profile-id`, `--profile-name`, `--save-changes`, `--proxy-id`, `--start-url`, `--extension`, `--viewport` - Same semantics as `kernel browsers create`
246247
- `--output json`, `-o json` - Output raw JSON object
247248
- `kernel browser-pools get <id-or-name>` - Get pool details
248249
- `--output json`, `-o json` - Output raw JSON object
249250
- `kernel browser-pools update <id-or-name>` - Update pool configuration
250-
- Same flags as create plus `--discard-all-idle` to discard all idle browsers in the pool and refill at the specified fill rate
251+
- Same flags as create plus `--clear-start-url` (remove the pool's start URL) and `--discard-all-idle` (discard all idle browsers and refill)
251252
- `--output json`, `-o json` - Output raw JSON object
252253
- `kernel browser-pools delete <id-or-name>` - Delete a pool
253254
- `--force` - Force delete even if browsers are leased

cmd/browser_pools.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ type BrowserPoolsCreateInput struct {
8686
ProfileName string
8787
ProfileSaveChanges BoolFlag
8888
ProxyID string
89+
StartURL string
8990
Extensions []string
9091
Viewport string
9192
Output string
@@ -131,6 +132,9 @@ func (c BrowserPoolsCmd) Create(ctx context.Context, in BrowserPoolsCreateInput)
131132
if in.ProxyID != "" {
132133
params.ProxyID = kernel.String(in.ProxyID)
133134
}
135+
if in.StartURL != "" {
136+
params.StartURL = kernel.String(in.StartURL)
137+
}
134138

135139
params.Extensions = buildExtensionsParam(in.Extensions)
136140

@@ -196,6 +200,7 @@ func (c BrowserPoolsCmd) Get(ctx context.Context, in BrowserPoolsGetInput) error
196200
{"Kiosk Mode", fmt.Sprintf("%t", cfg.KioskMode)},
197201
{"Profile", formatProfile(cfg.Profile)},
198202
{"Proxy ID", util.OrDash(cfg.ProxyID)},
203+
{"Start URL", util.OrDash(cfg.StartURL)},
199204
{"Extensions", formatExtensions(cfg.Extensions)},
200205
{"Viewport", formatViewport(cfg.Viewport)},
201206
}
@@ -217,6 +222,8 @@ type BrowserPoolsUpdateInput struct {
217222
ProfileName string
218223
ProfileSaveChanges BoolFlag
219224
ProxyID string
225+
StartURL string
226+
ClearStartURL bool
220227
Extensions []string
221228
Viewport string
222229
DiscardAllIdle BoolFlag
@@ -227,6 +234,9 @@ func (c BrowserPoolsCmd) Update(ctx context.Context, in BrowserPoolsUpdateInput)
227234
if in.Output != "" && in.Output != "json" {
228235
return fmt.Errorf("unsupported --output value: use 'json'")
229236
}
237+
if in.StartURL != "" && in.ClearStartURL {
238+
return fmt.Errorf("cannot specify both --start-url and --clear-start-url")
239+
}
230240

231241
params := kernel.BrowserPoolUpdateParams{}
232242

@@ -267,6 +277,11 @@ func (c BrowserPoolsCmd) Update(ctx context.Context, in BrowserPoolsUpdateInput)
267277
if in.ProxyID != "" {
268278
params.ProxyID = kernel.String(in.ProxyID)
269279
}
280+
if in.ClearStartURL {
281+
params.StartURL = kernel.String("")
282+
} else if in.StartURL != "" {
283+
params.StartURL = kernel.String(in.StartURL)
284+
}
270285

271286
params.Extensions = buildExtensionsParam(in.Extensions)
272287

@@ -352,6 +367,9 @@ func (c BrowserPoolsCmd) Acquire(ctx context.Context, in BrowserPoolsAcquireInpu
352367
{"CDP WebSocket URL", resp.CdpWsURL},
353368
{"Live View URL", resp.BrowserLiveViewURL},
354369
}
370+
if resp.StartURL != "" {
371+
tableData = append(tableData, []string{"Start URL", resp.StartURL})
372+
}
355373
PrintTableNoPad(tableData, true)
356374
return nil
357375
}
@@ -472,6 +490,7 @@ func init() {
472490
browserPoolsCreateCmd.Flags().String("profile-name", "", "Profile name")
473491
browserPoolsCreateCmd.Flags().Bool("save-changes", false, "Save changes to profile")
474492
browserPoolsCreateCmd.Flags().String("proxy-id", "", "Proxy ID")
493+
browserPoolsCreateCmd.Flags().String("start-url", "", "Initial page to open for new browsers")
475494
browserPoolsCreateCmd.Flags().StringSlice("extension", []string{}, "Extension IDs or names")
476495
browserPoolsCreateCmd.Flags().String("viewport", "", "Viewport size (e.g. 1280x800)")
477496

@@ -488,6 +507,8 @@ func init() {
488507
browserPoolsUpdateCmd.Flags().String("profile-name", "", "Profile name")
489508
browserPoolsUpdateCmd.Flags().Bool("save-changes", false, "Save changes to profile")
490509
browserPoolsUpdateCmd.Flags().String("proxy-id", "", "Proxy ID")
510+
browserPoolsUpdateCmd.Flags().String("start-url", "", "Initial page to open for new browsers")
511+
browserPoolsUpdateCmd.Flags().Bool("clear-start-url", false, "Clear the pool start URL")
491512
browserPoolsUpdateCmd.Flags().StringSlice("extension", []string{}, "Extension IDs or names")
492513
browserPoolsUpdateCmd.Flags().String("viewport", "", "Viewport size (e.g. 1280x800)")
493514
browserPoolsUpdateCmd.Flags().Bool("discard-all-idle", false, "Discard all idle browsers")
@@ -539,6 +560,7 @@ func runBrowserPoolsCreate(cmd *cobra.Command, args []string) error {
539560
profileName, _ := cmd.Flags().GetString("profile-name")
540561
saveChanges, _ := cmd.Flags().GetBool("save-changes")
541562
proxyID, _ := cmd.Flags().GetString("proxy-id")
563+
startURL, _ := cmd.Flags().GetString("start-url")
542564
extensions, _ := cmd.Flags().GetStringSlice("extension")
543565
viewport, _ := cmd.Flags().GetString("viewport")
544566
output, _ := cmd.Flags().GetString("output")
@@ -555,6 +577,7 @@ func runBrowserPoolsCreate(cmd *cobra.Command, args []string) error {
555577
ProfileName: profileName,
556578
ProfileSaveChanges: BoolFlag{Set: cmd.Flags().Changed("save-changes"), Value: saveChanges},
557579
ProxyID: proxyID,
580+
StartURL: startURL,
558581
Extensions: extensions,
559582
Viewport: viewport,
560583
Output: output,
@@ -585,6 +608,8 @@ func runBrowserPoolsUpdate(cmd *cobra.Command, args []string) error {
585608
profileName, _ := cmd.Flags().GetString("profile-name")
586609
saveChanges, _ := cmd.Flags().GetBool("save-changes")
587610
proxyID, _ := cmd.Flags().GetString("proxy-id")
611+
startURL, _ := cmd.Flags().GetString("start-url")
612+
clearStartURL, _ := cmd.Flags().GetBool("clear-start-url")
588613
extensions, _ := cmd.Flags().GetStringSlice("extension")
589614
viewport, _ := cmd.Flags().GetString("viewport")
590615
discardIdle, _ := cmd.Flags().GetBool("discard-all-idle")
@@ -603,6 +628,8 @@ func runBrowserPoolsUpdate(cmd *cobra.Command, args []string) error {
603628
ProfileName: profileName,
604629
ProfileSaveChanges: BoolFlag{Set: cmd.Flags().Changed("save-changes"), Value: saveChanges},
605630
ProxyID: proxyID,
631+
StartURL: startURL,
632+
ClearStartURL: clearStartURL,
606633
Extensions: extensions,
607634
Viewport: viewport,
608635
DiscardAllIdle: BoolFlag{Set: cmd.Flags().Changed("discard-all-idle"), Value: discardIdle},

cmd/browsers.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ type BrowsersCreateInput struct {
186186
ProfileName string
187187
ProfileSaveChanges BoolFlag
188188
ProxyID string
189+
StartURL string
189190
Extensions []string
190191
Viewport string
191192
Output string
@@ -392,6 +393,9 @@ func (b BrowsersCmd) Create(ctx context.Context, in BrowsersCreateInput) error {
392393
if in.ProxyID != "" {
393394
params.ProxyID = kernel.Opt(in.ProxyID)
394395
}
396+
if in.StartURL != "" {
397+
params.StartURL = kernel.Opt(in.StartURL)
398+
}
395399

396400
// Map extensions (IDs or names) into params.Extensions
397401
if len(in.Extensions) > 0 {
@@ -435,17 +439,17 @@ func (b BrowsersCmd) Create(ctx context.Context, in BrowsersCreateInput) error {
435439
return util.PrintPrettyJSON(browser)
436440
}
437441

438-
printBrowserSessionResult(browser.SessionID, browser.CdpWsURL, browser.BrowserLiveViewURL, browser.Persistence, browser.Profile)
442+
printBrowserSessionResult(browser.SessionID, browser.CdpWsURL, browser.BrowserLiveViewURL, browser.Persistence, browser.Profile, browser.StartURL)
439443
return nil
440444
}
441445

442-
func printBrowserSessionResult(sessionID, cdpURL, liveViewURL string, persistence kernel.BrowserPersistence, profile kernel.Profile) {
443-
tableData := buildBrowserTableData(sessionID, cdpURL, liveViewURL, persistence, profile)
446+
func printBrowserSessionResult(sessionID, cdpURL, liveViewURL string, persistence kernel.BrowserPersistence, profile kernel.Profile, startURL string) {
447+
tableData := buildBrowserTableData(sessionID, cdpURL, liveViewURL, persistence, profile, startURL)
444448
PrintTableNoPad(tableData, true)
445449
}
446450

447451
// buildBrowserTableData creates a base table with common browser session fields.
448-
func buildBrowserTableData(sessionID, cdpURL, liveViewURL string, persistence kernel.BrowserPersistence, profile kernel.Profile) pterm.TableData {
452+
func buildBrowserTableData(sessionID, cdpURL, liveViewURL string, persistence kernel.BrowserPersistence, profile kernel.Profile, startURL string) pterm.TableData {
449453
tableData := pterm.TableData{
450454
{"Property", "Value"},
451455
{"Session ID", sessionID},
@@ -464,6 +468,9 @@ func buildBrowserTableData(sessionID, cdpURL, liveViewURL string, persistence ke
464468
}
465469
tableData = append(tableData, []string{"Profile", profVal})
466470
}
471+
if startURL != "" {
472+
tableData = append(tableData, []string{"Start URL", startURL})
473+
}
467474
return tableData
468475
}
469476

@@ -554,6 +561,7 @@ func (b BrowsersCmd) Get(ctx context.Context, in BrowsersGetInput) error {
554561
browser.BrowserLiveViewURL,
555562
browser.Persistence,
556563
browser.Profile,
564+
browser.StartURL,
557565
)
558566

559567
// Append additional detailed fields
@@ -2525,6 +2533,7 @@ func init() {
25252533
browsersCreateCmd.Flags().String("profile-name", "", "Profile name to load into the browser session (mutually exclusive with --profile-id)")
25262534
browsersCreateCmd.Flags().Bool("save-changes", false, "If set, save changes back to the profile when the session ends")
25272535
browsersCreateCmd.Flags().String("proxy-id", "", "Proxy ID to use for the browser session")
2536+
browsersCreateCmd.Flags().String("start-url", "", "Initial page to open on launch")
25282537
browsersCreateCmd.Flags().StringSlice("extension", []string{}, "Extension IDs or names to load (repeatable; may be passed multiple times or comma-separated)")
25292538
browsersCreateCmd.Flags().String("viewport", "", "Browser viewport size (e.g., 1920x1080@25). Supported: 2560x1440@10, 1920x1080@25, 1920x1200@25, 1440x900@25, 1024x768@60, 1200x800@60, 1280x800@60")
25302539
browsersCreateCmd.Flags().Bool("viewport-interactive", false, "Interactively select viewport size from list")
@@ -2597,6 +2606,7 @@ func runBrowsersCreate(cmd *cobra.Command, args []string) error {
25972606
profileName, _ := cmd.Flags().GetString("profile-name")
25982607
saveChanges, _ := cmd.Flags().GetBool("save-changes")
25992608
proxyID, _ := cmd.Flags().GetString("proxy-id")
2609+
startURL, _ := cmd.Flags().GetString("start-url")
26002610
extensions, _ := cmd.Flags().GetStringSlice("extension")
26012611
viewport, _ := cmd.Flags().GetString("viewport")
26022612
viewportInteractive, _ := cmd.Flags().GetBool("viewport-interactive")
@@ -2676,7 +2686,7 @@ func runBrowsersCreate(cmd *cobra.Command, args []string) error {
26762686
if output == "json" {
26772687
return util.PrintPrettyJSON(resp)
26782688
}
2679-
printBrowserSessionResult(resp.SessionID, resp.CdpWsURL, resp.BrowserLiveViewURL, resp.Persistence, resp.Profile)
2689+
printBrowserSessionResult(resp.SessionID, resp.CdpWsURL, resp.BrowserLiveViewURL, resp.Persistence, resp.Profile, resp.StartURL)
26802690
return nil
26812691
}
26822692

@@ -2709,6 +2719,7 @@ func runBrowsersCreate(cmd *cobra.Command, args []string) error {
27092719
ProfileName: profileName,
27102720
ProfileSaveChanges: BoolFlag{Set: cmd.Flags().Changed("save-changes"), Value: saveChanges},
27112721
ProxyID: proxyID,
2722+
StartURL: startURL,
27122723
Extensions: extensions,
27132724
Viewport: viewport,
27142725
Output: output,

cmd/browsers_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1632,6 +1632,24 @@ func TestBrowsersCreate_WithViewportNoRefreshRate(t *testing.T) {
16321632
assert.False(t, captured.Viewport.RefreshRate.Valid())
16331633
}
16341634

1635+
func TestBrowsersCreate_WithStartURL(t *testing.T) {
1636+
setupStdoutCapture(t)
1637+
var captured kernel.BrowserNewParams
1638+
fake := &FakeBrowsersService{NewFunc: func(ctx context.Context, body kernel.BrowserNewParams, opts ...option.RequestOption) (*kernel.BrowserNewResponse, error) {
1639+
captured = body
1640+
return &kernel.BrowserNewResponse{SessionID: "session123", CdpWsURL: "ws://example"}, nil
1641+
}}
1642+
b := BrowsersCmd{browsers: fake}
1643+
1644+
err := b.Create(context.Background(), BrowsersCreateInput{
1645+
StartURL: "https://example.com",
1646+
})
1647+
1648+
assert.NoError(t, err)
1649+
assert.True(t, captured.StartURL.Valid())
1650+
assert.Equal(t, "https://example.com", captured.StartURL.Value)
1651+
}
1652+
16351653
func TestBrowsersCreate_WithInvalidViewport(t *testing.T) {
16361654
setupStdoutCapture(t)
16371655
fake := &FakeBrowsersService{}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ require (
99
github.com/charmbracelet/lipgloss/v2 v2.0.0-beta.1
1010
github.com/golang-jwt/jwt/v5 v5.2.2
1111
github.com/joho/godotenv v1.5.1
12-
github.com/kernel/kernel-go-sdk v0.52.0
12+
github.com/kernel/kernel-go-sdk v0.53.0
1313
github.com/klauspost/compress v1.18.5
1414
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
1515
github.com/pterm/pterm v0.12.80

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2
6464
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
6565
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
6666
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
67-
github.com/kernel/kernel-go-sdk v0.52.0 h1:ChRAMo6oMAEmazC610FtcqKFO/cqHzU9v1ECF0MiR8E=
68-
github.com/kernel/kernel-go-sdk v0.52.0/go.mod h1:EeZzSuHZVeHKxKCPUzxou2bovNGhXaz0RXrSqKNf1AQ=
67+
github.com/kernel/kernel-go-sdk v0.53.0 h1:XgcuJv3G4a6nr9LYBZ21gLUWvsIDLSG4YhZAngNrqE0=
68+
github.com/kernel/kernel-go-sdk v0.53.0/go.mod h1:EeZzSuHZVeHKxKCPUzxou2bovNGhXaz0RXrSqKNf1AQ=
6969
github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE=
7070
github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
7171
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=

0 commit comments

Comments
 (0)