@scalebrowser/sdk 0.6.0 → 0.8.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 +47 -0
- package/dist/index.cjs +51 -3
- package/dist/index.d.cts +251 -53
- package/dist/index.d.ts +251 -53
- package/dist/index.js +52 -3
- package/package.json +4 -3
package/dist/index.d.ts
CHANGED
|
@@ -81,7 +81,6 @@ interface PersonaMisc {
|
|
|
81
81
|
get_installed_related_apps: boolean;
|
|
82
82
|
max_touch_points: number;
|
|
83
83
|
pdf_viewer_enabled: boolean;
|
|
84
|
-
headless_guards: boolean;
|
|
85
84
|
}
|
|
86
85
|
interface Persona {
|
|
87
86
|
os: OsFamily;
|
|
@@ -111,7 +110,7 @@ type RecordingState = 'recording' | 'finishing' | 'finished' | 'failed';
|
|
|
111
110
|
type VideoState = 'queued' | 'rendering' | 'done' | 'failed' | 'cancelled';
|
|
112
111
|
type ExportPresetName = 'web' | 'social' | '4k' | 'editing' | 'gif';
|
|
113
112
|
type AudioStatus = 'ok' | 'silent' | 'off' | 'failed';
|
|
114
|
-
type RenderStage = 'planning' | 'narration' | 'compositing' | 'encoding' | 'finishing';
|
|
113
|
+
type RenderStage = 'planning' | 'narration' | 'compositing' | 'encoding' | 'finishing' | 'extras';
|
|
115
114
|
/** Which files a finished video has. Booleans on purpose, never paths. */
|
|
116
115
|
interface VideoAssets {
|
|
117
116
|
video: boolean;
|
|
@@ -159,10 +158,11 @@ type TimestampState = {
|
|
|
159
158
|
state: 'failed';
|
|
160
159
|
reason: string;
|
|
161
160
|
};
|
|
161
|
+
/** One spoken word and when it is heard in the finished video, in milliseconds from its start. */
|
|
162
162
|
interface TranscriptWord {
|
|
163
163
|
text: string;
|
|
164
|
-
|
|
165
|
-
|
|
164
|
+
start_ms: number;
|
|
165
|
+
end_ms: number;
|
|
166
166
|
}
|
|
167
167
|
/** One video row: queued and rendering renders included. */
|
|
168
168
|
interface Video {
|
|
@@ -177,7 +177,7 @@ interface Video {
|
|
|
177
177
|
kind: RecordingKind;
|
|
178
178
|
preset_name: string;
|
|
179
179
|
/** The resolved recipe this video renders (or rendered) under. */
|
|
180
|
-
preset:
|
|
180
|
+
preset: VideoPresetConfig;
|
|
181
181
|
export: ExportPresetName;
|
|
182
182
|
assets: VideoAssets;
|
|
183
183
|
duration_ms: number | null;
|
|
@@ -190,7 +190,8 @@ interface Video {
|
|
|
190
190
|
chapters: Chapter[];
|
|
191
191
|
transcript: TranscriptWord[] | null;
|
|
192
192
|
flags: VideoFlags | null;
|
|
193
|
-
share
|
|
193
|
+
/** The share link of this video ON THIS MACHINE, or nothing shared yet. */
|
|
194
|
+
share: ShareLinkLocal | null;
|
|
194
195
|
error: string | null;
|
|
195
196
|
created_at: number;
|
|
196
197
|
updated_at: number;
|
|
@@ -204,8 +205,11 @@ interface Recording {
|
|
|
204
205
|
kind: RecordingKind;
|
|
205
206
|
state: RecordingState;
|
|
206
207
|
title: string | null;
|
|
208
|
+
/** The id of the stored preset the recording was made under, `null` when it named none. */
|
|
207
209
|
preset_id: string | null;
|
|
208
|
-
preset
|
|
210
|
+
/** That preset's name as it read when the recording started. */
|
|
211
|
+
preset_name: string | null;
|
|
212
|
+
preset: VideoPresetConfig;
|
|
209
213
|
manifest_version: number;
|
|
210
214
|
css_width: number;
|
|
211
215
|
css_height: number;
|
|
@@ -299,10 +303,14 @@ interface VideoAccessGrant {
|
|
|
299
303
|
interface VideosStorage {
|
|
300
304
|
recordings_bytes: number;
|
|
301
305
|
videos_bytes: number;
|
|
306
|
+
/** The main files of the videos this machine still shares. */
|
|
302
307
|
link_bytes: number;
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
308
|
+
/** Known only to the control plane; `null` here. */
|
|
309
|
+
link_limit: number | null;
|
|
310
|
+
/** Known only to the control plane; `null` here. */
|
|
311
|
+
uploads_today: number | null;
|
|
312
|
+
/** Known only to the control plane; `null` here. */
|
|
313
|
+
uploads_limit: number | null;
|
|
306
314
|
capacity: {
|
|
307
315
|
recordings_active: number;
|
|
308
316
|
recordings_max: number;
|
|
@@ -322,6 +330,18 @@ interface CodecsStatus {
|
|
|
322
330
|
};
|
|
323
331
|
/** Hardware encoders that passed a real test encode, in preference order. */
|
|
324
332
|
hardware: string[];
|
|
333
|
+
/** Whether the hardware probe has run. Before it, an empty `hardware` means
|
|
334
|
+
* "not asked yet", not "none". */
|
|
335
|
+
probed: boolean;
|
|
336
|
+
/** Exports this daemon refuses whatever the order says, with the reason. An
|
|
337
|
+
* editor hides them rather than letting a render fail on them. */
|
|
338
|
+
exports_blocked: BlockedExport[];
|
|
339
|
+
}
|
|
340
|
+
/** One export the daemon refuses, e.g. `4k` while a 3840-wide capture is not
|
|
341
|
+
* offered. `reason` starts with its snake code. */
|
|
342
|
+
interface BlockedExport {
|
|
343
|
+
export: ExportPresetName;
|
|
344
|
+
reason: string;
|
|
325
345
|
}
|
|
326
346
|
/** What kind of file a media asset is. */
|
|
327
347
|
type MediaKind = 'image' | 'music' | 'subtitle_style';
|
|
@@ -380,16 +400,23 @@ interface ShareLinkLocal {
|
|
|
380
400
|
updated_at: number;
|
|
381
401
|
error: string | null;
|
|
382
402
|
}
|
|
403
|
+
/** `GET /v1/videos/:id/share`: the order, and the link's access code when this
|
|
404
|
+
* machine keeps one (sealed at rest). A link the daemon makes for a preset with
|
|
405
|
+
* `export.destination.passcode` gets a generated code of ten characters, and
|
|
406
|
+
* this is where its owner reads it. `Video.share`, `video_changed` and the
|
|
407
|
+
* `video` tool never carry the code. */
|
|
408
|
+
interface ShareStatus extends ShareLinkLocal {
|
|
409
|
+
/** Absent when this machine keeps no code: the link has none, or its
|
|
410
|
+
* revocation is ordered. */
|
|
411
|
+
code?: string;
|
|
412
|
+
}
|
|
383
413
|
|
|
384
414
|
/**
|
|
385
|
-
* Wire types: a 1:1 mirror of the daemon's serialized domain model
|
|
386
|
-
*
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
*
|
|
390
|
-
* every shared exported declaration and goes red on drift. The Python SDK
|
|
391
|
-
* (`sdks/python/src/scalebrowser/models*.py`) carries the same shapes by hand,
|
|
392
|
-
* deliberately without a gate; a TS↔pydantic comparator is its own tool.
|
|
415
|
+
* Wire types: a 1:1 mirror of the daemon's serialized domain model and of the
|
|
416
|
+
* endpoint contract, and the one source of both on the TypeScript side.
|
|
417
|
+
*
|
|
418
|
+
* These files import nothing but each other, which keeps them usable inside a
|
|
419
|
+
* browser bundle.
|
|
393
420
|
*
|
|
394
421
|
* All Rust enums serialize `snake_case` (serde `rename_all`). Timestamps are
|
|
395
422
|
* unix seconds (`number`, Rust `i64`). The truth for any disagreement is the
|
|
@@ -399,9 +426,6 @@ interface ShareLinkLocal {
|
|
|
399
426
|
/** `RuntimeState` (AC-PR-004). */
|
|
400
427
|
type RuntimeState = 'stopped' | 'starting' | 'running' | 'crashed';
|
|
401
428
|
declare const RUNTIME_STATES: readonly RuntimeState[];
|
|
402
|
-
/** `HostMode` (PRD §B, DEC-004). Default `linux_engine_spoof`. */
|
|
403
|
-
type HostMode = 'linux_engine_spoof' | 'local_native_windows';
|
|
404
|
-
declare const HOST_MODES: readonly HostMode[];
|
|
405
429
|
/** `GeoMode` (AC-PX-002). Default `follow_exit`. */
|
|
406
430
|
type GeoMode = 'strict_expected' | 'follow_exit' | 'off';
|
|
407
431
|
declare const GEO_MODES: readonly GeoMode[];
|
|
@@ -436,12 +460,21 @@ interface Profile {
|
|
|
436
460
|
seed: string;
|
|
437
461
|
engine_version: string;
|
|
438
462
|
persona: Persona;
|
|
439
|
-
host_mode: HostMode;
|
|
440
463
|
gpu_persona: string | null;
|
|
441
464
|
group_id: string | null;
|
|
442
465
|
proxy_id: string | null;
|
|
443
466
|
geo_mode: GeoMode;
|
|
444
467
|
expected_country: string | null;
|
|
468
|
+
/**
|
|
469
|
+
* Whether this profile claims its exit address for itself, so no other profile of
|
|
470
|
+
* the account starts on it (DEC-017). On for a new profile. Turn it off for a
|
|
471
|
+
* provider that hands out ONE address on purpose, a residential line you pay for
|
|
472
|
+
* or a whitelisted office address, where the rule would refuse every start after
|
|
473
|
+
* the first.
|
|
474
|
+
*
|
|
475
|
+
* Additive: a daemon predating it omits the field.
|
|
476
|
+
*/
|
|
477
|
+
exit_exclusive?: boolean;
|
|
445
478
|
data_dir: string;
|
|
446
479
|
created_at: number;
|
|
447
480
|
last_open_at: number | null;
|
|
@@ -468,7 +501,6 @@ interface Group {
|
|
|
468
501
|
interface PresetConfig {
|
|
469
502
|
/** Pin the batch to one engine build. Omit for per-profile version diversity. */
|
|
470
503
|
engine_version?: string | null;
|
|
471
|
-
host_mode?: HostMode | null;
|
|
472
504
|
geo_mode?: GeoMode | null;
|
|
473
505
|
/** The geo GATE's expectation, not the persona's drawn region. */
|
|
474
506
|
expected_country?: string | null;
|
|
@@ -586,7 +618,8 @@ interface VideoPresetConfig {
|
|
|
586
618
|
voice: string | null;
|
|
587
619
|
language: string;
|
|
588
620
|
subtitles: 'burned' | 'file' | 'off';
|
|
589
|
-
subtitle_style
|
|
621
|
+
/** `custom:<media_id>` names an uploaded font (media kind `subtitle_style`). */
|
|
622
|
+
subtitle_style: 'classic' | 'word' | `custom:${string}`;
|
|
590
623
|
page_audio: boolean;
|
|
591
624
|
music: MusicBed | null;
|
|
592
625
|
};
|
|
@@ -718,12 +751,54 @@ interface Proxy {
|
|
|
718
751
|
host: string;
|
|
719
752
|
port: number;
|
|
720
753
|
rotation: Rotation;
|
|
754
|
+
/**
|
|
755
|
+
* The operator's own name for this row, or `null` if they never gave one.
|
|
756
|
+
*
|
|
757
|
+
* The only field that tells two rows of one provider pool apart: kind, host,
|
|
758
|
+
* port and rotation are identical across a bought gateway, and the session tag
|
|
759
|
+
* that actually differs sits in the write-only username. Do not fall back to
|
|
760
|
+
* `last_exit_ip` for identity; the health check wrote it hours or days ago and
|
|
761
|
+
* a rotating exit no longer has that address.
|
|
762
|
+
*/
|
|
763
|
+
label: string | null;
|
|
721
764
|
last_exit_ip: string | null;
|
|
722
765
|
last_country: string | null;
|
|
766
|
+
/**
|
|
767
|
+
* The operator string the geo probe answered with, for example
|
|
768
|
+
* `"AS21928 T-Mobile USA, Inc."`. Part of the same measurement as the fields
|
|
769
|
+
* around it: one check writes them, an endpoint change clears them together.
|
|
770
|
+
* The daemon derives the address kind from it, which decides how long an
|
|
771
|
+
* address stays reserved for a profile.
|
|
772
|
+
*/
|
|
773
|
+
last_asn: string | null;
|
|
723
774
|
last_check_at: number | null;
|
|
724
775
|
healthy: boolean | null;
|
|
776
|
+
/** Round-trip latency of the last health check, in ms. */
|
|
777
|
+
last_latency_ms: number | null;
|
|
778
|
+
/**
|
|
779
|
+
* The row holds credentials that could not be decrypted (a database restored
|
|
780
|
+
* without its master key). Every launch through it fails closed, so a screen
|
|
781
|
+
* that shows only `healthy` paints such a row green while nothing can use it.
|
|
782
|
+
* Omitted by the daemon when false.
|
|
783
|
+
*/
|
|
784
|
+
credentials_unreadable?: boolean;
|
|
725
785
|
created_at: number;
|
|
726
786
|
}
|
|
787
|
+
/**
|
|
788
|
+
* Who depends on one proxy, as `GET /v1/proxies` reports it per row.
|
|
789
|
+
*
|
|
790
|
+
* `count` is exact, `names` holds at most three. A proxy shared by a fleet must
|
|
791
|
+
* not drag every profile name into the listing, so showing the names without the
|
|
792
|
+
* count would turn "three of forty" into "these three".
|
|
793
|
+
*/
|
|
794
|
+
interface ProxyUsage {
|
|
795
|
+
count: number;
|
|
796
|
+
names: string[];
|
|
797
|
+
}
|
|
798
|
+
/** A row of the proxy LIST: the proxy plus who uses it. The single GET has no `used_by`. */
|
|
799
|
+
interface ProxyRow extends Proxy {
|
|
800
|
+
used_by: ProxyUsage;
|
|
801
|
+
}
|
|
727
802
|
/** Per-detector outcome; `skip` means the page could not be evaluated, NOT a pass. */
|
|
728
803
|
type AuditVerdict = 'pass' | 'warn' | 'fail' | 'skip' | 'error';
|
|
729
804
|
interface AuditDetectorReport {
|
|
@@ -780,8 +855,9 @@ interface SessionImportBody {
|
|
|
780
855
|
}
|
|
781
856
|
/**
|
|
782
857
|
* Trusted-input payload (`POST /v1/profiles/:id/input`, G8, AC-API-003). Only
|
|
783
|
-
* `action` and `humanize` are fixed by
|
|
784
|
-
* fields below are the SDK's
|
|
858
|
+
* `action` and `humanize` are fixed by the API contract; the per-action
|
|
859
|
+
* coordinate fields below are the SDK's assumption about the daemon's input
|
|
860
|
+
* layer.
|
|
785
861
|
*/
|
|
786
862
|
type TrustedInputBody = {
|
|
787
863
|
action: 'move';
|
|
@@ -889,7 +965,7 @@ interface ExitStatus {
|
|
|
889
965
|
/**
|
|
890
966
|
* The per-profile task list and the profile's own durable memory.
|
|
891
967
|
*
|
|
892
|
-
*
|
|
968
|
+
* One of the files that are the daemon's wire contract.
|
|
893
969
|
*/
|
|
894
970
|
/**
|
|
895
971
|
* Where a task stands.
|
|
@@ -1168,13 +1244,6 @@ type StreamedEvent = LifecycleEvent & {
|
|
|
1168
1244
|
* the browser `EventSource` cannot do that) and reconnect with backoff. A
|
|
1169
1245
|
* `/v1/ws` websocket carries the same events; SSE is sufficient for one-way
|
|
1170
1246
|
* fan-out.
|
|
1171
|
-
*
|
|
1172
|
-
* Mirrors `web-ui/src/api/events.ts` line for line, deliberately: this package
|
|
1173
|
-
* ships to npm and should carry no dependency it does not need, so a shared
|
|
1174
|
-
* package would cost more than the copy does. The copy pays for itself with a
|
|
1175
|
-
* gate instead: `scripts/verify-mirrored-values.mjs` holds `MAX_BACKOFF_MS` and
|
|
1176
|
-
* the backoff line itself against the other side. Two clients of the same daemon
|
|
1177
|
-
* that come back at different speeds would be a decision nobody made.
|
|
1178
1247
|
*/
|
|
1179
1248
|
|
|
1180
1249
|
/** Injectable `fetch`; defaults to the global at call time. */
|
|
@@ -1218,8 +1287,7 @@ declare function eventStream(params: StreamParams): AsyncIterableIterator<Lifecy
|
|
|
1218
1287
|
* What the browser asks (interruptions), the bytes that go in and out
|
|
1219
1288
|
* (artifacts), and what the licence says (account).
|
|
1220
1289
|
*
|
|
1221
|
-
*
|
|
1222
|
-
* source of contract truth.
|
|
1290
|
+
* One of the files that are the daemon's wire contract.
|
|
1223
1291
|
*/
|
|
1224
1292
|
/** What an operator has taken out of an agent's hands. */
|
|
1225
1293
|
type InterruptionLock = 'always_block' | 'always_allow' | 'agent_decides';
|
|
@@ -1291,6 +1359,32 @@ interface ArtifactBytes {
|
|
|
1291
1359
|
/** Parsed out of `Content-Disposition`, when the daemon sent one. */
|
|
1292
1360
|
filename: string | null;
|
|
1293
1361
|
}
|
|
1362
|
+
/**
|
|
1363
|
+
* Which installation this daemon is: the data directory it serves and the binary
|
|
1364
|
+
* it runs from.
|
|
1365
|
+
*
|
|
1366
|
+
* One machine can hold several installations, and they are told apart by their
|
|
1367
|
+
* data directory, never by their address. A port is a preference: the desktop app
|
|
1368
|
+
* takes the first free one from 8787, and a `runtime.json` left behind by an
|
|
1369
|
+
* earlier daemon can name a port that something else now holds. Ask this before
|
|
1370
|
+
* assuming the daemon you reached is the one you meant.
|
|
1371
|
+
*/
|
|
1372
|
+
interface Connection {
|
|
1373
|
+
/** The address the native API is bound to, as resolved. */
|
|
1374
|
+
native_addr: string;
|
|
1375
|
+
/** The data directory, in a form suitable for showing or for a command line. */
|
|
1376
|
+
data_dir: string;
|
|
1377
|
+
/**
|
|
1378
|
+
* The same directory, in the form two daemons compare. Case is folded on
|
|
1379
|
+
* Windows and links are resolved, so do not show this one to anybody; compare
|
|
1380
|
+
* it with another daemon's value and nothing else.
|
|
1381
|
+
*/
|
|
1382
|
+
data_dir_key: string;
|
|
1383
|
+
/** Absolute path of the running binary, for a client that launches it over stdio. */
|
|
1384
|
+
executable?: string;
|
|
1385
|
+
/** The AdsPower-compatible adapter's address, when that adapter is enabled. */
|
|
1386
|
+
adspower_addr?: string;
|
|
1387
|
+
}
|
|
1294
1388
|
/**
|
|
1295
1389
|
* Licence state, for display.
|
|
1296
1390
|
*
|
|
@@ -1344,6 +1438,27 @@ interface RemoteStatus {
|
|
|
1344
1438
|
* whatever the switch says. */
|
|
1345
1439
|
ready: boolean;
|
|
1346
1440
|
}
|
|
1441
|
+
/**
|
|
1442
|
+
* What `GET /v1/exit-rule` answers: the machine's own exit-address exclusivity
|
|
1443
|
+
* switch.
|
|
1444
|
+
*
|
|
1445
|
+
* On by default. Turn it off for a provider that hands out ONE address on
|
|
1446
|
+
* purpose, a residential line you pay for or a whitelisted office address, where
|
|
1447
|
+
* the rule would refuse every start after the first.
|
|
1448
|
+
*/
|
|
1449
|
+
interface ExitRuleStatus {
|
|
1450
|
+
/** Does the rule apply on this machine? */
|
|
1451
|
+
enabled: boolean;
|
|
1452
|
+
/** Did a person decide this, or is the configured default still standing? */
|
|
1453
|
+
explicit: boolean;
|
|
1454
|
+
/**
|
|
1455
|
+
* How many profiles switched the rule off for themselves.
|
|
1456
|
+
*
|
|
1457
|
+
* A global "on" reads as "every profile is separated", and that stops being
|
|
1458
|
+
* true the moment one profile has its own switch off.
|
|
1459
|
+
*/
|
|
1460
|
+
profiles_opted_out: number;
|
|
1461
|
+
}
|
|
1347
1462
|
|
|
1348
1463
|
interface ScalebrowserClientOptions {
|
|
1349
1464
|
/** Daemon base URL. Default `http://127.0.0.1:8787`. */
|
|
@@ -1411,6 +1526,15 @@ declare class ControlApi extends ClientCore {
|
|
|
1411
1526
|
* connected or permitted. Same shape of tolerance as {@link getMetrics}.
|
|
1412
1527
|
*/
|
|
1413
1528
|
getAccount(signal?: AbortSignal): Promise<Account>;
|
|
1529
|
+
/**
|
|
1530
|
+
* Which installation answered: its data directory and its binary.
|
|
1531
|
+
*
|
|
1532
|
+
* `health()` tells you something is there. This tells you WHAT, and the two are
|
|
1533
|
+
* different questions whenever a machine holds more than one installation. The
|
|
1534
|
+
* data directory is the identity; the address is not, because a port is a
|
|
1535
|
+
* preference and a stale `runtime.json` can name one that moved.
|
|
1536
|
+
*/
|
|
1537
|
+
getConnection(signal?: AbortSignal): Promise<Connection>;
|
|
1414
1538
|
/** "Is the daemon alive?" Public, needs no token. */
|
|
1415
1539
|
health(signal?: AbortSignal): Promise<HealthStatus>;
|
|
1416
1540
|
/** "Can it serve?" Local facts only; the control plane is deliberately not consulted. */
|
|
@@ -1426,6 +1550,24 @@ interface ProfileIdsResult {
|
|
|
1426
1550
|
count: number;
|
|
1427
1551
|
ids: string[];
|
|
1428
1552
|
}
|
|
1553
|
+
/**
|
|
1554
|
+
* `GET /v1/profiles/count`: how many profiles match, split by runtime state.
|
|
1555
|
+
*
|
|
1556
|
+
* `total` counts ROWS, so it is the sum of the four states for every state this
|
|
1557
|
+
* daemon can read; a row in a state a newer build introduced counts in `total`
|
|
1558
|
+
* alone rather than being folded into `stopped`.
|
|
1559
|
+
*
|
|
1560
|
+
* The `state` filter is the one this route ignores. A caller labelling all four
|
|
1561
|
+
* scopes is sitting in one of them, so narrowing by it would answer the other
|
|
1562
|
+
* three with zero. Every other filter binds exactly as it does for the listing.
|
|
1563
|
+
*/
|
|
1564
|
+
interface ProfileCounts {
|
|
1565
|
+
total: number;
|
|
1566
|
+
stopped: number;
|
|
1567
|
+
starting: number;
|
|
1568
|
+
running: number;
|
|
1569
|
+
crashed: number;
|
|
1570
|
+
}
|
|
1429
1571
|
/** `POST /v1/bulk/start`: per-id results plus what the batch as a whole did. */
|
|
1430
1572
|
interface BulkStartResult {
|
|
1431
1573
|
results: {
|
|
@@ -1450,18 +1592,39 @@ interface ListProfilesParams {
|
|
|
1450
1592
|
interface CreateProfileBody {
|
|
1451
1593
|
name: string;
|
|
1452
1594
|
seed?: string;
|
|
1453
|
-
host_mode?: HostMode;
|
|
1454
1595
|
geo_mode?: GeoMode;
|
|
1455
1596
|
expected_country?: string | null;
|
|
1597
|
+
/**
|
|
1598
|
+
* Draw the identity for this region (ISO-3166 alpha-2, e.g. `"DE"`): language,
|
|
1599
|
+
* timezone and speech voices come out of one row of the model together. Omit to
|
|
1600
|
+
* draw unconstrained, weighted the way the population is.
|
|
1601
|
+
*
|
|
1602
|
+
* This is not `expected_country`, which only checks the exit and never touches
|
|
1603
|
+
* the identity. And it is a starting value, not a promise: under the default
|
|
1604
|
+
* `geo_mode` the launch rewrites the region to the country the profile really
|
|
1605
|
+
* exits in, which is its proxy's, or with no proxy the machine's own. The
|
|
1606
|
+
* daemon refuses the pairings where that collision is already known.
|
|
1607
|
+
*
|
|
1608
|
+
* Set only at create. A region the model cannot draw is a 400 listing the ones
|
|
1609
|
+
* it can.
|
|
1610
|
+
*/
|
|
1611
|
+
persona_country?: string;
|
|
1456
1612
|
group_id?: string | null;
|
|
1457
1613
|
proxy_id?: string | null;
|
|
1458
1614
|
}
|
|
1459
1615
|
/**
|
|
1460
|
-
* PATCH, all mutable fields optional. `
|
|
1461
|
-
* time (
|
|
1462
|
-
*
|
|
1616
|
+
* PATCH, all mutable fields optional. `seed` and `persona_country` are fixed at
|
|
1617
|
+
* create time (C5): they draw the identity, and redrawing it under a profile that
|
|
1618
|
+
* has already been used would be a new identity in an old profile's clothes.
|
|
1463
1619
|
*/
|
|
1464
|
-
type UpdateProfileBody = Omit<Partial<CreateProfileBody>, "
|
|
1620
|
+
type UpdateProfileBody = Omit<Partial<CreateProfileBody>, "seed" | "persona_country"> & {
|
|
1621
|
+
/**
|
|
1622
|
+
* Turn the exit-address rule off for this profile (DEC-017). Deliberately not
|
|
1623
|
+
* part of `CreateProfileBody`: a new profile always claims its address, and
|
|
1624
|
+
* switching that off is a later, deliberate act for a setup that needs it.
|
|
1625
|
+
*/
|
|
1626
|
+
exit_exclusive?: boolean;
|
|
1627
|
+
};
|
|
1465
1628
|
interface StartProfileBody {
|
|
1466
1629
|
headless?: boolean;
|
|
1467
1630
|
}
|
|
@@ -1510,6 +1673,12 @@ interface CreateProxyBody {
|
|
|
1510
1673
|
username?: string | null;
|
|
1511
1674
|
password?: string | null;
|
|
1512
1675
|
rotation?: Rotation;
|
|
1676
|
+
/**
|
|
1677
|
+
* The operator's own name for the row. Trimmed by the daemon; a blank string is
|
|
1678
|
+
* stored as null. On an update the field carries three states: omit the key to
|
|
1679
|
+
* leave the name alone, send `null` to clear it, send a string to set it.
|
|
1680
|
+
*/
|
|
1681
|
+
label?: string | null;
|
|
1513
1682
|
}
|
|
1514
1683
|
type UpdateProxyBody = Partial<CreateProxyBody>;
|
|
1515
1684
|
/**
|
|
@@ -1646,9 +1815,9 @@ declare class ExtensionsApi extends ClientCore {
|
|
|
1646
1815
|
* The account layer: mailboxes, passkeys and the one door a cookie value leaves
|
|
1647
1816
|
* through.
|
|
1648
1817
|
*
|
|
1649
|
-
*
|
|
1650
|
-
*
|
|
1651
|
-
*
|
|
1818
|
+
* One of the files that are the daemon's wire contract. The cookie
|
|
1819
|
+
* reveal has no UI counterpart: it is a REST-only route deliberately kept off
|
|
1820
|
+
* every screen.
|
|
1652
1821
|
*/
|
|
1653
1822
|
/** One configured mailbox. The password is never sent back. */
|
|
1654
1823
|
interface Inbox {
|
|
@@ -2051,7 +2220,7 @@ declare class TasksApi extends ClientCore {
|
|
|
2051
2220
|
* the live event stream carries them, and the run list describes the same rows.
|
|
2052
2221
|
* A second copy would let the two drift apart while both looked right.
|
|
2053
2222
|
*
|
|
2054
|
-
*
|
|
2223
|
+
* One of the files that are the daemon's wire contract.
|
|
2055
2224
|
*/
|
|
2056
2225
|
|
|
2057
2226
|
/** Who made the outcome claim. `derived` means nobody did. */
|
|
@@ -2171,7 +2340,7 @@ declare class VideosApi extends ClientCore {
|
|
|
2171
2340
|
* whether the link still lives is read from the control plane, not from
|
|
2172
2341
|
* here: a number carried along would be wrong the moment another machine
|
|
2173
2342
|
* revoked. */
|
|
2174
|
-
shareStatus(videoId: string, signal?: AbortSignal): Promise<
|
|
2343
|
+
shareStatus(videoId: string, signal?: AbortSignal): Promise<ShareStatus>;
|
|
2175
2344
|
/** Revoke the link. The files fall at once; the order stays until the control
|
|
2176
2345
|
* plane confirms. */
|
|
2177
2346
|
revokeShare(videoId: string, signal?: AbortSignal): Promise<void>;
|
|
@@ -2403,7 +2572,7 @@ interface Metrics {
|
|
|
2403
2572
|
* (shapes), nowhere else.
|
|
2404
2573
|
*/
|
|
2405
2574
|
|
|
2406
|
-
/**
|
|
2575
|
+
/** The daemon's own default capacity limits. */
|
|
2407
2576
|
declare const DEFAULT_CAPACITY: {
|
|
2408
2577
|
max_concurrent: number;
|
|
2409
2578
|
ram_budget_mb: number;
|
|
@@ -2431,6 +2600,18 @@ declare class ScalebrowserClient extends ClientCore {
|
|
|
2431
2600
|
* page you fetched. Asking for ids costs one request and no persona payloads.
|
|
2432
2601
|
*/
|
|
2433
2602
|
listProfileIds(params?: ListProfilesParams, signal?: AbortSignal): Promise<ProfileIdsResult>;
|
|
2603
|
+
/**
|
|
2604
|
+
* How many profiles match `params`, split by runtime state. One request, and
|
|
2605
|
+
* its size does not grow with the fleet.
|
|
2606
|
+
*
|
|
2607
|
+
* `listProfiles` is paged and answers a bare array, so counting what came back
|
|
2608
|
+
* counts the page. `listProfileIds` carries the same total but ships an
|
|
2609
|
+
* identifier per profile to do it, and cannot split by state at all.
|
|
2610
|
+
*
|
|
2611
|
+
* `params.state` is ignored here on purpose: a caller labelling every state is
|
|
2612
|
+
* sitting in one of them.
|
|
2613
|
+
*/
|
|
2614
|
+
countProfiles(params?: ListProfilesParams, signal?: AbortSignal): Promise<ProfileCounts>;
|
|
2434
2615
|
getProfile(id: string, signal?: AbortSignal): Promise<Profile>;
|
|
2435
2616
|
createProfile(body: CreateProfileBody): Promise<Profile>;
|
|
2436
2617
|
updateProfile(id: string, body: UpdateProfileBody): Promise<Profile>;
|
|
@@ -2511,7 +2692,8 @@ declare class ScalebrowserClient extends ClientCore {
|
|
|
2511
2692
|
* drifts the moment that model changes and every create 400s.
|
|
2512
2693
|
*/
|
|
2513
2694
|
getPersonaConstraints(signal?: AbortSignal): Promise<PersonaConstraintOptions>;
|
|
2514
|
-
|
|
2695
|
+
/** The list carries `used_by` per row; `getProxy` below does not. */
|
|
2696
|
+
listProxies(signal?: AbortSignal): Promise<ProxyRow[]>;
|
|
2515
2697
|
getProxy(id: string, signal?: AbortSignal): Promise<Proxy>;
|
|
2516
2698
|
createProxy(body: CreateProxyBody): Promise<Proxy>;
|
|
2517
2699
|
updateProxy(id: string, body: UpdateProxyBody): Promise<Proxy>;
|
|
@@ -2549,6 +2731,22 @@ declare class ScalebrowserClient extends ClientCore {
|
|
|
2549
2731
|
getRemoteAccess(signal?: AbortSignal): Promise<RemoteStatus>;
|
|
2550
2732
|
/** Turn remote access on or off for this machine. */
|
|
2551
2733
|
setRemoteAccess(enabled: boolean, signal?: AbortSignal): Promise<RemoteStatus>;
|
|
2734
|
+
/**
|
|
2735
|
+
* Does one exit address belong to one profile on this machine?
|
|
2736
|
+
*
|
|
2737
|
+
* Local like the remote-access switch above, and here for the same reason: on
|
|
2738
|
+
* a headless install there is no UI to click, and setting up fifty machines by
|
|
2739
|
+
* hand is not setting them up.
|
|
2740
|
+
*/
|
|
2741
|
+
getExitRule(signal?: AbortSignal): Promise<ExitRuleStatus>;
|
|
2742
|
+
/**
|
|
2743
|
+
* Turn the exit-address rule on or off for this machine.
|
|
2744
|
+
*
|
|
2745
|
+
* Off means two of your profiles can leave over the same address. Reach for it
|
|
2746
|
+
* when the provider hands out ONE address on purpose; a per-profile switch
|
|
2747
|
+
* exists for the narrower case (`updateProfile` with `exit_exclusive`).
|
|
2748
|
+
*/
|
|
2749
|
+
setExitRule(enabled: boolean, signal?: AbortSignal): Promise<ExitRuleStatus>;
|
|
2552
2750
|
/** Subscribe to lifecycle events. Returns an unsubscribe function. */
|
|
2553
2751
|
subscribeEvents(handlers: StreamHandlers): () => void;
|
|
2554
2752
|
/** `for await (const event of client.events())` over lifecycle events. */
|
|
@@ -2568,8 +2766,8 @@ interface ScalebrowserClient extends IdentityApi, RunsApi, VideosApi, ControlApi
|
|
|
2568
2766
|
}
|
|
2569
2767
|
|
|
2570
2768
|
/**
|
|
2571
|
-
* Error model: stable numeric API error codes
|
|
2572
|
-
*
|
|
2769
|
+
* Error model: the stable numeric API error codes and the typed exceptions
|
|
2770
|
+
* the SDK throws.
|
|
2573
2771
|
*/
|
|
2574
2772
|
/** Stable numeric API error codes (4001–4013, append-only: a retired code stays
|
|
2575
2773
|
* reserved rather than being reused). */
|
|
@@ -2606,7 +2804,7 @@ declare const ErrorCode: {
|
|
|
2606
2804
|
readonly ExitAddressTaken: 4013;
|
|
2607
2805
|
};
|
|
2608
2806
|
type ErrorCodeValue = (typeof ErrorCode)[keyof typeof ErrorCode];
|
|
2609
|
-
/** Error body shape: `{ code, message }
|
|
2807
|
+
/** Error body shape: `{ code, message }`. */
|
|
2610
2808
|
interface ApiErrorBody {
|
|
2611
2809
|
code?: number;
|
|
2612
2810
|
message?: string;
|
|
@@ -2661,6 +2859,6 @@ declare function errorMessage(err: unknown): string;
|
|
|
2661
2859
|
* ```
|
|
2662
2860
|
*/
|
|
2663
2861
|
|
|
2664
|
-
declare const VERSION = "0.
|
|
2862
|
+
declare const VERSION = "0.8.0";
|
|
2665
2863
|
|
|
2666
|
-
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 CdpConnectOptions, CdpError, type CdpEvent, CdpSession, type Chapter, type ClickOptions, type CodecsStatus, type CreateGroupBody, type CreateInboxBody, type CreatePresetBody, type CreateTasksBody, type CreateTasksResult, DEFAULT_CAPACITY, type DeleteInterruptionRuleParams, type EffectiveInterruptionLock, ErrorCode, type ErrorCodeValue, type EvaluateOptions, type ExitClaim, type ExitScope, type ExitStatus, type ExportPresetName, type ExtraOutput, type FetchLike, GEO_MODES, type GeoMode, type GoalSource, type Group,
|
|
2864
|
+
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 };
|
package/dist/index.js
CHANGED
|
@@ -288,6 +288,17 @@ var ControlApi = class extends ClientCore {
|
|
|
288
288
|
throw err;
|
|
289
289
|
}
|
|
290
290
|
}
|
|
291
|
+
/**
|
|
292
|
+
* Which installation answered: its data directory and its binary.
|
|
293
|
+
*
|
|
294
|
+
* `health()` tells you something is there. This tells you WHAT, and the two are
|
|
295
|
+
* different questions whenever a machine holds more than one installation. The
|
|
296
|
+
* data directory is the identity; the address is not, because a port is a
|
|
297
|
+
* preference and a stale `runtime.json` can name one that moved.
|
|
298
|
+
*/
|
|
299
|
+
getConnection(signal) {
|
|
300
|
+
return this.request("GET", "/v1/connection", void 0, { signal });
|
|
301
|
+
}
|
|
291
302
|
/** "Is the daemon alive?" Public, needs no token. */
|
|
292
303
|
health(signal) {
|
|
293
304
|
return this.request("GET", "/health", void 0, { signal });
|
|
@@ -1369,6 +1380,23 @@ var ScalebrowserClient = class extends ClientCore {
|
|
|
1369
1380
|
signal
|
|
1370
1381
|
});
|
|
1371
1382
|
}
|
|
1383
|
+
/**
|
|
1384
|
+
* How many profiles match `params`, split by runtime state. One request, and
|
|
1385
|
+
* its size does not grow with the fleet.
|
|
1386
|
+
*
|
|
1387
|
+
* `listProfiles` is paged and answers a bare array, so counting what came back
|
|
1388
|
+
* counts the page. `listProfileIds` carries the same total but ships an
|
|
1389
|
+
* identifier per profile to do it, and cannot split by state at all.
|
|
1390
|
+
*
|
|
1391
|
+
* `params.state` is ignored here on purpose: a caller labelling every state is
|
|
1392
|
+
* sitting in one of them.
|
|
1393
|
+
*/
|
|
1394
|
+
countProfiles(params = {}, signal) {
|
|
1395
|
+
return this.request("GET", "/v1/profiles/count", void 0, {
|
|
1396
|
+
query: { group: params.group, q: params.q },
|
|
1397
|
+
signal
|
|
1398
|
+
});
|
|
1399
|
+
}
|
|
1372
1400
|
getProfile(id, signal) {
|
|
1373
1401
|
return this.request("GET", `/v1/profiles/${enc(id)}`, void 0, { signal });
|
|
1374
1402
|
}
|
|
@@ -1518,6 +1546,7 @@ var ScalebrowserClient = class extends ClientCore {
|
|
|
1518
1546
|
);
|
|
1519
1547
|
}
|
|
1520
1548
|
// ── Proxies (credentials write-only) ────────────────────────────────────────
|
|
1549
|
+
/** The list carries `used_by` per row; `getProxy` below does not. */
|
|
1521
1550
|
listProxies(signal) {
|
|
1522
1551
|
return this.request("GET", "/v1/proxies", void 0, { signal });
|
|
1523
1552
|
}
|
|
@@ -1609,6 +1638,27 @@ var ScalebrowserClient = class extends ClientCore {
|
|
|
1609
1638
|
async setRemoteAccess(enabled, signal) {
|
|
1610
1639
|
return this.request("PUT", "/v1/remote", { enabled }, { signal });
|
|
1611
1640
|
}
|
|
1641
|
+
// ── Exit-address exclusivity (the machine's own switch) ─────────────────────
|
|
1642
|
+
/**
|
|
1643
|
+
* Does one exit address belong to one profile on this machine?
|
|
1644
|
+
*
|
|
1645
|
+
* Local like the remote-access switch above, and here for the same reason: on
|
|
1646
|
+
* a headless install there is no UI to click, and setting up fifty machines by
|
|
1647
|
+
* hand is not setting them up.
|
|
1648
|
+
*/
|
|
1649
|
+
async getExitRule(signal) {
|
|
1650
|
+
return this.request("GET", "/v1/exit-rule", void 0, { signal });
|
|
1651
|
+
}
|
|
1652
|
+
/**
|
|
1653
|
+
* Turn the exit-address rule on or off for this machine.
|
|
1654
|
+
*
|
|
1655
|
+
* Off means two of your profiles can leave over the same address. Reach for it
|
|
1656
|
+
* when the provider hands out ONE address on purpose; a per-profile switch
|
|
1657
|
+
* exists for the narrower case (`updateProfile` with `exit_exclusive`).
|
|
1658
|
+
*/
|
|
1659
|
+
async setExitRule(enabled, signal) {
|
|
1660
|
+
return this.request("PUT", "/v1/exit-rule", { enabled }, { signal });
|
|
1661
|
+
}
|
|
1612
1662
|
// ── Events (SSE) ───────────────────────────────────────────────────────────
|
|
1613
1663
|
/** Subscribe to lifecycle events. Returns an unsubscribe function. */
|
|
1614
1664
|
subscribeEvents(handlers) {
|
|
@@ -1677,12 +1727,11 @@ applyMixins(ScalebrowserClient, [
|
|
|
1677
1727
|
|
|
1678
1728
|
// src/types.ts
|
|
1679
1729
|
var RUNTIME_STATES = ["stopped", "starting", "running", "crashed"];
|
|
1680
|
-
var HOST_MODES = ["linux_engine_spoof", "local_native_windows"];
|
|
1681
1730
|
var GEO_MODES = ["strict_expected", "follow_exit", "off"];
|
|
1682
1731
|
var PROXY_KINDS = ["http", "socks5", "gateway"];
|
|
1683
1732
|
var ROTATIONS = ["sticky", "rotating"];
|
|
1684
1733
|
|
|
1685
1734
|
// src/index.ts
|
|
1686
|
-
var VERSION = "0.
|
|
1735
|
+
var VERSION = "0.8.0";
|
|
1687
1736
|
|
|
1688
|
-
export { ApiError, CdpError, CdpSession, DEFAULT_CAPACITY, ErrorCode, GEO_MODES,
|
|
1737
|
+
export { ApiError, CdpError, CdpSession, DEFAULT_CAPACITY, ErrorCode, GEO_MODES, NetworkError, PROXY_KINDS, ROTATIONS, RUNTIME_STATES, ScalebrowserClient, ScalebrowserError, VERSION, deriveMetricsFromProfiles, errorMessage, eventStream, openCdpSession, parseSseFrame, subscribeEvents };
|