From af02011057b49e8e3f4899c43ecba7f6a18b27b2 Mon Sep 17 00:00:00 2001
From: "kernel-internal[bot]"
<260533166+kernel-internal[bot]@users.noreply.github.com>
Date: Thu, 12 Nov 2026 19:26:00 +0000
Subject: [PATCH 1/3] feat: Say how many certificates the refresh PR body
leaves out
Stainless-Generated-From: 45f8ceb682d0ba1e874e5bc79edcbfd1aa1ce3c7
---
.stats.yml | 2 +-
api.md | 16 +++++
browser.go | 3 +
browserliveview.go | 125 ++++++++++++++++++++++++++++++++++++++++
browserliveview_test.go | 46 +++++++++++++++
vaultitem.go | 91 ++++++++++++++++++++---------
6 files changed, 254 insertions(+), 29 deletions(-)
create mode 100644 browserliveview.go
create mode 100644 browserliveview_test.go
diff --git a/.stats.yml b/.stats.yml
index 4725ed9..4731cdc 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1 +1 @@
-configured_endpoints: 178
+configured_endpoints: 179
diff --git a/api.md b/api.md
index 414f7b4..eccd410 100644
--- a/api.md
+++ b/api.md
@@ -228,6 +228,22 @@ Methods:
- client.Browsers.Telemetry.Events(ctx context.Context, idOrName string, query kernel.BrowserTelemetryEventsParams) (\*pagination.OffsetPagination[kernel.BrowserTelemetryEventsResponse], error)
- client.Browsers.Telemetry.Stream(ctx context.Context, idOrName string, params kernel.BrowserTelemetryStreamParams) (\*kernel.BrowserTelemetryStreamResponse, error)
+## LiveView
+
+Params Types:
+
+- kernel.BrowserLiveViewRequestParam
+- kernel.BrowserLiveViewScope
+
+Response Types:
+
+- kernel.BrowserLiveView
+- kernel.BrowserLiveViewScope
+
+Methods:
+
+- client.Browsers.LiveView.New(ctx context.Context, idOrName string, body kernel.BrowserLiveViewNewParams) (\*kernel.BrowserLiveView, error)
+
## Replays
Response Types:
diff --git a/browser.go b/browser.go
index a00d010..e8f2054 100644
--- a/browser.go
+++ b/browser.go
@@ -38,6 +38,8 @@ type BrowserService struct {
// Stream live telemetry events from a browser session, and manage the destinations
// sessions export them to.
Telemetry BrowserTelemetryService
+ // Create and manage browser sessions.
+ LiveView BrowserLiveViewService
// Record and manage browser session video replays.
Replays BrowserReplayService
// Read, write, and manage files on the browser instance.
@@ -62,6 +64,7 @@ func NewBrowserService(opts ...option.RequestOption) (r BrowserService) {
r = BrowserService{}
r.Options = opts
r.Telemetry = NewBrowserTelemetryService(opts...)
+ r.LiveView = NewBrowserLiveViewService(opts...)
r.Replays = NewBrowserReplayService(opts...)
r.Fs = NewBrowserFService(opts...)
r.Process = NewBrowserProcessService(opts...)
diff --git a/browserliveview.go b/browserliveview.go
new file mode 100644
index 0000000..454b4e5
--- /dev/null
+++ b/browserliveview.go
@@ -0,0 +1,125 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+package kernel
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "net/http"
+ "slices"
+ "time"
+
+ "github.com/kernel/kernel-go-sdk/internal/apijson"
+ shimjson "github.com/kernel/kernel-go-sdk/internal/encoding/json"
+ "github.com/kernel/kernel-go-sdk/internal/requestconfig"
+ "github.com/kernel/kernel-go-sdk/option"
+ "github.com/kernel/kernel-go-sdk/packages/param"
+ "github.com/kernel/kernel-go-sdk/packages/respjson"
+)
+
+// Create and manage browser sessions.
+//
+// BrowserLiveViewService contains methods and other services that help with
+// interacting with the kernel API.
+//
+// Note, unlike clients, this service does not read variables from the environment
+// automatically. You should not instantiate this service directly, and instead use
+// the [NewBrowserLiveViewService] method instead.
+type BrowserLiveViewService struct {
+ Options []option.RequestOption
+}
+
+// NewBrowserLiveViewService generates a new service that applies the given options
+// to each request. These options are applied after the parent client's options (if
+// there is one), and before any request-specific options.
+func NewBrowserLiveViewService(opts ...option.RequestOption) (r BrowserLiveViewService) {
+ r = BrowserLiveViewService{}
+ r.Options = opts
+ return
+}
+
+// Creates a live view URL for a headful browser that grants either read-only or
+// control access. The URL works only for the live view: it cannot connect to CDP,
+// WebDriver, or any other browser endpoint. A read-only URL shows the browser but
+// cannot send input, regardless of query parameters. The URL stays valid until the
+// browser is deleted, or until `ttl_seconds` elapse when set. For a browser
+// acquired from a pool, it stops working when the browser is released. Nothing is
+// stored, so a URL cannot be revoked before then.
+func (r *BrowserLiveViewService) New(ctx context.Context, idOrName string, body BrowserLiveViewNewParams, opts ...option.RequestOption) (res *BrowserLiveView, err error) {
+ opts = slices.Concat(r.Options, opts)
+ if idOrName == "" {
+ err = errors.New("missing required id_or_name parameter")
+ return nil, err
+ }
+ path := fmt.Sprintf("browsers/%s/live_view", idOrName)
+ err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
+ return res, err
+}
+
+type BrowserLiveView struct {
+ // `read` shows the browser without accepting input. `control` also lets the viewer
+ // drive the browser through the live view.
+ //
+ // Any of "read", "control".
+ Scope BrowserLiveViewScope `json:"scope" api:"required"`
+ // Live view URL. Treat it as a credential.
+ URL string `json:"url" api:"required"`
+ // When the URL expires. Absent when it stays valid until the browser is deleted.
+ ExpiresAt time.Time `json:"expires_at" format:"date-time"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Scope respjson.Field
+ URL respjson.Field
+ ExpiresAt respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r BrowserLiveView) RawJSON() string { return r.JSON.raw }
+func (r *BrowserLiveView) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+type BrowserLiveViewRequestParam struct {
+ // Seconds until the URL expires. Omit to keep it valid until the browser is
+ // deleted.
+ TtlSeconds param.Opt[int64] `json:"ttl_seconds,omitzero"`
+ // `read` shows the browser without accepting input. `control` also lets the viewer
+ // drive the browser through the live view.
+ //
+ // Any of "read", "control".
+ Scope BrowserLiveViewScope `json:"scope,omitzero"`
+ paramObj
+}
+
+func (r BrowserLiveViewRequestParam) MarshalJSON() (data []byte, err error) {
+ type shadow BrowserLiveViewRequestParam
+ return param.MarshalObject(r, (*shadow)(&r))
+}
+func (r *BrowserLiveViewRequestParam) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// `read` shows the browser without accepting input. `control` also lets the viewer
+// drive the browser through the live view.
+type BrowserLiveViewScope string
+
+const (
+ BrowserLiveViewScopeRead BrowserLiveViewScope = "read"
+ BrowserLiveViewScopeControl BrowserLiveViewScope = "control"
+)
+
+type BrowserLiveViewNewParams struct {
+ BrowserLiveViewRequest BrowserLiveViewRequestParam
+ paramObj
+}
+
+func (r BrowserLiveViewNewParams) MarshalJSON() (data []byte, err error) {
+ return shimjson.Marshal(r.BrowserLiveViewRequest)
+}
+func (r *BrowserLiveViewNewParams) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
diff --git a/browserliveview_test.go b/browserliveview_test.go
new file mode 100644
index 0000000..a4f4260
--- /dev/null
+++ b/browserliveview_test.go
@@ -0,0 +1,46 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+package kernel_test
+
+import (
+ "context"
+ "errors"
+ "os"
+ "testing"
+
+ "github.com/kernel/kernel-go-sdk"
+ "github.com/kernel/kernel-go-sdk/internal/testutil"
+ "github.com/kernel/kernel-go-sdk/option"
+)
+
+func TestBrowserLiveViewNewWithOptionalParams(t *testing.T) {
+ t.Skip("Mock server tests are disabled")
+ baseURL := "http://localhost:4010"
+ if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
+ baseURL = envURL
+ }
+ if !testutil.CheckTestServer(t, baseURL) {
+ return
+ }
+ client := kernel.NewClient(
+ option.WithBaseURL(baseURL),
+ option.WithAPIKey("My API Key"),
+ )
+ _, err := client.Browsers.LiveView.New(
+ context.TODO(),
+ "htzv5orfit78e1m2biiifpbv",
+ kernel.BrowserLiveViewNewParams{
+ BrowserLiveViewRequest: kernel.BrowserLiveViewRequestParam{
+ Scope: kernel.BrowserLiveViewScopeRead,
+ TtlSeconds: kernel.Int(3600),
+ },
+ },
+ )
+ if err != nil {
+ var apierr *kernel.Error
+ if errors.As(err, &apierr) {
+ t.Log(string(apierr.DumpRequest(true)))
+ }
+ t.Fatalf("err should be nil: %s", err.Error())
+ }
+}
diff --git a/vaultitem.go b/vaultitem.go
index 6bc58cf..5cc7992 100644
--- a/vaultitem.go
+++ b/vaultitem.go
@@ -2264,9 +2264,10 @@ type CredentialVaultItem struct {
AvailableExpansions []CredentialVaultItemAvailableExpansion `json:"available_expansions" api:"required"`
// Kernel credentials advertise collect and fill when eligible. 1Password
// credentials advertise 1pw_create_access_request until a request is made,
- // 1pw_access_request_status while its approval is pending, and 1pw_fill after
- // access is granted. Managed auth credentials advertise fill while ready and
- // nothing otherwise.
+ // 1pw_access_request_status while its approval is pending (and
+ // 1pw_create_access_request again once the 3-minute status-check window has
+ // passed), and 1pw_fill after access is granted. Managed auth credentials
+ // advertise fill while ready and nothing otherwise.
AvailableOperations []CredentialVaultItemAvailableOperation `json:"available_operations" api:"required"`
CreatedAt time.Time `json:"created_at" api:"required" format:"date-time"`
// Immutable item key assigned when the item is created.
@@ -2399,13 +2400,16 @@ type CredentialVaultItemActionUnion struct {
Name string `json:"name"`
URL string `json:"url"`
// This field is from variant [CredentialVaultItemAction1passwordAccessApproval].
+ AccessRequestReference string `json:"access_request_reference"`
+ // This field is from variant [CredentialVaultItemAction1passwordAccessApproval].
Instructions string `json:"instructions"`
JSON struct {
- ExpiresAt respjson.Field
- Name respjson.Field
- URL respjson.Field
- Instructions respjson.Field
- raw string
+ ExpiresAt respjson.Field
+ Name respjson.Field
+ URL respjson.Field
+ AccessRequestReference respjson.Field
+ Instructions respjson.Field
+ raw string
} `json:"-"`
}
@@ -2455,20 +2459,29 @@ func (r *CredentialVaultItemActionUnion) UnmarshalJSON(data []byte) error {
}
type CredentialVaultItemAction1passwordAccessApproval struct {
+ // The access_request_reference value from url, for approving inside your own iOS
+ // or Android app with 1Password's action extension or authorization activity. Pass
+ // it unchanged; the grant comes back to your app, and 1pw_access_request_status
+ // records it in Kernel. Treat it like url, which carries the same request text,
+ // and keep it out of logs.
+ AccessRequestReference string `json:"access_request_reference" api:"required"`
// Steps for the agent to hand approval to the human and poll the resulting
// decision.
Instructions string `json:"instructions" api:"required"`
Name constant.String1passwordAccessApproval `json:"name" default:"1password_access_approval"`
- // Native 1Password approval link. Present it to the account owner without
- // modifying it; it does not grant access until they approve in their app.
+ // Native 1Password approval link. Present it to the account owner unchanged,
+ // except that you may append `&return_url=` so 1Password sends
+ // them back to your app after they decide (1Password 8.12.46 or later on iOS,
+ // Android and desktop). It does not grant access until they approve in their app.
URL string `json:"url" api:"required" format:"uri"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
- Instructions respjson.Field
- Name respjson.Field
- URL respjson.Field
- ExtraFields map[string]respjson.Field
- raw string
+ AccessRequestReference respjson.Field
+ Instructions respjson.Field
+ Name respjson.Field
+ URL respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
} `json:"-"`
}
@@ -4735,7 +4748,9 @@ const (
type OnePasswordCredentialVaultItemStateAccessRequest struct {
ID string `json:"id" api:"required"`
HasAutofillToken bool `json:"has_autofill_token" api:"required"`
- // One of pending, resolved, denied, or failed.
+ // One of pending, resolved, denied, failed, expired, or unknown. expired returns
+ // the item to pending_authorization so access can be requested again; unknown is a
+ // state 1Password added later and is treated as failed.
State string `json:"state" api:"required"`
// Provider-created timestamp as returned by the broker.
CreatedAt string `json:"createdAt"`
@@ -7438,14 +7453,17 @@ type VaultItemUnionAction struct {
// This field is from variant [CredentialVaultItemActionUnion].
ExpiresAt time.Time `json:"expires_at"`
// This field is from variant [CredentialVaultItemActionUnion].
+ AccessRequestReference string `json:"access_request_reference"`
+ // This field is from variant [CredentialVaultItemActionUnion].
Instructions string `json:"instructions"`
JSON struct {
- Name respjson.Field
- URL respjson.Field
- CaptureToken respjson.Field
- ExpiresAt respjson.Field
- Instructions respjson.Field
- raw string
+ Name respjson.Field
+ URL respjson.Field
+ CaptureToken respjson.Field
+ ExpiresAt respjson.Field
+ AccessRequestReference respjson.Field
+ Instructions respjson.Field
+ raw string
} `json:"-"`
}
@@ -8604,14 +8622,17 @@ type VaultItemOperationResponseUnionAction struct {
// This field is from variant [CredentialVaultItemActionUnion].
ExpiresAt time.Time `json:"expires_at"`
// This field is from variant [CredentialVaultItemActionUnion].
+ AccessRequestReference string `json:"access_request_reference"`
+ // This field is from variant [CredentialVaultItemActionUnion].
Instructions string `json:"instructions"`
JSON struct {
- Name respjson.Field
- URL respjson.Field
- CaptureToken respjson.Field
- ExpiresAt respjson.Field
- Instructions respjson.Field
- raw string
+ Name respjson.Field
+ URL respjson.Field
+ CaptureToken respjson.Field
+ ExpiresAt respjson.Field
+ AccessRequestReference respjson.Field
+ Instructions respjson.Field
+ raw string
} `json:"-"`
}
@@ -10404,6 +10425,12 @@ type VaultItemPerformOperationParams struct {
Of1pwCreateAccessRequest *OnePasswordRequestAccessVaultItemOperationRequestParam `json:",inline"`
// This field is a request body variant, only one variant field can be set.
// Retrieve the status of a 1Password access request after presenting the approval
+ // link. Kernel paces checks on 1Password's schedule, timed from the first status
+ // check (at once, then every 2 seconds, slowing to every 10 and 20 seconds). Each
+ // call reads a fresh status, waiting up to 20 seconds for its first scheduled
+ // check. If 1Password rate limits the account, it returns 429 with Retry-After.
+ // After 3 minutes the approval prompt has closed; ask the owner whether they
+ // approved and check once more, or invoke 1pw_create_access_request for a new
// link. On a confirmed failed status, ask the end-user before deleting and
// recreating the credential item for at most one new request. Do not retry an
// uncertain dispatched request. The response contains no secret values.
@@ -10502,6 +10529,12 @@ func (r *VaultItemPerformOperationParams) UnmarshalJSON(data []byte) error {
}
// Retrieve the status of a 1Password access request after presenting the approval
+// link. Kernel paces checks on 1Password's schedule, timed from the first status
+// check (at once, then every 2 seconds, slowing to every 10 and 20 seconds). Each
+// call reads a fresh status, waiting up to 20 seconds for its first scheduled
+// check. If 1Password rate limits the account, it returns 429 with Retry-After.
+// After 3 minutes the approval prompt has closed; ask the owner whether they
+// approved and check once more, or invoke 1pw_create_access_request for a new
// link. On a confirmed failed status, ask the end-user before deleting and
// recreating the credential item for at most one new request. Do not retry an
// uncertain dispatched request. The response contains no secret values.
@@ -10510,6 +10543,8 @@ func (r *VaultItemPerformOperationParams) UnmarshalJSON(data []byte) error {
//
// The property Type is required.
type VaultItemPerformOperationParamsBody1pwAccessRequestStatus struct {
+ // How long to keep checking on the schedule. The call still waits for its first
+ // scheduled check, at most 20 seconds, when that comes later.
TimeoutSeconds param.Opt[int64] `json:"timeout_seconds,omitzero"`
// This field can be elided, and will marshal its zero value as
// "1pw_access_request_status".
From 198927d239c7867726ce2562532ab3df4a8fce4d Mon Sep 17 00:00:00 2001
From: "kernel-internal[bot]"
<260533166+kernel-internal[bot]@users.noreply.github.com>
Date: Thu, 12 Nov 2026 19:30:36 +0000
Subject: [PATCH 2/3] release: 0.148.0
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 7 +++++++
README.md | 2 +-
internal/version.go | 2 +-
4 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index e205138..2b1627b 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.147.0"
+ ".": "0.148.0"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 34545e1..4312f31 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,12 @@
# Changelog
+## [0.148.0](https://github.com/kernel/kernel-go-sdk/compare/v0.147.0...v0.148.0) (2026-11-12)
+
+
+### Features
+
+* Say how many certificates the refresh PR body leaves out ([af02011](https://github.com/kernel/kernel-go-sdk/commit/af02011057b49e8e3f4899c43ecba7f6a18b27b2))
+
## [0.147.0](https://github.com/kernel/kernel-go-sdk/compare/v0.146.0...v0.147.0) (2026-11-12)
diff --git a/README.md b/README.md
index 29bd833..1d628fa 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.147.0'
+go get -u 'github.com/kernel/kernel-go-sdk@v0.148.0'
```
diff --git a/internal/version.go b/internal/version.go
index 489e078..5d2eeda 100644
--- a/internal/version.go
+++ b/internal/version.go
@@ -2,4 +2,4 @@
package internal
-const PackageVersion = "0.147.0" // x-release-please-version
+const PackageVersion = "0.148.0" // x-release-please-version
From b548486af8e2ef34991fbe7d6727f8d86f342ce6 Mon Sep 17 00:00:00 2001
From: masnwilliams <43387599+masnwilliams@users.noreply.github.com>
Date: Thu, 12 Nov 2026 19:36:20 +0000
Subject: [PATCH 3/3] chore: correct 0.148.0 changelog entries
---
CHANGELOG.md | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4312f31..8f28796 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,7 +5,9 @@
### Features
-* Say how many certificates the refresh PR body leaves out ([af02011](https://github.com/kernel/kernel-go-sdk/commit/af02011057b49e8e3f4899c43ecba7f6a18b27b2))
+* Add scoped live view URLs ([af02011](https://github.com/kernel/kernel-go-sdk/commit/af02011057b49e8e3f4899c43ecba7f6a18b27b2))
+* Pace 1Password status checks on the partner schedule ([af02011](https://github.com/kernel/kernel-go-sdk/commit/af02011057b49e8e3f4899c43ecba7f6a18b27b2))
+* Return the 1Password access request reference on the approval action ([af02011](https://github.com/kernel/kernel-go-sdk/commit/af02011057b49e8e3f4899c43ecba7f6a18b27b2))
## [0.147.0](https://github.com/kernel/kernel-go-sdk/compare/v0.146.0...v0.147.0) (2026-11-12)