diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 0114ce37..c486f6de 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.92.0"
+ ".": "0.93.0"
}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f62b102b..3a4b9b3a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,14 @@
# Changelog
+## [0.93.0](https://github.com/kernel/kernel-go-sdk/compare/v0.92.0...v0.93.0) (2026-08-19)
+
+
+### Features
+
+* Add proxy_error to browser telemetry event schema ([467fea7](https://github.com/kernel/kernel-go-sdk/commit/467fea72ee93a0d8e4a520169cf5e14e5d4076ee))
+* Bind managed auth submissions to interactions ([796d424](https://github.com/kernel/kernel-go-sdk/commit/796d4245c87a39acbb0d408b05f0de830c500772))
+* Harden canonical managed auth interactions ([6e62bf5](https://github.com/kernel/kernel-go-sdk/commit/6e62bf5b91e5d315b90b6c9c7296e09e312fb338))
+
## [0.92.0](https://github.com/kernel/kernel-go-sdk/compare/v0.91.0...v0.92.0) (2026-08-17)
diff --git a/README.md b/README.md
index cd9fc575..9d3fe382 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.92.0'
+go get -u 'github.com/kernel/kernel-go-sdk@v0.93.0'
```
diff --git a/api.md b/api.md
index 463c4dc0..17139df9 100644
--- a/api.md
+++ b/api.md
@@ -143,6 +143,7 @@ Response Types:
- kernel.BrowserPageNavigationEvent
- kernel.BrowserPageNavigationSettledEvent
- kernel.BrowserPageTabOpenedEvent
+- kernel.BrowserProxyErrorEvent
- kernel.BrowserServiceCrashedEvent
- kernel.BrowserSystemOomKillEvent
- kernel.BrowserTelemetryCategoriesConfig
diff --git a/authconnection.go b/authconnection.go
index 8a1138a3..1e309829 100644
--- a/authconnection.go
+++ b/authconnection.go
@@ -399,6 +399,9 @@ type ManagedAuth struct {
HealthChecks bool `json:"health_checks"`
// URL to redirect user to for hosted login (present when flow in progress)
HostedURL string `json:"hosted_url" api:"nullable" format:"uri"`
+ // Opaque identifier for the current canonical interaction. Required when
+ // submitting fields or choices and changes for each new actionable pause.
+ InteractionID string `json:"interaction_id" api:"nullable"`
// Deprecated alias for `last_auth_check_at`. Despite the name, this is the last
// health-check timestamp, not the last successful authentication. Use
// `last_auth_check_at` instead.
@@ -466,6 +469,7 @@ type ManagedAuth struct {
HealthCheckInterval respjson.Field
HealthChecks respjson.Field
HostedURL respjson.Field
+ InteractionID respjson.Field
LastAuthAt respjson.Field
LastAuthCheckAt respjson.Field
LiveViewURL respjson.Field
@@ -784,6 +788,10 @@ func (r *ManagedAuthDiscoveredField) UnmarshalJSON(data []byte) error {
type ManagedAuthField struct {
// Stable field identifier for canonical submit.
ID string `json:"id" api:"required"`
+ // Why the field requires user input.
+ //
+ // Any of "missing", "rejected".
+ Reason string `json:"reason" api:"required"`
// Credential reference name to store the submitted value under.
Ref string `json:"ref" api:"required"`
// Managed-auth field type.
@@ -796,20 +804,17 @@ type ManagedAuthField struct {
Label string `json:"label"`
// Selector for the visible field, when available.
ObservedSelector string `json:"observed_selector" api:"nullable"`
- // Whether the submitted value must replace an existing credential after explicit
- // rejection.
- ReplaceExisting bool `json:"replace_existing"`
// Whether this field is required.
Required bool `json:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
ID respjson.Field
+ Reason respjson.Field
Ref respjson.Field
Type respjson.Field
Hint respjson.Field
Label respjson.Field
ObservedSelector respjson.Field
- ReplaceExisting respjson.Field
Required respjson.Field
ExtraFields map[string]respjson.Field
raw string
@@ -1726,6 +1731,9 @@ func (r *ManagedAuthUpdateRequestProxyParam) UnmarshalJSON(data []byte) error {
// fields/sso_button_selector/sso_provider/mfa_option_id/sign_in_option_id remain
// supported during deprecation.
type SubmitFieldsRequestParam struct {
+ // Opaque interaction ID returned with canonical fields and choices. Required for
+ // canonical submissions.
+ InteractionID param.Opt[string] `json:"interaction_id,omitzero"`
// The MFA method type to select (when mfa_options were returned)
MfaOptionID param.Opt[string] `json:"mfa_option_id,omitzero"`
// Canonical choice ID selected by the user.
@@ -1804,6 +1812,8 @@ type AuthConnectionFollowResponseUnion struct {
// This field is from variant [AuthConnectionFollowResponseManagedAuthState].
HostedURL string `json:"hosted_url"`
// This field is from variant [AuthConnectionFollowResponseManagedAuthState].
+ InteractionID string `json:"interaction_id"`
+ // This field is from variant [AuthConnectionFollowResponseManagedAuthState].
LiveViewURL string `json:"live_view_url"`
// This field is from variant [AuthConnectionFollowResponseManagedAuthState].
MfaOptions []AuthConnectionFollowResponseManagedAuthStateMfaOption `json:"mfa_options"`
@@ -1830,6 +1840,7 @@ type AuthConnectionFollowResponseUnion struct {
Fields respjson.Field
FlowType respjson.Field
HostedURL respjson.Field
+ InteractionID respjson.Field
LiveViewURL respjson.Field
MfaOptions respjson.Field
PendingSSOButtons respjson.Field
@@ -1930,6 +1941,9 @@ type AuthConnectionFollowResponseManagedAuthState struct {
FlowType string `json:"flow_type"`
// URL to redirect user to for hosted login.
HostedURL string `json:"hosted_url" format:"uri"`
+ // Opaque identifier for the current canonical interaction. Required when
+ // submitting fields or choices and changes for each new actionable pause.
+ InteractionID string `json:"interaction_id"`
// Browser live view URL for debugging.
LiveViewURL string `json:"live_view_url" format:"uri"`
// MFA method options (present when flow_step=AWAITING_INPUT; may also be present
@@ -1961,6 +1975,7 @@ type AuthConnectionFollowResponseManagedAuthState struct {
Fields respjson.Field
FlowType respjson.Field
HostedURL respjson.Field
+ InteractionID respjson.Field
LiveViewURL respjson.Field
MfaOptions respjson.Field
PendingSSOButtons respjson.Field
@@ -2078,6 +2093,10 @@ func (r *AuthConnectionFollowResponseManagedAuthStateDiscoveredField) UnmarshalJ
type AuthConnectionFollowResponseManagedAuthStateField struct {
// Stable field identifier for canonical submit.
ID string `json:"id" api:"required"`
+ // Why the field requires user input.
+ //
+ // Any of "missing", "rejected".
+ Reason string `json:"reason" api:"required"`
// Credential reference name to store the submitted value under.
Ref string `json:"ref" api:"required"`
// Managed-auth field type.
@@ -2090,20 +2109,17 @@ type AuthConnectionFollowResponseManagedAuthStateField struct {
Label string `json:"label"`
// Selector for the visible field, when available.
ObservedSelector string `json:"observed_selector" api:"nullable"`
- // Whether the submitted value must replace an existing credential after explicit
- // rejection.
- ReplaceExisting bool `json:"replace_existing"`
// Whether this field is required.
Required bool `json:"required"`
// JSON contains metadata for fields, check presence with [respjson.Field.Valid].
JSON struct {
ID respjson.Field
+ Reason respjson.Field
Ref respjson.Field
Type respjson.Field
Hint respjson.Field
Label respjson.Field
ObservedSelector respjson.Field
- ReplaceExisting respjson.Field
Required respjson.Field
ExtraFields map[string]respjson.Field
raw string
diff --git a/authconnection_test.go b/authconnection_test.go
index aefb2ba3..361ddf30 100644
--- a/authconnection_test.go
+++ b/authconnection_test.go
@@ -509,6 +509,7 @@ func TestAuthConnectionSubmitWithOptionalParams(t *testing.T) {
"email": "user@example.com",
"password": "secret",
},
+ InteractionID: kernel.String("mai_abc123xyz"),
MfaOptionID: kernel.String("sms"),
SelectedChoiceID: kernel.String("google"),
SignInOptionID: kernel.String("work-account"),
diff --git a/browsertelemetry.go b/browsertelemetry.go
index bceb98b7..55581a3f 100644
--- a/browsertelemetry.go
+++ b/browsertelemetry.go
@@ -1925,6 +1925,86 @@ func (r *BrowserPageTabOpenedEventData) UnmarshalJSON(data []byte) error {
return apijson.UnmarshalRoot(data, r)
}
+// A branded proxy-layer failure observed by the browser. Emitted when the metro
+// egress host-proxy serves a branded 5xx error page whose response carries the
+// X-Kernel-Proxy-Error header. Low-volume and carries a typed code. Its value is
+// per-session and per-URL attribution for sessions that already capture the
+// network stream: proxy failures are only observable while the CDP network
+// collector is running, so this is an opt-in refinement of the raw network events
+// rather than a default-on alerting signal.
+type BrowserProxyErrorEvent struct {
+ Category constant.Network `json:"category" default:"network"`
+ // Provenance metadata identifying which producer emitted the event.
+ Source BrowserEventSource `json:"source" api:"required"`
+ // Event timestamp in Unix microseconds.
+ Ts int64 `json:"ts" api:"required"`
+ Type constant.ProxyError `json:"type" default:"proxy_error"`
+ // Browser event context stamped by the browser monitor onto all CDP-sourced
+ // events. Identifies the target, frame, and navigation epoch in which the event
+ // occurred.
+ Data BrowserProxyErrorEventData `json:"data"`
+ // True if the data field was truncated due to size limits.
+ Truncated bool `json:"truncated"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Category respjson.Field
+ Source respjson.Field
+ Ts respjson.Field
+ Type respjson.Field
+ Data respjson.Field
+ Truncated respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+}
+
+// Returns the unmodified JSON received from the API
+func (r BrowserProxyErrorEvent) RawJSON() string { return r.JSON.raw }
+func (r *BrowserProxyErrorEvent) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
+// Browser event context stamped by the browser monitor onto all CDP-sourced
+// events. Identifies the target, frame, and navigation epoch in which the event
+// occurred.
+type BrowserProxyErrorEventData struct {
+ // Proxy-layer error code: the X-Kernel-Proxy-Error response header value from a
+ // branded 5xx error page served by the metro egress host-proxy. Values mirror what
+ // the proxy emits: destination_blocked, provider_blacklisted,
+ // provider_unreachable, proxy_unavailable, upstream_timeout, upstream_dns_failure,
+ // upstream_connect_failed. Unknown header values are dropped.
+ //
+ // Any of "destination_blocked", "provider_blacklisted", "provider_unreachable",
+ // "proxy_unavailable", "upstream_timeout", "upstream_dns_failure",
+ // "upstream_connect_failed".
+ Code string `json:"code" api:"required"`
+ // CDP request identifier matching the originating request.
+ RequestID string `json:"request_id" api:"required"`
+ // HTTP response status of the branded error page (502).
+ Status int64 `json:"status" api:"required"`
+ // HTTP method of the failed request, when known.
+ Method string `json:"method"`
+ // CDP Network.ResourceType for the request, when known.
+ ResourceType string `json:"resource_type"`
+ // JSON contains metadata for fields, check presence with [respjson.Field.Valid].
+ JSON struct {
+ Code respjson.Field
+ RequestID respjson.Field
+ Status respjson.Field
+ Method respjson.Field
+ ResourceType respjson.Field
+ ExtraFields map[string]respjson.Field
+ raw string
+ } `json:"-"`
+ BrowserEventContext
+}
+
+// Returns the unmodified JSON received from the API
+func (r BrowserProxyErrorEventData) RawJSON() string { return r.JSON.raw }
+func (r *BrowserProxyErrorEventData) UnmarshalJSON(data []byte) error {
+ return apijson.UnmarshalRoot(data, r)
+}
+
// A managed service exited unexpectedly. Intentional stops do not produce this
// event; only unexpected exits and terminal restart-give-up transitions do.
type BrowserServiceCrashedEvent struct {
@@ -2277,15 +2357,16 @@ func (r *BrowserTelemetryConfig) UnmarshalJSON(data []byte) error {
// [BrowserConsoleLogEvent], [BrowserConsoleErrorEvent],
// [BrowserNetworkRequestEvent], [BrowserNetworkResponseEvent],
// [BrowserNetworkLoadingFailedEvent], [BrowserNetworkIdleEvent],
-// [BrowserPageNavigationEvent], [BrowserPageDomContentLoadedEvent],
-// [BrowserPageLoadEvent], [BrowserPageTabOpenedEvent],
-// [BrowserPageLayoutShiftEvent], [BrowserPageLcpEvent],
-// [BrowserPageLayoutSettledEvent], [BrowserPageNavigationSettledEvent],
-// [BrowserInteractionClickEvent], [BrowserInteractionKeyEvent],
-// [BrowserInteractionScrollSettledEvent], [BrowserMonitorScreenshotEvent],
-// [BrowserMonitorDisconnectedEvent], [BrowserMonitorReconnectedEvent],
-// [BrowserMonitorReconnectFailedEvent], [BrowserMonitorInitFailedEvent],
-// [BrowserAPICallEvent], [BrowserCdpConnectEvent], [BrowserCdpDisconnectEvent],
+// [BrowserProxyErrorEvent], [BrowserPageNavigationEvent],
+// [BrowserPageDomContentLoadedEvent], [BrowserPageLoadEvent],
+// [BrowserPageTabOpenedEvent], [BrowserPageLayoutShiftEvent],
+// [BrowserPageLcpEvent], [BrowserPageLayoutSettledEvent],
+// [BrowserPageNavigationSettledEvent], [BrowserInteractionClickEvent],
+// [BrowserInteractionKeyEvent], [BrowserInteractionScrollSettledEvent],
+// [BrowserMonitorScreenshotEvent], [BrowserMonitorDisconnectedEvent],
+// [BrowserMonitorReconnectedEvent], [BrowserMonitorReconnectFailedEvent],
+// [BrowserMonitorInitFailedEvent], [BrowserAPICallEvent],
+// [BrowserCdpConnectEvent], [BrowserCdpDisconnectEvent],
// [BrowserLiveViewConnectEvent], [BrowserLiveViewDisconnectEvent],
// [BrowserCaptchaSolveResultEvent], [BrowserSystemOomKillEvent],
// [BrowserServiceCrashedEvent].
@@ -2299,7 +2380,7 @@ type BrowserTelemetryEventUnion struct {
Source BrowserEventSource `json:"source"`
Ts int64 `json:"ts"`
// Any of "console_log", "console_error", "network_request", "network_response",
- // "network_loading_failed", "network_idle", "page_navigation",
+ // "network_loading_failed", "network_idle", "proxy_error", "page_navigation",
// "page_dom_content_loaded", "page_load", "page_tab_opened", "page_layout_shift",
// "page_lcp", "page_layout_settled", "page_navigation_settled",
// "interaction_click", "interaction_key", "interaction_scroll_settled",
@@ -2311,17 +2392,18 @@ type BrowserTelemetryEventUnion struct {
// This field is a union of [BrowserConsoleLogEventData],
// [BrowserConsoleErrorEventData], [BrowserNetworkRequestEventData],
// [BrowserNetworkResponseEventData], [BrowserNetworkLoadingFailedEventData],
- // [BrowserEventContext], [BrowserPageNavigationEventData],
- // [BrowserPageDomContentLoadedEventData], [BrowserPageLoadEventData],
- // [BrowserPageTabOpenedEventData], [BrowserPageLayoutShiftEventData],
- // [BrowserPageLcpEventData], [BrowserInteractionClickEventData],
- // [BrowserInteractionKeyEventData], [BrowserInteractionScrollSettledEventData],
- // [BrowserMonitorScreenshotEventData], [BrowserMonitorDisconnectedEventData],
- // [BrowserMonitorReconnectedEventData], [BrowserMonitorReconnectFailedEventData],
- // [BrowserMonitorInitFailedEventData], [BrowserAPICallEventData],
- // [BrowserCdpDisconnectEventData], [BrowserLiveViewConnectEventData],
- // [BrowserLiveViewDisconnectEventData], [BrowserCaptchaSolveResultEventData],
- // [BrowserSystemOomKillEventData], [BrowserServiceCrashedEventData]
+ // [BrowserEventContext], [BrowserProxyErrorEventData],
+ // [BrowserPageNavigationEventData], [BrowserPageDomContentLoadedEventData],
+ // [BrowserPageLoadEventData], [BrowserPageTabOpenedEventData],
+ // [BrowserPageLayoutShiftEventData], [BrowserPageLcpEventData],
+ // [BrowserInteractionClickEventData], [BrowserInteractionKeyEventData],
+ // [BrowserInteractionScrollSettledEventData], [BrowserMonitorScreenshotEventData],
+ // [BrowserMonitorDisconnectedEventData], [BrowserMonitorReconnectedEventData],
+ // [BrowserMonitorReconnectFailedEventData], [BrowserMonitorInitFailedEventData],
+ // [BrowserAPICallEventData], [BrowserCdpDisconnectEventData],
+ // [BrowserLiveViewConnectEventData], [BrowserLiveViewDisconnectEventData],
+ // [BrowserCaptchaSolveResultEventData], [BrowserSystemOomKillEventData],
+ // [BrowserServiceCrashedEventData]
Data BrowserTelemetryEventUnionData `json:"data"`
Truncated bool `json:"truncated"`
JSON struct {
@@ -2348,6 +2430,7 @@ func (BrowserNetworkRequestEvent) implBrowserTelemetryEventUnion() {}
func (BrowserNetworkResponseEvent) implBrowserTelemetryEventUnion() {}
func (BrowserNetworkLoadingFailedEvent) implBrowserTelemetryEventUnion() {}
func (BrowserNetworkIdleEvent) implBrowserTelemetryEventUnion() {}
+func (BrowserProxyErrorEvent) implBrowserTelemetryEventUnion() {}
func (BrowserPageNavigationEvent) implBrowserTelemetryEventUnion() {}
func (BrowserPageDomContentLoadedEvent) implBrowserTelemetryEventUnion() {}
func (BrowserPageLoadEvent) implBrowserTelemetryEventUnion() {}
@@ -2382,6 +2465,7 @@ func (BrowserServiceCrashedEvent) implBrowserTelemetryEventUnion() {}
// case kernel.BrowserNetworkResponseEvent:
// case kernel.BrowserNetworkLoadingFailedEvent:
// case kernel.BrowserNetworkIdleEvent:
+// case kernel.BrowserProxyErrorEvent:
// case kernel.BrowserPageNavigationEvent:
// case kernel.BrowserPageDomContentLoadedEvent:
// case kernel.BrowserPageLoadEvent:
@@ -2423,6 +2507,8 @@ func (u BrowserTelemetryEventUnion) AsAny() anyBrowserTelemetryEvent {
return u.AsNetworkLoadingFailed()
case "network_idle":
return u.AsNetworkIdle()
+ case "proxy_error":
+ return u.AsProxyError()
case "page_navigation":
return u.AsPageNavigation()
case "page_dom_content_loaded":
@@ -2505,6 +2591,11 @@ func (u BrowserTelemetryEventUnion) AsNetworkIdle() (v BrowserNetworkIdleEvent)
return
}
+func (u BrowserTelemetryEventUnion) AsProxyError() (v BrowserProxyErrorEvent) {
+ apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
+ return
+}
+
func (u BrowserTelemetryEventUnion) AsPageNavigation() (v BrowserPageNavigationEvent) {
apijson.UnmarshalRoot(json.RawMessage(u.JSON.raw), &v)
return
@@ -2644,10 +2735,11 @@ type BrowserTelemetryEventUnionData struct {
// This field is from variant [BrowserConsoleLogEventData],
// [BrowserConsoleErrorEventData], [BrowserNetworkRequestEventData],
// [BrowserNetworkResponseEventData], [BrowserNetworkLoadingFailedEventData],
- // [BrowserEventContext], [BrowserPageDomContentLoadedEventData],
- // [BrowserPageLoadEventData], [BrowserPageLayoutShiftEventData],
- // [BrowserPageLcpEventData], [BrowserInteractionClickEventData],
- // [BrowserInteractionKeyEventData], [BrowserInteractionScrollSettledEventData].
+ // [BrowserEventContext], [BrowserProxyErrorEventData],
+ // [BrowserPageDomContentLoadedEventData], [BrowserPageLoadEventData],
+ // [BrowserPageLayoutShiftEventData], [BrowserPageLcpEventData],
+ // [BrowserInteractionClickEventData], [BrowserInteractionKeyEventData],
+ // [BrowserInteractionScrollSettledEventData].
NavSeq int64 `json:"nav_seq"`
SessionID string `json:"session_id"`
TargetID string `json:"target_id"`
@@ -2683,7 +2775,7 @@ type BrowserTelemetryEventUnionData struct {
Body string `json:"body"`
// This field is from variant [BrowserNetworkResponseEventData].
MimeType string `json:"mime_type"`
- // This field is a union of [int64], [int64], [string]
+ // This field is a union of [int64], [int64], [int64], [string]
Status BrowserTelemetryEventUnionDataStatus `json:"status"`
// This field is from variant [BrowserNetworkResponseEventData].
StatusText string `json:"status_text"`
@@ -2691,6 +2783,8 @@ type BrowserTelemetryEventUnionData struct {
Canceled bool `json:"canceled"`
// This field is from variant [BrowserNetworkLoadingFailedEventData].
ErrorText string `json:"error_text"`
+ // This field is from variant [BrowserProxyErrorEventData].
+ Code string `json:"code"`
// This field is from variant [BrowserPageNavigationEventData].
ParentFrameID string `json:"parent_frame_id"`
CdpTimestamp float64 `json:"cdp_timestamp"`
@@ -2797,6 +2891,7 @@ type BrowserTelemetryEventUnionData struct {
StatusText respjson.Field
Canceled respjson.Field
ErrorText respjson.Field
+ Code respjson.Field
ParentFrameID respjson.Field
CdpTimestamp respjson.Field
OpenerID respjson.Field
diff --git a/internal/version.go b/internal/version.go
index 7892089e..6cb9969a 100644
--- a/internal/version.go
+++ b/internal/version.go
@@ -2,4 +2,4 @@
package internal
-const PackageVersion = "0.92.0" // x-release-please-version
+const PackageVersion = "0.93.0" // x-release-please-version
diff --git a/shared/constant/constants.go b/shared/constant/constants.go
index 30dd2fd5..a6bd9e37 100644
--- a/shared/constant/constants.go
+++ b/shared/constant/constants.go
@@ -61,6 +61,7 @@ type PageLoad string // Always "page_load"
type PageNavigation string // Always "page_navigation"
type PageNavigationSettled string // Always "page_navigation_settled"
type PageTabOpened string // Always "page_tab_opened"
+type ProxyError string // Always "proxy_error"
type Screenshot string // Always "screenshot"
type ServiceCrashed string // Always "service_crashed"
type SseHeartbeat string // Always "sse_heartbeat"
@@ -112,6 +113,7 @@ func (c PageLoad) Default() PageLoad { return "page_
func (c PageNavigation) Default() PageNavigation { return "page_navigation" }
func (c PageNavigationSettled) Default() PageNavigationSettled { return "page_navigation_settled" }
func (c PageTabOpened) Default() PageTabOpened { return "page_tab_opened" }
+func (c ProxyError) Default() ProxyError { return "proxy_error" }
func (c Screenshot) Default() Screenshot { return "screenshot" }
func (c ServiceCrashed) Default() ServiceCrashed { return "service_crashed" }
func (c SseHeartbeat) Default() SseHeartbeat { return "sse_heartbeat" }
@@ -161,6 +163,7 @@ func (c PageLoad) MarshalJSON() ([]byte, error) { return marshal
func (c PageNavigation) MarshalJSON() ([]byte, error) { return marshalString(c) }
func (c PageNavigationSettled) MarshalJSON() ([]byte, error) { return marshalString(c) }
func (c PageTabOpened) MarshalJSON() ([]byte, error) { return marshalString(c) }
+func (c ProxyError) MarshalJSON() ([]byte, error) { return marshalString(c) }
func (c Screenshot) MarshalJSON() ([]byte, error) { return marshalString(c) }
func (c ServiceCrashed) MarshalJSON() ([]byte, error) { return marshalString(c) }
func (c SseHeartbeat) MarshalJSON() ([]byte, error) { return marshalString(c) }