diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 3e05ae5..3ca4935 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.108.0" + ".": "0.109.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f7d4fa..8c07b44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## [0.109.0](https://github.com/kernel/kernel-go-sdk/compare/v0.108.0...v0.109.0) (2026-09-17) + + +### Features + +* Accept opaque AgentCard vaulted card IDs ([5cfcedd](https://github.com/kernel/kernel-go-sdk/commit/5cfceddfb1ea8ad60df078bd8e89b11ca1aaa8d2)) +* Expose organization-wide concurrent browser capacity ([6367486](https://github.com/kernel/kernel-go-sdk/commit/6367486e6e06cdc3d9dc13c107dddca490e9b9bc)) +* Preserve credential field order ([3038f83](https://github.com/kernel/kernel-go-sdk/commit/3038f83eb3f7cc6a59059a0a04bdb111300ea77c)) + ## [0.108.0](https://github.com/kernel/kernel-go-sdk/compare/v0.107.0...v0.108.0) (2026-09-17) diff --git a/README.md b/README.md index 7665273..cf8467e 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.108.0' +go get -u 'github.com/kernel/kernel-go-sdk@v0.109.0' ``` diff --git a/internal/version.go b/internal/version.go index da08950..80772ca 100644 --- a/internal/version.go +++ b/internal/version.go @@ -2,4 +2,4 @@ package internal -const PackageVersion = "0.108.0" // x-release-please-version +const PackageVersion = "0.109.0" // x-release-please-version diff --git a/organizationlimit.go b/organizationlimit.go index 06e579d..e82300e 100644 --- a/organizationlimit.go +++ b/organizationlimit.go @@ -36,7 +36,8 @@ func NewOrganizationLimitService(opts ...option.RequestOption) (r OrganizationLi return } -// Get the organization's effective limits and managed auth and vault usage. +// Get the organization's effective limits and current concurrency, managed auth, +// and vault usage. func (r *OrganizationLimitService) Get(ctx context.Context, opts ...option.RequestOption) (res *OrgLimits, err error) { opts = slices.Concat(r.Options, opts) path := "org/limits" @@ -59,6 +60,13 @@ type OrgLimits struct { // org-wide across every project. Compare against max_auth_connections to show // remaining capacity before a create is rejected with 403 insufficient_plan. AuthConnectionsUsed int64 `json:"auth_connections_used" api:"required"` + // Number of concurrent browser slots currently available to the organization. This + // is the effective concurrency limit minus active on-demand sessions and browser + // pool reservations, floored at zero. Null when usage cannot be read. + ConcurrentSessionsAvailable int64 `json:"concurrent_sessions_available" api:"required"` + // Current organization-wide concurrent browser usage, including active on-demand + // sessions and browser pool reservations. Null when usage cannot be read. + ConcurrentSessionsUsed int64 `json:"concurrent_sessions_used" api:"required"` // Maximum managed auth connections the organization's plan allows. Null means // unlimited. Counted org-wide, so it cannot be multiplied across projects. MaxAuthConnections int64 `json:"max_auth_connections" api:"required"` @@ -84,6 +92,8 @@ type OrgLimits struct { // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { AuthConnectionsUsed respjson.Field + ConcurrentSessionsAvailable respjson.Field + ConcurrentSessionsUsed respjson.Field MaxAuthConnections respjson.Field MaxVaults respjson.Field MinHealthCheckIntervalSeconds respjson.Field diff --git a/vaultitem.go b/vaultitem.go index 2668241..65943e3 100644 --- a/vaultitem.go +++ b/vaultitem.go @@ -637,8 +637,9 @@ type CardVaultItemSpecAgentcard struct { Provider constant.Agentcard `json:"provider" default:"agentcard"` // Wallet item key used to authorize checkouts. Wallet string `json:"wallet" api:"required"` - // AgentCard vaulted card to pay with. Omitted, the cardholder picks on the - // approval screen. + // Opaque card ID returned by AgentCard for a card in the connected wallet. Pass it + // through unchanged without assuming a prefix or format. Omitted, the cardholder + // picks on the approval screen. CardID string `json:"card_id"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { @@ -917,8 +918,9 @@ type CardVaultItemSpecAgentcardParam struct { Merchant string `json:"merchant" api:"required"` // Wallet item key used to authorize checkouts. Wallet string `json:"wallet" api:"required"` - // AgentCard vaulted card to pay with. Omitted, the cardholder picks on the - // approval screen. + // Opaque card ID returned by AgentCard for a card in the connected wallet. Pass it + // through unchanged without assuming a prefix or format. Omitted, the cardholder + // picks on the approval screen. CardID param.Opt[string] `json:"card_id,omitzero"` // This field can be elided, and will marshal its zero value as "agentcard". Provider constant.Agentcard `json:"provider" default:"agentcard"` @@ -1240,6 +1242,8 @@ const ( ) type CredentialVaultFieldDefinition struct { + // Stable field name used to key values, updates, and browser fills. + Name string `json:"name" api:"required"` // Whether a nonempty value is required for readiness and form submission. Required bool `json:"required" api:"required"` // Whether the value is omitted from every item response. Reserve true for secrets @@ -1259,6 +1263,7 @@ type CredentialVaultFieldDefinition struct { Type CredentialVaultFieldType `json:"type" api:"required"` // JSON contains metadata for fields, check presence with [respjson.Field.Valid]. JSON struct { + Name respjson.Field Required respjson.Field Sensitive respjson.Field Type respjson.Field @@ -1273,8 +1278,10 @@ func (r *CredentialVaultFieldDefinition) UnmarshalJSON(data []byte) error { return apijson.UnmarshalRoot(data, r) } -// The property Type is required. +// The properties Name, Type are required. type CredentialVaultFieldInputParam struct { + // Unique stable field name used to key values, updates, and browser fills. + Name string `json:"name" api:"required"` // Text, email, and password have form inputs; totp does not and is omitted from // both Kernel-hosted and customer React forms. Password and totp must be // sensitive. A totp value is an RFC 4648 Base32 generator seed (case-insensitive, @@ -1498,7 +1505,9 @@ const ( type CredentialVaultItemRequestParam struct { // Credential fields are for login and other non-payment credentials. Do not store, // collect, or fill credit card data in credential items. Use wallet and card item - // types for credit cards and payment checkout instead. + // types for credit cards and payment checkout instead. Field order is preserved in + // the user-facing collection form, so list fields in the same top-to-bottom order + // as the website. Spec CredentialVaultItemSpecInputParam `json:"spec,omitzero" api:"required"` // Any of "credential". Type CredentialVaultItemRequestType `json:"type,omitzero" api:"required"` @@ -1520,7 +1529,8 @@ const ( ) type CredentialVaultItemSpec struct { - Fields map[string]CredentialVaultFieldDefinition `json:"fields" api:"required"` + // Ordered field definitions rendered in this order by credential collection forms. + Fields []CredentialVaultFieldDefinition `json:"fields" api:"required"` // Recognizable site or service name displayed verbatim as the form title, without // suffixes such as sign-in credentials. Display text only, not an enforced // destination policy. @@ -1542,11 +1552,15 @@ func (r *CredentialVaultItemSpec) UnmarshalJSON(data []byte) error { // Credential fields are for login and other non-payment credentials. Do not store, // collect, or fill credit card data in credential items. Use wallet and card item -// types for credit cards and payment checkout instead. +// types for credit cards and payment checkout instead. Field order is preserved in +// the user-facing collection form, so list fields in the same top-to-bottom order +// as the website. // // The property Fields is required. type CredentialVaultItemSpecInputParam struct { - Fields map[string]CredentialVaultFieldInputParam `json:"fields,omitzero" api:"required"` + // Ordered field definitions. Use the website's top-to-bottom field order; the + // collection form renders this order unchanged. + Fields []CredentialVaultFieldInputParam `json:"fields,omitzero" api:"required"` // The site's recognizable display name, used verbatim as the user-facing form // title (for example, Hacker News). Use only the site or service name; do not // append sign-in, login, credentials, or task instructions. This is display text, @@ -2152,7 +2166,7 @@ type VaultItemUnionSpec struct { // This field is from variant [CardVaultItemSpecUnion]. CardID string `json:"card_id"` // This field is from variant [CredentialVaultItemSpec]. - Fields map[string]CredentialVaultFieldDefinition `json:"fields"` + Fields []CredentialVaultFieldDefinition `json:"fields"` // This field is from variant [CredentialVaultItemSpec]. Description string `json:"description"` JSON struct { @@ -2905,7 +2919,7 @@ type VaultItemOperationResponseUnionSpec struct { // This field is from variant [CardVaultItemSpecUnion]. CardID string `json:"card_id"` // This field is from variant [CredentialVaultItemSpec]. - Fields map[string]CredentialVaultFieldDefinition `json:"fields"` + Fields []CredentialVaultFieldDefinition `json:"fields"` // This field is from variant [CredentialVaultItemSpec]. Description string `json:"description"` JSON struct {