You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit ba58e9a
Browse filesBrowse the repository at this point in the historyBrowse files
Add --timezone and --locale to browsers create and update (#302)
## Summary
Adds `--timezone` and `--locale` to `kernel browsers create` and `kernel
browsers update`, plus `--clear-timezone` and `--clear-locale` to
`update`, so a session's timezone and locale can be set from the CLI.
Bumps `kernel-go-sdk` from v0.126.0 to v0.129.0, which adds the
`location` request and response fields.
- **create:** `--timezone Europe/Berlin --locale de-DE` sets either
override. An omitted flag uses the browser region's default.
- **update:** `--timezone`/`--locale` set an override.
`--clear-timezone`/`--clear-locale` send `null`, which clears it so the
browser goes back to its region's default, like `--clear-name` and the
other clear flags. An empty value is rejected with a pointer to the
clear flag, and set plus clear is an error. An omitted flag leaves the
field unchanged. Any one of the four counts as an update.
- **output:** `create`, `get`, and `update` show the effective timezone
and locale with their source, e.g. `Europe/Berlin (override)` or
`America/New_York (default)`. `-o json` already returned `location`.
The flags aren't added to pool acquire (`browsers create --pool-id`),
which doesn't accept a location; passing them there gets the existing
"flags will be ignored" warning.
## Validation
- `make test` (`go vet ./...`, `go test ./...`). New tests cover the
create and update params, `null` for the clear flags, the empty-value
and set-plus-clear errors (without calling the API), omitted flags not
being sent, `--clear-timezone --locale de-DE` reaching the API through
the cobra command, and the table output.
- `golangci-lint run ./cmd/`: no new findings.
- Ran the built binary against production on an organization with
location enabled: create with `--timezone Europe/Berlin --locale de-DE`,
then `update --clear-timezone --locale ja-JP` (timezone back to
`America/New_York (default)`, locale `ja-JP (override)`), then `update
--clear-locale` (both defaults). `update --timezone=""` and `update
--locale de-DE --clear-locale` were rejected locally. `get` showed the
same values. The browser was deleted afterwards.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> **Low Risk**
> CLI and SDK wiring for an existing browser location API; no auth or
infrastructure changes, with solid test coverage.
>
> **Overview**
> Adds CLI support for browser session **timezone** (IANA) and
**locale** (BCP 47) via new flags on `kernel browsers create` and
`kernel browsers update`, with `--clear-timezone` / `--clear-locale` on
update to reset overrides to the region default.
>
> Create sends optional `location` fields on the API; update sets values
or sends `null` to clear, with the usual validation (non-empty set
values, no mixing set and clear). **create**, **get**, and **update**
table output now shows effective timezone/locale and whether each comes
from an override or the region default.
>
> Bumps **kernel-go-sdk** from v0.126.0 to v0.129.0 for the `location`
request/response types. README and tests cover flag wiring, PATCH
payloads, errors, and display. Pool acquire (`create --pool-id`) does
not accept location; those flags still trigger the existing “ignored
with pool” behavior.
>
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
de106a4. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
---------
Co-authored-by: tnsardesai <18272584+tnsardesai@users.noreply.github.com>
- `--allowed-host <host>` - Set an egress allowlist at creation: the only destinations the browser may reach through Kernel-managed egress (repeatable or comma-separated, max 100). Other destinations are refused with a 403 whose `X-Kernel-Proxy-Error` header is `network_policy_denied`. Filters Kernel-managed egress only, not all browser VM traffic. Accepts exact hostnames (`example.com`), a leading wildcard that matches subdomains but not the domain itself (`*.example.com`), public IPs (`8.8.8.8`, `[2001:4860:4860::8888]`), and public CIDRs (`8.8.4.0/24`); no ports, paths, or schemes. `--start-url` must be allowed. Omit for unfiltered egress; an empty list is invalid. Requires proxy v3; cannot be combined with `--pool-id` or `--pool-name`, even with `--yes` (set the allowlist on the pool with `kernel browser-pools create/update --allowed-host`). An existing list can be replaced or removed later with `browsers update --allowed-host` / `--clear-allowed-hosts`, but cannot be added later if omitted at creation or removed.
272
272
-`--proxy-route '<host>[,<host>...]=<proxy>'` - Route matching browser requests through a selected proxy (repeatable, max 10 routes with 1–50 hosts each). Example: `--proxy-route 'api.ipify.org,*.ipify.org=name:my-dc-proxy'`. The proxy is an ID by default; use `id:<id>` or `name:<name>` explicitly. Exact hostnames beat wildcards; longer wildcard suffixes beat shorter ones. `*.example.com` matches subdomains, not `example.com`. Matching ignores case and ports. Unmatched hosts use `--proxy-*` or default egress. Routes apply from the start of the session, including to `--start-url`. Routes are create-only and cannot be combined with `--pool-id`/`--pool-name`; configure them on the pool instead.
273
273
-`--start-url <url>` - Initial page to open on launch
274
+
-`--timezone <iana>` - Session timezone, e.g. `Europe/Berlin`. Defaults to the browser region's timezone
275
+
-`--locale <bcp47>` - Session locale used for languages and date and number formatting, e.g. `de-DE`. Defaults to the browser region's locale
274
276
-`--proxy-id <id>` / `--proxy-name <name>` - Use that proxy for the session regardless of stealth (mutually exclusive with each other and with `--proxy-mode`)
275
277
-`--proxy-mode direct|default` - Egress mode instead of a selected proxy: `direct` for no proxy regardless of stealth, `default` for the stealth-derived default (Kernel's stealth proxy with `--stealth`, direct egress otherwise). Omit all proxy flags to get the default.
276
278
-`--name <name>` - Optional unique name for the session (used to find it later by name; can be changed with `browsers update --name`)
-`--tag <KEY=VALUE>` - Set a tag, repeatable; up to 50 pairs. Replaces the entire tag set (not merged); mutually exclusive with `--clear-tags`
299
301
-`--clear-tags` - Remove all tags from the session
302
+
-`--timezone <iana>` - Set the session timezone, e.g. `America/Los_Angeles`. Applies without restarting the browser; mutually exclusive with `--clear-timezone`
303
+
-`--clear-timezone` - Clear the timezone override and use the browser region's default
304
+
-`--locale <bcp47>` - Set the session locale, e.g. `de-DE`. Applies without restarting the browser; mutually exclusive with `--clear-locale`
305
+
-`--clear-locale` - Clear the locale override and use the browser region's default
300
306
-`--telemetry=all` - Enable telemetry for all categories
301
307
-`--telemetry=off` - Disable telemetry
302
308
-`--telemetry=<list>` - Per-category config, e.g. `--telemetry=network=on,page=off`
- Rename or clear the session name (--name or --clear-name)
2938
3009
- Replace or clear the session tags (--tag or --clear-tags)
2939
3010
- Navigate the session to a URL (--start-url)
3011
+
- Set or clear the session timezone and locale (--timezone, --locale, --clear-timezone, --clear-locale)
2940
3012
- Replace or remove the egress allowlist (--allowed-host or --clear-allowed-hosts)
2941
3013
2942
3014
Notes:
2943
3015
- Profiles can only be loaded into sessions that don't already have a profile.
2944
3016
- --start-url navigation is best-effort: the update succeeds even if the page fails to load.
2945
3017
- --start-url combined with --profile-id/--profile-name overrides the profile's restored tabs.
2946
3018
- --tag replaces the entire tag set (it is not merged with existing tags).
3019
+
- --timezone and --locale apply without restarting the browser. --clear-timezone and
3020
+
--clear-locale go back to the browser region's default. Omit a flag to leave that field unchanged.
3021
+
--start-url in the same update opens once the new location applies.
2947
3022
- --allowed-host replaces an existing allowlist only; it cannot add one to a browser created
2948
3023
without one. Omit to leave the list unchanged; an empty list is invalid.
2949
3024
- --clear-allowed-hosts removes the allowlist and returns to unfiltered egress. Once removed,
@@ -3006,6 +3081,10 @@ func init() {
3006
3081
browsersUpdateCmd.Flags().Bool("clear-tags", false, "Remove all tags from the browser session")
3007
3082
browsersUpdateCmd.Flags().StringSlice("allowed-host", nil, "Replace an existing egress allowlist (repeat or comma-separated, max 100), using the same entry rules as 'browsers create --allowed-host'. Cannot add one to a browser created without one or after removal. Omit to leave unchanged; an empty list is invalid. Applies without restarting the browser; --start-url must be allowed by the new list. Requires proxy v3; on leased pooled browsers the pool's allowlist is restored on release (mutually exclusive with --clear-allowed-hosts). See notes for propagation timing")
3008
3083
browsersUpdateCmd.Flags().Bool("clear-allowed-hosts", false, "Remove the egress allowlist and return to unfiltered egress; an allowlist cannot be added back to this browser")
3084
+
browsersUpdateCmd.Flags().String("timezone", "", "Set the session timezone (IANA, e.g. America/Los_Angeles) (mutually exclusive with --clear-timezone)")
3085
+
browsersUpdateCmd.Flags().Bool("clear-timezone", false, "Clear the session timezone override and use the browser region's default")
3086
+
browsersUpdateCmd.Flags().String("locale", "", "Set the session locale used for languages and date and number formatting (BCP 47, e.g. de-DE) (mutually exclusive with --clear-locale)")
3087
+
browsersUpdateCmd.Flags().Bool("clear-locale", false, "Clear the session locale override and use the browser region's default")
3009
3088
browsersUpdateCmd.Flags().String("start-url", "", "Navigate the browser to this URL after applying the update. Overrides the restored tabs when a profile is loaded in the same update. Navigation is best-effort, so failures do not fail the update")
3010
3089
3011
3090
browsersCmd.AddCommand(browsersListCmd)
@@ -3302,6 +3381,8 @@ unrestricted code execution inside the browser VM and is not sandboxed.`,
3302
3381
browsersCreateCmd.Flags().StringSlice("allowed-host", nil, "Set an egress allowlist at creation: the only destinations the browser may reach through Kernel-managed egress (repeat or comma-separated, max 100); anything else is refused with a 403 (network_policy_denied). Filters Kernel-managed egress only, not all browser VM traffic. Accepts exact hostnames ('example.com'), a leading wildcard matching subdomains only ('*.example.com'), public IPs ('8.8.8.8', '[2001:4860:4860::8888]'), and public CIDRs ('8.8.4.0/24'). No ports, paths, or schemes. --start-url must be allowed. Omit for unfiltered egress; an empty list is invalid. Requires proxy v3; cannot be combined with --pool-id or --pool-name, even with --yes. An existing list can be replaced or removed with 'browsers update'; it cannot be added later if omitted at creation or removed")
3303
3382
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. Routes also apply to start_url and other setup traffic. Create-only")
3304
3383
browsersCreateCmd.Flags().String("start-url", "", "Initial page to open on launch")
3384
+
browsersCreateCmd.Flags().String("timezone", "", "Session timezone (IANA, e.g. Europe/Berlin); defaults to the browser region's timezone")
3385
+
browsersCreateCmd.Flags().String("locale", "", "Session locale used for languages and date and number formatting (BCP 47, e.g. de-DE); defaults to the browser region's locale")
3305
3386
browsersCreateCmd.Flags().StringSlice("extension", []string{}, "Extension IDs or names to load (repeatable; may be passed multiple times or comma-separated)")
0 commit comments