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
6 changes: 3 additions & 3 deletions cmd/auth_connections.go
Original file line number Diff line number Diff line change
Expand Up @@ -1363,7 +1363,7 @@ func init() {
authConnectionsCreateCmd.Flags().String("proxy-id", "", "Proxy ID to use for this connection's browser sessions (mutually exclusive with --proxy-name and --proxy-mode)")
authConnectionsCreateCmd.Flags().String("proxy-name", "", "Proxy name to use for this connection's browser sessions (mutually exclusive with --proxy-id and --proxy-mode)")
authConnectionsCreateCmd.Flags().String("proxy-mode", "", "Proxy egress mode instead of a selected proxy: 'direct' for no proxy regardless of stealth, or 'default' for the stealth-derived default")
authConnectionsCreateCmd.Flags().String("region", "", "Geographic region for browser sessions: 'us-east', 'eu-west', or 'ap-southeast'. Defaults to us-east")
authConnectionsCreateCmd.Flags().String("region", "", "Geographic region for browser sessions: 'us-east', 'us-west', 'eu-west', or 'ap-southeast'. Defaults to us-east")
authConnectionsCreateCmd.Flags().Bool("stealth", true, "Run this connection's browser sessions in stealth mode; use --stealth=false to disable")
authConnectionsCreateCmd.Flags().Bool("no-save-credentials", false, "Disable saving credentials after successful login")
authConnectionsCreateCmd.Flags().Int("health-check-interval", 0, "Interval in seconds between health checks. Defaults to 3600 or your plan minimum, whichever is larger. The maximum is 86400; the minimum depends on your plan (Enterprise 300, Startup 1200, Hobbyist 3600, Free 21600)")
Expand Down Expand Up @@ -1392,7 +1392,7 @@ func init() {
authConnectionsUpdateCmd.Flags().String("proxy-id", "", "Proxy ID to use for future browser sessions (mutually exclusive with --proxy-name and --proxy-mode)")
authConnectionsUpdateCmd.Flags().String("proxy-name", "", "Proxy name to use for future browser sessions (mutually exclusive with --proxy-id and --proxy-mode)")
authConnectionsUpdateCmd.Flags().String("proxy-mode", "", "Proxy egress mode instead of a selected proxy: 'direct' for no proxy regardless of stealth, or 'default' to drop a selected proxy and use the stealth-derived default")
authConnectionsUpdateCmd.Flags().String("region", "", "Geographic region for future browser sessions: 'us-east', 'eu-west', or 'ap-southeast'")
authConnectionsUpdateCmd.Flags().String("region", "", "Geographic region for future browser sessions: 'us-east', 'us-west', 'eu-west', or 'ap-southeast'")
authConnectionsUpdateCmd.Flags().Bool("stealth", true, "Set whether future browser sessions run in stealth mode; use --stealth=false to disable")
authConnectionsUpdateCmd.Flags().Bool("save-credentials", false, "Enable saving credentials after successful login")
authConnectionsUpdateCmd.Flags().Bool("no-save-credentials", false, "Disable saving credentials after successful login")
Expand Down Expand Up @@ -1427,7 +1427,7 @@ func init() {
authConnectionsLoginCmd.Flags().String("proxy-id", "", "Proxy ID to use for this login (mutually exclusive with --proxy-name and --proxy-mode)")
authConnectionsLoginCmd.Flags().String("proxy-name", "", "Proxy name to use for this login (mutually exclusive with --proxy-id and --proxy-mode)")
authConnectionsLoginCmd.Flags().String("proxy-mode", "", "Proxy egress mode for this login instead of a selected proxy: 'direct' for no proxy regardless of stealth, or 'default' for the stealth-derived default")
authConnectionsLoginCmd.Flags().String("region", "", "Geographic region override for this login: 'us-east', 'eu-west', or 'ap-southeast'")
authConnectionsLoginCmd.Flags().String("region", "", "Geographic region override for this login: 'us-east', 'us-west', 'eu-west', or 'ap-southeast'")
authConnectionsLoginCmd.Flags().Bool("stealth", true, "Override stealth mode for this login's browser session; use --stealth=false to disable")
authConnectionsLoginCmd.Flags().Bool("record-session", false, "Override whether this login's browser session is recorded; use --record-session=false to disable")
authConnectionsLoginCmd.Flags().String("skill-mode", "", "Whether this login reads and writes learned domain skills: 'enabled' (default) or 'disabled'. Automatic reauths inherit the selected mode until a later accepted login sets enabled or omits the flag")
Expand Down
4 changes: 2 additions & 2 deletions cmd/browser_pools.go
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,7 @@ func init() {
browserPoolsListCmd.Flags().String("query", "", "Search browser pools by name (IDs match by exact value)")
browserPoolsListCmd.Flags().Int("limit", 0, "Maximum number of pools to return")
browserPoolsListCmd.Flags().Int("offset", 0, "Number of pools to skip (for pagination)")
browserPoolsListCmd.Flags().String("region", "", "Filter by geographic region: 'us-east', 'eu-west', or 'ap-southeast' (omit to list pools in all regions)")
browserPoolsListCmd.Flags().String("region", "", "Filter by geographic region: 'us-east', 'us-west', 'eu-west', or 'ap-southeast' (omit to list pools in all regions)")

addJSONOutputFlag(browserPoolsCreateCmd)
browserPoolsCreateCmd.Flags().String("name", "", "Optional unique name for the pool")
Expand All @@ -809,7 +809,7 @@ func init() {
browserPoolsCreateCmd.Flags().String("profile-id", "", "Profile ID")
browserPoolsCreateCmd.Flags().String("profile-name", "", "Profile name")
browserPoolsCreateCmd.Flags().String("proxy-id", "", "Proxy ID")
browserPoolsCreateCmd.Flags().String("region", "", "Geographic region for the pool: 'us-east', 'eu-west', or 'ap-southeast'. Fixed once the pool is created; requires a Start-Up or Enterprise plan and defaults to us-east")
browserPoolsCreateCmd.Flags().String("region", "", "Geographic region for the pool: 'us-east', 'us-west', 'eu-west', or 'ap-southeast'. Fixed once the pool is created; requires a Start-Up or Enterprise plan and defaults to us-east")
browserPoolsCreateCmd.Flags().StringSlice("private-host", nil, "Destinations browsers in the pool reach directly through their own network instead of Kernel-managed egress, for private hosts on a VPN or tunnel they join (repeat or comma-separated, max 32). Accepts hostname patterns ('*.example.ts.net'), IPs ('10.1.30.63', '[fd00::1]'), and private CIDRs ('100.64.0.0/10'). Replaces the default private ranges (RFC1918, 100.64.0.0/10, fc00::/7); omit to keep them")
browserPoolsCreateCmd.Flags().String("start-url", "", "Initial page to open for new browsers")
browserPoolsCreateCmd.Flags().StringSlice("extension", []string{}, "Extension IDs or names")
Expand Down
7 changes: 7 additions & 0 deletions cmd/browser_pools_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ func TestBrowserPoolsList_ForwardsRegion(t *testing.T) {
assert.Equal(t, kernel.BrowserPoolListParamsRegionApSoutheast, captured.Region)
assert.Contains(t, outBuf.String(), "ap-southeast")

err = c.List(context.Background(), BrowserPoolsListInput{Region: "us-west"})
assert.NoError(t, err)
assert.Equal(t, kernel.BrowserPoolListParamsRegionUsWest, captured.Region)

// Omitting the flag leaves the param unset, so all regions are listed.
captured = kernel.BrowserPoolListParams{}
err = c.List(context.Background(), BrowserPoolsListInput{})
Expand All @@ -175,6 +179,9 @@ func TestBrowserPoolsCreate_WithRegion(t *testing.T) {
require.NoError(t, c.Create(context.Background(), BrowserPoolsCreateInput{Size: 1, Region: "ap-southeast"}))
assert.Equal(t, kernel.BrowserPoolNewParamsRegionApSoutheast, captured.Region)

require.NoError(t, c.Create(context.Background(), BrowserPoolsCreateInput{Size: 1, Region: "us-west"}))
assert.Equal(t, kernel.BrowserPoolNewParamsRegionUsWest, captured.Region)

// Omitting the flag leaves the region unset so the API default applies.
require.NoError(t, c.Create(context.Background(), BrowserPoolsCreateInput{Size: 1}))
assert.Empty(t, string(captured.Region))
Expand Down
6 changes: 3 additions & 3 deletions cmd/browsers.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ func parseViewport(viewport string) (width, height, refreshRate int64, err error
// availableRegions returns the geographic regions the API accepts for browser
// sessions and pools.
func availableRegions() []string {
return []string{"us-east", "eu-west", "ap-southeast"}
return []string{"us-east", "us-west", "eu-west", "ap-southeast"}
}

// parseRegionFlag validates a --region value. An empty value means the flag was
Expand Down Expand Up @@ -2927,7 +2927,7 @@ func init() {
browsersListCmd.Flags().Int("limit", 0, "Maximum number of results to return (default 20, max 100)")
browsersListCmd.Flags().Int("offset", 0, "Number of results to skip (for pagination)")
browsersListCmd.Flags().String("query", "", "Search browsers by name, session ID, profile ID, proxy ID, or pool name")
browsersListCmd.Flags().String("region", "", "Filter by geographic region: 'us-east', 'eu-west', or 'ap-southeast' (omit to list sessions in all regions)")
browsersListCmd.Flags().String("region", "", "Filter by geographic region: 'us-east', 'us-west', 'eu-west', or 'ap-southeast' (omit to list sessions in all regions)")
browsersListCmd.Flags().StringArray("tag", nil, "Filter by tag KEY=VALUE (repeatable; a session must match every pair)")

// get flags
Expand Down Expand Up @@ -3251,7 +3251,7 @@ unrestricted code execution inside the browser VM and is not sandboxed.`,
browsersCreateCmd.Flags().String("proxy-id", "", "Proxy ID to use for the browser session (mutually exclusive with --proxy-name and --proxy-mode)")
browsersCreateCmd.Flags().String("proxy-name", "", "Proxy name to use for the browser session; must match exactly one active proxy in the project (mutually exclusive with --proxy-id and --proxy-mode)")
browsersCreateCmd.Flags().String("proxy-mode", "", "Proxy egress mode instead of a selected proxy: 'direct' for no proxy regardless of stealth, or 'default' for the browser default (Kernel's stealth proxy when --stealth is set, direct egress otherwise)")
browsersCreateCmd.Flags().String("region", "", "Geographic region for the session: 'us-east', 'eu-west', or 'ap-southeast'. Fixed once the session is created; requires a Start-Up or Enterprise plan and defaults to us-east")
browsersCreateCmd.Flags().String("region", "", "Geographic region for the session: 'us-east', 'us-west', 'eu-west', or 'ap-southeast'. Fixed once the session is created; requires a Start-Up or Enterprise plan and defaults to us-east")
browsersCreateCmd.Flags().StringSlice("private-host", nil, "Destinations the browser reaches directly through its own network instead of Kernel-managed egress, for private hosts on a VPN or tunnel the session joins (repeat or comma-separated, max 32). Accepts hostname patterns ('*.example.ts.net'), IPs ('10.1.30.63', '[fd00::1]'), and private CIDRs ('100.64.0.0/10'). Replaces the default private ranges (RFC1918, 100.64.0.0/10, fc00::/7); omit to keep them. Fixed once the session is created")
browsersCreateCmd.Flags().StringArray("proxy-route", nil, "Route HOST[,HOST...]=PROXY through a proxy (repeatable, max 10 routes and 50 hosts per route). PROXY is an ID by default; use id:ID or name:NAME explicitly. Exact hosts beat wildcards (longer suffixes win); *.example.com excludes example.com. Unmatched hosts use --proxy-* or default egress; start_url uses the top-level proxy. Create-only")
browsersCreateCmd.Flags().String("start-url", "", "Initial page to open on launch")
Expand Down
34 changes: 34 additions & 0 deletions cmd/browsers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,10 @@ func TestBrowsersList_WithRegion_PassesParam(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, kernel.BrowserListParamsRegionApSoutheast, captured.Region)

err = b.List(context.Background(), BrowsersListInput{Region: "us-west"})
assert.NoError(t, err)
assert.Equal(t, kernel.BrowserListParamsRegionUsWest, captured.Region)

// Omitting the flag leaves the param unset, so all regions are listed.
captured = kernel.BrowserListParams{}
err = b.List(context.Background(), BrowsersListInput{})
Expand Down Expand Up @@ -745,6 +749,13 @@ func TestBrowsersCreate_WithRegion(t *testing.T) {
require.NoError(t, err)
assert.Contains(t, string(raw), `"region":"ap-southeast"`)

err = b.Create(context.Background(), BrowsersCreateInput{Region: "us-west"})
require.NoError(t, err)
assert.Equal(t, kernel.BrowserNewParamsRegionUsWest, captured.Region)
raw, err = captured.MarshalJSON()
require.NoError(t, err)
assert.Contains(t, string(raw), `"region":"us-west"`)

// Omitting the flag sends nothing; the server defaults to us-east.
err = b.Create(context.Background(), BrowsersCreateInput{})
require.NoError(t, err)
Expand All @@ -758,6 +769,29 @@ func TestBrowsersCreate_WithRegion(t *testing.T) {
assert.Error(t, b.Create(context.Background(), BrowsersCreateInput{Region: "emea"}))
}

func TestBrowsersCreate_DisabledRegion(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "/browsers", r.URL.Path)
var body struct {
Region string `json:"region"`
}
assert.NoError(t, json.NewDecoder(r.Body).Decode(&body))
assert.Equal(t, "us-west", body.Region)
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusForbidden)
_, _ = io.WriteString(w, `{"code":"region_not_enabled","message":"region \"us-west\" is not enabled for your organization"}`)
}))
defer server.Close()
client := kernel.NewClient(option.WithBaseURL(server.URL), option.WithAPIKey("test-key"))
b := BrowsersCmd{browsers: &client.Browsers}

err := b.Create(context.Background(), BrowsersCreateInput{Region: "us-west"})
require.EqualError(t, err, `region_not_enabled: region "us-west" is not enabled for your organization`)
var apiErr *kernel.Error
require.ErrorAs(t, err, &apiErr)
assert.Equal(t, http.StatusForbidden, apiErr.StatusCode)
}

func TestBrowsersCreate_WithMemory(t *testing.T) {
setupStdoutCapture(t)

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.117.0
github.com/kernel/kernel-go-sdk v0.120.0
github.com/klauspost/compress v1.18.5
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
github.com/pterm/pterm v0.12.80
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,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.117.0 h1:b6/am7RkJyhadi/98pMHAyuiwyEoDD6smZ4V92pUJ40=
github.com/kernel/kernel-go-sdk v0.117.0/go.mod h1:EeZzSuHZVeHKxKCPUzxou2bovNGhXaz0RXrSqKNf1AQ=
github.com/kernel/kernel-go-sdk v0.120.0 h1:m4E5OPcv3jZfODi+zP5waICXL1fvcoBD0xdvDAAP4hM=
github.com/kernel/kernel-go-sdk v0.120.0/go.mod h1:EeZzSuHZVeHKxKCPUzxou2bovNGhXaz0RXrSqKNf1AQ=
github.com/klauspost/compress v1.18.5 h1:/h1gH5Ce+VWNLSWqPzOVn6XBO+vJbCNGvjoaGBFW2IE=
github.com/klauspost/compress v1.18.5/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
Expand Down
Loading