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