From 79d4c5c4ab915159c0536019ea1504576a9c26f4 Mon Sep 17 00:00:00 2001 From: "kernel-internal[bot]" <260533166+kernel-internal[bot]@users.noreply.github.com> Date: Wed, 12 Aug 2026 17:14:55 +0000 Subject: [PATCH 1/3] feat: Support project selection by ID or name Stainless-Generated-From: 1e38bfb1a4fe9067677b94c42d243729102ef9a9 --- api.md | 10 ++++----- internal/requestconfig/requestconfig.go | 2 ++ option/requestoption.go | 8 +++++++ project.go | 28 ++++++++++++------------- project_test.go | 6 +++--- projectlimit.go | 16 +++++++------- projectlimit_test.go | 4 ++-- 7 files changed, 42 insertions(+), 32 deletions(-) diff --git a/api.md b/api.md index b33173f..60e3df2 100644 --- a/api.md +++ b/api.md @@ -409,10 +409,10 @@ Response Types: Methods: - client.Projects.New(ctx context.Context, body kernel.ProjectNewParams) (\*kernel.Project, error) -- client.Projects.Get(ctx context.Context, id string) (\*kernel.Project, error) -- client.Projects.Update(ctx context.Context, id string, body kernel.ProjectUpdateParams) (\*kernel.Project, error) +- client.Projects.Get(ctx context.Context, idOrName string) (\*kernel.Project, error) +- client.Projects.Update(ctx context.Context, idOrName string, body kernel.ProjectUpdateParams) (\*kernel.Project, error) - client.Projects.List(ctx context.Context, query kernel.ProjectListParams) (\*pagination.OffsetPagination[kernel.Project], error) -- client.Projects.Delete(ctx context.Context, id string) error +- client.Projects.Delete(ctx context.Context, idOrName string) error ## Limits @@ -426,8 +426,8 @@ Response Types: Methods: -- client.Projects.Limits.Get(ctx context.Context, id string) (\*kernel.ProjectLimits, error) -- client.Projects.Limits.Update(ctx context.Context, id string, body kernel.ProjectLimitUpdateParams) (\*kernel.ProjectLimits, error) +- client.Projects.Limits.Get(ctx context.Context, idOrName string) (\*kernel.ProjectLimits, error) +- client.Projects.Limits.Update(ctx context.Context, idOrName string, body kernel.ProjectLimitUpdateParams) (\*kernel.ProjectLimits, error) # Organization diff --git a/internal/requestconfig/requestconfig.go b/internal/requestconfig/requestconfig.go index 334b381..ffc3826 100644 --- a/internal/requestconfig/requestconfig.go +++ b/internal/requestconfig/requestconfig.go @@ -220,6 +220,7 @@ type RequestConfig struct { Middlewares []middleware APIKey string ProjectID string + Project string // If ResponseBodyInto not nil, then we will attempt to deserialize into // ResponseBodyInto. If Destination is a []byte, then it will return the body as // is. @@ -595,6 +596,7 @@ func (cfg *RequestConfig) Clone(ctx context.Context) *RequestConfig { Middlewares: cfg.Middlewares, APIKey: cfg.APIKey, ProjectID: cfg.ProjectID, + Project: cfg.Project, } return new diff --git a/option/requestoption.go b/option/requestoption.go index 9b0d4f8..dd3634e 100644 --- a/option/requestoption.go +++ b/option/requestoption.go @@ -288,3 +288,11 @@ func WithProjectID(value string) RequestOption { return r.Apply(WithHeader("X-Kernel-Project-Id", value)) }) } + +// WithProject returns a RequestOption that sets the client setting "project". +func WithProject(value string) RequestOption { + return requestconfig.RequestOptionFunc(func(r *requestconfig.RequestConfig) error { + r.Project = value + return r.Apply(WithHeader("X-Kernel-Project", value)) + }) +} diff --git a/project.go b/project.go index fdac65b..fee6046 100644 --- a/project.go +++ b/project.go @@ -58,25 +58,25 @@ func (r *ProjectService) New(ctx context.Context, body ProjectNewParams, opts .. } // Get a project by its ID or by its name. Names are unique within an organization. -func (r *ProjectService) Get(ctx context.Context, id string, opts ...option.RequestOption) (res *Project, err error) { +func (r *ProjectService) Get(ctx context.Context, idOrName string, opts ...option.RequestOption) (res *Project, err error) { opts = slices.Concat(r.Options, opts) - if id == "" { - err = errors.New("missing required id parameter") + if idOrName == "" { + err = errors.New("missing required id_or_name parameter") return nil, err } - path := fmt.Sprintf("org/projects/%s", id) + path := fmt.Sprintf("org/projects/%s", idOrName) err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) return res, err } // Update a project's name or status. -func (r *ProjectService) Update(ctx context.Context, id string, body ProjectUpdateParams, opts ...option.RequestOption) (res *Project, err error) { +func (r *ProjectService) Update(ctx context.Context, idOrName string, body ProjectUpdateParams, opts ...option.RequestOption) (res *Project, err error) { opts = slices.Concat(r.Options, opts) - if id == "" { - err = errors.New("missing required id parameter") + if idOrName == "" { + err = errors.New("missing required id_or_name parameter") return nil, err } - path := fmt.Sprintf("org/projects/%s", id) + path := fmt.Sprintf("org/projects/%s", idOrName) err = requestconfig.ExecuteNewRequest(ctx, http.MethodPatch, path, body, &res, opts...) return res, err } @@ -105,21 +105,21 @@ func (r *ProjectService) ListAutoPaging(ctx context.Context, query ProjectListPa } // Soft-delete a project. The project must be empty (no active resources). -func (r *ProjectService) Delete(ctx context.Context, id string, opts ...option.RequestOption) (err error) { +func (r *ProjectService) Delete(ctx context.Context, idOrName string, opts ...option.RequestOption) (err error) { opts = slices.Concat(r.Options, opts) opts = append([]option.RequestOption{option.WithHeader("Accept", "*/*")}, opts...) - if id == "" { - err = errors.New("missing required id parameter") + if idOrName == "" { + err = errors.New("missing required id_or_name parameter") return err } - path := fmt.Sprintf("org/projects/%s", id) + path := fmt.Sprintf("org/projects/%s", idOrName) err = requestconfig.ExecuteNewRequest(ctx, http.MethodDelete, path, nil, nil, opts...) return err } // The property Name is required. type CreateProjectRequestParam struct { - // Project name (1-255 Unicode code points) + // Project name (1-255 Unicode code points; cannot contain `/` or `%`) Name string `json:"name" api:"required"` paramObj } @@ -172,7 +172,7 @@ const ( ) type UpdateProjectRequestParam struct { - // New project name (1-255 Unicode code points) + // New project name (1-255 Unicode code points; cannot contain `/` or `%`) Name param.Opt[string] `json:"name,omitzero"` // New project status // diff --git a/project_test.go b/project_test.go index 40f1724..95a8054 100644 --- a/project_test.go +++ b/project_test.go @@ -53,7 +53,7 @@ func TestProjectGet(t *testing.T) { option.WithBaseURL(baseURL), option.WithAPIKey("My API Key"), ) - _, err := client.Projects.Get(context.TODO(), "id") + _, err := client.Projects.Get(context.TODO(), "id_or_name") if err != nil { var apierr *kernel.Error if errors.As(err, &apierr) { @@ -78,7 +78,7 @@ func TestProjectUpdateWithOptionalParams(t *testing.T) { ) _, err := client.Projects.Update( context.TODO(), - "id", + "id_or_name", kernel.ProjectUpdateParams{ UpdateProjectRequest: kernel.UpdateProjectRequestParam{ Name: kernel.String("x"), @@ -136,7 +136,7 @@ func TestProjectDelete(t *testing.T) { option.WithBaseURL(baseURL), option.WithAPIKey("My API Key"), ) - err := client.Projects.Delete(context.TODO(), "id") + err := client.Projects.Delete(context.TODO(), "id_or_name") if err != nil { var apierr *kernel.Error if errors.As(err, &apierr) { diff --git a/projectlimit.go b/projectlimit.go index 85c0101..b268ee8 100644 --- a/projectlimit.go +++ b/projectlimit.go @@ -42,13 +42,13 @@ func NewProjectLimitService(opts ...option.RequestOption) (r ProjectLimitService // Get the resource limit overrides for a project. Null values mean no // project-level cap (org limit applies). -func (r *ProjectLimitService) Get(ctx context.Context, id string, opts ...option.RequestOption) (res *ProjectLimits, err error) { +func (r *ProjectLimitService) Get(ctx context.Context, idOrName string, opts ...option.RequestOption) (res *ProjectLimits, err error) { opts = slices.Concat(r.Options, opts) - if id == "" { - err = errors.New("missing required id parameter") + if idOrName == "" { + err = errors.New("missing required id_or_name parameter") return nil, err } - path := fmt.Sprintf("org/projects/%s/limits", id) + path := fmt.Sprintf("org/projects/%s/limits", idOrName) err = requestconfig.ExecuteNewRequest(ctx, http.MethodGet, path, nil, &res, opts...) return res, err } @@ -56,13 +56,13 @@ func (r *ProjectLimitService) Get(ctx context.Context, id string, opts ...option // Update resource limit overrides for a project. Only fields present in the // request are modified. Set a field to 0 to remove that limit cap; omit a field to // leave it unchanged. -func (r *ProjectLimitService) Update(ctx context.Context, id string, body ProjectLimitUpdateParams, opts ...option.RequestOption) (res *ProjectLimits, err error) { +func (r *ProjectLimitService) Update(ctx context.Context, idOrName string, body ProjectLimitUpdateParams, opts ...option.RequestOption) (res *ProjectLimits, err error) { opts = slices.Concat(r.Options, opts) - if id == "" { - err = errors.New("missing required id parameter") + if idOrName == "" { + err = errors.New("missing required id_or_name parameter") return nil, err } - path := fmt.Sprintf("org/projects/%s/limits", id) + path := fmt.Sprintf("org/projects/%s/limits", idOrName) err = requestconfig.ExecuteNewRequest(ctx, http.MethodPatch, path, body, &res, opts...) return res, err } diff --git a/projectlimit_test.go b/projectlimit_test.go index 180bbf4..dfd3560 100644 --- a/projectlimit_test.go +++ b/projectlimit_test.go @@ -26,7 +26,7 @@ func TestProjectLimitGet(t *testing.T) { option.WithBaseURL(baseURL), option.WithAPIKey("My API Key"), ) - _, err := client.Projects.Limits.Get(context.TODO(), "id") + _, err := client.Projects.Limits.Get(context.TODO(), "id_or_name") if err != nil { var apierr *kernel.Error if errors.As(err, &apierr) { @@ -51,7 +51,7 @@ func TestProjectLimitUpdateWithOptionalParams(t *testing.T) { ) _, err := client.Projects.Limits.Update( context.TODO(), - "id", + "id_or_name", kernel.ProjectLimitUpdateParams{ UpdateProjectLimitsRequest: kernel.UpdateProjectLimitsRequestParam{ MaxConcurrentInvocations: kernel.Int(0), From 6a142ab834fe7714d460b5507795546144b3c114 Mon Sep 17 00:00:00 2001 From: "kernel-internal[bot]" <260533166+kernel-internal[bot]@users.noreply.github.com> Date: Wed, 12 Aug 2026 23:31:07 +0000 Subject: [PATCH 2/3] feat: Preserve canonical managed auth input metadata Stainless-Generated-From: 2b635b10cbd732d85925d7d166623c3f94e0ef4d --- authconnection.go | 66 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/authconnection.go b/authconnection.go index 5ee635c..8a1138a 100644 --- a/authconnection.go +++ b/authconnection.go @@ -666,19 +666,35 @@ type ManagedAuthChoice struct { // Any of "mfa_method", "sso_provider", "sign_in_method", "auth_method", // "identifier_method", "account", "other". Type string `json:"type" api:"required"` + // Context captured for a choice. + Context string `json:"context" api:"nullable"` // Additional context for the choice. Description string `json:"description" api:"nullable"` + // Display text captured for a choice. + DisplayText string `json:"display_text" api:"nullable"` + // Masked phone number or email address shown for an MFA choice. + MaskedDestination string `json:"masked_destination" api:"nullable"` + // Semantic MFA method. Choice id remains the stable identity of the exact option + // selected. + // + // Any of "sms", "call", "email", "totp", "push", "password", "passkey", "switch", + // "other". + MfaType string `json:"mfa_type" api:"nullable"` // Selector for the visible choice, when available. ObservedSelector string `json:"observed_selector" api:"nullable"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { - ID respjson.Field - Label respjson.Field - Type respjson.Field - Description respjson.Field - ObservedSelector respjson.Field - ExtraFields map[string]respjson.Field - raw string + ID respjson.Field + Label respjson.Field + Type respjson.Field + Context respjson.Field + Description respjson.Field + DisplayText respjson.Field + MaskedDestination respjson.Field + MfaType respjson.Field + ObservedSelector respjson.Field + ExtraFields map[string]respjson.Field + raw string } `json:"-"` } @@ -774,6 +790,8 @@ type ManagedAuthField struct { // // Any of "identifier", "password", "code", "totp_code", "totp_secret", "text". Type string `json:"type" api:"required"` + // Context shown near the field, including a masked code destination. + Hint string `json:"hint"` // Human-readable label shown to the user. Label string `json:"label"` // Selector for the visible field, when available. @@ -788,6 +806,7 @@ type ManagedAuthField struct { ID respjson.Field Ref respjson.Field Type respjson.Field + Hint respjson.Field Label respjson.Field ObservedSelector respjson.Field ReplaceExisting respjson.Field @@ -1970,19 +1989,35 @@ type AuthConnectionFollowResponseManagedAuthStateChoice struct { // Any of "mfa_method", "sso_provider", "sign_in_method", "auth_method", // "identifier_method", "account", "other". Type string `json:"type" api:"required"` + // Context captured for a choice. + Context string `json:"context" api:"nullable"` // Additional context for the choice. Description string `json:"description" api:"nullable"` + // Display text captured for a choice. + DisplayText string `json:"display_text" api:"nullable"` + // Masked phone number or email address shown for an MFA choice. + MaskedDestination string `json:"masked_destination" api:"nullable"` + // Semantic MFA method. Choice id remains the stable identity of the exact option + // selected. + // + // Any of "sms", "call", "email", "totp", "push", "password", "passkey", "switch", + // "other". + MfaType string `json:"mfa_type" api:"nullable"` // Selector for the visible choice, when available. ObservedSelector string `json:"observed_selector" api:"nullable"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { - ID respjson.Field - Label respjson.Field - Type respjson.Field - Description respjson.Field - ObservedSelector respjson.Field - ExtraFields map[string]respjson.Field - raw string + ID respjson.Field + Label respjson.Field + Type respjson.Field + Context respjson.Field + Description respjson.Field + DisplayText respjson.Field + MaskedDestination respjson.Field + MfaType respjson.Field + ObservedSelector respjson.Field + ExtraFields map[string]respjson.Field + raw string } `json:"-"` } @@ -2049,6 +2084,8 @@ type AuthConnectionFollowResponseManagedAuthStateField struct { // // Any of "identifier", "password", "code", "totp_code", "totp_secret", "text". Type string `json:"type" api:"required"` + // Context shown near the field, including a masked code destination. + Hint string `json:"hint"` // Human-readable label shown to the user. Label string `json:"label"` // Selector for the visible field, when available. @@ -2063,6 +2100,7 @@ type AuthConnectionFollowResponseManagedAuthStateField struct { ID respjson.Field Ref respjson.Field Type respjson.Field + Hint respjson.Field Label respjson.Field ObservedSelector respjson.Field ReplaceExisting respjson.Field From e8382ff6a656c98ae2d24a6b1edc9a5724cc2669 Mon Sep 17 00:00:00 2001 From: "kernel-internal[bot]" <260533166+kernel-internal[bot]@users.noreply.github.com> Date: Wed, 12 Aug 2026 23:35:44 +0000 Subject: [PATCH 3/3] release: 0.90.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 8 ++++++++ README.md | 2 +- internal/version.go | 2 +- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 6af24e3..f286375 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.89.0" + ".": "0.90.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 30e4789..b8df63d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [0.90.0](https://github.com/kernel/kernel-go-sdk/compare/v0.89.0...v0.90.0) (2026-08-12) + + +### Features + +* Preserve canonical managed auth input metadata ([6a142ab](https://github.com/kernel/kernel-go-sdk/commit/6a142ab834fe7714d460b5507795546144b3c114)) +* Support project selection by ID or name ([79d4c5c](https://github.com/kernel/kernel-go-sdk/commit/79d4c5c4ab915159c0536019ea1504576a9c26f4)) + ## [0.89.0](https://github.com/kernel/kernel-go-sdk/compare/v0.88.0...v0.89.0) (2026-08-12) diff --git a/README.md b/README.md index de6b76e..acdff03 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.89.0' +go get -u 'github.com/kernel/kernel-go-sdk@v0.90.0' ``` diff --git a/internal/version.go b/internal/version.go index c4c63b1..4e3e961 100644 --- a/internal/version.go +++ b/internal/version.go @@ -2,4 +2,4 @@ package internal -const PackageVersion = "0.89.0" // x-release-please-version +const PackageVersion = "0.90.0" // x-release-please-version