@scalebrowser/sdk 1.1.0 → 1.2.0

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/CHANGELOG.md CHANGED
@@ -9,6 +9,26 @@ reconstructing it here would look like a record that had been kept all along.
9
9
  The daemon and the SDK version independently. An SDK release names the daemon
10
10
  version it was tested against wherever that matters.
11
11
 
12
+ ## 1.2.0 (2026-10-22)
13
+
14
+ Two fixes in the CDP driver, both measured against a real browser, and three
15
+ methods for routes the daemon serves since 0.24.0. Nothing is removed or renamed.
16
+
17
+ - `navigate()` waited for the load by reading `document.readyState` in the
18
+ page's own world. A page that wraps that getter saw two reads with no script of
19
+ its own on the stack. The wait now reads from an isolated world.
20
+ - `evaluate(expr, { isolated: true })` kept the id of its isolated world across a
21
+ navigation, so every isolated read after a page change failed with
22
+ `Cannot find context with specified id`. It now asks for the world of the
23
+ current document on every call.
24
+ - `revealRequest(profileId, seq, { vault_password })`: what a recorded request
25
+ carried (the full address with its query, every header value and, on request,
26
+ the body), behind the vault password. `seq` is the number the agent's
27
+ `net_capture` tool lists.
28
+ - `getAgentTools()` and `setAgentToolGroup(group, enabled)`: which optional MCP tool
29
+ groups agents on this machine see.
30
+ - The README lists every method of the client.
31
+
12
32
  ## 1.1.0 (2026-10-04)
13
33
 
14
34
  Three fields the daemon has sent since 0.20.0 now have types. All three are
package/README.md CHANGED
@@ -62,10 +62,13 @@ try {
62
62
 
63
63
  Every `/v1` endpoint is a typed method on `ScalebrowserClient`:
64
64
 
65
- - **Profiles**: `listProfiles`, `getProfile`, `createProfile`, `updateProfile`,
66
- `deleteProfile`, `startProfile`, `stopProfile`
65
+ - **Profiles**: `listProfiles`, `listProfileIds`, `countProfiles`, `getProfile`,
66
+ `createProfile`, `updateProfile`, `deleteProfile`, `startProfile`, `stopProfile`.
67
+ `releaseProfile` drops an agent's lease without its handle (the operator's way
68
+ out), and `takeoverProfile` asks for a profile that is open on another machine
69
+ of your account
67
70
  - **Bulk**: `bulkCreateProfiles`, `bulkStart`, `bulkStop`, `bulkDelete`,
68
- `bulkAssignProxy`
71
+ `bulkAssignProxy`, `bulkAssignExtensions`
69
72
  - **Groups / Presets**: `listGroups`/`createGroup`/`getGroup`/`updateGroup`/`deleteGroup`,
70
73
  `listPresets`/`createPreset`/`getPreset`/`updatePreset`/`deletePreset`,
71
74
  `getPersonaConstraints`. A preset is `config` (what the profiles do:
@@ -78,13 +81,20 @@ Every `/v1` endpoint is a typed method on `ScalebrowserClient`:
78
81
  it; pass `id` to reuse an existing proxy's stored credentials). Credentials
79
82
  are write-only, never returned
80
83
  - **Extensions**: `listExtensions`, `attachExtension`, `detachExtension`, plus
81
- the daemon-wide library (`uploadExtension`, `getLibraryExtension`,
82
- `deleteLibraryExtension`). An attached package IS loaded into the browser at
84
+ the daemon-wide library (`listLibraryExtensions`, `uploadExtension`,
85
+ `getLibraryExtension`, `deleteLibraryExtension`, `deleteLibraryExtensionVersion`). An attached package IS loaded into the browser at
83
86
  launch, under the canonical Web-Store id its own key derives
84
- - **Credentials**: `listCredentials`, `putCredential`, `revealCredential`
85
- (needs the vault password), `exportCredentials`, `importCredentials`
87
+ - **Credentials**: `listCredentials`, `putCredential`, `deleteCredential`,
88
+ `revealCredential` (needs the vault password), `exportCredentials`,
89
+ `importCredentials`. The vault password itself: `vaultStatus`, `setVaultPassword`
90
+ - **Secret layer**: `getSecretLayer`, `setSecretLayer`, `listSecrets`,
91
+ `updateSecret`, `deleteSecret`. `scrubText` filters a text you hold against a
92
+ profile's values, and `runWithSecrets` runs a command with named values in its
93
+ environment, so no value crosses a socket
86
94
  - **Cookies**: `revealCookies`, the one route a cookie VALUE leaves through,
87
95
  behind the same vault password
96
+ - **Recorded requests**: `revealRequest`, the one route what a request carried (query,
97
+ header values, body) leaves through, behind the same vault password
88
98
  - **Sessions**: `exportSession`, `importSession`
89
99
  - **Mailboxes**: `listInboxes`, `createInbox`, `updateInbox`, `deleteInbox`,
90
100
  `getInboxBindings`, `bindInbox`, `unbindInbox`, which is where a profile's
@@ -98,6 +108,30 @@ Every `/v1` endpoint is a typed method on `ScalebrowserClient`:
98
108
  may answer when the browser asks something
99
109
  - **Artifacts**: `putArtifact` (hand the daemon a file to upload later),
100
110
  `getArtifact` (fetch a screenshot, download or saved PDF as bytes)
111
+ - **Tasks and memory**: `listTasks`, `createTasks`, `cancelTask`, `deleteTask`,
112
+ plus a profile's standing instructions for agents, its `PROFILE.md`:
113
+ `getProfileMemory`, `putProfileMemory`, `deleteProfileMemory`
114
+ - **Videos**: `listVideos`, `getVideo`, `renameVideo`, `deleteVideo`,
115
+ `cancelVideo`, `rerenderVideo`, `videoAccess`, `downloadVideoFile`,
116
+ `videosStorage`; recordings with `listRecordings`, `getRecording`,
117
+ `deleteRecordingRaw`, `renderRecording`; public links with `share`,
118
+ `shareStatus`, `revokeShare`
119
+ - **Video presets**: `listVideoPresets`, `getVideoPreset`, `createVideoPreset`,
120
+ `updateVideoPreset`, `duplicateVideoPreset`, `deleteVideoPreset`, and a look
121
+ at an unsaved config with `previewVideoPreset`, `previewVideoPresetClip`,
122
+ `downloadVideoPresetClip`. The files a preset points at: `listMedia`,
123
+ `uploadMedia`, `deleteMedia`, `mediaFile`. Narration keys: `listTtsProviders`,
124
+ `putTtsProvider`, `verifyTtsProvider`, `deleteTtsProvider`. Encoders:
125
+ `getCodecs`, `setCodecEnabled`
126
+ - **Fingerprint audit**: `startAudit` drives the profile's running browser through
127
+ the external detector pages, `getAudit` reads the state and the last report
128
+ - **Exit addresses**: `getExitStatus` (which addresses a profile owns), and the
129
+ machine's rule that one address belongs to one profile: `getExitRule`,
130
+ `setExitRule`
131
+ - **Machine settings**: `getRemoteAccess`, `setRemoteAccess` (may a chat service
132
+ reach this machine's browsers), `getAgentTools`, `setAgentToolGroup` (which
133
+ optional MCP tool groups agents see), `getConnection` (which installation
134
+ answered: its data directory and its binary)
101
135
  - **Input**: `sendInput`
102
136
  - **Metrics / Account / Health**: `getMetrics`, `getAccount`, `health`, `ready`.
103
137
  The first two answer 404 on a daemon without them, which the SDK treats as
@@ -105,7 +139,9 @@ Every `/v1` endpoint is a typed method on `ScalebrowserClient`:
105
139
  state, and the account reads `licensed: false`, which is what "self-hosted, no
106
140
  control plane" means
107
141
 
108
- Errors map to typed exceptions carrying the daemon's numeric code (4001–4012):
142
+ `setToken` swaps the bearer token on a live client.
143
+
144
+ Errors map to typed exceptions carrying the daemon's numeric code (4001–4013):
109
145
 
110
146
  ```ts
111
147
  import { ApiError, ErrorCode } from '@scalebrowser/sdk';
@@ -140,7 +176,10 @@ for await (const e of sb.events()) {
140
176
  `CdpSession` (returned by `connectCdp` / `launch`) gives you:
141
177
 
142
178
  - `send<T>(method, params?)`: raw CDP command, awaited by id (concurrent-safe)
143
- - `navigate(url, { wait, timeout })`, `evaluate<T>(expr, { isolated })`
179
+ - `navigate(url, { wait, timeout })`, `evaluate<T>(expr, { isolated })`. The
180
+ wait for the load reads from an isolated world, so a page that watches its own
181
+ `document.readyState` sees no foreign read; `isolated: true` asks for the world
182
+ of the document that is loaded now, on every call
144
183
  - `createIsolatedWorld(frameId?, worldName?)`
145
184
  - `attachToPage({ targetId?, create?, url? })`
146
185
  - `on(method, cb)` / `events()`: CDP event subscription scoped to the session
package/dist/index.cjs CHANGED
@@ -588,6 +588,16 @@ var IdentityApi = class extends ClientCore {
588
588
  revealCookies(profileId, body) {
589
589
  return this.request("POST", `/v1/profiles/${enc(profileId)}/cookies/reveal`, body);
590
590
  }
591
+ // ── Recorded requests ──────────────────────────────────────────────────────
592
+ /**
593
+ * The one door what a recorded request carried leaves through, and it needs the vault
594
+ * password: the full address with its query, every header value (`Cookie`,
595
+ * `Authorization`) and, on request, the body. The agent's `net_capture` answers by
596
+ * shape only. `seq` is the number it listed.
597
+ */
598
+ revealRequest(profileId, seq, body) {
599
+ return this.request("POST", `/v1/profiles/${enc(profileId)}/network/${seq}/reveal`, body);
600
+ }
591
601
  };
592
602
 
593
603
  // src/client-tasks.ts
@@ -1142,7 +1152,6 @@ var CdpSession = class _CdpSession {
1142
1152
  sessionId;
1143
1153
  #client;
1144
1154
  #profileId;
1145
- #isolatedContextId;
1146
1155
  constructor(conn, sessionId, client, profileId) {
1147
1156
  this.#conn = conn;
1148
1157
  this.sessionId = sessionId;
@@ -1196,14 +1205,21 @@ var CdpSession = class _CdpSession {
1196
1205
  awaitPromise: opts.awaitPromise ?? true,
1197
1206
  returnByValue: opts.returnByValue ?? true
1198
1207
  };
1199
- if (opts.isolated) params["contextId"] = await this.#isolatedContext();
1208
+ if (opts.isolated) params["contextId"] = await this.createIsolatedWorld();
1200
1209
  const res = await this.send("Runtime.evaluate", params);
1201
1210
  if (res.exceptionDetails) {
1202
1211
  throw new CdpError(-1, res.exceptionDetails.text || res.exceptionDetails.exception?.description || "evaluate exception");
1203
1212
  }
1204
1213
  return res.result.value;
1205
1214
  }
1206
- /** Create an isolated world for the (main) frame and return its execution context id. */
1215
+ /**
1216
+ * Create an isolated world for the (main) frame and return its execution context id.
1217
+ *
1218
+ * The id belongs to the document that is loaded right now. After a navigation it
1219
+ * names a context that no longer exists, so ask again instead of keeping it:
1220
+ * Chrome hands back the same world for the same name, so asking costs one round
1221
+ * trip.
1222
+ */
1207
1223
  async createIsolatedWorld(frameId, worldName = "__sb") {
1208
1224
  let frame = frameId;
1209
1225
  if (!frame) {
@@ -1261,14 +1277,18 @@ var CdpSession = class _CdpSession {
1261
1277
  }
1262
1278
  return this.#client.sendInput(this.#profileId, { ...body, humanize: true });
1263
1279
  }
1264
- async #isolatedContext() {
1265
- if (this.#isolatedContextId === void 0) this.#isolatedContextId = await this.createIsolatedWorld();
1266
- return this.#isolatedContextId;
1267
- }
1280
+ // The poll reads in an isolated world: a page that wraps `document.readyState`
1281
+ // sees a read from its own world, with a caller that is none of its scripts.
1282
+ // While the new document commits, the world of the old one can vanish between
1283
+ // asking for it and reading in it; the browser refuses that read with its own
1284
+ // error code, and it is retried. A closed connection still fails at once.
1268
1285
  async #waitForLoad(timeout) {
1269
1286
  const deadline = Date.now() + timeout;
1270
1287
  for (; ; ) {
1271
- const ready = await this.evaluate("document.readyState");
1288
+ const ready = await this.evaluate("document.readyState", { isolated: true }).catch((err) => {
1289
+ if (err instanceof CdpError && err.code !== -1) return void 0;
1290
+ throw err;
1291
+ });
1272
1292
  if (ready === "complete") return;
1273
1293
  if (Date.now() > deadline) throw new CdpError(-1, "navigation wait timed out");
1274
1294
  await delay(50);
@@ -1665,6 +1685,24 @@ var ScalebrowserClient = class extends ClientCore {
1665
1685
  async setExitRule(enabled, signal) {
1666
1686
  return this.request("PUT", "/v1/exit-rule", { enabled }, { signal });
1667
1687
  }
1688
+ /**
1689
+ * Which optional MCP tool groups agents on this machine see.
1690
+ *
1691
+ * Agents see the basic tools by default; video, tasks, profile management,
1692
+ * the captcha helpers, the extras and the developer tools are one switch each.
1693
+ */
1694
+ async getAgentTools(signal) {
1695
+ return this.request("GET", "/v1/agent-tools", void 0, { signal });
1696
+ }
1697
+ /**
1698
+ * Turn one tool group on or off for every agent on this machine.
1699
+ *
1700
+ * It applies to the next tool list an agent asks for. A session that listed
1701
+ * its tools before keeps that list until it reconnects.
1702
+ */
1703
+ async setAgentToolGroup(group, enabled, signal) {
1704
+ return this.request("PUT", "/v1/agent-tools", { group, enabled }, { signal });
1705
+ }
1668
1706
  // ── Events (SSE) ───────────────────────────────────────────────────────────
1669
1707
  /** Subscribe to lifecycle events. Returns an unsubscribe function. */
1670
1708
  subscribeEvents(handlers) {
@@ -1738,7 +1776,7 @@ var PROXY_KINDS = ["http", "socks5", "gateway"];
1738
1776
  var ROTATIONS = ["sticky", "rotating"];
1739
1777
 
1740
1778
  // src/index.ts
1741
- var VERSION = "1.1.0";
1779
+ var VERSION = "1.2.0";
1742
1780
 
1743
1781
  exports.ApiError = ApiError;
1744
1782
  exports.CdpError = CdpError;
package/dist/index.d.cts CHANGED
@@ -1481,6 +1481,29 @@ interface RemoteStatus {
1481
1481
  * purpose, a residential line you pay for or a whitelisted office address, where
1482
1482
  * the rule would refuse every start after the first.
1483
1483
  */
1484
+ /** An optional tool group: `basic` is always served and has no switch. */
1485
+ type ToolGroupId = 'video' | 'tasks' | 'fleet' | 'captcha' | 'extras' | 'developer';
1486
+ /** One switchable group of MCP tools. */
1487
+ interface AgentToolGroup {
1488
+ id: ToolGroupId;
1489
+ /** Do agents on this machine see these tools? */
1490
+ enabled: boolean;
1491
+ /** Did a person decide this, or is the configured default still standing? */
1492
+ explicit: boolean;
1493
+ /** The tools the group adds, among the profiles this daemon serves. */
1494
+ tools: string[];
1495
+ }
1496
+ /**
1497
+ * What `GET /v1/agent-tools` answers: which optional tool groups agents see.
1498
+ *
1499
+ * Off by default. An agent sees the basic tools until a group is switched on,
1500
+ * which keeps the tool list it pays for on every request short.
1501
+ */
1502
+ interface AgentTools {
1503
+ groups: AgentToolGroup[];
1504
+ /** How many tools an agent sees right now. */
1505
+ served: number;
1506
+ }
1484
1507
  interface ExitRuleStatus {
1485
1508
  /** Does the rule apply on this machine? */
1486
1509
  enabled: boolean;
@@ -1989,6 +2012,69 @@ interface RevealCookiesResult {
1989
2012
  domain: string;
1990
2013
  cookies: RevealedCookie[];
1991
2014
  }
2015
+ /** One header, name and value as the network stack saw them. */
2016
+ interface RequestHeader {
2017
+ name: string;
2018
+ value: string;
2019
+ }
2020
+ /**
2021
+ * What a request looked like, with every value that could be a secret left out: the
2022
+ * address stops at the path, headers are listed by name. This is the form the agent's
2023
+ * `net_capture` tool answers with.
2024
+ */
2025
+ interface RequestShape {
2026
+ /** Increasing, never reused. The number the reveal route takes. */
2027
+ seq: number;
2028
+ method: string;
2029
+ origin: string;
2030
+ path: string;
2031
+ /** The address had a query. The query itself is not here. */
2032
+ has_query: boolean;
2033
+ /** The fetch destination (`document`, `script`, `image`), empty for fetch/XHR. */
2034
+ resource_type: string;
2035
+ top_frame_origin: string;
2036
+ /** `pending`, `loading`, `complete`, `failed` or `aborted`. */
2037
+ state: string;
2038
+ /** Status of the final response; 0 while there is none. */
2039
+ status: number;
2040
+ mime_type: string;
2041
+ protocol: string;
2042
+ from_cache: boolean;
2043
+ net_error: number;
2044
+ redirects: number;
2045
+ encoded_bytes: number;
2046
+ body_bytes: number;
2047
+ /** Whether the body can still be revealed. */
2048
+ has_body: boolean;
2049
+ /** Why it cannot: `too_large`, `evicted` or `incomplete`. Empty otherwise. */
2050
+ body_dropped: string;
2051
+ request_header_names: string[];
2052
+ response_header_names: string[];
2053
+ age_ms: number;
2054
+ }
2055
+ interface RevealRequestBody {
2056
+ /** The same gate a cookie value sits behind. */
2057
+ vault_password: string;
2058
+ /** Return the decoded body too. Left out by default. */
2059
+ include_body?: boolean;
2060
+ /** Longest body to return (default 1 MiB, at most 8 MiB). */
2061
+ max_body_bytes?: number | null;
2062
+ }
2063
+ /** A recorded request in full: the query, every header value and, on request, the body. */
2064
+ interface RevealRequestResult {
2065
+ seq: number;
2066
+ /** The final address, query included. */
2067
+ url: string;
2068
+ shape: RequestShape;
2069
+ request_headers: RequestHeader[];
2070
+ response_headers: RequestHeader[];
2071
+ /** The decoded body: text if it was valid UTF-8, base64 otherwise (`body_base64`). */
2072
+ body: string | null;
2073
+ body_base64: boolean;
2074
+ body_truncated: boolean;
2075
+ /** Why the body is missing although asked for: `decode_failed` or `decoded_too_large`. Empty otherwise. */
2076
+ body_error: string;
2077
+ }
1992
2078
  /** What a stored value is. */
1993
2079
  type SecretKind = 'api_token' | 'password' | 'recovery_code' | 'totp_seed' | 'private_key' | 'unknown';
1994
2080
  /** How the layer came to know it. The first three are the honest origins. */
@@ -2223,6 +2309,13 @@ declare class IdentityApi extends ClientCore {
2223
2309
  * every other cookie surface answers with metadata only.
2224
2310
  */
2225
2311
  revealCookies(profileId: string, body: RevealCookiesBody): Promise<RevealCookiesResult>;
2312
+ /**
2313
+ * The one door what a recorded request carried leaves through, and it needs the vault
2314
+ * password: the full address with its query, every header value (`Cookie`,
2315
+ * `Authorization`) and, on request, the body. The agent's `net_capture` answers by
2316
+ * shape only. `seq` is the number it listed.
2317
+ */
2318
+ revealRequest(profileId: string, seq: number, body: RevealRequestBody): Promise<RevealRequestResult>;
2226
2319
  }
2227
2320
 
2228
2321
  declare class TasksApi extends ClientCore {
@@ -2547,7 +2640,14 @@ declare class CdpSession {
2547
2640
  navigate(url: string, opts?: NavigateOptions): Promise<NavigateResult>;
2548
2641
  /** Evaluate a JS expression in the page (or an isolated world) and return its value. */
2549
2642
  evaluate<T = unknown>(expression: string, opts?: EvaluateOptions): Promise<T>;
2550
- /** Create an isolated world for the (main) frame and return its execution context id. */
2643
+ /**
2644
+ * Create an isolated world for the (main) frame and return its execution context id.
2645
+ *
2646
+ * The id belongs to the document that is loaded right now. After a navigation it
2647
+ * names a context that no longer exists, so ask again instead of keeping it:
2648
+ * Chrome hands back the same world for the same name, so asking costs one round
2649
+ * trip.
2650
+ */
2551
2651
  createIsolatedWorld(frameId?: string, worldName?: string): Promise<number>;
2552
2652
  humanizeMove(x: number, y: number, opts?: MoveOptions): Promise<unknown>;
2553
2653
  humanizeClick(x: number, y: number, opts?: ClickOptions): Promise<unknown>;
@@ -2809,6 +2909,20 @@ declare class ScalebrowserClient extends ClientCore {
2809
2909
  * exists for the narrower case (`updateProfile` with `exit_exclusive`).
2810
2910
  */
2811
2911
  setExitRule(enabled: boolean, signal?: AbortSignal): Promise<ExitRuleStatus>;
2912
+ /**
2913
+ * Which optional MCP tool groups agents on this machine see.
2914
+ *
2915
+ * Agents see the basic tools by default; video, tasks, profile management,
2916
+ * the captcha helpers, the extras and the developer tools are one switch each.
2917
+ */
2918
+ getAgentTools(signal?: AbortSignal): Promise<AgentTools>;
2919
+ /**
2920
+ * Turn one tool group on or off for every agent on this machine.
2921
+ *
2922
+ * It applies to the next tool list an agent asks for. A session that listed
2923
+ * its tools before keeps that list until it reconnects.
2924
+ */
2925
+ setAgentToolGroup(group: ToolGroupId, enabled: boolean, signal?: AbortSignal): Promise<AgentTools>;
2812
2926
  /** Subscribe to lifecycle events. Returns an unsubscribe function. */
2813
2927
  subscribeEvents(handlers: StreamHandlers): () => void;
2814
2928
  /** `for await (const event of client.events())` over lifecycle events. */
@@ -2921,6 +3035,6 @@ declare function errorMessage(err: unknown): string;
2921
3035
  * ```
2922
3036
  */
2923
3037
 
2924
- declare const VERSION = "1.1.0";
3038
+ declare const VERSION = "1.2.0";
2925
3039
 
2926
- export { type Account, type ActivitySnapshot, type AgentRun, ApiError, type ApiErrorBody, type ArtifactBytes, type ArtifactPutResult, type AttachOptions, type AudioStatus, type AuditDetectorReport, type AuditReport, type AuditStatus, type AuditVerdict, type BindInboxBody, type BlockedExport, type CdpConnectOptions, CdpError, type CdpEvent, CdpSession, type Chapter, type ClickOptions, type CodecsStatus, type Connection, type CreateGroupBody, type CreateInboxBody, type CreatePresetBody, type CreateTasksBody, type CreateTasksResult, DEFAULT_CAPACITY, type DeleteInterruptionRuleParams, type EffectiveInterruptionLock, ErrorCode, type ErrorCodeValue, type EvaluateOptions, type ExitClaim, type ExitRuleStatus, type ExitScope, type ExitStatus, type ExportPresetName, type ExtraOutput, type FetchLike, GEO_MODES, type GeoMode, type GoalSource, type Group, type HealthStatus, 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 ListTasksParams, type ListVideosParams, type MediaAsset, type MediaKind, type MusicBed, type NarrationLine, type NavigateOptions, NetworkError, type OsFamily, type OutcomeSource, PROXY_KINDS, type PasskeyRow, type PatchTaskBody, type PersonaConstraintOptions, type Preset, type PresetConfig, type PresetConstraints, type PreviewHidden, type PreviewMoment, type Profile, type ProfileActivity, type ProfileMemory, type ProfileTask, type ProtectionLevel, type ProtectionStatus, type Proxy, type ProxyKind, type ProxyRow, type ProxyUsage, ROTATIONS, RUNTIME_STATES, type ReadyStatus, type Recording, type RecordingKind, type RecordingState, type RemoteStatus, type RenderProgress, type RenderRequestBody, type RenderStage, 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 ShareLinkLocal, type ShareStatus, type ShotFocus, type ShotIntent, type StepKind, type StepTarget, type StreamHandlers, type StreamParams, type StreamStatus, type TaskState, type TimestampState, type TranscriptWord, type TrustedInputBody, type TtsProviderView, type TtsVerifyResult, type UpdateGroupBody, type UpdateInboxBody, type UpdatePresetBody, VERSION, type Video, type VideoAccessGrant, type VideoAssetName, type VideoAssets, type VideoBackground, type VideoCard, type VideoDestination, type VideoFlags, type VideoPreset, type VideoPresetClip, type VideoPresetClipBody, type VideoPresetClipProgress, type VideoPresetClipStarted, type VideoPresetConfig, type VideoPresetPreview, type VideoPresetPreviewBody, type VideoState, type VideosPage, type VideosStorage, type WriteMemoryBody, deriveMetricsFromProfiles, errorMessage, eventStream, openCdpSession, parseSseFrame, subscribeEvents };
3040
+ export { type Account, type ActivitySnapshot, type AgentRun, type AgentToolGroup, type AgentTools, ApiError, type ApiErrorBody, type ArtifactBytes, type ArtifactPutResult, type AttachOptions, type AudioStatus, type AuditDetectorReport, type AuditReport, type AuditStatus, type AuditVerdict, type BindInboxBody, type BlockedExport, type CdpConnectOptions, CdpError, type CdpEvent, CdpSession, type Chapter, type ClickOptions, type CodecsStatus, type Connection, type CreateGroupBody, type CreateInboxBody, type CreatePresetBody, type CreateTasksBody, type CreateTasksResult, DEFAULT_CAPACITY, type DeleteInterruptionRuleParams, type EffectiveInterruptionLock, ErrorCode, type ErrorCodeValue, type EvaluateOptions, type ExitClaim, type ExitRuleStatus, type ExitScope, type ExitStatus, type ExportPresetName, type ExtraOutput, type FetchLike, GEO_MODES, type GeoMode, type GoalSource, type Group, type HealthStatus, 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 ListTasksParams, type ListVideosParams, type MediaAsset, type MediaKind, type MusicBed, type NarrationLine, type NavigateOptions, NetworkError, type OsFamily, type OutcomeSource, PROXY_KINDS, type PasskeyRow, type PatchTaskBody, type PersonaConstraintOptions, type Preset, type PresetConfig, type PresetConstraints, type PreviewHidden, type PreviewMoment, type Profile, type ProfileActivity, type ProfileMemory, type ProfileTask, type ProtectionLevel, type ProtectionStatus, type Proxy, type ProxyKind, type ProxyRow, type ProxyUsage, ROTATIONS, RUNTIME_STATES, type ReadyStatus, type Recording, type RecordingKind, type RecordingState, type RemoteStatus, type RenderProgress, type RenderRequestBody, type RenderStage, type RequestHeader, type RequestShape, type RevealCookiesBody, type RevealCookiesResult, type RevealRequestBody, type RevealRequestResult, 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 ShareLinkLocal, type ShareStatus, type ShotFocus, type ShotIntent, type StepKind, type StepTarget, type StreamHandlers, type StreamParams, type StreamStatus, type TaskState, type TimestampState, type ToolGroupId, type TranscriptWord, type TrustedInputBody, type TtsProviderView, type TtsVerifyResult, type UpdateGroupBody, type UpdateInboxBody, type UpdatePresetBody, VERSION, type Video, type VideoAccessGrant, type VideoAssetName, type VideoAssets, type VideoBackground, type VideoCard, type VideoDestination, type VideoFlags, type VideoPreset, type VideoPresetClip, type VideoPresetClipBody, type VideoPresetClipProgress, type VideoPresetClipStarted, type VideoPresetConfig, type VideoPresetPreview, type VideoPresetPreviewBody, type VideoState, type VideosPage, type VideosStorage, type WriteMemoryBody, deriveMetricsFromProfiles, errorMessage, eventStream, openCdpSession, parseSseFrame, subscribeEvents };
package/dist/index.d.ts CHANGED
@@ -1481,6 +1481,29 @@ interface RemoteStatus {
1481
1481
  * purpose, a residential line you pay for or a whitelisted office address, where
1482
1482
  * the rule would refuse every start after the first.
1483
1483
  */
1484
+ /** An optional tool group: `basic` is always served and has no switch. */
1485
+ type ToolGroupId = 'video' | 'tasks' | 'fleet' | 'captcha' | 'extras' | 'developer';
1486
+ /** One switchable group of MCP tools. */
1487
+ interface AgentToolGroup {
1488
+ id: ToolGroupId;
1489
+ /** Do agents on this machine see these tools? */
1490
+ enabled: boolean;
1491
+ /** Did a person decide this, or is the configured default still standing? */
1492
+ explicit: boolean;
1493
+ /** The tools the group adds, among the profiles this daemon serves. */
1494
+ tools: string[];
1495
+ }
1496
+ /**
1497
+ * What `GET /v1/agent-tools` answers: which optional tool groups agents see.
1498
+ *
1499
+ * Off by default. An agent sees the basic tools until a group is switched on,
1500
+ * which keeps the tool list it pays for on every request short.
1501
+ */
1502
+ interface AgentTools {
1503
+ groups: AgentToolGroup[];
1504
+ /** How many tools an agent sees right now. */
1505
+ served: number;
1506
+ }
1484
1507
  interface ExitRuleStatus {
1485
1508
  /** Does the rule apply on this machine? */
1486
1509
  enabled: boolean;
@@ -1989,6 +2012,69 @@ interface RevealCookiesResult {
1989
2012
  domain: string;
1990
2013
  cookies: RevealedCookie[];
1991
2014
  }
2015
+ /** One header, name and value as the network stack saw them. */
2016
+ interface RequestHeader {
2017
+ name: string;
2018
+ value: string;
2019
+ }
2020
+ /**
2021
+ * What a request looked like, with every value that could be a secret left out: the
2022
+ * address stops at the path, headers are listed by name. This is the form the agent's
2023
+ * `net_capture` tool answers with.
2024
+ */
2025
+ interface RequestShape {
2026
+ /** Increasing, never reused. The number the reveal route takes. */
2027
+ seq: number;
2028
+ method: string;
2029
+ origin: string;
2030
+ path: string;
2031
+ /** The address had a query. The query itself is not here. */
2032
+ has_query: boolean;
2033
+ /** The fetch destination (`document`, `script`, `image`), empty for fetch/XHR. */
2034
+ resource_type: string;
2035
+ top_frame_origin: string;
2036
+ /** `pending`, `loading`, `complete`, `failed` or `aborted`. */
2037
+ state: string;
2038
+ /** Status of the final response; 0 while there is none. */
2039
+ status: number;
2040
+ mime_type: string;
2041
+ protocol: string;
2042
+ from_cache: boolean;
2043
+ net_error: number;
2044
+ redirects: number;
2045
+ encoded_bytes: number;
2046
+ body_bytes: number;
2047
+ /** Whether the body can still be revealed. */
2048
+ has_body: boolean;
2049
+ /** Why it cannot: `too_large`, `evicted` or `incomplete`. Empty otherwise. */
2050
+ body_dropped: string;
2051
+ request_header_names: string[];
2052
+ response_header_names: string[];
2053
+ age_ms: number;
2054
+ }
2055
+ interface RevealRequestBody {
2056
+ /** The same gate a cookie value sits behind. */
2057
+ vault_password: string;
2058
+ /** Return the decoded body too. Left out by default. */
2059
+ include_body?: boolean;
2060
+ /** Longest body to return (default 1 MiB, at most 8 MiB). */
2061
+ max_body_bytes?: number | null;
2062
+ }
2063
+ /** A recorded request in full: the query, every header value and, on request, the body. */
2064
+ interface RevealRequestResult {
2065
+ seq: number;
2066
+ /** The final address, query included. */
2067
+ url: string;
2068
+ shape: RequestShape;
2069
+ request_headers: RequestHeader[];
2070
+ response_headers: RequestHeader[];
2071
+ /** The decoded body: text if it was valid UTF-8, base64 otherwise (`body_base64`). */
2072
+ body: string | null;
2073
+ body_base64: boolean;
2074
+ body_truncated: boolean;
2075
+ /** Why the body is missing although asked for: `decode_failed` or `decoded_too_large`. Empty otherwise. */
2076
+ body_error: string;
2077
+ }
1992
2078
  /** What a stored value is. */
1993
2079
  type SecretKind = 'api_token' | 'password' | 'recovery_code' | 'totp_seed' | 'private_key' | 'unknown';
1994
2080
  /** How the layer came to know it. The first three are the honest origins. */
@@ -2223,6 +2309,13 @@ declare class IdentityApi extends ClientCore {
2223
2309
  * every other cookie surface answers with metadata only.
2224
2310
  */
2225
2311
  revealCookies(profileId: string, body: RevealCookiesBody): Promise<RevealCookiesResult>;
2312
+ /**
2313
+ * The one door what a recorded request carried leaves through, and it needs the vault
2314
+ * password: the full address with its query, every header value (`Cookie`,
2315
+ * `Authorization`) and, on request, the body. The agent's `net_capture` answers by
2316
+ * shape only. `seq` is the number it listed.
2317
+ */
2318
+ revealRequest(profileId: string, seq: number, body: RevealRequestBody): Promise<RevealRequestResult>;
2226
2319
  }
2227
2320
 
2228
2321
  declare class TasksApi extends ClientCore {
@@ -2547,7 +2640,14 @@ declare class CdpSession {
2547
2640
  navigate(url: string, opts?: NavigateOptions): Promise<NavigateResult>;
2548
2641
  /** Evaluate a JS expression in the page (or an isolated world) and return its value. */
2549
2642
  evaluate<T = unknown>(expression: string, opts?: EvaluateOptions): Promise<T>;
2550
- /** Create an isolated world for the (main) frame and return its execution context id. */
2643
+ /**
2644
+ * Create an isolated world for the (main) frame and return its execution context id.
2645
+ *
2646
+ * The id belongs to the document that is loaded right now. After a navigation it
2647
+ * names a context that no longer exists, so ask again instead of keeping it:
2648
+ * Chrome hands back the same world for the same name, so asking costs one round
2649
+ * trip.
2650
+ */
2551
2651
  createIsolatedWorld(frameId?: string, worldName?: string): Promise<number>;
2552
2652
  humanizeMove(x: number, y: number, opts?: MoveOptions): Promise<unknown>;
2553
2653
  humanizeClick(x: number, y: number, opts?: ClickOptions): Promise<unknown>;
@@ -2809,6 +2909,20 @@ declare class ScalebrowserClient extends ClientCore {
2809
2909
  * exists for the narrower case (`updateProfile` with `exit_exclusive`).
2810
2910
  */
2811
2911
  setExitRule(enabled: boolean, signal?: AbortSignal): Promise<ExitRuleStatus>;
2912
+ /**
2913
+ * Which optional MCP tool groups agents on this machine see.
2914
+ *
2915
+ * Agents see the basic tools by default; video, tasks, profile management,
2916
+ * the captcha helpers, the extras and the developer tools are one switch each.
2917
+ */
2918
+ getAgentTools(signal?: AbortSignal): Promise<AgentTools>;
2919
+ /**
2920
+ * Turn one tool group on or off for every agent on this machine.
2921
+ *
2922
+ * It applies to the next tool list an agent asks for. A session that listed
2923
+ * its tools before keeps that list until it reconnects.
2924
+ */
2925
+ setAgentToolGroup(group: ToolGroupId, enabled: boolean, signal?: AbortSignal): Promise<AgentTools>;
2812
2926
  /** Subscribe to lifecycle events. Returns an unsubscribe function. */
2813
2927
  subscribeEvents(handlers: StreamHandlers): () => void;
2814
2928
  /** `for await (const event of client.events())` over lifecycle events. */
@@ -2921,6 +3035,6 @@ declare function errorMessage(err: unknown): string;
2921
3035
  * ```
2922
3036
  */
2923
3037
 
2924
- declare const VERSION = "1.1.0";
3038
+ declare const VERSION = "1.2.0";
2925
3039
 
2926
- export { type Account, type ActivitySnapshot, type AgentRun, ApiError, type ApiErrorBody, type ArtifactBytes, type ArtifactPutResult, type AttachOptions, type AudioStatus, type AuditDetectorReport, type AuditReport, type AuditStatus, type AuditVerdict, type BindInboxBody, type BlockedExport, type CdpConnectOptions, CdpError, type CdpEvent, CdpSession, type Chapter, type ClickOptions, type CodecsStatus, type Connection, type CreateGroupBody, type CreateInboxBody, type CreatePresetBody, type CreateTasksBody, type CreateTasksResult, DEFAULT_CAPACITY, type DeleteInterruptionRuleParams, type EffectiveInterruptionLock, ErrorCode, type ErrorCodeValue, type EvaluateOptions, type ExitClaim, type ExitRuleStatus, type ExitScope, type ExitStatus, type ExportPresetName, type ExtraOutput, type FetchLike, GEO_MODES, type GeoMode, type GoalSource, type Group, type HealthStatus, 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 ListTasksParams, type ListVideosParams, type MediaAsset, type MediaKind, type MusicBed, type NarrationLine, type NavigateOptions, NetworkError, type OsFamily, type OutcomeSource, PROXY_KINDS, type PasskeyRow, type PatchTaskBody, type PersonaConstraintOptions, type Preset, type PresetConfig, type PresetConstraints, type PreviewHidden, type PreviewMoment, type Profile, type ProfileActivity, type ProfileMemory, type ProfileTask, type ProtectionLevel, type ProtectionStatus, type Proxy, type ProxyKind, type ProxyRow, type ProxyUsage, ROTATIONS, RUNTIME_STATES, type ReadyStatus, type Recording, type RecordingKind, type RecordingState, type RemoteStatus, type RenderProgress, type RenderRequestBody, type RenderStage, 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 ShareLinkLocal, type ShareStatus, type ShotFocus, type ShotIntent, type StepKind, type StepTarget, type StreamHandlers, type StreamParams, type StreamStatus, type TaskState, type TimestampState, type TranscriptWord, type TrustedInputBody, type TtsProviderView, type TtsVerifyResult, type UpdateGroupBody, type UpdateInboxBody, type UpdatePresetBody, VERSION, type Video, type VideoAccessGrant, type VideoAssetName, type VideoAssets, type VideoBackground, type VideoCard, type VideoDestination, type VideoFlags, type VideoPreset, type VideoPresetClip, type VideoPresetClipBody, type VideoPresetClipProgress, type VideoPresetClipStarted, type VideoPresetConfig, type VideoPresetPreview, type VideoPresetPreviewBody, type VideoState, type VideosPage, type VideosStorage, type WriteMemoryBody, deriveMetricsFromProfiles, errorMessage, eventStream, openCdpSession, parseSseFrame, subscribeEvents };
3040
+ export { type Account, type ActivitySnapshot, type AgentRun, type AgentToolGroup, type AgentTools, ApiError, type ApiErrorBody, type ArtifactBytes, type ArtifactPutResult, type AttachOptions, type AudioStatus, type AuditDetectorReport, type AuditReport, type AuditStatus, type AuditVerdict, type BindInboxBody, type BlockedExport, type CdpConnectOptions, CdpError, type CdpEvent, CdpSession, type Chapter, type ClickOptions, type CodecsStatus, type Connection, type CreateGroupBody, type CreateInboxBody, type CreatePresetBody, type CreateTasksBody, type CreateTasksResult, DEFAULT_CAPACITY, type DeleteInterruptionRuleParams, type EffectiveInterruptionLock, ErrorCode, type ErrorCodeValue, type EvaluateOptions, type ExitClaim, type ExitRuleStatus, type ExitScope, type ExitStatus, type ExportPresetName, type ExtraOutput, type FetchLike, GEO_MODES, type GeoMode, type GoalSource, type Group, type HealthStatus, 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 ListTasksParams, type ListVideosParams, type MediaAsset, type MediaKind, type MusicBed, type NarrationLine, type NavigateOptions, NetworkError, type OsFamily, type OutcomeSource, PROXY_KINDS, type PasskeyRow, type PatchTaskBody, type PersonaConstraintOptions, type Preset, type PresetConfig, type PresetConstraints, type PreviewHidden, type PreviewMoment, type Profile, type ProfileActivity, type ProfileMemory, type ProfileTask, type ProtectionLevel, type ProtectionStatus, type Proxy, type ProxyKind, type ProxyRow, type ProxyUsage, ROTATIONS, RUNTIME_STATES, type ReadyStatus, type Recording, type RecordingKind, type RecordingState, type RemoteStatus, type RenderProgress, type RenderRequestBody, type RenderStage, type RequestHeader, type RequestShape, type RevealCookiesBody, type RevealCookiesResult, type RevealRequestBody, type RevealRequestResult, 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 ShareLinkLocal, type ShareStatus, type ShotFocus, type ShotIntent, type StepKind, type StepTarget, type StreamHandlers, type StreamParams, type StreamStatus, type TaskState, type TimestampState, type ToolGroupId, type TranscriptWord, type TrustedInputBody, type TtsProviderView, type TtsVerifyResult, type UpdateGroupBody, type UpdateInboxBody, type UpdatePresetBody, VERSION, type Video, type VideoAccessGrant, type VideoAssetName, type VideoAssets, type VideoBackground, type VideoCard, type VideoDestination, type VideoFlags, type VideoPreset, type VideoPresetClip, type VideoPresetClipBody, type VideoPresetClipProgress, type VideoPresetClipStarted, type VideoPresetConfig, type VideoPresetPreview, type VideoPresetPreviewBody, type VideoState, type VideosPage, type VideosStorage, type WriteMemoryBody, deriveMetricsFromProfiles, errorMessage, eventStream, openCdpSession, parseSseFrame, subscribeEvents };
package/dist/index.js CHANGED
@@ -582,6 +582,16 @@ var IdentityApi = class extends ClientCore {
582
582
  revealCookies(profileId, body) {
583
583
  return this.request("POST", `/v1/profiles/${enc(profileId)}/cookies/reveal`, body);
584
584
  }
585
+ // ── Recorded requests ──────────────────────────────────────────────────────
586
+ /**
587
+ * The one door what a recorded request carried leaves through, and it needs the vault
588
+ * password: the full address with its query, every header value (`Cookie`,
589
+ * `Authorization`) and, on request, the body. The agent's `net_capture` answers by
590
+ * shape only. `seq` is the number it listed.
591
+ */
592
+ revealRequest(profileId, seq, body) {
593
+ return this.request("POST", `/v1/profiles/${enc(profileId)}/network/${seq}/reveal`, body);
594
+ }
585
595
  };
586
596
 
587
597
  // src/client-tasks.ts
@@ -1136,7 +1146,6 @@ var CdpSession = class _CdpSession {
1136
1146
  sessionId;
1137
1147
  #client;
1138
1148
  #profileId;
1139
- #isolatedContextId;
1140
1149
  constructor(conn, sessionId, client, profileId) {
1141
1150
  this.#conn = conn;
1142
1151
  this.sessionId = sessionId;
@@ -1190,14 +1199,21 @@ var CdpSession = class _CdpSession {
1190
1199
  awaitPromise: opts.awaitPromise ?? true,
1191
1200
  returnByValue: opts.returnByValue ?? true
1192
1201
  };
1193
- if (opts.isolated) params["contextId"] = await this.#isolatedContext();
1202
+ if (opts.isolated) params["contextId"] = await this.createIsolatedWorld();
1194
1203
  const res = await this.send("Runtime.evaluate", params);
1195
1204
  if (res.exceptionDetails) {
1196
1205
  throw new CdpError(-1, res.exceptionDetails.text || res.exceptionDetails.exception?.description || "evaluate exception");
1197
1206
  }
1198
1207
  return res.result.value;
1199
1208
  }
1200
- /** Create an isolated world for the (main) frame and return its execution context id. */
1209
+ /**
1210
+ * Create an isolated world for the (main) frame and return its execution context id.
1211
+ *
1212
+ * The id belongs to the document that is loaded right now. After a navigation it
1213
+ * names a context that no longer exists, so ask again instead of keeping it:
1214
+ * Chrome hands back the same world for the same name, so asking costs one round
1215
+ * trip.
1216
+ */
1201
1217
  async createIsolatedWorld(frameId, worldName = "__sb") {
1202
1218
  let frame = frameId;
1203
1219
  if (!frame) {
@@ -1255,14 +1271,18 @@ var CdpSession = class _CdpSession {
1255
1271
  }
1256
1272
  return this.#client.sendInput(this.#profileId, { ...body, humanize: true });
1257
1273
  }
1258
- async #isolatedContext() {
1259
- if (this.#isolatedContextId === void 0) this.#isolatedContextId = await this.createIsolatedWorld();
1260
- return this.#isolatedContextId;
1261
- }
1274
+ // The poll reads in an isolated world: a page that wraps `document.readyState`
1275
+ // sees a read from its own world, with a caller that is none of its scripts.
1276
+ // While the new document commits, the world of the old one can vanish between
1277
+ // asking for it and reading in it; the browser refuses that read with its own
1278
+ // error code, and it is retried. A closed connection still fails at once.
1262
1279
  async #waitForLoad(timeout) {
1263
1280
  const deadline = Date.now() + timeout;
1264
1281
  for (; ; ) {
1265
- const ready = await this.evaluate("document.readyState");
1282
+ const ready = await this.evaluate("document.readyState", { isolated: true }).catch((err) => {
1283
+ if (err instanceof CdpError && err.code !== -1) return void 0;
1284
+ throw err;
1285
+ });
1266
1286
  if (ready === "complete") return;
1267
1287
  if (Date.now() > deadline) throw new CdpError(-1, "navigation wait timed out");
1268
1288
  await delay(50);
@@ -1659,6 +1679,24 @@ var ScalebrowserClient = class extends ClientCore {
1659
1679
  async setExitRule(enabled, signal) {
1660
1680
  return this.request("PUT", "/v1/exit-rule", { enabled }, { signal });
1661
1681
  }
1682
+ /**
1683
+ * Which optional MCP tool groups agents on this machine see.
1684
+ *
1685
+ * Agents see the basic tools by default; video, tasks, profile management,
1686
+ * the captcha helpers, the extras and the developer tools are one switch each.
1687
+ */
1688
+ async getAgentTools(signal) {
1689
+ return this.request("GET", "/v1/agent-tools", void 0, { signal });
1690
+ }
1691
+ /**
1692
+ * Turn one tool group on or off for every agent on this machine.
1693
+ *
1694
+ * It applies to the next tool list an agent asks for. A session that listed
1695
+ * its tools before keeps that list until it reconnects.
1696
+ */
1697
+ async setAgentToolGroup(group, enabled, signal) {
1698
+ return this.request("PUT", "/v1/agent-tools", { group, enabled }, { signal });
1699
+ }
1662
1700
  // ── Events (SSE) ───────────────────────────────────────────────────────────
1663
1701
  /** Subscribe to lifecycle events. Returns an unsubscribe function. */
1664
1702
  subscribeEvents(handlers) {
@@ -1732,6 +1770,6 @@ var PROXY_KINDS = ["http", "socks5", "gateway"];
1732
1770
  var ROTATIONS = ["sticky", "rotating"];
1733
1771
 
1734
1772
  // src/index.ts
1735
- var VERSION = "1.1.0";
1773
+ var VERSION = "1.2.0";
1736
1774
 
1737
1775
  export { ApiError, CdpError, CdpSession, DEFAULT_CAPACITY, ErrorCode, GEO_MODES, NetworkError, PROXY_KINDS, ROTATIONS, RUNTIME_STATES, ScalebrowserClient, ScalebrowserError, VERSION, deriveMetricsFromProfiles, errorMessage, eventStream, openCdpSession, parseSseFrame, subscribeEvents };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scalebrowser/sdk",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Official Node/TypeScript SDK for the Scalebrowser daemon: typed REST client plus a direct-CDP driver plane (nodriver-style, not Playwright).",
5
5
  "type": "module",
6
6
  "license": "MIT",