opensteer 0.6.0 → 0.6.2

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
@@ -2,7 +2,22 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
- - None.
5
+ - Added cloud browser profile targeting in SDK config/launch:
6
+ `cloud.browserProfile` and `launch({ cloudBrowserProfile })`.
7
+ - Added env support for cloud browser profile defaults:
8
+ `OPENSTEER_CLOUD_PROFILE_ID` and
9
+ `OPENSTEER_CLOUD_PROFILE_REUSE_IF_ACTIVE`.
10
+ - Added CLI launch flags for cloud profile targeting:
11
+ `--cloud-profile-id` and `--cloud-profile-reuse-if-active`.
12
+ - Added new profile CLI group:
13
+ `opensteer profile list`, `opensteer profile create`, and
14
+ `opensteer profile sync` (cookie sync only, no full profile import).
15
+ - Extended cloud error-code mapping to preserve browser-profile cloud errors
16
+ (for example `CLOUD_BROWSER_PROFILE_NOT_FOUND`) instead of collapsing to
17
+ generic transport errors.
18
+ - Extraction now resolves relative URL-like attributes against the iframe
19
+ document base URL when the extracted element lives inside an accessible
20
+ iframe, while preserving existing main-frame extraction behavior.
6
21
 
7
22
  ## 0.6.0
8
23
 
package/README.md CHANGED
@@ -44,6 +44,7 @@ npx playwright install chromium
44
44
  - Descriptor-aware actions with selector persistence for replay
45
45
  - Structured extraction with typed schemas
46
46
  - CUA agent support (`openai`, `anthropic`, `google`)
47
+ - Stealth cursor preview for interactive actions (CLI default on, SDK default off)
47
48
 
48
49
  ## Quick Start: SDK
49
50
 
@@ -71,6 +72,15 @@ try {
71
72
  }
72
73
  ```
73
74
 
75
+ Enable cursor preview in SDK:
76
+
77
+ ```ts
78
+ const opensteer = new Opensteer({
79
+ name: "quickstart",
80
+ cursor: { enabled: true },
81
+ });
82
+ ```
83
+
74
84
  ## Quick Start: CUA Agent
75
85
 
76
86
  ```ts
@@ -101,6 +111,10 @@ opensteer open https://example.com --session demo --name quickstart
101
111
  opensteer snapshot action --session demo
102
112
  opensteer click --description "main call to action" --session demo
103
113
 
114
+ # Cursor controls
115
+ opensteer cursor status --session demo
116
+ opensteer cursor off --session demo
117
+
104
118
  # Extraction snapshot + structured extract
105
119
  opensteer snapshot extraction --session demo
106
120
  opensteer extract '{"title":"string","href":"string"}' --description "hero section" --session demo
@@ -113,6 +127,11 @@ For non-interactive runs, set `OPENSTEER_SESSION` or `OPENSTEER_CLIENT_ID`.
113
127
  Runtime daemon routing for `OPENSTEER_SESSION` is scoped by canonical `cwd`
114
128
  (`realpath(cwd)`) + logical session id.
115
129
 
130
+ Cursor defaults:
131
+
132
+ - CLI sessions: enabled by default (toggle with `--cursor` or `opensteer cursor on|off`)
133
+ - SDK instances: disabled by default (set `cursor.enabled: true` to opt in)
134
+
116
135
  ## For AI Agents
117
136
 
118
137
  Use this workflow to keep scripts replayable and maintainable:
@@ -151,12 +170,56 @@ OPENSTEER_MODE=cloud
151
170
  OPENSTEER_API_KEY=<your_api_key>
152
171
  ```
153
172
 
173
+ - Interactive CLI login:
174
+
175
+ ```bash
176
+ opensteer auth login
177
+ opensteer auth status
178
+ opensteer auth logout
179
+ ```
180
+
181
+ - `opensteer auth login` opens your default browser when possible. Use
182
+ `--no-browser` on remote shells, containers, or CI and paste the printed URL
183
+ into a browser manually. In `--json` mode, login prompts go to stderr and the
184
+ final JSON result stays on stdout.
185
+ - Saved machine logins remain scoped per resolved cloud API host (`baseUrl`).
186
+ The CLI also remembers the last selected cloud host, so `opensteer auth
187
+ status`, `opensteer auth logout`, and other cloud commands reuse it by
188
+ default unless `--base-url` or env vars select a different host.
189
+
154
190
  - `OPENSTEER_BASE_URL` overrides the default cloud host
191
+ - `OPENSTEER_ACCESS_TOKEN` provides bearer auth for cloud commands
155
192
  - `OPENSTEER_AUTH_SCHEME` supports `api-key` (default) or `bearer`
193
+ - Credential precedence: explicit flags > environment variables > saved machine login
194
+ - `OPENSTEER_CLOUD_PROFILE_ID` optionally launches into a specific cloud browser profile
195
+ - `OPENSTEER_CLOUD_PROFILE_REUSE_IF_ACTIVE` (`true|false`) optionally reuses an active profile session
156
196
  - `cloud: true` or a `cloud` options object overrides `OPENSTEER_MODE`
157
197
  - Cloud mode is fail-fast (no automatic fallback to local)
158
198
  - `Opensteer.from(page)`, `uploadFile`, `exportCookies`, and `importCookies` are local-only
159
199
 
200
+ Select a cloud browser profile in SDK:
201
+
202
+ ```ts
203
+ const opensteer = new Opensteer({
204
+ cloud: {
205
+ accessToken: process.env.OPENSTEER_ACCESS_TOKEN,
206
+ browserProfile: {
207
+ profileId: "bp_123",
208
+ reuseIfActive: true,
209
+ },
210
+ },
211
+ });
212
+ ```
213
+
214
+ Sync local profile cookies into a cloud profile:
215
+
216
+ ```bash
217
+ opensteer profile sync \
218
+ --from-profile-dir ~/Library/Application\ Support/Google/Chrome/Default \
219
+ --to-profile-id bp_123 \
220
+ --domain github.com
221
+ ```
222
+
160
223
  ## Resolution and Replay
161
224
 
162
225
  For descriptor-aware actions (`click`, `input`, `hover`, `select`, `scroll`):
package/bin/opensteer.mjs CHANGED
@@ -26,6 +26,8 @@ const SKILLS_INSTALLER_SCRIPT = join(
26
26
  'cli',
27
27
  'skills-installer.js'
28
28
  )
29
+ const PROFILE_CLI_SCRIPT = join(__dirname, '..', 'dist', 'cli', 'profile.js')
30
+ const AUTH_CLI_SCRIPT = join(__dirname, '..', 'dist', 'cli', 'auth.js')
29
31
  const SKILLS_HELP_TEXT = `Usage: opensteer skills <install|add> [options]
30
32
 
31
33
  Installs the first-party Opensteer skill using the upstream "skills" CLI.
@@ -47,6 +49,28 @@ Examples:
47
49
  opensteer skills add --agent codex --global --yes
48
50
  opensteer skills install --all --yes
49
51
  `
52
+ const PROFILE_HELP_TEXT = `Usage: opensteer profile <command> [options]
53
+
54
+ Manage cloud browser profiles and sync local cookie state into cloud profiles.
55
+
56
+ Commands:
57
+ list
58
+ create --name <name>
59
+ sync
60
+
61
+ Run "opensteer profile --help" after building for full command details.
62
+ `
63
+ const AUTH_HELP_TEXT = `Usage: opensteer auth <command> [options]
64
+
65
+ Authenticate Opensteer CLI with Opensteer Cloud.
66
+
67
+ Commands:
68
+ login
69
+ status
70
+ logout
71
+
72
+ Run "opensteer auth --help" after building for full command details.
73
+ `
50
74
 
51
75
  const CONNECT_TIMEOUT = 15000
52
76
  const POLL_INTERVAL = 100
@@ -307,7 +331,16 @@ function getMetadataPath(session) {
307
331
  function buildRequest(command, flags, positional) {
308
332
  const id = 1
309
333
  const globalFlags = {}
310
- for (const key of ['headless', 'json', 'connect-url', 'channel', 'profile-dir']) {
334
+ for (const key of [
335
+ 'headless',
336
+ 'json',
337
+ 'connect-url',
338
+ 'channel',
339
+ 'profile-dir',
340
+ 'cloud-profile-id',
341
+ 'cloud-profile-reuse-if-active',
342
+ 'cursor',
343
+ ]) {
311
344
  if (key in flags) {
312
345
  globalFlags[key] = flags[key]
313
346
  delete flags[key]
@@ -408,6 +441,10 @@ function buildRequest(command, flags, positional) {
408
441
  case 'snapshot':
409
442
  args.mode = positional[0] || args.mode
410
443
  break
444
+
445
+ case 'cursor':
446
+ args.mode = positional[0] || args.mode || 'status'
447
+ break
411
448
  }
412
449
 
413
450
  return { id, command, args }
@@ -918,6 +955,105 @@ async function runSkillsSubcommand(args) {
918
955
  }
919
956
  }
920
957
 
958
+ async function runProfileSubcommand(args) {
959
+ if (isProfileHelpRequest(args)) {
960
+ process.stdout.write(PROFILE_HELP_TEXT)
961
+ return
962
+ }
963
+
964
+ if (!existsSync(PROFILE_CLI_SCRIPT)) {
965
+ throw new Error(
966
+ `Profile CLI module was not found at "${PROFILE_CLI_SCRIPT}". Run "npm run build" to generate dist artifacts.`
967
+ )
968
+ }
969
+
970
+ const moduleUrl = pathToFileURL(PROFILE_CLI_SCRIPT).href
971
+ const { runOpensteerProfileCli } = await import(moduleUrl)
972
+ const exitCode = await runOpensteerProfileCli(args)
973
+ if (exitCode !== 0) {
974
+ process.exit(exitCode)
975
+ }
976
+ }
977
+
978
+ async function runAuthSubcommand(args) {
979
+ if (isAuthHelpRequest(args)) {
980
+ process.stdout.write(AUTH_HELP_TEXT)
981
+ return
982
+ }
983
+
984
+ if (!existsSync(AUTH_CLI_SCRIPT)) {
985
+ throw new Error(
986
+ `Auth CLI module was not found at "${AUTH_CLI_SCRIPT}". Run "npm run build" to generate dist artifacts.`
987
+ )
988
+ }
989
+
990
+ const moduleUrl = pathToFileURL(AUTH_CLI_SCRIPT).href
991
+ const { runOpensteerAuthCli } = await import(moduleUrl)
992
+ const exitCode = await runOpensteerAuthCli(args)
993
+ if (exitCode !== 0) {
994
+ process.exit(exitCode)
995
+ }
996
+ }
997
+
998
+ function isAuthHelpRequest(args) {
999
+ if (args.length === 0) return true
1000
+ const [subcommand, ...rest] = args
1001
+ if (subcommand === '--help' || subcommand === '-h' || subcommand === 'help') {
1002
+ return true
1003
+ }
1004
+ return rest.includes('--help') || rest.includes('-h')
1005
+ }
1006
+
1007
+ async function ensureOpenCloudCredentials(flags, scopeDir) {
1008
+ if (!existsSync(AUTH_CLI_SCRIPT)) {
1009
+ throw new Error(
1010
+ `Auth CLI module was not found at "${AUTH_CLI_SCRIPT}". Run "npm run build" to generate dist artifacts.`
1011
+ )
1012
+ }
1013
+
1014
+ const apiKeyFlag =
1015
+ typeof flags['api-key'] === 'string' ? flags['api-key'] : undefined
1016
+ const accessTokenFlag =
1017
+ typeof flags['access-token'] === 'string'
1018
+ ? flags['access-token']
1019
+ : undefined
1020
+
1021
+ const moduleUrl = pathToFileURL(AUTH_CLI_SCRIPT).href
1022
+ const { ensureCloudCredentialsForOpenCommand } = await import(moduleUrl)
1023
+ return await ensureCloudCredentialsForOpenCommand({
1024
+ scopeDir,
1025
+ env: process.env,
1026
+ apiKeyFlag,
1027
+ accessTokenFlag,
1028
+ interactive: isInteractiveTerminal(),
1029
+ writeProgress: (message) => process.stderr.write(message),
1030
+ writeStderr: (message) => process.stderr.write(message),
1031
+ })
1032
+ }
1033
+
1034
+ function isProfileHelpRequest(args) {
1035
+ if (args.length === 0) return true
1036
+ const [subcommand, ...rest] = args
1037
+ if (subcommand === '--help' || subcommand === '-h' || subcommand === 'help') {
1038
+ return true
1039
+ }
1040
+ return rest.includes('--help') || rest.includes('-h')
1041
+ }
1042
+
1043
+ function buildOpenCloudAuthPayload(auth) {
1044
+ if (!auth) {
1045
+ return null
1046
+ }
1047
+
1048
+ return {
1049
+ ...(auth.kind === 'access-token'
1050
+ ? { accessToken: auth.token }
1051
+ : { apiKey: auth.token }),
1052
+ baseUrl: auth.baseUrl,
1053
+ authScheme: auth.authScheme,
1054
+ }
1055
+ }
1056
+
921
1057
  function printHelp() {
922
1058
  console.log(`Usage: opensteer <command> [options]
923
1059
 
@@ -937,6 +1073,7 @@ Sessions:
937
1073
  Observation:
938
1074
  snapshot [--mode action] Get page snapshot
939
1075
  state Get page URL, title, and snapshot
1076
+ cursor [on|off|status] Configure/query cursor preview mode
940
1077
  screenshot [file] Take screenshot
941
1078
 
942
1079
  Actions:
@@ -981,6 +1118,10 @@ Skills:
981
1118
  skills install [options] Install Opensteer skill pack for supported agents
982
1119
  skills add [options] Alias for "skills install"
983
1120
  skills --help Show skills installer help
1121
+ profile <command> Manage cloud browser profiles and cookie sync
1122
+ auth <command> Manage cloud login credentials (login/status/logout)
1123
+ login Alias for "auth login"
1124
+ logout Alias for "auth logout"
984
1125
 
985
1126
  Global Flags:
986
1127
  --session <id> Logical session id (scoped by canonical cwd)
@@ -989,6 +1130,10 @@ Global Flags:
989
1130
  --connect-url <url> Connect to a running browser (e.g. http://localhost:9222)
990
1131
  --channel <browser> Use installed browser (chrome, chrome-beta, msedge)
991
1132
  --profile-dir <path> Browser profile directory for logged-in sessions
1133
+ --cloud-profile-id <id> Launch cloud session with a specific browser profile
1134
+ --cloud-profile-reuse-if-active <true|false>
1135
+ Reuse active cloud session for that browser profile
1136
+ --cursor <true|false> Enable/disable cursor preview for the session
992
1137
  --element <N> Target element by counter
993
1138
  --selector <css> Target element by CSS selector
994
1139
  --description <text> Description for selector persistence
@@ -999,8 +1144,10 @@ Environment:
999
1144
  OPENSTEER_SESSION Logical session id (equivalent to --session)
1000
1145
  OPENSTEER_CLIENT_ID Stable client identity for default session binding
1001
1146
  OPENSTEER_NAME Default selector namespace for 'open' when --name is omitted
1147
+ OPENSTEER_CURSOR Default cursor enablement (SDK + CLI session bootstrap)
1002
1148
  OPENSTEER_MODE Runtime routing: "local" (default) or "cloud"
1003
- OPENSTEER_API_KEY Required when cloud mode is selected
1149
+ OPENSTEER_API_KEY Cloud API key credential
1150
+ OPENSTEER_ACCESS_TOKEN Cloud bearer access token credential
1004
1151
  OPENSTEER_BASE_URL Override cloud control-plane base URL
1005
1152
  OPENSTEER_AUTH_SCHEME Cloud auth scheme: api-key (default) or bearer
1006
1153
  OPENSTEER_REMOTE_ANNOUNCE Cloud session announcement policy: always (default), off, tty
@@ -1020,6 +1167,52 @@ async function main() {
1020
1167
  }
1021
1168
  return
1022
1169
  }
1170
+ if (rawArgs[0] === 'auth') {
1171
+ try {
1172
+ await runAuthSubcommand(rawArgs.slice(1))
1173
+ } catch (err) {
1174
+ const message =
1175
+ err instanceof Error ? err.message : 'Failed to run auth command'
1176
+ process.stderr.write(`${message}\n`)
1177
+ process.exit(1)
1178
+ }
1179
+ return
1180
+ }
1181
+ if (rawArgs[0] === 'login') {
1182
+ try {
1183
+ await runAuthSubcommand(['login', ...rawArgs.slice(1)])
1184
+ } catch (err) {
1185
+ const message =
1186
+ err instanceof Error ? err.message : 'Failed to run login command'
1187
+ process.stderr.write(`${message}\n`)
1188
+ process.exit(1)
1189
+ }
1190
+ return
1191
+ }
1192
+ if (rawArgs[0] === 'logout') {
1193
+ try {
1194
+ await runAuthSubcommand(['logout', ...rawArgs.slice(1)])
1195
+ } catch (err) {
1196
+ const message =
1197
+ err instanceof Error ? err.message : 'Failed to run logout command'
1198
+ process.stderr.write(`${message}\n`)
1199
+ process.exit(1)
1200
+ }
1201
+ return
1202
+ }
1203
+ if (rawArgs[0] === 'profile') {
1204
+ try {
1205
+ await runProfileSubcommand(rawArgs.slice(1))
1206
+ } catch (err) {
1207
+ const message =
1208
+ err instanceof Error ? err.message : 'Failed to run profile command'
1209
+ process.stderr.write(`${message}\n`)
1210
+ process.exit(1)
1211
+ }
1212
+ return
1213
+ }
1214
+
1215
+ const scopeDir = resolveScopeDir()
1023
1216
 
1024
1217
  const { command, flags, positional } = parseArgs(process.argv)
1025
1218
 
@@ -1038,9 +1231,21 @@ async function main() {
1038
1231
  return
1039
1232
  }
1040
1233
 
1234
+ let openCloudAuth = null
1235
+ if (command === 'open') {
1236
+ try {
1237
+ openCloudAuth = await ensureOpenCloudCredentials(flags, scopeDir)
1238
+ } catch (err) {
1239
+ error(
1240
+ err instanceof Error
1241
+ ? err.message
1242
+ : 'Failed to resolve cloud authentication for open command.'
1243
+ )
1244
+ }
1245
+ }
1246
+
1041
1247
  let resolvedSession
1042
1248
  let resolvedName
1043
- const scopeDir = resolveScopeDir()
1044
1249
  try {
1045
1250
  resolvedSession = resolveSession(flags, scopeDir)
1046
1251
  resolvedName = resolveName(flags, resolvedSession.session)
@@ -1080,10 +1285,16 @@ async function main() {
1080
1285
  delete flags.name
1081
1286
  delete flags.session
1082
1287
  delete flags.all
1288
+ delete flags['api-key']
1289
+ delete flags['access-token']
1083
1290
 
1084
1291
  const request = buildRequest(command, flags, positional)
1085
1292
  if (command === 'open') {
1086
1293
  request.args.name = name
1294
+ const cloudAuthPayload = buildOpenCloudAuthPayload(openCloudAuth)
1295
+ if (cloudAuthPayload) {
1296
+ request.args['cloud-auth'] = cloudAuthPayload
1297
+ }
1087
1298
  }
1088
1299
 
1089
1300
  if (!(await isServerHealthy(runtimeSession))) {
@@ -0,0 +1,168 @@
1
+ import { O as OpensteerAuthScheme } from './types-BxiRblC7.js';
2
+
3
+ type ActionFailureCode = 'TARGET_NOT_FOUND' | 'TARGET_UNAVAILABLE' | 'TARGET_STALE' | 'TARGET_AMBIGUOUS' | 'BLOCKED_BY_INTERCEPTOR' | 'NOT_VISIBLE' | 'NOT_ENABLED' | 'NOT_EDITABLE' | 'INVALID_TARGET' | 'INVALID_OPTIONS' | 'ACTION_TIMEOUT' | 'UNKNOWN';
4
+ type ActionFailureClassificationSource = 'typed_error' | 'playwright_call_log' | 'dom_probe' | 'message_heuristic' | 'unknown';
5
+ interface ActionFailureBlocker {
6
+ tag: string;
7
+ id: string | null;
8
+ classes: string[];
9
+ role: string | null;
10
+ text: string | null;
11
+ }
12
+ interface ActionFailureDetails {
13
+ blocker?: ActionFailureBlocker;
14
+ observation?: string;
15
+ }
16
+ interface ActionFailure {
17
+ code: ActionFailureCode;
18
+ message: string;
19
+ retryable: boolean;
20
+ classificationSource: ActionFailureClassificationSource;
21
+ details?: ActionFailureDetails;
22
+ }
23
+
24
+ type CloudActionMethod = 'goto' | 'snapshot' | 'state' | 'click' | 'dblclick' | 'rightclick' | 'hover' | 'input' | 'select' | 'scroll' | 'tabs' | 'newTab' | 'switchTab' | 'closeTab' | 'getCookies' | 'setCookie' | 'clearCookies' | 'pressKey' | 'type' | 'getElementText' | 'getElementValue' | 'getElementAttributes' | 'getElementBoundingBox' | 'getHtml' | 'getTitle' | 'waitForText' | 'extract' | 'extractFromPlan' | 'clearCache' | 'uploadFile' | 'exportCookies' | 'importCookies' | 'screenshot';
25
+ type CloudErrorCode = 'CLOUD_AUTH_FAILED' | 'CLOUD_SESSION_NOT_FOUND' | 'CLOUD_SESSION_CLOSED' | 'CLOUD_UNSUPPORTED_METHOD' | 'CLOUD_INVALID_REQUEST' | 'CLOUD_MODEL_NOT_ALLOWED' | 'CLOUD_ACTION_FAILED' | 'CLOUD_CAPACITY_EXHAUSTED' | 'CLOUD_RUNTIME_UNAVAILABLE' | 'CLOUD_RUNTIME_MISMATCH' | 'CLOUD_SESSION_STALE' | 'CLOUD_CONTROL_PLANE_ERROR' | 'CLOUD_CONTRACT_MISMATCH' | 'CLOUD_PROXY_UNAVAILABLE' | 'CLOUD_PROXY_REQUIRED' | 'CLOUD_BILLING_LIMIT_REACHED' | 'CLOUD_RATE_LIMITED' | 'CLOUD_BROWSER_PROFILE_NOT_FOUND' | 'CLOUD_BROWSER_PROFILE_BUSY' | 'CLOUD_BROWSER_PROFILE_DISABLED' | 'CLOUD_BROWSER_PROFILE_PROXY_UNAVAILABLE' | 'CLOUD_BROWSER_PROFILE_SYNC_FAILED' | 'CLOUD_INTERNAL';
26
+ declare const cloudSessionContractVersion: "v3";
27
+ type CloudSessionContractVersion = typeof cloudSessionContractVersion;
28
+ type CloudSessionSourceType = 'agent-thread' | 'agent-run' | 'local-cloud' | 'manual';
29
+ interface CloudBrowserProfileLaunchPreference {
30
+ profileId: string;
31
+ reuseIfActive?: boolean;
32
+ }
33
+ interface CloudSessionLaunchConfig {
34
+ browserProfile?: CloudBrowserProfileLaunchPreference;
35
+ }
36
+ interface CloudSessionCreateRequest {
37
+ cloudSessionContractVersion: CloudSessionContractVersion;
38
+ sourceType: 'local-cloud';
39
+ clientSessionHint: string;
40
+ localRunId: string;
41
+ name?: string;
42
+ model?: string;
43
+ launchContext?: Record<string, unknown>;
44
+ launchConfig?: CloudSessionLaunchConfig;
45
+ }
46
+ interface CloudSessionSummary {
47
+ sessionId: string;
48
+ workspaceId: string;
49
+ state: string;
50
+ createdAt: number;
51
+ sourceType: CloudSessionSourceType;
52
+ sourceRef?: string;
53
+ label?: string;
54
+ }
55
+ interface CloudSessionCreateResponse {
56
+ sessionId: string;
57
+ actionWsUrl: string;
58
+ cdpWsUrl: string;
59
+ actionToken: string;
60
+ cdpToken: string;
61
+ expiresAt?: number;
62
+ cloudSessionUrl: string;
63
+ cloudSession: CloudSessionSummary;
64
+ }
65
+ interface CloudSelectorCacheImportEntry {
66
+ namespace: string;
67
+ siteOrigin: string;
68
+ method: string;
69
+ descriptionHash: string;
70
+ path: unknown;
71
+ schemaHash?: string;
72
+ createdAt: number;
73
+ updatedAt: number;
74
+ }
75
+ interface CloudSelectorCacheImportRequest {
76
+ entries: CloudSelectorCacheImportEntry[];
77
+ }
78
+ interface CloudSelectorCacheImportResponse {
79
+ imported: number;
80
+ inserted: number;
81
+ updated: number;
82
+ skipped: number;
83
+ }
84
+ interface CloudActionRequest {
85
+ id: number;
86
+ method: CloudActionMethod;
87
+ args: Record<string, unknown>;
88
+ sessionId: string;
89
+ token: string;
90
+ }
91
+ interface CloudActionSuccess {
92
+ id: number;
93
+ ok: true;
94
+ result: unknown;
95
+ }
96
+ interface CloudActionFailure {
97
+ id: number;
98
+ ok: false;
99
+ error: string;
100
+ code: CloudErrorCode;
101
+ details?: CloudActionFailureDetails;
102
+ }
103
+ type CloudActionResponse = CloudActionSuccess | CloudActionFailure;
104
+ interface CloudActionFailureDetails {
105
+ actionFailure?: ActionFailure;
106
+ }
107
+ type BrowserProfileStatus = 'active' | 'archived' | 'error';
108
+ type BrowserProfileProxyPolicy = 'strict_sticky';
109
+ type CloudFingerprintMode = 'off' | 'auto';
110
+ type BrowserProfileArchiveFormat = 'tar.gz';
111
+ interface BrowserProfileDescriptor {
112
+ profileId: string;
113
+ teamId: string;
114
+ ownerUserId: string;
115
+ name: string;
116
+ status: BrowserProfileStatus;
117
+ proxyPolicy: BrowserProfileProxyPolicy;
118
+ stickyProxyId?: string;
119
+ proxyCountryCode?: string;
120
+ proxyRegion?: string;
121
+ proxyCity?: string;
122
+ fingerprintMode: CloudFingerprintMode;
123
+ fingerprintHash?: string;
124
+ activeSessionId?: string;
125
+ lastSessionId?: string;
126
+ lastLaunchedAt?: number;
127
+ latestRevision?: number;
128
+ latestStorageId?: string;
129
+ latestSizeBytes?: number;
130
+ latestArchiveSha256?: string;
131
+ latestArchiveFormat?: BrowserProfileArchiveFormat;
132
+ createdAt: number;
133
+ updatedAt: number;
134
+ lastError?: string;
135
+ }
136
+ interface BrowserProfileListResponse {
137
+ profiles: BrowserProfileDescriptor[];
138
+ nextCursor?: string;
139
+ }
140
+ interface BrowserProfileCreateRequest {
141
+ name: string;
142
+ proxy?: {
143
+ proxyId?: string;
144
+ countryCode?: string;
145
+ region?: string;
146
+ city?: string;
147
+ };
148
+ fingerprint?: {
149
+ mode?: CloudFingerprintMode;
150
+ };
151
+ }
152
+
153
+ interface BrowserProfileListRequest {
154
+ cursor?: string;
155
+ limit?: number;
156
+ status?: BrowserProfileStatus;
157
+ }
158
+ declare class BrowserProfileClient {
159
+ private readonly baseUrl;
160
+ private readonly key;
161
+ private readonly authScheme;
162
+ constructor(baseUrl: string, key: string, authScheme?: OpensteerAuthScheme);
163
+ list(request?: BrowserProfileListRequest): Promise<BrowserProfileListResponse>;
164
+ get(profileId: string): Promise<BrowserProfileDescriptor>;
165
+ create(request: BrowserProfileCreateRequest): Promise<BrowserProfileDescriptor>;
166
+ }
167
+
168
+ export { type ActionFailure as A, type BrowserProfileStatus as B, type CloudErrorCode as C, type CloudSessionSourceType as D, type CloudSessionSummary as E, cloudSessionContractVersion as F, type BrowserProfileListRequest as a, type BrowserProfileListResponse as b, type BrowserProfileCreateRequest as c, type BrowserProfileDescriptor as d, type ActionFailureCode as e, type CloudActionFailureDetails as f, type CloudSessionCreateRequest as g, type CloudSessionCreateResponse as h, type CloudSelectorCacheImportRequest as i, type CloudSelectorCacheImportResponse as j, type CloudActionMethod as k, type CloudSelectorCacheImportEntry as l, type ActionFailureBlocker as m, type ActionFailureClassificationSource as n, type ActionFailureDetails as o, type BrowserProfileArchiveFormat as p, BrowserProfileClient as q, type BrowserProfileProxyPolicy as r, type CloudActionFailure as s, type CloudActionRequest as t, type CloudActionResponse as u, type CloudActionSuccess as v, type CloudBrowserProfileLaunchPreference as w, type CloudFingerprintMode as x, type CloudSessionContractVersion as y, type CloudSessionLaunchConfig as z };