From 48baab7aa0e23ed519a08b52142927340a8d451b Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Tue, 24 Mar 2026 02:56:23 +0000 Subject: [PATCH 01/12] chore(internal): update gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c6d0501..8554aff 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .prism.log +.stdy.log codegen.log Brewfile.lock.json .idea/ From 8296238ce0b45903e3d40420100aa29a3ab105fd Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Wed, 25 Mar 2026 02:31:06 +0000 Subject: [PATCH 02/12] chore(ci): skip lint on metadata-only changes Note that we still want to run tests, as these depend on the metadata. --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5eb5472..156d569 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,8 @@ jobs: runs-on: ${{ github.repository == 'stainless-sdks/kernel-go' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: |- github.repository == 'stainless-sdks/kernel-go' && - (github.event_name == 'push' || github.event.pull_request.head.repo.fork) + (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && + (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata') steps: - uses: actions/checkout@v6 From dd77af45f77a98e96f5d140bb737377f1d72456a Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 26 Mar 2026 02:52:01 +0000 Subject: [PATCH 03/12] chore(internal): support default value struct tag --- app.go | 2 +- authconnection.go | 2 +- deployment.go | 14 +++++++------- internal/apiform/tag.go | 26 +++++++++++++++++++++----- internal/apijson/encoder.go | 8 ++++++++ internal/apijson/json_test.go | 17 +++++++++++++++++ internal/apijson/tag.go | 26 +++++++++++++++++++++----- invocation.go | 2 +- shared/shared.go | 6 +++--- 9 files changed, 80 insertions(+), 23 deletions(-) diff --git a/app.go b/app.go index d3f4230..bac9291 100644 --- a/app.go +++ b/app.go @@ -76,7 +76,7 @@ type AppListResponse struct { // Environment variables configured for this app version EnvVars map[string]string `json:"env_vars" api:"required"` // Deployment region code - Region constant.AwsUsEast1a `json:"region" api:"required"` + Region constant.AwsUsEast1a `json:"region" default:"aws.us-east-1a"` // Version label for the application Version string `json:"version" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. diff --git a/authconnection.go b/authconnection.go index a9df222..ed76924 100644 --- a/authconnection.go +++ b/authconnection.go @@ -875,7 +875,7 @@ func (r *AuthConnectionFollowResponseUnion) UnmarshalJSON(data []byte) error { // An event representing the current state of a managed auth flow. type AuthConnectionFollowResponseManagedAuthState struct { // Event type identifier (always "managed_auth_state"). - Event constant.ManagedAuthState `json:"event" api:"required"` + Event constant.ManagedAuthState `json:"event" default:"managed_auth_state"` // Current flow status. // // Any of "IN_PROGRESS", "SUCCESS", "FAILED", "EXPIRED", "CANCELED". diff --git a/deployment.go b/deployment.go index 37b7e64..5d0380c 100644 --- a/deployment.go +++ b/deployment.go @@ -130,7 +130,7 @@ type DeploymentStateEvent struct { // Deployment record information. Deployment DeploymentStateEventDeployment `json:"deployment" api:"required"` // Event type identifier (always "deployment_state"). - Event constant.DeploymentState `json:"event" api:"required"` + Event constant.DeploymentState `json:"event" default:"deployment_state"` // Time the state was reported. Timestamp time.Time `json:"timestamp" api:"required" format:"date-time"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. @@ -156,7 +156,7 @@ type DeploymentStateEventDeployment struct { // Timestamp when the deployment was created CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"` // Deployment region code - Region constant.AwsUsEast1a `json:"region" api:"required"` + Region constant.AwsUsEast1a `json:"region" default:"aws.us-east-1a"` // Current status of the deployment // // Any of "queued", "in_progress", "running", "failed", "stopped". @@ -197,7 +197,7 @@ type DeploymentNewResponse struct { // Timestamp when the deployment was created CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"` // Deployment region code - Region constant.AwsUsEast1a `json:"region" api:"required"` + Region constant.AwsUsEast1a `json:"region" default:"aws.us-east-1a"` // Current status of the deployment // // Any of "queued", "in_progress", "running", "failed", "stopped". @@ -249,7 +249,7 @@ type DeploymentGetResponse struct { // Timestamp when the deployment was created CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"` // Deployment region code - Region constant.AwsUsEast1a `json:"region" api:"required"` + Region constant.AwsUsEast1a `json:"region" default:"aws.us-east-1a"` // Current status of the deployment // // Any of "queued", "in_progress", "running", "failed", "stopped". @@ -301,7 +301,7 @@ type DeploymentListResponse struct { // Timestamp when the deployment was created CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"` // Deployment region code - Region constant.AwsUsEast1a `json:"region" api:"required"` + Region constant.AwsUsEast1a `json:"region" default:"aws.us-east-1a"` // Current status of the deployment // // Any of "queued", "in_progress", "running", "failed", "stopped". @@ -433,9 +433,9 @@ type DeploymentFollowResponseAppVersionSummaryEvent struct { // Name of the application AppName string `json:"app_name" api:"required"` // Event type identifier (always "app_version_summary"). - Event constant.AppVersionSummary `json:"event" api:"required"` + Event constant.AppVersionSummary `json:"event" default:"app_version_summary"` // Deployment region code - Region constant.AwsUsEast1a `json:"region" api:"required"` + Region constant.AwsUsEast1a `json:"region" default:"aws.us-east-1a"` // Time the state was reported. Timestamp time.Time `json:"timestamp" api:"required" format:"date-time"` // Version label for the application diff --git a/internal/apiform/tag.go b/internal/apiform/tag.go index d9915d4..f0c9d14 100644 --- a/internal/apiform/tag.go +++ b/internal/apiform/tag.go @@ -9,13 +9,15 @@ const apiStructTag = "api" const jsonStructTag = "json" const formStructTag = "form" const formatStructTag = "format" +const defaultStructTag = "default" type parsedStructTag struct { - name string - required bool - extras bool - metadata bool - omitzero bool + name string + required bool + extras bool + metadata bool + omitzero bool + defaultValue any } func parseFormStructTag(field reflect.StructField) (tag parsedStructTag, ok bool) { @@ -45,9 +47,23 @@ func parseFormStructTag(field reflect.StructField) (tag parsedStructTag, ok bool } parseApiStructTag(field, &tag) + parseDefaultStructTag(field, &tag) return tag, ok } +func parseDefaultStructTag(field reflect.StructField, tag *parsedStructTag) { + if field.Type.Kind() != reflect.String { + // Only strings are currently supported + return + } + + raw, ok := field.Tag.Lookup(defaultStructTag) + if !ok { + return + } + tag.defaultValue = raw +} + func parseApiStructTag(field reflect.StructField, tag *parsedStructTag) { raw, ok := field.Tag.Lookup(apiStructTag) if !ok { diff --git a/internal/apijson/encoder.go b/internal/apijson/encoder.go index 0decb73..afe611e 100644 --- a/internal/apijson/encoder.go +++ b/internal/apijson/encoder.go @@ -12,6 +12,8 @@ import ( "time" "github.com/tidwall/sjson" + + shimjson "github.com/kernel/kernel-go-sdk/internal/encoding/json" ) var encoders sync.Map // map[encoderEntry]encoderFunc @@ -271,6 +273,12 @@ func (e *encoder) newStructTypeEncoder(t reflect.Type) encoderFunc { if err != nil { return nil, err } + if ef.tag.defaultValue != nil && (!field.IsValid() || field.IsZero()) { + encoded, err = shimjson.Marshal(ef.tag.defaultValue) + if err != nil { + return nil, err + } + } if encoded == nil { continue } diff --git a/internal/apijson/json_test.go b/internal/apijson/json_test.go index 19b3614..2853bf9 100644 --- a/internal/apijson/json_test.go +++ b/internal/apijson/json_test.go @@ -614,3 +614,20 @@ func TestEncode(t *testing.T) { }) } } + +type StructWithDefault struct { + Type string `json:"type" default:"foo"` +} + +func TestDefault(t *testing.T) { + value := StructWithDefault{} + expected := `{"type":"foo"}` + + raw, err := Marshal(value) + if err != nil { + t.Fatalf("serialization of %v failed with error %v", value, err) + } + if string(raw) != expected { + t.Fatalf("expected %+#v to serialize to %s but got %s", value, expected, string(raw)) + } +} diff --git a/internal/apijson/tag.go b/internal/apijson/tag.go index 17b2130..efcaf8c 100644 --- a/internal/apijson/tag.go +++ b/internal/apijson/tag.go @@ -8,13 +8,15 @@ import ( const apiStructTag = "api" const jsonStructTag = "json" const formatStructTag = "format" +const defaultStructTag = "default" type parsedStructTag struct { - name string - required bool - extras bool - metadata bool - inline bool + name string + required bool + extras bool + metadata bool + inline bool + defaultValue any } func parseJSONStructTag(field reflect.StructField) (tag parsedStructTag, ok bool) { @@ -42,9 +44,23 @@ func parseJSONStructTag(field reflect.StructField) (tag parsedStructTag, ok bool // the `api` struct tag is only used alongside `json` for custom behaviour parseApiStructTag(field, &tag) + parseDefaultStructTag(field, &tag) return tag, ok } +func parseDefaultStructTag(field reflect.StructField, tag *parsedStructTag) { + if field.Type.Kind() != reflect.String { + // Only strings are currently supported + return + } + + raw, ok := field.Tag.Lookup(defaultStructTag) + if !ok { + return + } + tag.defaultValue = raw +} + func parseApiStructTag(field reflect.StructField, tag *parsedStructTag) { raw, ok := field.Tag.Lookup(apiStructTag) if !ok { diff --git a/invocation.go b/invocation.go index 3a75523..775dd29 100644 --- a/invocation.go +++ b/invocation.go @@ -150,7 +150,7 @@ func (r *InvocationService) ListBrowsers(ctx context.Context, id string, opts .. // An event representing the current state of an invocation. type InvocationStateEvent struct { // Event type identifier (always "invocation_state"). - Event constant.InvocationState `json:"event" api:"required"` + Event constant.InvocationState `json:"event" default:"invocation_state"` Invocation InvocationStateEventInvocation `json:"invocation" api:"required"` // Time the state was reported. Timestamp time.Time `json:"timestamp" api:"required" format:"date-time"` diff --git a/shared/shared.go b/shared/shared.go index 10fcf8f..09471ec 100644 --- a/shared/shared.go +++ b/shared/shared.go @@ -257,7 +257,7 @@ func (r *ErrorDetail) UnmarshalJSON(data []byte) error { type ErrorEvent struct { Error ErrorModel `json:"error" api:"required"` // Event type identifier (always "error"). - Event constant.Error `json:"event" api:"required"` + Event constant.Error `json:"event" default:"error"` // Time the error occurred. Timestamp time.Time `json:"timestamp" api:"required" format:"date-time"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. @@ -307,7 +307,7 @@ func (r *ErrorModel) UnmarshalJSON(data []byte) error { // Heartbeat event sent periodically to keep SSE connection alive. type HeartbeatEvent struct { // Event type identifier (always "sse_heartbeat"). - Event constant.SseHeartbeat `json:"event" api:"required"` + Event constant.SseHeartbeat `json:"event" default:"sse_heartbeat"` // Time the heartbeat was sent. Timestamp time.Time `json:"timestamp" api:"required" format:"date-time"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. @@ -331,7 +331,7 @@ func (HeartbeatEvent) ImplAuthConnectionFollowResponseUnion() {} // A log entry from the application. type LogEvent struct { // Event type identifier (always "log"). - Event constant.Log `json:"event" api:"required"` + Event constant.Log `json:"event" default:"log"` // Log message text. Message string `json:"message" api:"required"` // Time the log entry was produced. From cabda49a25334cd3fa3fc747f69b8a515e2b77d9 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 26 Mar 2026 02:56:45 +0000 Subject: [PATCH 04/12] chore(client): fix multipart serialisation of Default() fields --- internal/apiform/encoder.go | 8 ++++++++ internal/apiform/form_test.go | 36 +++++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/internal/apiform/encoder.go b/internal/apiform/encoder.go index b93e5a3..cf9e767 100644 --- a/internal/apiform/encoder.go +++ b/internal/apiform/encoder.go @@ -265,6 +265,14 @@ func (e *encoder) newStructTypeEncoder(t reflect.Type) encoderFunc { } return typeEncoderFn(key, value, writer) } + } else if ptag.defaultValue != nil { + typeEncoderFn := e.typeEncoder(field.Type) + encoderFn = func(key string, value reflect.Value, writer *multipart.Writer) error { + if value.IsZero() { + return typeEncoderFn(key, reflect.ValueOf(ptag.defaultValue), writer) + } + return typeEncoderFn(key, value, writer) + } } else { encoderFn = e.typeEncoder(field.Type) } diff --git a/internal/apiform/form_test.go b/internal/apiform/form_test.go index 76d8a92..0660fd1 100644 --- a/internal/apiform/form_test.go +++ b/internal/apiform/form_test.go @@ -123,6 +123,11 @@ type StructUnion struct { param.APIUnion } +type ConstantStruct struct { + Anchor string `form:"anchor" default:"created_at"` + Seconds int `form:"seconds"` +} + type MultipartMarshalerParent struct { Middle MultipartMarshalerMiddleNext `form:"middle"` } @@ -554,6 +559,37 @@ Content-Disposition: form-data; name="union" Union: UnionTime(time.Date(2010, 05, 23, 0, 0, 0, 0, time.UTC)), }, }, + "constant_zero_value": { + `--xxx +Content-Disposition: form-data; name="anchor" + +created_at +--xxx +Content-Disposition: form-data; name="seconds" + +3600 +--xxx-- +`, + ConstantStruct{ + Seconds: 3600, + }, + }, + "constant_explicit_value": { + `--xxx +Content-Disposition: form-data; name="anchor" + +created_at_override +--xxx +Content-Disposition: form-data; name="seconds" + +3600 +--xxx-- +`, + ConstantStruct{ + Anchor: "created_at_override", + Seconds: 3600, + }, + }, "deeply-nested-struct,brackets": { `--xxx Content-Disposition: form-data; name="middle[middleNext][child]" From e740db79ec07414b5b0b5ff3be98b9e089a9bb45 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 26 Mar 2026 14:38:55 +0000 Subject: [PATCH 05/12] feat: [kernel-1008] browser pools add custom policy --- .stats.yml | 4 ++-- browserpool.go | 16 ++++++++++++++++ browserpool_test.go | 8 +++++++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/.stats.yml b/.stats.yml index be60802..8a5c9d0 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 104 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-bb2ac8e0d3a1c08e8afcbcbad7cb733d0f84bd22a8d233c1ec3100a01ee078ae.yml -openapi_spec_hash: a83f7d1c422c85d6dc6158af7afe1d09 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-aeb5ea5c2632fe7fd905d509bc6cbb06999d17c458ec44ffd713935ba5b848f9.yml +openapi_spec_hash: fef45a8569f1d3de04c86e95b1112665 config_hash: 16e4457a0bb26e98a335a1c2a572290a diff --git a/browserpool.go b/browserpool.go index 303f117..54ac2aa 100644 --- a/browserpool.go +++ b/browserpool.go @@ -173,6 +173,11 @@ type BrowserPoolBrowserPoolConfig struct { // your organization's pooled sessions limit (the sum of all pool sizes cannot // exceed your limit). Size int64 `json:"size" api:"required"` + // Custom Chrome enterprise policy overrides applied to all browsers in this pool. + // Keys are Chrome enterprise policy names; values must match their expected types. + // Blocked: kernel-managed policies (extensions, proxy, CDP/automation). See + // https://chromeenterprise.google/policies/ + ChromePolicy map[string]any `json:"chrome_policy"` // List of browser extensions to load into the session. Provide each by id or name. Extensions []shared.BrowserExtension `json:"extensions"` // Percentage of the pool to fill per minute. Defaults to 10%. @@ -213,6 +218,7 @@ type BrowserPoolBrowserPoolConfig struct { // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { Size respjson.Field + ChromePolicy respjson.Field Extensions respjson.Field FillRatePerMinute respjson.Field Headless respjson.Field @@ -337,6 +343,11 @@ type BrowserPoolNewParams struct { // Default idle timeout in seconds for browsers acquired from this pool before they // are destroyed. Defaults to 600 seconds if not specified TimeoutSeconds param.Opt[int64] `json:"timeout_seconds,omitzero"` + // Custom Chrome enterprise policy overrides applied to all browsers in this pool. + // Keys are Chrome enterprise policy names; values must match their expected types. + // Blocked: kernel-managed policies (extensions, proxy, CDP/automation). See + // https://chromeenterprise.google/policies/ + ChromePolicy map[string]any `json:"chrome_policy,omitzero"` // List of browser extensions to load into the session. Provide each by id or name. Extensions []shared.BrowserExtensionParam `json:"extensions,omitzero"` // Profile selection for the browser session. Provide either id or name. If @@ -393,6 +404,11 @@ type BrowserPoolUpdateParams struct { // Default idle timeout in seconds for browsers acquired from this pool before they // are destroyed. Defaults to 600 seconds if not specified TimeoutSeconds param.Opt[int64] `json:"timeout_seconds,omitzero"` + // Custom Chrome enterprise policy overrides applied to all browsers in this pool. + // Keys are Chrome enterprise policy names; values must match their expected types. + // Blocked: kernel-managed policies (extensions, proxy, CDP/automation). See + // https://chromeenterprise.google/policies/ + ChromePolicy map[string]any `json:"chrome_policy,omitzero"` // List of browser extensions to load into the session. Provide each by id or name. Extensions []shared.BrowserExtensionParam `json:"extensions,omitzero"` // Profile selection for the browser session. Provide either id or name. If diff --git a/browserpool_test.go b/browserpool_test.go index 0bed0f3..fd59d64 100644 --- a/browserpool_test.go +++ b/browserpool_test.go @@ -29,6 +29,9 @@ func TestBrowserPoolNewWithOptionalParams(t *testing.T) { ) _, err := client.BrowserPools.New(context.TODO(), kernel.BrowserPoolNewParams{ Size: 10, + ChromePolicy: map[string]any{ + "foo": "bar", + }, Extensions: []shared.BrowserExtensionParam{{ ID: kernel.String("id"), Name: kernel.String("name"), @@ -100,7 +103,10 @@ func TestBrowserPoolUpdateWithOptionalParams(t *testing.T) { context.TODO(), "id_or_name", kernel.BrowserPoolUpdateParams{ - Size: 10, + Size: 10, + ChromePolicy: map[string]any{ + "foo": "bar", + }, DiscardAllIdle: kernel.Bool(false), Extensions: []shared.BrowserExtensionParam{{ ID: kernel.String("id"), From 66d97d350f30d933b1cd4596da6e3fb4cac8c4a1 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 03:43:40 +0000 Subject: [PATCH 06/12] fix: prevent duplicate ? in query params --- internal/requestconfig/requestconfig.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/internal/requestconfig/requestconfig.go b/internal/requestconfig/requestconfig.go index 4be744f..451dae0 100644 --- a/internal/requestconfig/requestconfig.go +++ b/internal/requestconfig/requestconfig.go @@ -121,7 +121,16 @@ func NewRequestConfig(ctx context.Context, method string, u string, body any, ds } params := q.Encode() if params != "" { - u = u + "?" + params + parsed, err := url.Parse(u) + if err != nil { + return nil, err + } + if parsed.RawQuery != "" { + parsed.RawQuery = parsed.RawQuery + "&" + params + u = parsed.String() + } else { + u = u + "?" + params + } } } if body, ok := body.([]byte); ok { From 05d2048b0cc9027c63a4036b9f722044423f4e25 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 03:48:04 +0000 Subject: [PATCH 07/12] chore: remove unnecessary error check for url parsing --- internal/requestconfig/requestconfig.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/internal/requestconfig/requestconfig.go b/internal/requestconfig/requestconfig.go index 451dae0..6595f2b 100644 --- a/internal/requestconfig/requestconfig.go +++ b/internal/requestconfig/requestconfig.go @@ -121,10 +121,7 @@ func NewRequestConfig(ctx context.Context, method string, u string, body any, ds } params := q.Encode() if params != "" { - parsed, err := url.Parse(u) - if err != nil { - return nil, err - } + parsed, _ := url.Parse(u) if parsed.RawQuery != "" { parsed.RawQuery = parsed.RawQuery + "&" + params u = parsed.String() From 74f5c6a22be0f953416968dfc92b0354f66d5cd9 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Fri, 27 Mar 2026 03:48:50 +0000 Subject: [PATCH 08/12] feat(internal): support comma format in multipart form encoding --- internal/apiform/encoder.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/internal/apiform/encoder.go b/internal/apiform/encoder.go index cf9e767..5cf185c 100644 --- a/internal/apiform/encoder.go +++ b/internal/apiform/encoder.go @@ -183,6 +183,18 @@ func (e *encoder) newPrimitiveTypeEncoder(t reflect.Type) encoderFunc { func (e *encoder) newArrayTypeEncoder(t reflect.Type) encoderFunc { itemEncoder := e.typeEncoder(t.Elem()) keyFn := e.arrayKeyEncoder() + if e.arrayFmt == "comma" { + return func(key string, v reflect.Value, writer *multipart.Writer) error { + if v.Len() == 0 { + return nil + } + elements := make([]string, v.Len()) + for i := 0; i < v.Len(); i++ { + elements[i] = fmt.Sprint(v.Index(i).Interface()) + } + return writer.WriteField(key, strings.Join(elements, ",")) + } + } return func(key string, v reflect.Value, writer *multipart.Writer) error { if keyFn == nil { return fmt.Errorf("apiform: unsupported array format") From 708da0fffff51a8f20905f9983e5beb1181a6a48 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 28 Mar 2026 04:04:47 +0000 Subject: [PATCH 09/12] chore(ci): support opting out of skipping builds on metadata-only commits --- .github/workflows/ci.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 156d569..ee48f67 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,8 +24,7 @@ jobs: runs-on: ${{ github.repository == 'stainless-sdks/kernel-go' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: |- github.repository == 'stainless-sdks/kernel-go' && - (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && - (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata') + (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata') steps: - uses: actions/checkout@v6 From abfd9883774e74c2d4c2cc482377364432318e27 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Sat, 28 Mar 2026 04:11:45 +0000 Subject: [PATCH 10/12] chore: update docs for api:"required" --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9594193..a60c391 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ func main() { The kernel library uses the [`omitzero`](https://tip.golang.org/doc/go1.24#encodingjsonpkgencodingjson) semantics from the Go 1.24+ `encoding/json` release for request fields. -Required primitive fields (`int64`, `string`, etc.) feature the tag \`json:"...,required"\`. These +Required primitive fields (`int64`, `string`, etc.) feature the tag \`api:"required"\`. These fields are always serialized, even their zero values. Optional primitive types are wrapped in a `param.Opt[T]`. These fields can be set with the provided constructors, `kernel.String(string)`, `kernel.Int(int64)`, etc. From f584af5155e3fe8bb6dd87f48e1c5ee6cfe47111 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2026 18:01:05 +0000 Subject: [PATCH 11/12] feat: Add disable_default_proxy for stealth browsers --- .stats.yml | 4 ++-- browser.go | 3 +++ browser_test.go | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.stats.yml b/.stats.yml index 8a5c9d0..8ed1b33 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 104 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-aeb5ea5c2632fe7fd905d509bc6cbb06999d17c458ec44ffd713935ba5b848f9.yml -openapi_spec_hash: fef45a8569f1d3de04c86e95b1112665 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-20310988401243aa5c4a2e2ac6cba5dd90873fb7b83497a2d50c691352c0dd7b.yml +openapi_spec_hash: e19e650b4b2c8c8fde1f739c4aab6b33 config_hash: 16e4457a0bb26e98a335a1c2a572290a diff --git a/browser.go b/browser.go index 4aef02f..87daf2e 100644 --- a/browser.go +++ b/browser.go @@ -671,6 +671,9 @@ type BrowserUpdateParams struct { // ID of the proxy to use. Omit to leave unchanged, set to empty string to remove // proxy. ProxyID param.Opt[string] `json:"proxy_id,omitzero"` + // If true, stealth browsers connect directly instead of using the default stealth + // proxy. + DisableDefaultProxy param.Opt[bool] `json:"disable_default_proxy,omitzero"` // Profile to load into the browser session. Only allowed if the session does not // already have a profile loaded. Profile shared.BrowserProfileParam `json:"profile,omitzero"` diff --git a/browser_test.go b/browser_test.go index a649334..40b7829 100644 --- a/browser_test.go +++ b/browser_test.go @@ -110,6 +110,7 @@ func TestBrowserUpdateWithOptionalParams(t *testing.T) { context.TODO(), "htzv5orfit78e1m2biiifpbv", kernel.BrowserUpdateParams{ + DisableDefaultProxy: kernel.Bool(true), Profile: shared.BrowserProfileParam{ ID: kernel.String("id"), Name: kernel.String("name"), From 8154c255b6f0bff434121cdde0746133224bedb4 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2026 18:01:32 +0000 Subject: [PATCH 12/12] release: 0.45.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 26 ++++++++++++++++++++++++++ README.md | 2 +- internal/version.go | 2 +- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index cc51f6f..fc0d7ff 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.44.0" + ".": "0.45.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 7785f78..36ae3e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,31 @@ # Changelog +## 0.45.0 (2026-03-30) + +Full Changelog: [v0.44.0...v0.45.0](https://github.com/kernel/kernel-go-sdk/compare/v0.44.0...v0.45.0) + +### Features + +* [kernel-1008] browser pools add custom policy ([e740db7](https://github.com/kernel/kernel-go-sdk/commit/e740db79ec07414b5b0b5ff3be98b9e089a9bb45)) +* Add disable_default_proxy for stealth browsers ([f584af5](https://github.com/kernel/kernel-go-sdk/commit/f584af5155e3fe8bb6dd87f48e1c5ee6cfe47111)) +* **internal:** support comma format in multipart form encoding ([74f5c6a](https://github.com/kernel/kernel-go-sdk/commit/74f5c6a22be0f953416968dfc92b0354f66d5cd9)) + + +### Bug Fixes + +* prevent duplicate ? in query params ([66d97d3](https://github.com/kernel/kernel-go-sdk/commit/66d97d350f30d933b1cd4596da6e3fb4cac8c4a1)) + + +### Chores + +* **ci:** skip lint on metadata-only changes ([8296238](https://github.com/kernel/kernel-go-sdk/commit/8296238ce0b45903e3d40420100aa29a3ab105fd)) +* **ci:** support opting out of skipping builds on metadata-only commits ([708da0f](https://github.com/kernel/kernel-go-sdk/commit/708da0fffff51a8f20905f9983e5beb1181a6a48)) +* **client:** fix multipart serialisation of Default() fields ([cabda49](https://github.com/kernel/kernel-go-sdk/commit/cabda49a25334cd3fa3fc747f69b8a515e2b77d9)) +* **internal:** support default value struct tag ([dd77af4](https://github.com/kernel/kernel-go-sdk/commit/dd77af45f77a98e96f5d140bb737377f1d72456a)) +* **internal:** update gitignore ([48baab7](https://github.com/kernel/kernel-go-sdk/commit/48baab7aa0e23ed519a08b52142927340a8d451b)) +* remove unnecessary error check for url parsing ([05d2048](https://github.com/kernel/kernel-go-sdk/commit/05d2048b0cc9027c63a4036b9f722044423f4e25)) +* update docs for api:"required" ([abfd988](https://github.com/kernel/kernel-go-sdk/commit/abfd9883774e74c2d4c2cc482377364432318e27)) + ## 0.44.0 (2026-03-20) Full Changelog: [v0.43.0...v0.44.0](https://github.com/kernel/kernel-go-sdk/compare/v0.43.0...v0.44.0) diff --git a/README.md b/README.md index a60c391..c114a13 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ Or to pin the version: ```sh -go get -u 'github.com/kernel/kernel-go-sdk@v0.44.0' +go get -u 'github.com/kernel/kernel-go-sdk@v0.45.0' ``` diff --git a/internal/version.go b/internal/version.go index 27842b2..0f8ee25 100644 --- a/internal/version.go +++ b/internal/version.go @@ -2,4 +2,4 @@ package internal -const PackageVersion = "0.44.0" // x-release-please-version +const PackageVersion = "0.45.0" // x-release-please-version