@scalebrowser/sdk 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,65 +1,5 @@
1
1
  import WebSocket from 'ws';
2
2
 
3
- /**
4
- * Error model — stable numeric API error codes (SPEC §5,
5
- * `crates/core/src/error.rs`) and the typed exceptions the SDK throws.
6
- */
7
- /** Stable numeric API error codes (4001–4010). */
8
- declare const ErrorCode: {
9
- readonly NotFound: 4001;
10
- readonly ProxyGeo: 4002;
11
- readonly Capacity: 4003;
12
- readonly EngineMissing: 4004;
13
- readonly Preflight: 4005;
14
- readonly AlreadyRunning: 4006;
15
- /** Retired: the removed Methode-D (VM) tier produced this. Reserved (never reused)
16
- * to match the server's append-only code contract; never returned now. */
17
- readonly VmProvisionFailed: 4007;
18
- /** The subscription's abo-wide concurrent-browser allowance is used up (DEC-012).
19
- * Distinct from Capacity (4003 = this machine is full, wait): the caller's move
20
- * is to stop a running browser anywhere or upgrade the plan. */
21
- readonly ConcurrencyLimit: 4008;
22
- readonly Unauthorized: 4010;
23
- };
24
- type ErrorCodeValue = (typeof ErrorCode)[keyof typeof ErrorCode];
25
- /** Error body shape: `{ code, message }` (docs/features/api.md). */
26
- interface ApiErrorBody {
27
- code?: number;
28
- message?: string;
29
- }
30
- /** Base class for every error this SDK throws — lets callers `catch` one type. */
31
- declare class ScalebrowserError extends Error {
32
- constructor(message: string);
33
- }
34
- /**
35
- * A typed transport/contract error. Carries the HTTP `status` and the daemon's
36
- * numeric `code` so callers (and the auth layer) can react — e.g. 401 / code
37
- * 4010 → re-authenticate.
38
- */
39
- declare class ApiError extends ScalebrowserError {
40
- readonly status: number;
41
- readonly code?: number;
42
- readonly body?: ApiErrorBody;
43
- constructor(status: number, body?: ApiErrorBody, fallbackMessage?: string);
44
- /** True for auth failures that must trigger re-authentication. */
45
- get isAuthError(): boolean;
46
- /** Short label for the error code, if any. */
47
- get codeLabel(): string | undefined;
48
- }
49
- /** A network-level failure (daemon unreachable, socket error, fetch rejected). */
50
- declare class NetworkError extends ScalebrowserError {
51
- readonly cause?: unknown;
52
- constructor(message: string, cause?: unknown);
53
- }
54
- /** A CDP command that returned an `error` frame, or a closed CDP connection. */
55
- declare class CdpError extends ScalebrowserError {
56
- readonly code: number;
57
- readonly data?: unknown;
58
- constructor(code: number, message: string, data?: unknown);
59
- }
60
- /** Narrow an unknown thrown value to a user-facing message. */
61
- declare function errorMessage(err: unknown): string;
62
-
63
3
  interface Screen {
64
4
  width: number;
65
5
  height: number;
@@ -167,14 +107,14 @@ interface Persona {
167
107
  }
168
108
 
169
109
  /**
170
- * Wire types — a 1:1 mirror of the daemon's serialized domain model
110
+ * Wire types: a 1:1 mirror of the daemon's serialized domain model
171
111
  * (`crates/core/src/model.rs`, `persona.rs`, `events.rs`) and the endpoint
172
112
  * contract in `docs/features/api.md`. Mirrored against `web-ui/src/api/types/`
173
113
  * (a directory of split files behind the `web-ui/src/api/types.ts` barrel), and
174
114
  * that mirror is ENFORCED: `web-ui/src/test/sdk-type-mirror.test.ts` compares
175
115
  * every shared exported declaration and goes red on drift. The Python SDK
176
116
  * (`sdks/python/src/scalebrowser/models*.py`) carries the same shapes by hand,
177
- * deliberately without a gate — a TS↔pydantic comparator is its own tool.
117
+ * deliberately without a gate; a TS↔pydantic comparator is its own tool.
178
118
  *
179
119
  * All Rust enums serialize `snake_case` (serde `rename_all`). Timestamps are
180
120
  * unix seconds (`number`, Rust `i64`). The truth for any disagreement is the
@@ -200,7 +140,7 @@ declare const ROTATIONS: readonly Rotation[];
200
140
  type SessionKind = 'cookies' | 'local_storage' | 'indexed_db' | 'service_worker';
201
141
  type OsFamily = 'windows' | 'macos' | 'linux';
202
142
  /** How protected a profile is right now, decided by the daemon WITHOUT starting a
203
- * browser — it runs the same gates the launch runs. `blocked` means the launch
143
+ * browser: it runs the same gates the launch runs. `blocked` means the launch
204
144
  * will refuse this profile; `warn` means it starts but something measurably
205
145
  * weakens it (most often a missing proxy). */
206
146
  type ProtectionLevel = 'ok' | 'warn' | 'blocked';
@@ -235,7 +175,7 @@ interface Profile {
235
175
  protection?: ProtectionStatus;
236
176
  /**
237
177
  * Platform slugs this profile has a stored login for, sorted by the daemon.
238
- * Additive — a daemon predating the credential vault simply omits it.
178
+ * Additive; a daemon predating the credential vault simply omits it.
239
179
  */
240
180
  platforms?: string[];
241
181
  }
@@ -247,7 +187,7 @@ interface Group {
247
187
  /**
248
188
  * Operating config: what the created profiles DO. Every key mirrors a
249
189
  * `POST /v1/profiles` body field. The daemon refuses an unknown key with a 400
250
- * rather than dropping it — a preset makes up to 1000 profiles, so a swallowed
190
+ * rather than dropping it, because a preset makes up to 1000 profiles, so a swallowed
251
191
  * key is a thousand wrong ones.
252
192
  */
253
193
  interface PresetConfig {
@@ -255,12 +195,12 @@ interface PresetConfig {
255
195
  engine_version?: string | null;
256
196
  host_mode?: HostMode | null;
257
197
  geo_mode?: GeoMode | null;
258
- /** The geo GATE's expectation — not the persona's drawn region. */
198
+ /** The geo GATE's expectation, not the persona's drawn region. */
259
199
  expected_country?: string | null;
260
200
  group_id?: string | null;
261
201
  proxy_id?: string | null;
262
202
  /**
263
- * Library ids every profile of the batch is created with. Empty is normal —
203
+ * Library ids every profile of the batch is created with. Empty is normal, since
264
204
  * about half of real Chrome users carry no extension.
265
205
  *
266
206
  * An id the library no longer holds refuses the whole batch: a thousand profiles
@@ -271,7 +211,7 @@ interface PresetConfig {
271
211
  /**
272
212
  * Generator constraints: what the created profiles ARE. Exactly one axis,
273
213
  * because an axis is only honest here if the daemon does not overwrite it at
274
- * launch — the GPU, screen, DPR and Chrome version all are.
214
+ * launch; the GPU, screen, DPR and Chrome version all are.
275
215
  */
276
216
  interface PresetConstraints {
277
217
  /**
@@ -287,11 +227,11 @@ interface Preset {
287
227
  config: PresetConfig;
288
228
  created_at: number;
289
229
  }
290
- /** `GET /v1/persona/constraints` — the values a preset may constrain to. */
230
+ /** `GET /v1/persona/constraints`: the values a preset may constrain to. */
291
231
  interface PersonaConstraintOptions {
292
232
  countries: string[];
293
233
  }
294
- /** Proxy — credentials are write-only (`#[serde(skip_serializing)]`); never returned. */
234
+ /** Proxy; credentials are write-only (`#[serde(skip_serializing)]`) and never returned. */
295
235
  interface Proxy {
296
236
  id: string;
297
237
  kind: ProxyKind;
@@ -323,7 +263,7 @@ interface AuditStatus {
323
263
  state: 'idle' | 'running' | 'finished';
324
264
  started_at?: number;
325
265
  finished_at?: number;
326
- /** Why the RUN failed — distinct from a detector's own `skip`. */
266
+ /** Why the RUN failed, distinct from a detector's own `skip`. */
327
267
  error?: string;
328
268
  report?: AuditReport;
329
269
  }
@@ -418,7 +358,7 @@ interface RunStep {
418
358
  /** Path of the still under the runs API; the image is fetched separately. */
419
359
  shot_path: string | null;
420
360
  /**
421
- * What the call produced, in one line — "3 blocks, 122 characters",
361
+ * What the call produced, in one line: "3 blocks, 122 characters",
422
362
  * "no visible change · 14 elements".
423
363
  *
424
364
  * `summary` says what the agent asked for, this says what came back. A step
@@ -495,7 +435,7 @@ type LifecycleEvent = {
495
435
  goal: string;
496
436
  at: number;
497
437
  }
498
- /** One tool call was appended to a run's trail — the whole stored step. */
438
+ /** One tool call was appended to a run's trail: the whole stored step. */
499
439
  | {
500
440
  type: 'run_step';
501
441
  run_id: string;
@@ -533,7 +473,7 @@ type LifecycleEvent = {
533
473
  /**
534
474
  * An event as it arrives, with its position in this connection's stream.
535
475
  *
536
- * The daemon numbers every frame, starting at 1. A jump means frames were lost —
476
+ * The daemon numbers every frame, starting at 1. A jump means frames were lost, and
537
477
  * the only way to tell "nothing happened" from "something happened and I did not
538
478
  * get it". Optional so a daemon predating the numbering still type-checks.
539
479
  */
@@ -544,13 +484,13 @@ type StreamedEvent = LifecycleEvent & {
544
484
  /**
545
485
  * Live lifecycle event stream (`GET /v1/events`, AC-API-003).
546
486
  *
547
- * Read as `text/event-stream` over `fetch` (so the Bearer header is attached —
487
+ * Read as `text/event-stream` over `fetch` (so the Bearer header is attached, which
548
488
  * the browser `EventSource` cannot do that) and reconnect with backoff. A
549
489
  * `/v1/ws` websocket carries the same events; SSE is sufficient for one-way
550
490
  * fan-out. Mirrors `web-ui/src/api/events.ts`.
551
491
  */
552
492
 
553
- /** Injectable `fetch` — defaults to the global at call time. */
493
+ /** Injectable `fetch`; defaults to the global at call time. */
554
494
  type FetchLike = typeof globalThis.fetch;
555
495
  type StreamStatus = 'connecting' | 'open' | 'closed';
556
496
  interface StreamParams {
@@ -597,7 +537,7 @@ declare function eventStream(params: StreamParams): AsyncIterableIterator<Lifecy
597
537
  /** What an operator has taken out of an agent's hands. */
598
538
  type InterruptionLock = 'always_block' | 'always_allow' | 'agent_decides';
599
539
  /**
600
- * One answer, in the browser's OWN vocabulary — hence `allowOnce` in camelCase
540
+ * One answer, in the browser's OWN vocabulary, hence `allowOnce` in camelCase
601
541
  * while everything else in this API is snake_case. The daemon's enum is
602
542
  * `#[serde(rename_all = "camelCase")]`; sending `allow_once` is a 400.
603
543
  */
@@ -636,7 +576,7 @@ interface InterruptionRuleRow {
636
576
  origin: string;
637
577
  kind: string;
638
578
  choice: InterruptionChoice;
639
- /** Who wrote it — an agent must not be able to widen what the operator allowed. */
579
+ /** Who wrote it: an agent must not be able to widen what the operator allowed. */
640
580
  author: 'operator' | 'agent';
641
581
  profile_id: string | null;
642
582
  }
@@ -668,13 +608,13 @@ interface ArtifactBytes {
668
608
  * Licence state, for display.
669
609
  *
670
610
  * The daemon decides on every launch whether a start is allowed; this never
671
- * gets a say in it. Never gate your own code on it — a green light on a profile
611
+ * gets a say in it. Never gate your own code on it: a green light on a profile
672
612
  * the launch gate refuses is worse than no light.
673
613
  */
674
614
  interface Account {
675
615
  /** Whether an entitlement snapshot has arrived. Also `false` in the seconds
676
616
  * between signing in and the first refresh, so it never answers "is this
677
- * machine connected to an account" — `signed_in` does. */
617
+ * machine connected to an account"; `signed_in` does. */
678
618
  licensed: boolean;
679
619
  /** Whether an account is connected to this machine. One without an account
680
620
  * starts no browser (DEC-014). */
@@ -731,7 +671,7 @@ declare class ClientCore {
731
671
  setToken(token: string | null): void;
732
672
  protected request<T>(method: string, path: string, body?: unknown, opts?: RequestOptions): Promise<T>;
733
673
  /**
734
- * A route that answers with bytes, not JSON — artifacts and run stills.
674
+ * A route that answers with bytes, not JSON: artifacts and run stills.
735
675
  *
736
676
  * Separate from {@link ClientCore.request} rather than a flag on it, because the two
737
677
  * differ in the error path as well: a failed byte fetch still answers JSON,
@@ -758,7 +698,7 @@ declare class ControlApi extends ClientCore {
758
698
  */
759
699
  putArtifact(profileId: string, bytes: Uint8Array | ArrayBuffer, name?: string): Promise<ArtifactPutResult>;
760
700
  /**
761
- * Fetch one artifact's bytes — a screenshot, a download, a saved PDF.
701
+ * Fetch one artifact's bytes: a screenshot, a download, a saved PDF.
762
702
  *
763
703
  * A miss is a plain 404 whether the id never existed, expired, or belonged to
764
704
  * a released lease: the caller's next move is the same in all three cases.
@@ -768,13 +708,13 @@ declare class ControlApi extends ClientCore {
768
708
  * Licence state for display. The launch gate stays the authority on starts.
769
709
  *
770
710
  * A daemon predating the route answers 404, and that is not an error worth
771
- * throwing — but it is read pessimistically: nothing can be shown to be
711
+ * throwing, but it is read pessimistically: nothing can be shown to be
772
712
  * connected or permitted. Same shape of tolerance as {@link getMetrics}.
773
713
  */
774
714
  getAccount(signal?: AbortSignal): Promise<Account>;
775
715
  /** "Is the daemon alive?" Public, needs no token. */
776
716
  health(signal?: AbortSignal): Promise<HealthStatus>;
777
- /** "Can it serve?" Local facts only — the control plane is deliberately not consulted. */
717
+ /** "Can it serve?" Local facts only; the control plane is deliberately not consulted. */
778
718
  ready(signal?: AbortSignal): Promise<ReadyStatus>;
779
719
  }
780
720
 
@@ -782,12 +722,12 @@ declare class ControlApi extends ClientCore {
782
722
  * a paged fleet while looking authoritative, so ordering is a server parameter. */
783
723
  type ProfileSort = 'created_at' | 'name' | 'runtime_state' | 'last_open_at';
784
724
  type SortOrder = 'asc' | 'desc';
785
- /** `GET /v1/profiles/ids` — every id matching the same filters, unpaged. */
725
+ /** `GET /v1/profiles/ids`: every id matching the same filters, unpaged. */
786
726
  interface ProfileIdsResult {
787
727
  count: number;
788
728
  ids: string[];
789
729
  }
790
- /** `POST /v1/bulk/start` — per-id results plus what the batch as a whole did. */
730
+ /** `POST /v1/bulk/start`: per-id results plus what the batch as a whole did. */
791
731
  interface BulkStartResult {
792
732
  results: {
793
733
  id: string;
@@ -818,7 +758,7 @@ interface CreateProfileBody {
818
758
  proxy_id?: string | null;
819
759
  }
820
760
  /**
821
- * PATCH — all mutable fields optional. `host_mode` and `seed` are fixed at create
761
+ * PATCH, all mutable fields optional. `host_mode` and `seed` are fixed at create
822
762
  * time (C4/C5): a DIFFERING `host_mode` is refused with 400, an unchanged echo is
823
763
  * accepted. Changing a tier requires delete + recreate.
824
764
  */
@@ -836,6 +776,17 @@ interface StartProfileResult {
836
776
  pid: number | null;
837
777
  started_at: number;
838
778
  }
779
+ /** What a takeover request answered.
780
+ *
781
+ * `free` means the profile is yours to start now; `pending` means the machine that
782
+ * held it has been told and is closing its browser, so ask again in a moment.
783
+ * Never start on `pending`: two machines on one identity is what a site reads as
784
+ * a cloned account. */
785
+ interface TakeoverResult {
786
+ state: 'free' | 'pending';
787
+ /** The holder as a person reads it: its label, else a short machine id. */
788
+ holder?: string | null;
789
+ }
839
790
  interface StopProfileResult {
840
791
  stopped: boolean;
841
792
  }
@@ -875,11 +826,11 @@ interface ProxyCheckResult {
875
826
  ja4t_mismatch?: boolean;
876
827
  warnings?: string[];
877
828
  checked_at?: number;
878
- /** Round-trip RTT — `null` on an unreachable exit (a timeout is not a latency). */
829
+ /** Round-trip RTT, `null` on an unreachable exit (a timeout is not a latency). */
879
830
  latency_ms?: number | null;
880
831
  }
881
832
  /**
882
- * Body of `POST /v1/proxies/check` — probe a proxy config that is NOT persisted
833
+ * Body of `POST /v1/proxies/check`: probe a proxy config that is NOT persisted
883
834
  * (health + geo before you commit it).
884
835
  *
885
836
  * Edit-mode: pass the `id` of an existing proxy and omit `username`/`password`
@@ -893,7 +844,7 @@ interface CheckProxyConfigBody {
893
844
  username?: string | null;
894
845
  password?: string | null;
895
846
  rotation?: Rotation;
896
- /** Existing proxy id — enables the stored-credential fallback. */
847
+ /** Existing proxy id; enables the stored-credential fallback. */
897
848
  id?: string | null;
898
849
  }
899
850
  /**
@@ -913,7 +864,7 @@ interface Extension {
913
864
  * dir does not leave every row pointing at nothing.
914
865
  */
915
866
  dir: string;
916
- /** SHA-256 of the unpacked tree — names the CONTENT of this version. */
867
+ /** SHA-256 of the unpacked tree; it names the CONTENT of this version. */
917
868
  content_hash: string;
918
869
  added_at: number;
919
870
  }
@@ -922,7 +873,7 @@ interface Extension {
922
873
  * extensions response; `engine_switches` is what the launch actually emits.
923
874
  *
924
875
  * `id_model` is `"canonical"`: the id comes from the package's key and is the same
925
- * for every profile — deliberately, since it is the id millions of real users
876
+ * for every profile, deliberately, since it is the id millions of real users
926
877
  * report. Only the FILES are per-profile (`delivery: "per_profile_copy"`).
927
878
  */
928
879
  interface ExtensionPolicy {
@@ -937,7 +888,7 @@ interface ExtensionsResult {
937
888
  /** Assigned library ids, as an idempotent set. */
938
889
  extensions: string[];
939
890
  /**
940
- * The set this profile actually loads — ONE version per extension, drawn from the
891
+ * The set this profile actually loads: ONE version per extension, drawn from the
941
892
  * profile's seed over what the library stocks. Shorter than `extensions` when an id
942
893
  * no longer resolves.
943
894
  */
@@ -945,7 +896,7 @@ interface ExtensionsResult {
945
896
  policy: ExtensionPolicy;
946
897
  /**
947
898
  * What is worth knowing about THIS set, judged by the daemon with the same
948
- * function the launch gate uses. Empty for an unremarkable set — including an
899
+ * function the launch gate uses. Empty for an unremarkable set, including an
949
900
  * empty one, since about half of real Chrome users carry no extension.
950
901
  *
951
902
  * Never recompute it client-side: a second opinion could contradict the gate.
@@ -954,7 +905,7 @@ interface ExtensionsResult {
954
905
  }
955
906
  /** One finding about a profile's extension set. */
956
907
  interface ExtensionAdvice {
957
- /** `warn` — a launch is never blocked by an extension. */
908
+ /** `warn`: a launch is never blocked by an extension. */
958
909
  level: string;
959
910
  message: string;
960
911
  }
@@ -967,14 +918,14 @@ declare class ExtensionsApi extends ClientCore {
967
918
  * existing ones (profiles draw their own); re-uploading the same version replaces it.
968
919
  */
969
920
  uploadExtension(crx: Uint8Array | ArrayBuffer): Promise<Extension>;
970
- /** One library entry — the most recently added version. */
921
+ /** One library entry: the most recently added version. */
971
922
  getLibraryExtension(id: string, signal?: AbortSignal): Promise<Extension>;
972
923
  /** Remove EVERY version of a package, its files and every profile's assignment of it. */
973
924
  deleteLibraryExtension(id: string): Promise<unknown>;
974
925
  /**
975
926
  * Remove ONE stocked version.
976
927
  *
977
- * Assignments survive — they name the extension, not the version — unless this
928
+ * Assignments survive, because they name the extension and not the version, unless this
978
929
  * was the last version, in which case they go with it.
979
930
  */
980
931
  deleteLibraryExtensionVersion(id: string, version: string): Promise<unknown>;
@@ -986,58 +937,6 @@ declare class ExtensionsApi extends ClientCore {
986
937
  detachExtension(profileId: string, extRef: string): Promise<ExtensionsResult>;
987
938
  }
988
939
 
989
- /**
990
- * One stored platform login — everything about it EXCEPT the secrets.
991
- *
992
- * The username IS returned: it is the account's display identity, not a secret on
993
- * any platform, and without it two stored accounts are indistinguishable. The
994
- * password and two-factor key travel only through `revealCredential`, which needs
995
- * the vault password.
996
- */
997
- interface CredentialMeta {
998
- platform: string;
999
- username: string | null;
1000
- login_url: string | null;
1001
- has_password: boolean;
1002
- has_totp: boolean;
1003
- /** Typed into a sign-up form but never confirmed — the account may not exist. */
1004
- pending?: boolean;
1005
- created_at: number;
1006
- updated_at: number;
1007
- last_used_at: number | null;
1008
- /** No longer opens with the current master key: listable, deletable, unusable. */
1009
- secrets_unreadable?: boolean;
1010
- }
1011
- /** An omitted secret means "leave it unchanged", not "delete it". */
1012
- interface PutCredentialBody {
1013
- username?: string | null;
1014
- password?: string | null;
1015
- /** Base32 setup key. Grouped, lower-case input is normalised by the daemon. */
1016
- totp_secret?: string | null;
1017
- login_url?: string | null;
1018
- }
1019
- /** The only shape in this SDK that carries a password. */
1020
- interface RevealedCredential {
1021
- platform: string;
1022
- username: string | null;
1023
- password: string | null;
1024
- totp_secret: string | null;
1025
- }
1026
- /** A passphrase-sealed backup of one profile's logins. */
1027
- interface CredentialBundle {
1028
- bundle: string;
1029
- count: number;
1030
- }
1031
- interface CredentialImportResult {
1032
- /** Boolean, like the session import — the number is in `count`. */
1033
- imported: boolean;
1034
- count: number;
1035
- platforms: string[];
1036
- }
1037
- interface VaultStatus {
1038
- configured: boolean;
1039
- }
1040
-
1041
940
  /**
1042
941
  * The account layer: mailboxes, passkeys and the one door a cookie value leaves
1043
942
  * through.
@@ -1064,7 +963,7 @@ interface Inbox {
1064
963
  address_domain: string | null;
1065
964
  created_at: number;
1066
965
  /**
1067
- * The stored password could not be decrypted — a restored database without
966
+ * The stored password could not be decrypted: a restored database without
1068
967
  * its key. The row stays visible and deletable; every use of it fails closed.
1069
968
  */
1070
969
  credentials_unreadable?: boolean;
@@ -1106,7 +1005,7 @@ interface InboxBindings {
1106
1005
  bindings: InboxBinding[];
1107
1006
  }
1108
1007
  /**
1109
- * One passkey of a profile — a login that needs no password.
1008
+ * One passkey of a profile: a login that needs no password.
1110
1009
  *
1111
1010
  * `credential_id` names the row for deletion and nothing else. The private key
1112
1011
  * has no field here and no endpoint: it IS the account, and it could not be
@@ -1120,7 +1019,7 @@ interface PasskeyRow {
1120
1019
  user_display: string | null;
1121
1020
  created_at: number;
1122
1021
  last_used_at: number | null;
1123
- /** True when a stored secret cannot be decrypted — the sign-in WILL fail. */
1022
+ /** True when a stored secret cannot be decrypted; the sign-in WILL fail. */
1124
1023
  secrets_unreadable: boolean;
1125
1024
  /**
1126
1025
  * When the key stopped being usable, if it has. A retired key is never loaded
@@ -1131,7 +1030,7 @@ interface PasskeyRow {
1131
1030
  retired_at: number | null;
1132
1031
  /**
1133
1032
  * `unknown` is a reason this build cannot name, and it deliberately claims
1134
- * nothing — reading it as `operator` would tell you that you had deleted
1033
+ * nothing, because reading it as `operator` would tell you that you had deleted
1135
1034
  * something you never touched.
1136
1035
  */
1137
1036
  retired_reason: 'operator' | 'agent' | 'site_revoked' | 'unknown' | null;
@@ -1154,6 +1053,150 @@ interface RevealCookiesResult {
1154
1053
  domain: string;
1155
1054
  cookies: RevealedCookie[];
1156
1055
  }
1056
+ /** What a stored value is. */
1057
+ type SecretKind = 'api_token' | 'password' | 'recovery_code' | 'totp_seed' | 'private_key' | 'unknown';
1058
+ /** How the layer came to know it. The first three are the honest origins. */
1059
+ type SecretOrigin = 'generated' | 'stored' | 'typed' | 'captured';
1060
+ /** How narrowly it is bound to where it may be used. */
1061
+ type SecretBindingMode = 'domain' | 'host' | 'prefix' | 'exact' | 'off';
1062
+ /** Where it stands between "just seen" and "known good". */
1063
+ type SecretState = 'quarantined' | 'confirmed' | 'doubtful' | 'released';
1064
+ interface SecretRow {
1065
+ id: string;
1066
+ /** The immutable name inside the placeholder. Renaming changes the title. */
1067
+ label: string;
1068
+ display_title?: string | null;
1069
+ /** The placeholder for THIS daemon run. A new run draws a new session part. */
1070
+ secret_ref?: string;
1071
+ kind: SecretKind;
1072
+ origin: SecretOrigin;
1073
+ detected_by?: string | null;
1074
+ binding_mode: SecretBindingMode;
1075
+ binding_value?: string | null;
1076
+ field_bound: boolean;
1077
+ state: SecretState;
1078
+ sole_copy: boolean;
1079
+ /** Only present where the length is the FORMAT's rather than the value's. */
1080
+ length?: number | null;
1081
+ expires_at?: number | null;
1082
+ created_at: number;
1083
+ updated_at: number;
1084
+ last_used_at?: number | null;
1085
+ value_unreadable?: boolean;
1086
+ }
1087
+ interface SecretListResult {
1088
+ secrets: SecretRow[];
1089
+ /** Values still being censored that have no entry, because the list is full. */
1090
+ withheld_without_an_entry: number;
1091
+ layer_enabled: boolean;
1092
+ }
1093
+ /** What may be changed about one entry. The label is deliberately absent. */
1094
+ interface SecretPatchBody {
1095
+ display_title?: string;
1096
+ binding_mode?: SecretBindingMode;
1097
+ binding_value?: string;
1098
+ clear_binding_value?: boolean;
1099
+ field_bound?: boolean;
1100
+ state?: SecretState;
1101
+ expires_at?: number;
1102
+ clear_expires_at?: boolean;
1103
+ }
1104
+ interface SecretRunMention {
1105
+ run_id: string;
1106
+ goal: string;
1107
+ started_at: number;
1108
+ steps: number;
1109
+ }
1110
+ interface SecretDeleteResult {
1111
+ deleted: string;
1112
+ label: string;
1113
+ /** The runs this entry appeared in, so nothing is removed blind. */
1114
+ appeared_in_runs: SecretRunMention[];
1115
+ }
1116
+ interface SecretScrubResult {
1117
+ text: string;
1118
+ /** Which entries were replaced, by label. Never a value. */
1119
+ replaced: string[];
1120
+ }
1121
+ interface SecretRunBody {
1122
+ /** `NAME=<label>` pairs. At least one is required. */
1123
+ env: string[];
1124
+ /** The command and its arguments, already split. Never a shell line. */
1125
+ command: string[];
1126
+ cwd?: string;
1127
+ timeout_secs?: number;
1128
+ }
1129
+ interface SecretRunResult {
1130
+ command: string;
1131
+ exit_code: number | null;
1132
+ stdout: string;
1133
+ stderr: string;
1134
+ values_supplied: string[];
1135
+ }
1136
+
1137
+ /**
1138
+ * One stored platform login: everything about it EXCEPT the secrets.
1139
+ *
1140
+ * The username IS returned: it is the account's display identity, not a secret on
1141
+ * any platform, and without it two stored accounts are indistinguishable. The
1142
+ * password and two-factor key travel only through `revealCredential`, which needs
1143
+ * the vault password.
1144
+ */
1145
+ interface CredentialMeta {
1146
+ platform: string;
1147
+ username: string | null;
1148
+ login_url: string | null;
1149
+ has_password: boolean;
1150
+ has_totp: boolean;
1151
+ /** Typed into a sign-up form but never confirmed, so the account may not exist. */
1152
+ pending?: boolean;
1153
+ created_at: number;
1154
+ updated_at: number;
1155
+ last_used_at: number | null;
1156
+ /** No longer opens with the current master key: listable, deletable, unusable. */
1157
+ secrets_unreadable?: boolean;
1158
+ /** Where this login may be typed (Secret Layer). */
1159
+ binding_mode: SecretBindingMode;
1160
+ binding_value?: string | null;
1161
+ /** Is the field-kind check on for this login? */
1162
+ field_bound: boolean;
1163
+ }
1164
+ /** An omitted secret means "leave it unchanged", not "delete it". */
1165
+ interface PutCredentialBody {
1166
+ username?: string | null;
1167
+ password?: string | null;
1168
+ /** Base32 setup key. Grouped, lower-case input is normalised by the daemon. */
1169
+ totp_secret?: string | null;
1170
+ login_url?: string | null;
1171
+ /**
1172
+ * Where this login may be typed. Absent leaves it as it is, so changing a
1173
+ * password never silently widens a binding.
1174
+ */
1175
+ binding_mode?: SecretBindingMode;
1176
+ binding_value?: string;
1177
+ field_bound?: boolean;
1178
+ }
1179
+ /** The only shape in this SDK that carries a password. */
1180
+ interface RevealedCredential {
1181
+ platform: string;
1182
+ username: string | null;
1183
+ password: string | null;
1184
+ totp_secret: string | null;
1185
+ }
1186
+ /** A passphrase-sealed backup of one profile's logins. */
1187
+ interface CredentialBundle {
1188
+ bundle: string;
1189
+ count: number;
1190
+ }
1191
+ interface CredentialImportResult {
1192
+ /** Boolean, like the session import; the number is in `count`. */
1193
+ imported: boolean;
1194
+ count: number;
1195
+ platforms: string[];
1196
+ }
1197
+ interface VaultStatus {
1198
+ configured: boolean;
1199
+ }
1157
1200
 
1158
1201
  declare class IdentityApi extends ClientCore {
1159
1202
  /** Which platforms this profile can log into. Never carries a secret. */
@@ -1161,7 +1204,7 @@ declare class IdentityApi extends ClientCore {
1161
1204
  /**
1162
1205
  * Store or update one login.
1163
1206
  *
1164
- * An omitted secret keeps its stored value rather than clearing it — an edit form
1207
+ * An omitted secret keeps its stored value rather than clearing it, because an edit form
1165
1208
  * never saw the password in the clear, so it cannot resend one; delete the row to
1166
1209
  * remove a credential. `totp_secret` may be pasted exactly as a site presents it
1167
1210
  * (grouped, lower case): it is normalised and test-decoded by the daemon, so a
@@ -1177,7 +1220,7 @@ declare class IdentityApi extends ClientCore {
1177
1220
  *
1178
1221
  * `password` is deliberately separate from the vault password: a backup gets
1179
1222
  * handed to another machine, and that must not also hand over daemon access. This
1180
- * is the answer to a lost master key — a daemon-generated password exists nowhere
1223
+ * is the answer to a lost master key: a daemon-generated password exists nowhere
1181
1224
  * else.
1182
1225
  */
1183
1226
  exportCredentials(profileId: string, vaultPassword: string, password: string): Promise<CredentialBundle>;
@@ -1206,6 +1249,37 @@ declare class IdentityApi extends ClientCore {
1206
1249
  * a headstone, the second clears the headstone for good.
1207
1250
  */
1208
1251
  deletePasskey(profileId: string, credentialId: string): Promise<unknown>;
1252
+ /** The entries this profile keeps, with the placeholder that stands for each. */
1253
+ listSecrets(profileId: string, signal?: AbortSignal): Promise<SecretListResult>;
1254
+ /** Change a title, a binding, or the state. Never the label. */
1255
+ updateSecret(profileId: string, secretId: string, body: SecretPatchBody): Promise<SecretRow>;
1256
+ /** Delete an entry. The reply names the runs it appeared in. */
1257
+ deleteSecret(profileId: string, secretId: string): Promise<SecretDeleteResult>;
1258
+ /**
1259
+ * Filter a text you hold against this profile's values.
1260
+ *
1261
+ * The SDK path exists because censoring only makes sense where a MODEL is
1262
+ * reading: your own code is not, and a placeholder in the middle of it would
1263
+ * break parsing. So the daemon offers the filter as a call rather than
1264
+ * applying it to a channel it does not own.
1265
+ */
1266
+ scrubText(profileId: string, text: string): Promise<SecretScrubResult>;
1267
+ /**
1268
+ * Run a command with named values in its environment.
1269
+ *
1270
+ * The daemon starts the child, so no value crosses a socket. At least one
1271
+ * `env` entry is required: without the rule an `npm publish` would carry every
1272
+ * value of the profile.
1273
+ */
1274
+ runWithSecrets(profileId: string, body: SecretRunBody): Promise<SecretRunResult>;
1275
+ /** Is the secret layer on? It is by default. */
1276
+ getSecretLayer(signal?: AbortSignal): Promise<{
1277
+ enabled: boolean;
1278
+ }>;
1279
+ /** Turn the secret layer on or off for the whole daemon. */
1280
+ setSecretLayer(enabled: boolean): Promise<{
1281
+ enabled: boolean;
1282
+ }>;
1209
1283
  /**
1210
1284
  * The one door a cookie VALUE leaves through, and it needs the vault password.
1211
1285
  *
@@ -1221,7 +1295,7 @@ declare class IdentityApi extends ClientCore {
1221
1295
  * All of it is display: nothing here starts, stops or changes anything.
1222
1296
  *
1223
1297
  * `RunActor`, `RunOutcome`, `StepKind`, `StepTarget`, `RunStep` and
1224
- * `ProfileActivity` are NOT redeclared here — they live in `types.ts` because
1298
+ * `ProfileActivity` are NOT redeclared here; they live in `types.ts` because
1225
1299
  * the live event stream carries them, and the run list describes the same rows.
1226
1300
  * A second copy would let the two drift apart while both looked right.
1227
1301
  *
@@ -1239,7 +1313,7 @@ interface AgentRun {
1239
1313
  profile_id: string;
1240
1314
  profile_name: string;
1241
1315
  actor: RunActor;
1242
- /** Never empty — described when it was not declared (see `goal_source`). */
1316
+ /** Never empty; described when it was not declared (see `goal_source`). */
1243
1317
  goal: string;
1244
1318
  goal_source: GoalSource;
1245
1319
  /**
@@ -1280,7 +1354,7 @@ declare class RunsApi extends ClientCore {
1280
1354
  listRuns(params?: ListRunsParams, signal?: AbortSignal): Promise<AgentRun[]>;
1281
1355
  /** One run. */
1282
1356
  getRun(runId: string, signal?: AbortSignal): Promise<AgentRun>;
1283
- /** A run's steps, oldest first — the order they happened in. */
1357
+ /** A run's steps, oldest first: the order they happened in. */
1284
1358
  listRunSteps(runId: string, params?: ListStepsParams, signal?: AbortSignal): Promise<RunStep[]>;
1285
1359
  /**
1286
1360
  * The still taken at one step, as JPEG bytes.
@@ -1294,7 +1368,7 @@ declare class RunsApi extends ClientCore {
1294
1368
  }
1295
1369
 
1296
1370
  /**
1297
- * Direct-CDP driver (DEC-006, AC-FP-005) — a minimal, nodriver-style Chrome
1371
+ * Direct-CDP driver (DEC-006, AC-FP-005): a minimal, nodriver-style Chrome
1298
1372
  * DevTools Protocol client over a raw websocket. This is the recommended SDK
1299
1373
  * driver plane: it is NOT the Playwright/Puppeteer control plane (which is a
1300
1374
  * detection vector independent of patch quality). We never call `Runtime.enable`
@@ -1328,7 +1402,7 @@ declare class CdpConnection {
1328
1402
  request<T>(method: string, params?: Record<string, unknown>, sessionId?: string): Promise<T>;
1329
1403
  subscribe(cb: (event: CdpEvent) => void): () => void;
1330
1404
  /** Register a callback fired once when the connection closes (immediately if
1331
- * it already has) — event streams use this to end instead of hanging. */
1405
+ * it already has); event streams use this to end instead of hanging. */
1332
1406
  onClose(cb: () => void): () => void;
1333
1407
  close(): void;
1334
1408
  get closed(): boolean;
@@ -1357,7 +1431,7 @@ interface ClickOptions {
1357
1431
  button?: string;
1358
1432
  clickCount?: number;
1359
1433
  /**
1360
- * B5: element-relative targeting — the effective target width (an element's
1434
+ * B5: element-relative targeting. The effective target width (an element's
1361
1435
  * bounding-box size). The daemon's Fitts-law approach lands within the element
1362
1436
  * instead of on a fixed corner. Prefer {@link CdpSession.humanizeClickElement}.
1363
1437
  */
@@ -1472,7 +1546,7 @@ interface Metrics {
1472
1546
  availability?: MetricsAvailability;
1473
1547
  profiles?: ProfileResource[];
1474
1548
  /**
1475
- * Launchable host memory (MiB) — the capacity gate's own reading. "How many
1549
+ * Launchable host memory (MiB), the capacity gate's own reading. "How many
1476
1550
  * more browsers fit" derives from THIS; `ram_budget_mb − ram_used_mb` does
1477
1551
  * not subtract (used is host-wide, the budget is the daemon's own ceiling).
1478
1552
  */
@@ -1480,11 +1554,11 @@ interface Metrics {
1480
1554
  }
1481
1555
 
1482
1556
  /**
1483
- * `ScalebrowserClient` — the one typed HTTP surface every REST call goes
1557
+ * `ScalebrowserClient`: the one typed HTTP surface every REST call goes
1484
1558
  * through. It centralises the base URL, Bearer auth, query-string building, JSON
1485
1559
  * (de)serialisation and error mapping (`{ code, message }` → {@link ApiError}).
1486
1560
  * Backend endpoint drift is a change in THIS file (paths) plus `types.ts`
1487
- * (shapes) — nowhere else.
1561
+ * (shapes), nowhere else.
1488
1562
  */
1489
1563
 
1490
1564
  /** Mirrors `CapacityConfig::default()` (`crates/core/src/config.rs`). */
@@ -1501,7 +1575,7 @@ interface LaunchHandle {
1501
1575
  readonly result: StartProfileResult;
1502
1576
  /** Close the CDP connection and stop the profile. */
1503
1577
  stop(): Promise<void>;
1504
- /** `await using` support — calls {@link stop}. */
1578
+ /** `await using` support; calls {@link stop}. */
1505
1579
  [Symbol.asyncDispose](): Promise<void>;
1506
1580
  }
1507
1581
  /** Fallback: compute what we can purely from profile runtime states. */
@@ -1509,7 +1583,7 @@ declare function deriveMetricsFromProfiles(profiles: Profile[]): Metrics;
1509
1583
  declare class ScalebrowserClient extends ClientCore {
1510
1584
  listProfiles(params?: ListProfilesParams, signal?: AbortSignal): Promise<Profile[]>;
1511
1585
  /**
1512
- * Every id matching `params`, unpaged — what "act on all matches" needs.
1586
+ * Every id matching `params`, unpaged: what "act on all matches" needs.
1513
1587
  *
1514
1588
  * `listProfiles` is paged, so acting on "everything" from it only ever covers the
1515
1589
  * page you fetched. Asking for ids costs one request and no persona payloads.
@@ -1522,6 +1596,12 @@ declare class ScalebrowserClient extends ClientCore {
1522
1596
  /** Start a profile → CDP ws endpoint. Errors: 4002/4003/4005/4006/4008. */
1523
1597
  startProfile(id: string, body?: StartProfileBody): Promise<StartProfileResult>;
1524
1598
  stopProfile(id: string): Promise<StopProfileResult>;
1599
+ /** Ask for a profile that is open on another machine of this account.
1600
+ *
1601
+ * Closes nothing here and nothing there: the control plane revokes the holder's
1602
+ * right, the holder closes its own browser at its next heartbeat. Start only
1603
+ * after this answered `free`. Errors: 4012 when it is held elsewhere. */
1604
+ takeoverProfile(id: string): Promise<TakeoverResult>;
1525
1605
  bulkCreateProfiles(body: BulkCreateBody): Promise<Profile[]>;
1526
1606
  /**
1527
1607
  * Start a batch. `headless` is the ONE visibility decision for the run; omitted
@@ -1565,7 +1645,7 @@ declare class ScalebrowserClient extends ClientCore {
1565
1645
  /** Health + geo check (exit-ip/country/healthy + JA4↔JA4T verdict). */
1566
1646
  checkProxy(id: string): Promise<ProxyCheckResult>;
1567
1647
  /**
1568
- * Probe a proxy config WITHOUT persisting it — validate before you commit.
1648
+ * Probe a proxy config WITHOUT persisting it: validate before you commit.
1569
1649
  * Pass `id` (and omit the credentials) to probe an existing proxy's stored,
1570
1650
  * write-only credentials in an edit form.
1571
1651
  */
@@ -1597,9 +1677,80 @@ interface ScalebrowserClient extends IdentityApi, RunsApi, ControlApi, Extension
1597
1677
  }
1598
1678
 
1599
1679
  /**
1600
- * `@scalebrowser/sdk` — the official Node/TypeScript SDK for the Scalebrowser
1680
+ * Error model: stable numeric API error codes (SPEC §5,
1681
+ * `crates/core/src/error.rs`) and the typed exceptions the SDK throws.
1682
+ */
1683
+ /** Stable numeric API error codes (4001–4012, append-only: a retired code stays
1684
+ * reserved rather than being reused). */
1685
+ declare const ErrorCode: {
1686
+ readonly NotFound: 4001;
1687
+ readonly ProxyGeo: 4002;
1688
+ readonly Capacity: 4003;
1689
+ readonly EngineMissing: 4004;
1690
+ readonly Preflight: 4005;
1691
+ readonly AlreadyRunning: 4006;
1692
+ /** Retired: the removed Methode-D (VM) tier produced this. Reserved (never reused)
1693
+ * to match the server's append-only code contract; never returned now. */
1694
+ readonly VmProvisionFailed: 4007;
1695
+ /** The subscription's abo-wide concurrent-browser allowance is used up (DEC-012).
1696
+ * Distinct from Capacity (4003 = this machine is full, wait): the caller's move
1697
+ * is to stop a running browser anywhere or upgrade the plan. */
1698
+ readonly ConcurrencyLimit: 4008;
1699
+ readonly Unauthorized: 4010;
1700
+ /** No account is connected to this machine, so nothing may run (DEC-014).
1701
+ * Distinct from Unauthorized (4010 = the daemon's own bearer token is wrong, so
1702
+ * re-read the token): 4011 means the machine needs to be signed in, and no token
1703
+ * a client holds can substitute for that. Connect it in the desktop app. */
1704
+ readonly NotSignedIn: 4011;
1705
+ /** This ONE profile is open on another machine of the same account (DEC-015).
1706
+ * Distinct from ConcurrencyLimit (4008 = the plan is full, buy more or free any
1707
+ * browser): the caller's move here costs nothing. Close it on that machine, or
1708
+ * take it over from the app running there. */
1709
+ readonly ProfileInUse: 4012;
1710
+ };
1711
+ type ErrorCodeValue = (typeof ErrorCode)[keyof typeof ErrorCode];
1712
+ /** Error body shape: `{ code, message }` (docs/features/api.md). */
1713
+ interface ApiErrorBody {
1714
+ code?: number;
1715
+ message?: string;
1716
+ }
1717
+ /** Base class for every error this SDK throws, so callers can `catch` one type. */
1718
+ declare class ScalebrowserError extends Error {
1719
+ constructor(message: string);
1720
+ }
1721
+ /**
1722
+ * A typed transport/contract error. Carries the HTTP `status` and the daemon's
1723
+ * numeric `code` so callers (and the auth layer) can react, e.g. 401 / code
1724
+ * 4010 → re-authenticate.
1725
+ */
1726
+ declare class ApiError extends ScalebrowserError {
1727
+ readonly status: number;
1728
+ readonly code?: number;
1729
+ readonly body?: ApiErrorBody;
1730
+ constructor(status: number, body?: ApiErrorBody, fallbackMessage?: string);
1731
+ /** True for auth failures that must trigger re-authentication. */
1732
+ get isAuthError(): boolean;
1733
+ /** Short label for the error code, if any. */
1734
+ get codeLabel(): string | undefined;
1735
+ }
1736
+ /** A network-level failure (daemon unreachable, socket error, fetch rejected). */
1737
+ declare class NetworkError extends ScalebrowserError {
1738
+ readonly cause?: unknown;
1739
+ constructor(message: string, cause?: unknown);
1740
+ }
1741
+ /** A CDP command that returned an `error` frame, or a closed CDP connection. */
1742
+ declare class CdpError extends ScalebrowserError {
1743
+ readonly code: number;
1744
+ readonly data?: unknown;
1745
+ constructor(code: number, message: string, data?: unknown);
1746
+ }
1747
+ /** Narrow an unknown thrown value to a user-facing message. */
1748
+ declare function errorMessage(err: unknown): string;
1749
+
1750
+ /**
1751
+ * `@scalebrowser/sdk`: the official Node/TypeScript SDK for the Scalebrowser
1601
1752
  * daemon. A typed REST client plus a direct-CDP driver plane (nodriver-style,
1602
- * NOT Playwright — DEC-006).
1753
+ * NOT Playwright, DEC-006).
1603
1754
  *
1604
1755
  * ```ts
1605
1756
  * import { ScalebrowserClient } from '@scalebrowser/sdk';
@@ -1613,6 +1764,6 @@ interface ScalebrowserClient extends IdentityApi, RunsApi, ControlApi, Extension
1613
1764
  * ```
1614
1765
  */
1615
1766
 
1616
- declare const VERSION = "0.3.0";
1767
+ declare const VERSION = "0.4.1";
1617
1768
 
1618
- export { type Account, type ActivitySnapshot, type AgentRun, ApiError, type ApiErrorBody, type ArtifactBytes, type ArtifactPutResult, type AttachOptions, type AuditDetectorReport, type AuditReport, type AuditStatus, type AuditVerdict, type BindInboxBody, type CdpConnectOptions, CdpError, type CdpEvent, CdpSession, type ClickOptions, type CreateGroupBody, type CreateInboxBody, type CreatePresetBody, DEFAULT_CAPACITY, type DeleteInterruptionRuleParams, type EffectiveInterruptionLock, ErrorCode, type ErrorCodeValue, type EvaluateOptions, type FetchLike, GEO_MODES, type GeoMode, type GoalSource, type Group, HOST_MODES, type HealthStatus, type HostMode, type Inbox, type InboxBinding, type InboxBindings, type InboxChannel, type InputClient, type InterruptionChoice, type InterruptionLock, type InterruptionLockRow, type InterruptionLockView, type InterruptionRuleRow, type LaunchHandle, type ListRunsParams, type ListStepsParams, type NavigateOptions, NetworkError, type OsFamily, type OutcomeSource, PROXY_KINDS, type PasskeyRow, type PersonaConstraintOptions, type Preset, type PresetConfig, type PresetConstraints, type Profile, type ProfileActivity, type ProtectionLevel, type ProtectionStatus, type Proxy, type ProxyKind, ROTATIONS, RUNTIME_STATES, type ReadyStatus, type RevealCookiesBody, type RevealCookiesResult, type RevealedCookie, type Rotation, type RunActor, type RunOutcome, type RunStep, type RuntimeState, ScalebrowserClient, type ScalebrowserClientOptions, ScalebrowserError, type ScrollOptions, type SessionExportBody, type SessionExportResult, type SessionImportBody, type SessionKind, type SetInterruptionLockBody, type SetInterruptionRuleBody, type StepKind, type StepTarget, type StreamHandlers, type StreamParams, type StreamStatus, type TrustedInputBody, type UpdateGroupBody, type UpdateInboxBody, type UpdatePresetBody, VERSION, deriveMetricsFromProfiles, errorMessage, eventStream, openCdpSession, parseSseFrame, subscribeEvents };
1769
+ export { type Account, type ActivitySnapshot, type AgentRun, ApiError, type ApiErrorBody, type ArtifactBytes, type ArtifactPutResult, type AttachOptions, type AuditDetectorReport, type AuditReport, type AuditStatus, type AuditVerdict, type BindInboxBody, type CdpConnectOptions, CdpError, type CdpEvent, CdpSession, type ClickOptions, type CreateGroupBody, type CreateInboxBody, type CreatePresetBody, DEFAULT_CAPACITY, type DeleteInterruptionRuleParams, type EffectiveInterruptionLock, ErrorCode, type ErrorCodeValue, type EvaluateOptions, type FetchLike, GEO_MODES, type GeoMode, type GoalSource, type Group, HOST_MODES, type HealthStatus, type HostMode, type Inbox, type InboxBinding, type InboxBindings, type InboxChannel, type InputClient, type InterruptionChoice, type InterruptionLock, type InterruptionLockRow, type InterruptionLockView, type InterruptionRuleRow, type LaunchHandle, type ListRunsParams, type ListStepsParams, type NavigateOptions, NetworkError, type OsFamily, type OutcomeSource, PROXY_KINDS, type PasskeyRow, type PersonaConstraintOptions, type Preset, type PresetConfig, type PresetConstraints, type Profile, type ProfileActivity, type ProtectionLevel, type ProtectionStatus, type Proxy, type ProxyKind, ROTATIONS, RUNTIME_STATES, type ReadyStatus, type RevealCookiesBody, type RevealCookiesResult, type RevealedCookie, type Rotation, type RunActor, type RunOutcome, type RunStep, type RuntimeState, ScalebrowserClient, type ScalebrowserClientOptions, ScalebrowserError, type ScrollOptions, type SecretBindingMode, type SecretDeleteResult, type SecretKind, type SecretListResult, type SecretOrigin, type SecretPatchBody, type SecretRow, type SecretRunBody, type SecretRunMention, type SecretRunResult, type SecretScrubResult, type SecretState, type SessionExportBody, type SessionExportResult, type SessionImportBody, type SessionKind, type SetInterruptionLockBody, type SetInterruptionRuleBody, type StepKind, type StepTarget, type StreamHandlers, type StreamParams, type StreamStatus, type TrustedInputBody, type UpdateGroupBody, type UpdateInboxBody, type UpdatePresetBody, VERSION, deriveMetricsFromProfiles, errorMessage, eventStream, openCdpSession, parseSseFrame, subscribeEvents };