opensteer 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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,57 @@ 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 host (`baseUrl` +
186
+ `siteUrl`). The CLI also remembers the last selected cloud host, so
187
+ `opensteer auth status`, `opensteer auth logout`, and other cloud commands
188
+ reuse it by default unless `--base-url`, `--site-url`, or env vars select a
189
+ different host.
190
+
154
191
  - `OPENSTEER_BASE_URL` overrides the default cloud host
192
+ - `OPENSTEER_ACCESS_TOKEN` provides bearer auth for cloud commands
155
193
  - `OPENSTEER_AUTH_SCHEME` supports `api-key` (default) or `bearer`
194
+ - Credential precedence: explicit flags > environment variables > saved machine login
195
+ - `OPENSTEER_CLOUD_PROFILE_ID` optionally launches into a specific cloud browser profile
196
+ - `OPENSTEER_CLOUD_PROFILE_REUSE_IF_ACTIVE` (`true|false`) optionally reuses an active profile session
156
197
  - `cloud: true` or a `cloud` options object overrides `OPENSTEER_MODE`
157
198
  - Cloud mode is fail-fast (no automatic fallback to local)
158
199
  - `Opensteer.from(page)`, `uploadFile`, `exportCookies`, and `importCookies` are local-only
159
200
 
201
+ Select a cloud browser profile in SDK:
202
+
203
+ ```ts
204
+ const opensteer = new Opensteer({
205
+ cloud: {
206
+ accessToken: process.env.OPENSTEER_ACCESS_TOKEN,
207
+ browserProfile: {
208
+ profileId: "bp_123",
209
+ reuseIfActive: true,
210
+ },
211
+ },
212
+ });
213
+ ```
214
+
215
+ Sync local profile cookies into a cloud profile:
216
+
217
+ ```bash
218
+ opensteer profile sync \
219
+ --from-profile-dir ~/Library/Application\ Support/Google/Chrome/Default \
220
+ --to-profile-id bp_123 \
221
+ --domain github.com
222
+ ```
223
+
160
224
  ## Resolution and Replay
161
225
 
162
226
  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,9 +1144,12 @@ 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
1152
+ OPENSTEER_CLOUD_SITE_URL Override cloud site URL for device login endpoints
1005
1153
  OPENSTEER_AUTH_SCHEME Cloud auth scheme: api-key (default) or bearer
1006
1154
  OPENSTEER_REMOTE_ANNOUNCE Cloud session announcement policy: always (default), off, tty
1007
1155
  `)
@@ -1020,6 +1168,52 @@ async function main() {
1020
1168
  }
1021
1169
  return
1022
1170
  }
1171
+ if (rawArgs[0] === 'auth') {
1172
+ try {
1173
+ await runAuthSubcommand(rawArgs.slice(1))
1174
+ } catch (err) {
1175
+ const message =
1176
+ err instanceof Error ? err.message : 'Failed to run auth command'
1177
+ process.stderr.write(`${message}\n`)
1178
+ process.exit(1)
1179
+ }
1180
+ return
1181
+ }
1182
+ if (rawArgs[0] === 'login') {
1183
+ try {
1184
+ await runAuthSubcommand(['login', ...rawArgs.slice(1)])
1185
+ } catch (err) {
1186
+ const message =
1187
+ err instanceof Error ? err.message : 'Failed to run login command'
1188
+ process.stderr.write(`${message}\n`)
1189
+ process.exit(1)
1190
+ }
1191
+ return
1192
+ }
1193
+ if (rawArgs[0] === 'logout') {
1194
+ try {
1195
+ await runAuthSubcommand(['logout', ...rawArgs.slice(1)])
1196
+ } catch (err) {
1197
+ const message =
1198
+ err instanceof Error ? err.message : 'Failed to run logout command'
1199
+ process.stderr.write(`${message}\n`)
1200
+ process.exit(1)
1201
+ }
1202
+ return
1203
+ }
1204
+ if (rawArgs[0] === 'profile') {
1205
+ try {
1206
+ await runProfileSubcommand(rawArgs.slice(1))
1207
+ } catch (err) {
1208
+ const message =
1209
+ err instanceof Error ? err.message : 'Failed to run profile command'
1210
+ process.stderr.write(`${message}\n`)
1211
+ process.exit(1)
1212
+ }
1213
+ return
1214
+ }
1215
+
1216
+ const scopeDir = resolveScopeDir()
1023
1217
 
1024
1218
  const { command, flags, positional } = parseArgs(process.argv)
1025
1219
 
@@ -1038,9 +1232,21 @@ async function main() {
1038
1232
  return
1039
1233
  }
1040
1234
 
1235
+ let openCloudAuth = null
1236
+ if (command === 'open') {
1237
+ try {
1238
+ openCloudAuth = await ensureOpenCloudCredentials(flags, scopeDir)
1239
+ } catch (err) {
1240
+ error(
1241
+ err instanceof Error
1242
+ ? err.message
1243
+ : 'Failed to resolve cloud authentication for open command.'
1244
+ )
1245
+ }
1246
+ }
1247
+
1041
1248
  let resolvedSession
1042
1249
  let resolvedName
1043
- const scopeDir = resolveScopeDir()
1044
1250
  try {
1045
1251
  resolvedSession = resolveSession(flags, scopeDir)
1046
1252
  resolvedName = resolveName(flags, resolvedSession.session)
@@ -1080,10 +1286,16 @@ async function main() {
1080
1286
  delete flags.name
1081
1287
  delete flags.session
1082
1288
  delete flags.all
1289
+ delete flags['api-key']
1290
+ delete flags['access-token']
1083
1291
 
1084
1292
  const request = buildRequest(command, flags, positional)
1085
1293
  if (command === 'open') {
1086
1294
  request.args.name = name
1295
+ const cloudAuthPayload = buildOpenCloudAuthPayload(openCloudAuth)
1296
+ if (cloudAuthPayload) {
1297
+ request.args['cloud-auth'] = cloudAuthPayload
1298
+ }
1087
1299
  }
1088
1300
 
1089
1301
  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 };