opensteer 0.4.6 → 0.4.8
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 +6 -3
- package/README.md +9 -4
- package/bin/opensteer.mjs +5 -3
- package/dist/{chunk-MGZ3QEYT.js → chunk-GQ7HNCM2.js} +544 -245
- package/dist/cli/server.cjs +540 -241
- package/dist/cli/server.js +3 -2
- package/dist/index.cjs +550 -250
- package/dist/index.d.cts +64 -41
- package/dist/index.d.ts +64 -41
- package/dist/index.js +13 -11
- package/package.json +73 -80
|
@@ -4936,33 +4936,36 @@ var OpensteerActionError = class extends Error {
|
|
|
4936
4936
|
}
|
|
4937
4937
|
};
|
|
4938
4938
|
|
|
4939
|
-
// src/
|
|
4940
|
-
var
|
|
4939
|
+
// src/cloud/contracts.ts
|
|
4940
|
+
var cloudSessionContractVersion = "v3";
|
|
4941
|
+
|
|
4942
|
+
// src/cloud/errors.ts
|
|
4943
|
+
var OpensteerCloudError = class extends Error {
|
|
4941
4944
|
code;
|
|
4942
4945
|
status;
|
|
4943
4946
|
details;
|
|
4944
4947
|
constructor(code, message, status, details) {
|
|
4945
4948
|
super(message);
|
|
4946
|
-
this.name = "
|
|
4949
|
+
this.name = "OpensteerCloudError";
|
|
4947
4950
|
this.code = code;
|
|
4948
4951
|
this.status = status;
|
|
4949
4952
|
this.details = details;
|
|
4950
4953
|
}
|
|
4951
4954
|
};
|
|
4952
|
-
function
|
|
4953
|
-
return new
|
|
4954
|
-
"
|
|
4955
|
-
message || `${method} is not supported in
|
|
4955
|
+
function cloudUnsupportedMethodError(method, message) {
|
|
4956
|
+
return new OpensteerCloudError(
|
|
4957
|
+
"CLOUD_UNSUPPORTED_METHOD",
|
|
4958
|
+
message || `${method} is not supported in cloud mode.`
|
|
4956
4959
|
);
|
|
4957
4960
|
}
|
|
4958
|
-
function
|
|
4959
|
-
return new
|
|
4960
|
-
"
|
|
4961
|
-
"
|
|
4961
|
+
function cloudNotLaunchedError() {
|
|
4962
|
+
return new OpensteerCloudError(
|
|
4963
|
+
"CLOUD_SESSION_NOT_FOUND",
|
|
4964
|
+
"Cloud session is not connected. Call launch() first."
|
|
4962
4965
|
);
|
|
4963
4966
|
}
|
|
4964
4967
|
|
|
4965
|
-
// src/
|
|
4968
|
+
// src/cloud/action-ws-client.ts
|
|
4966
4969
|
import WebSocket from "ws";
|
|
4967
4970
|
var ActionWsClient = class _ActionWsClient {
|
|
4968
4971
|
ws;
|
|
@@ -4980,18 +4983,18 @@ var ActionWsClient = class _ActionWsClient {
|
|
|
4980
4983
|
});
|
|
4981
4984
|
ws.on("error", (error) => {
|
|
4982
4985
|
this.rejectAll(
|
|
4983
|
-
new
|
|
4984
|
-
"
|
|
4985
|
-
`
|
|
4986
|
+
new OpensteerCloudError(
|
|
4987
|
+
"CLOUD_TRANSPORT_ERROR",
|
|
4988
|
+
`Cloud action websocket error: ${error.message}`
|
|
4986
4989
|
)
|
|
4987
4990
|
);
|
|
4988
4991
|
});
|
|
4989
4992
|
ws.on("close", () => {
|
|
4990
4993
|
this.closed = true;
|
|
4991
4994
|
this.rejectAll(
|
|
4992
|
-
new
|
|
4993
|
-
"
|
|
4994
|
-
"
|
|
4995
|
+
new OpensteerCloudError(
|
|
4996
|
+
"CLOUD_SESSION_CLOSED",
|
|
4997
|
+
"Cloud action websocket closed."
|
|
4995
4998
|
)
|
|
4996
4999
|
);
|
|
4997
5000
|
});
|
|
@@ -5003,8 +5006,8 @@ var ActionWsClient = class _ActionWsClient {
|
|
|
5003
5006
|
ws.once("open", () => resolve());
|
|
5004
5007
|
ws.once("error", (error) => {
|
|
5005
5008
|
reject(
|
|
5006
|
-
new
|
|
5007
|
-
"
|
|
5009
|
+
new OpensteerCloudError(
|
|
5010
|
+
"CLOUD_TRANSPORT_ERROR",
|
|
5008
5011
|
`Failed to connect action websocket: ${error.message}`
|
|
5009
5012
|
)
|
|
5010
5013
|
);
|
|
@@ -5014,9 +5017,9 @@ var ActionWsClient = class _ActionWsClient {
|
|
|
5014
5017
|
}
|
|
5015
5018
|
async request(method, args) {
|
|
5016
5019
|
if (this.closed || this.ws.readyState !== WebSocket.OPEN) {
|
|
5017
|
-
throw new
|
|
5018
|
-
"
|
|
5019
|
-
"
|
|
5020
|
+
throw new OpensteerCloudError(
|
|
5021
|
+
"CLOUD_SESSION_CLOSED",
|
|
5022
|
+
"Cloud action websocket is closed."
|
|
5020
5023
|
);
|
|
5021
5024
|
}
|
|
5022
5025
|
const id = this.nextRequestId;
|
|
@@ -5035,8 +5038,8 @@ var ActionWsClient = class _ActionWsClient {
|
|
|
5035
5038
|
this.ws.send(JSON.stringify(payload));
|
|
5036
5039
|
} catch (error) {
|
|
5037
5040
|
this.pending.delete(id);
|
|
5038
|
-
const message = error instanceof Error ? error.message : "Failed to send
|
|
5039
|
-
throw new
|
|
5041
|
+
const message = error instanceof Error ? error.message : "Failed to send cloud action request.";
|
|
5042
|
+
throw new OpensteerCloudError("CLOUD_TRANSPORT_ERROR", message);
|
|
5040
5043
|
}
|
|
5041
5044
|
return await resultPromise;
|
|
5042
5045
|
}
|
|
@@ -5054,9 +5057,9 @@ var ActionWsClient = class _ActionWsClient {
|
|
|
5054
5057
|
parsed = JSON.parse(rawDataToUtf8(raw));
|
|
5055
5058
|
} catch {
|
|
5056
5059
|
this.rejectAll(
|
|
5057
|
-
new
|
|
5058
|
-
"
|
|
5059
|
-
"Invalid
|
|
5060
|
+
new OpensteerCloudError(
|
|
5061
|
+
"CLOUD_TRANSPORT_ERROR",
|
|
5062
|
+
"Invalid cloud action response payload."
|
|
5060
5063
|
)
|
|
5061
5064
|
);
|
|
5062
5065
|
return;
|
|
@@ -5069,7 +5072,7 @@ var ActionWsClient = class _ActionWsClient {
|
|
|
5069
5072
|
return;
|
|
5070
5073
|
}
|
|
5071
5074
|
pending.reject(
|
|
5072
|
-
new
|
|
5075
|
+
new OpensteerCloudError(
|
|
5073
5076
|
parsed.code,
|
|
5074
5077
|
parsed.error,
|
|
5075
5078
|
void 0,
|
|
@@ -5097,7 +5100,7 @@ function withTokenQuery(wsUrl, token) {
|
|
|
5097
5100
|
return url.toString();
|
|
5098
5101
|
}
|
|
5099
5102
|
|
|
5100
|
-
// src/
|
|
5103
|
+
// src/cloud/local-cache-sync.ts
|
|
5101
5104
|
import fs2 from "fs";
|
|
5102
5105
|
import path3 from "path";
|
|
5103
5106
|
function collectLocalSelectorCacheEntries(storage) {
|
|
@@ -5221,26 +5224,26 @@ function dedupeNewest(entries) {
|
|
|
5221
5224
|
return [...byKey.values()];
|
|
5222
5225
|
}
|
|
5223
5226
|
|
|
5224
|
-
// src/
|
|
5227
|
+
// src/cloud/cdp-client.ts
|
|
5225
5228
|
import {
|
|
5226
5229
|
chromium
|
|
5227
5230
|
} from "playwright";
|
|
5228
|
-
var
|
|
5231
|
+
var CloudCdpClient = class {
|
|
5229
5232
|
async connect(args) {
|
|
5230
5233
|
const endpoint = withTokenQuery2(args.wsUrl, args.token);
|
|
5231
5234
|
let browser;
|
|
5232
5235
|
try {
|
|
5233
5236
|
browser = await chromium.connectOverCDP(endpoint);
|
|
5234
5237
|
} catch (error) {
|
|
5235
|
-
const message = error instanceof Error ? error.message : "Failed to connect to
|
|
5236
|
-
throw new
|
|
5238
|
+
const message = error instanceof Error ? error.message : "Failed to connect to cloud CDP endpoint.";
|
|
5239
|
+
throw new OpensteerCloudError("CLOUD_TRANSPORT_ERROR", message);
|
|
5237
5240
|
}
|
|
5238
5241
|
const context = browser.contexts()[0];
|
|
5239
5242
|
if (!context) {
|
|
5240
5243
|
await browser.close();
|
|
5241
|
-
throw new
|
|
5242
|
-
"
|
|
5243
|
-
"
|
|
5244
|
+
throw new OpensteerCloudError(
|
|
5245
|
+
"CLOUD_INTERNAL",
|
|
5246
|
+
"Cloud browser returned no context."
|
|
5244
5247
|
);
|
|
5245
5248
|
}
|
|
5246
5249
|
const page = context.pages()[0] || await context.newPage();
|
|
@@ -5253,9 +5256,9 @@ function withTokenQuery2(wsUrl, token) {
|
|
|
5253
5256
|
return url.toString();
|
|
5254
5257
|
}
|
|
5255
5258
|
|
|
5256
|
-
// src/
|
|
5259
|
+
// src/cloud/session-client.ts
|
|
5257
5260
|
var CACHE_IMPORT_BATCH_SIZE = 200;
|
|
5258
|
-
var
|
|
5261
|
+
var CloudSessionClient = class {
|
|
5259
5262
|
baseUrl;
|
|
5260
5263
|
key;
|
|
5261
5264
|
authScheme;
|
|
@@ -5276,7 +5279,17 @@ var RemoteSessionClient = class {
|
|
|
5276
5279
|
if (!response.ok) {
|
|
5277
5280
|
throw await parseHttpError(response);
|
|
5278
5281
|
}
|
|
5279
|
-
|
|
5282
|
+
let body;
|
|
5283
|
+
try {
|
|
5284
|
+
body = await response.json();
|
|
5285
|
+
} catch {
|
|
5286
|
+
throw new OpensteerCloudError(
|
|
5287
|
+
"CLOUD_CONTRACT_MISMATCH",
|
|
5288
|
+
"Invalid cloud session create response: expected a JSON object.",
|
|
5289
|
+
response.status
|
|
5290
|
+
);
|
|
5291
|
+
}
|
|
5292
|
+
return parseCreateResponse(body, response.status);
|
|
5280
5293
|
}
|
|
5281
5294
|
async close(sessionId) {
|
|
5282
5295
|
const response = await fetch(`${this.baseUrl}/sessions/${sessionId}`, {
|
|
@@ -5335,6 +5348,134 @@ var RemoteSessionClient = class {
|
|
|
5335
5348
|
function normalizeBaseUrl(baseUrl) {
|
|
5336
5349
|
return baseUrl.replace(/\/+$/, "");
|
|
5337
5350
|
}
|
|
5351
|
+
function parseCreateResponse(body, status) {
|
|
5352
|
+
const root = requireObject(
|
|
5353
|
+
body,
|
|
5354
|
+
"Invalid cloud session create response: expected a JSON object.",
|
|
5355
|
+
status
|
|
5356
|
+
);
|
|
5357
|
+
const sessionId = requireString(root, "sessionId", status);
|
|
5358
|
+
const actionWsUrl = requireString(root, "actionWsUrl", status);
|
|
5359
|
+
const cdpWsUrl = requireString(root, "cdpWsUrl", status);
|
|
5360
|
+
const actionToken = requireString(root, "actionToken", status);
|
|
5361
|
+
const cdpToken = requireString(root, "cdpToken", status);
|
|
5362
|
+
const cloudSessionUrl = requireString(root, "cloudSessionUrl", status);
|
|
5363
|
+
const cloudSessionRoot = requireObject(
|
|
5364
|
+
root.cloudSession,
|
|
5365
|
+
"Invalid cloud session create response: cloudSession must be an object.",
|
|
5366
|
+
status
|
|
5367
|
+
);
|
|
5368
|
+
const cloudSession = {
|
|
5369
|
+
sessionId: requireString(cloudSessionRoot, "sessionId", status, "cloudSession"),
|
|
5370
|
+
workspaceId: requireString(
|
|
5371
|
+
cloudSessionRoot,
|
|
5372
|
+
"workspaceId",
|
|
5373
|
+
status,
|
|
5374
|
+
"cloudSession"
|
|
5375
|
+
),
|
|
5376
|
+
state: requireString(cloudSessionRoot, "state", status, "cloudSession"),
|
|
5377
|
+
createdAt: requireNumber(cloudSessionRoot, "createdAt", status, "cloudSession"),
|
|
5378
|
+
sourceType: requireSourceType(cloudSessionRoot, "sourceType", status, "cloudSession"),
|
|
5379
|
+
sourceRef: optionalString(cloudSessionRoot, "sourceRef", status, "cloudSession"),
|
|
5380
|
+
label: optionalString(cloudSessionRoot, "label", status, "cloudSession")
|
|
5381
|
+
};
|
|
5382
|
+
const expiresAt = optionalNumber(root, "expiresAt", status);
|
|
5383
|
+
return {
|
|
5384
|
+
sessionId,
|
|
5385
|
+
actionWsUrl,
|
|
5386
|
+
cdpWsUrl,
|
|
5387
|
+
actionToken,
|
|
5388
|
+
cdpToken,
|
|
5389
|
+
expiresAt,
|
|
5390
|
+
cloudSessionUrl,
|
|
5391
|
+
cloudSession
|
|
5392
|
+
};
|
|
5393
|
+
}
|
|
5394
|
+
function requireObject(value, message, status) {
|
|
5395
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
5396
|
+
throw new OpensteerCloudError("CLOUD_CONTRACT_MISMATCH", message, status);
|
|
5397
|
+
}
|
|
5398
|
+
return value;
|
|
5399
|
+
}
|
|
5400
|
+
function requireString(source, field, status, parent) {
|
|
5401
|
+
const value = source[field];
|
|
5402
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
5403
|
+
throw new OpensteerCloudError(
|
|
5404
|
+
"CLOUD_CONTRACT_MISMATCH",
|
|
5405
|
+
`Invalid cloud session create response: ${formatFieldPath(
|
|
5406
|
+
field,
|
|
5407
|
+
parent
|
|
5408
|
+
)} must be a non-empty string.`,
|
|
5409
|
+
status
|
|
5410
|
+
);
|
|
5411
|
+
}
|
|
5412
|
+
return value;
|
|
5413
|
+
}
|
|
5414
|
+
function requireNumber(source, field, status, parent) {
|
|
5415
|
+
const value = source[field];
|
|
5416
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
5417
|
+
throw new OpensteerCloudError(
|
|
5418
|
+
"CLOUD_CONTRACT_MISMATCH",
|
|
5419
|
+
`Invalid cloud session create response: ${formatFieldPath(
|
|
5420
|
+
field,
|
|
5421
|
+
parent
|
|
5422
|
+
)} must be a finite number.`,
|
|
5423
|
+
status
|
|
5424
|
+
);
|
|
5425
|
+
}
|
|
5426
|
+
return value;
|
|
5427
|
+
}
|
|
5428
|
+
function optionalString(source, field, status, parent) {
|
|
5429
|
+
const value = source[field];
|
|
5430
|
+
if (value == null) {
|
|
5431
|
+
return void 0;
|
|
5432
|
+
}
|
|
5433
|
+
if (typeof value !== "string") {
|
|
5434
|
+
throw new OpensteerCloudError(
|
|
5435
|
+
"CLOUD_CONTRACT_MISMATCH",
|
|
5436
|
+
`Invalid cloud session create response: ${formatFieldPath(
|
|
5437
|
+
field,
|
|
5438
|
+
parent
|
|
5439
|
+
)} must be a string when present.`,
|
|
5440
|
+
status
|
|
5441
|
+
);
|
|
5442
|
+
}
|
|
5443
|
+
return value;
|
|
5444
|
+
}
|
|
5445
|
+
function optionalNumber(source, field, status, parent) {
|
|
5446
|
+
const value = source[field];
|
|
5447
|
+
if (value == null) {
|
|
5448
|
+
return void 0;
|
|
5449
|
+
}
|
|
5450
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
5451
|
+
throw new OpensteerCloudError(
|
|
5452
|
+
"CLOUD_CONTRACT_MISMATCH",
|
|
5453
|
+
`Invalid cloud session create response: ${formatFieldPath(
|
|
5454
|
+
field,
|
|
5455
|
+
parent
|
|
5456
|
+
)} must be a finite number when present.`,
|
|
5457
|
+
status
|
|
5458
|
+
);
|
|
5459
|
+
}
|
|
5460
|
+
return value;
|
|
5461
|
+
}
|
|
5462
|
+
function requireSourceType(source, field, status, parent) {
|
|
5463
|
+
const value = source[field];
|
|
5464
|
+
if (value === "agent-thread" || value === "agent-run" || value === "local-cloud" || value === "manual") {
|
|
5465
|
+
return value;
|
|
5466
|
+
}
|
|
5467
|
+
throw new OpensteerCloudError(
|
|
5468
|
+
"CLOUD_CONTRACT_MISMATCH",
|
|
5469
|
+
`Invalid cloud session create response: ${formatFieldPath(
|
|
5470
|
+
field,
|
|
5471
|
+
parent
|
|
5472
|
+
)} must be one of "agent-thread", "agent-run", "local-cloud", or "manual".`,
|
|
5473
|
+
status
|
|
5474
|
+
);
|
|
5475
|
+
}
|
|
5476
|
+
function formatFieldPath(field, parent) {
|
|
5477
|
+
return parent ? `"${parent}.${field}"` : `"${field}"`;
|
|
5478
|
+
}
|
|
5338
5479
|
function zeroImportResponse() {
|
|
5339
5480
|
return {
|
|
5340
5481
|
imported: 0,
|
|
@@ -5358,19 +5499,19 @@ async function parseHttpError(response) {
|
|
|
5358
5499
|
} catch {
|
|
5359
5500
|
body = null;
|
|
5360
5501
|
}
|
|
5361
|
-
const code = typeof body?.code === "string" ?
|
|
5362
|
-
const message = typeof body?.error === "string" ? body.error : `
|
|
5363
|
-
return new
|
|
5502
|
+
const code = typeof body?.code === "string" ? toCloudErrorCode(body.code) : "CLOUD_TRANSPORT_ERROR";
|
|
5503
|
+
const message = typeof body?.error === "string" ? body.error : `Cloud request failed with status ${response.status}.`;
|
|
5504
|
+
return new OpensteerCloudError(code, message, response.status, body?.details);
|
|
5364
5505
|
}
|
|
5365
|
-
function
|
|
5366
|
-
if (code === "
|
|
5506
|
+
function toCloudErrorCode(code) {
|
|
5507
|
+
if (code === "CLOUD_AUTH_FAILED" || code === "CLOUD_SESSION_NOT_FOUND" || code === "CLOUD_SESSION_CLOSED" || code === "CLOUD_UNSUPPORTED_METHOD" || code === "CLOUD_INVALID_REQUEST" || code === "CLOUD_MODEL_NOT_ALLOWED" || code === "CLOUD_ACTION_FAILED" || code === "CLOUD_INTERNAL" || code === "CLOUD_CAPACITY_EXHAUSTED" || code === "CLOUD_RUNTIME_UNAVAILABLE" || code === "CLOUD_RUNTIME_MISMATCH" || code === "CLOUD_SESSION_STALE" || code === "CLOUD_CONTRACT_MISMATCH" || code === "CLOUD_CONTROL_PLANE_ERROR") {
|
|
5367
5508
|
return code;
|
|
5368
5509
|
}
|
|
5369
|
-
return "
|
|
5510
|
+
return "CLOUD_TRANSPORT_ERROR";
|
|
5370
5511
|
}
|
|
5371
5512
|
|
|
5372
5513
|
// src/opensteer.ts
|
|
5373
|
-
import { createHash } from "crypto";
|
|
5514
|
+
import { createHash, randomUUID as randomUUID2 } from "crypto";
|
|
5374
5515
|
|
|
5375
5516
|
// src/browser/pool.ts
|
|
5376
5517
|
import {
|
|
@@ -5786,7 +5927,7 @@ var BrowserPool = class {
|
|
|
5786
5927
|
const context = contexts[0];
|
|
5787
5928
|
const pages = context.pages();
|
|
5788
5929
|
const page = pages.length > 0 ? pages[0] : await context.newPage();
|
|
5789
|
-
return { browser, context, page,
|
|
5930
|
+
return { browser, context, page, isExternal: true };
|
|
5790
5931
|
} catch (error) {
|
|
5791
5932
|
if (browser) {
|
|
5792
5933
|
await browser.close().catch(() => void 0);
|
|
@@ -5821,7 +5962,7 @@ var BrowserPool = class {
|
|
|
5821
5962
|
context = await browser.newContext(options.context || {});
|
|
5822
5963
|
page = await context.newPage();
|
|
5823
5964
|
}
|
|
5824
|
-
return { browser, context, page,
|
|
5965
|
+
return { browser, context, page, isExternal: false };
|
|
5825
5966
|
}
|
|
5826
5967
|
async launchSandbox(options) {
|
|
5827
5968
|
const browser = await chromium2.launch({
|
|
@@ -5832,7 +5973,7 @@ var BrowserPool = class {
|
|
|
5832
5973
|
const context = await browser.newContext(options.context || {});
|
|
5833
5974
|
const page = await context.newPage();
|
|
5834
5975
|
this.browser = browser;
|
|
5835
|
-
return { browser, context, page,
|
|
5976
|
+
return { browser, context, page, isExternal: false };
|
|
5836
5977
|
}
|
|
5837
5978
|
};
|
|
5838
5979
|
|
|
@@ -5840,6 +5981,7 @@ var BrowserPool = class {
|
|
|
5840
5981
|
import fs3 from "fs";
|
|
5841
5982
|
import path4 from "path";
|
|
5842
5983
|
import { fileURLToPath } from "url";
|
|
5984
|
+
import { parse as parseDotenv } from "dotenv";
|
|
5843
5985
|
var DEFAULT_CONFIG = {
|
|
5844
5986
|
browser: {
|
|
5845
5987
|
headless: false,
|
|
@@ -5855,6 +5997,53 @@ var DEFAULT_CONFIG = {
|
|
|
5855
5997
|
model: "gpt-5.1",
|
|
5856
5998
|
debug: false
|
|
5857
5999
|
};
|
|
6000
|
+
function dotenvFileOrder(nodeEnv) {
|
|
6001
|
+
const normalized = nodeEnv?.trim() || "";
|
|
6002
|
+
const files = [];
|
|
6003
|
+
if (normalized) {
|
|
6004
|
+
files.push(`.env.${normalized}.local`);
|
|
6005
|
+
}
|
|
6006
|
+
if (normalized !== "test") {
|
|
6007
|
+
files.push(".env.local");
|
|
6008
|
+
}
|
|
6009
|
+
if (normalized) {
|
|
6010
|
+
files.push(`.env.${normalized}`);
|
|
6011
|
+
}
|
|
6012
|
+
files.push(".env");
|
|
6013
|
+
return files;
|
|
6014
|
+
}
|
|
6015
|
+
function loadDotenvValues(rootDir, baseEnv) {
|
|
6016
|
+
const values = {};
|
|
6017
|
+
if (parseBool(baseEnv.OPENSTEER_DISABLE_DOTENV_AUTOLOAD) === true) {
|
|
6018
|
+
return values;
|
|
6019
|
+
}
|
|
6020
|
+
const baseDir = path4.resolve(rootDir);
|
|
6021
|
+
const nodeEnv = baseEnv.NODE_ENV?.trim() || "";
|
|
6022
|
+
for (const filename of dotenvFileOrder(nodeEnv)) {
|
|
6023
|
+
const filePath = path4.join(baseDir, filename);
|
|
6024
|
+
if (!fs3.existsSync(filePath)) continue;
|
|
6025
|
+
try {
|
|
6026
|
+
const raw = fs3.readFileSync(filePath, "utf8");
|
|
6027
|
+
const parsed = parseDotenv(raw);
|
|
6028
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
6029
|
+
if (values[key] === void 0) {
|
|
6030
|
+
values[key] = value;
|
|
6031
|
+
}
|
|
6032
|
+
}
|
|
6033
|
+
} catch {
|
|
6034
|
+
continue;
|
|
6035
|
+
}
|
|
6036
|
+
}
|
|
6037
|
+
return values;
|
|
6038
|
+
}
|
|
6039
|
+
function resolveEnv(rootDir) {
|
|
6040
|
+
const baseEnv = process.env;
|
|
6041
|
+
const dotenvValues = loadDotenvValues(rootDir, baseEnv);
|
|
6042
|
+
return {
|
|
6043
|
+
...dotenvValues,
|
|
6044
|
+
...baseEnv
|
|
6045
|
+
};
|
|
6046
|
+
}
|
|
5858
6047
|
function hasOwn(config, key) {
|
|
5859
6048
|
if (!config || typeof config !== "object") return false;
|
|
5860
6049
|
return Object.prototype.hasOwnProperty.call(config, key);
|
|
@@ -5869,28 +6058,27 @@ function assertNoLegacyAiConfig(source, config) {
|
|
|
5869
6058
|
);
|
|
5870
6059
|
}
|
|
5871
6060
|
}
|
|
5872
|
-
function
|
|
6061
|
+
function assertNoLegacyRuntimeConfig(source, config) {
|
|
5873
6062
|
if (!config || typeof config !== "object") return;
|
|
5874
6063
|
const configRecord = config;
|
|
5875
6064
|
if (hasOwn(configRecord, "runtime")) {
|
|
5876
6065
|
throw new Error(
|
|
5877
|
-
`Legacy "runtime" config is no longer supported in ${source}. Use top-level "
|
|
6066
|
+
`Legacy "runtime" config is no longer supported in ${source}. Use top-level "cloud" instead.`
|
|
5878
6067
|
);
|
|
5879
6068
|
}
|
|
5880
|
-
if (hasOwn(configRecord, "
|
|
6069
|
+
if (hasOwn(configRecord, "mode")) {
|
|
5881
6070
|
throw new Error(
|
|
5882
|
-
`Top-level "
|
|
6071
|
+
`Top-level "mode" config is no longer supported in ${source}. Use "cloud: true" to enable cloud mode.`
|
|
5883
6072
|
);
|
|
5884
6073
|
}
|
|
5885
|
-
|
|
5886
|
-
if (typeof remoteValue === "boolean") {
|
|
6074
|
+
if (hasOwn(configRecord, "remote")) {
|
|
5887
6075
|
throw new Error(
|
|
5888
|
-
`
|
|
6076
|
+
`Top-level "remote" config is no longer supported in ${source}. Use "cloud" options instead.`
|
|
5889
6077
|
);
|
|
5890
6078
|
}
|
|
5891
|
-
if (
|
|
6079
|
+
if (hasOwn(configRecord, "apiKey")) {
|
|
5892
6080
|
throw new Error(
|
|
5893
|
-
`
|
|
6081
|
+
`Top-level "apiKey" config is not supported in ${source}. Use "cloud.apiKey" instead.`
|
|
5894
6082
|
);
|
|
5895
6083
|
}
|
|
5896
6084
|
}
|
|
@@ -5936,20 +6124,20 @@ function parseNumber(value) {
|
|
|
5936
6124
|
if (!Number.isFinite(parsed)) return void 0;
|
|
5937
6125
|
return parsed;
|
|
5938
6126
|
}
|
|
5939
|
-
function
|
|
6127
|
+
function parseRuntimeMode(value, source) {
|
|
5940
6128
|
if (value == null) return void 0;
|
|
5941
6129
|
if (typeof value !== "string") {
|
|
5942
6130
|
throw new Error(
|
|
5943
|
-
`Invalid ${source} value "${String(value)}". Use "local" or "
|
|
6131
|
+
`Invalid ${source} value "${String(value)}". Use "local" or "cloud".`
|
|
5944
6132
|
);
|
|
5945
6133
|
}
|
|
5946
6134
|
const normalized = value.trim().toLowerCase();
|
|
5947
6135
|
if (!normalized) return void 0;
|
|
5948
|
-
if (normalized === "local" || normalized === "
|
|
6136
|
+
if (normalized === "local" || normalized === "cloud") {
|
|
5949
6137
|
return normalized;
|
|
5950
6138
|
}
|
|
5951
6139
|
throw new Error(
|
|
5952
|
-
`Invalid ${source} value "${value}". Use "local" or "
|
|
6140
|
+
`Invalid ${source} value "${value}". Use "local" or "cloud".`
|
|
5953
6141
|
);
|
|
5954
6142
|
}
|
|
5955
6143
|
function parseAuthScheme(value, source) {
|
|
@@ -5968,99 +6156,138 @@ function parseAuthScheme(value, source) {
|
|
|
5968
6156
|
`Invalid ${source} value "${value}". Use "api-key" or "bearer".`
|
|
5969
6157
|
);
|
|
5970
6158
|
}
|
|
5971
|
-
function
|
|
5972
|
-
|
|
6159
|
+
function parseCloudAnnounce(value, source) {
|
|
6160
|
+
if (value == null) return void 0;
|
|
6161
|
+
if (typeof value !== "string") {
|
|
6162
|
+
throw new Error(
|
|
6163
|
+
`Invalid ${source} value "${String(value)}". Use "always", "off", or "tty".`
|
|
6164
|
+
);
|
|
6165
|
+
}
|
|
6166
|
+
const normalized = value.trim().toLowerCase();
|
|
6167
|
+
if (!normalized) return void 0;
|
|
6168
|
+
if (normalized === "always" || normalized === "off" || normalized === "tty") {
|
|
6169
|
+
return normalized;
|
|
6170
|
+
}
|
|
6171
|
+
throw new Error(
|
|
6172
|
+
`Invalid ${source} value "${value}". Use "always", "off", or "tty".`
|
|
6173
|
+
);
|
|
6174
|
+
}
|
|
6175
|
+
function resolveOpensteerApiKey(env) {
|
|
6176
|
+
const value = env.OPENSTEER_API_KEY?.trim();
|
|
5973
6177
|
if (!value) return void 0;
|
|
5974
6178
|
return value;
|
|
5975
6179
|
}
|
|
5976
|
-
function resolveOpensteerAuthScheme() {
|
|
5977
|
-
return parseAuthScheme(
|
|
5978
|
-
process.env.OPENSTEER_AUTH_SCHEME,
|
|
5979
|
-
"OPENSTEER_AUTH_SCHEME"
|
|
5980
|
-
);
|
|
6180
|
+
function resolveOpensteerAuthScheme(env) {
|
|
6181
|
+
return parseAuthScheme(env.OPENSTEER_AUTH_SCHEME, "OPENSTEER_AUTH_SCHEME");
|
|
5981
6182
|
}
|
|
5982
|
-
function
|
|
6183
|
+
function normalizeCloudOptions(value) {
|
|
5983
6184
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
5984
6185
|
return void 0;
|
|
5985
6186
|
}
|
|
5986
6187
|
return value;
|
|
5987
6188
|
}
|
|
5988
|
-
function
|
|
5989
|
-
|
|
5990
|
-
if (
|
|
6189
|
+
function parseCloudEnabled(value, source) {
|
|
6190
|
+
if (value == null) return void 0;
|
|
6191
|
+
if (typeof value === "boolean") return value;
|
|
6192
|
+
if (typeof value === "object" && !Array.isArray(value)) return true;
|
|
6193
|
+
throw new Error(
|
|
6194
|
+
`Invalid ${source} value "${String(value)}". Use true, false, or a cloud options object.`
|
|
6195
|
+
);
|
|
6196
|
+
}
|
|
6197
|
+
function resolveCloudSelection(config, env = process.env) {
|
|
6198
|
+
const configCloud = parseCloudEnabled(config.cloud, "cloud");
|
|
6199
|
+
if (configCloud !== void 0) {
|
|
5991
6200
|
return {
|
|
5992
|
-
|
|
5993
|
-
source: "config.
|
|
6201
|
+
cloud: configCloud,
|
|
6202
|
+
source: "config.cloud"
|
|
5994
6203
|
};
|
|
5995
6204
|
}
|
|
5996
|
-
const envMode =
|
|
6205
|
+
const envMode = parseRuntimeMode(env.OPENSTEER_MODE, "OPENSTEER_MODE");
|
|
5997
6206
|
if (envMode) {
|
|
5998
6207
|
return {
|
|
5999
|
-
|
|
6208
|
+
cloud: envMode === "cloud",
|
|
6000
6209
|
source: "env.OPENSTEER_MODE"
|
|
6001
6210
|
};
|
|
6002
6211
|
}
|
|
6003
6212
|
return {
|
|
6004
|
-
|
|
6213
|
+
cloud: false,
|
|
6005
6214
|
source: "default"
|
|
6006
6215
|
};
|
|
6007
6216
|
}
|
|
6008
6217
|
function resolveConfig(input = {}) {
|
|
6009
|
-
|
|
6218
|
+
const initialRootDir = input.storage?.rootDir ?? process.cwd();
|
|
6219
|
+
const runtimeDefaults = mergeDeep(DEFAULT_CONFIG, {
|
|
6220
|
+
storage: {
|
|
6221
|
+
rootDir: initialRootDir
|
|
6222
|
+
}
|
|
6223
|
+
});
|
|
6224
|
+
assertNoLegacyAiConfig("Opensteer constructor config", input);
|
|
6225
|
+
assertNoLegacyRuntimeConfig("Opensteer constructor config", input);
|
|
6226
|
+
const fileConfig = loadConfigFile(initialRootDir);
|
|
6227
|
+
assertNoLegacyAiConfig(".opensteer/config.json", fileConfig);
|
|
6228
|
+
assertNoLegacyRuntimeConfig(".opensteer/config.json", fileConfig);
|
|
6229
|
+
const fileRootDir = typeof fileConfig.storage?.rootDir === "string" ? fileConfig.storage.rootDir : void 0;
|
|
6230
|
+
const envRootDir = input.storage?.rootDir ?? fileRootDir ?? initialRootDir;
|
|
6231
|
+
const env = resolveEnv(envRootDir);
|
|
6232
|
+
if (env.OPENSTEER_AI_MODEL) {
|
|
6010
6233
|
throw new Error(
|
|
6011
6234
|
"OPENSTEER_AI_MODEL is no longer supported. Use OPENSTEER_MODEL instead."
|
|
6012
6235
|
);
|
|
6013
6236
|
}
|
|
6014
|
-
if (
|
|
6237
|
+
if (env.OPENSTEER_RUNTIME != null) {
|
|
6015
6238
|
throw new Error(
|
|
6016
6239
|
"OPENSTEER_RUNTIME is no longer supported. Use OPENSTEER_MODE instead."
|
|
6017
6240
|
);
|
|
6018
6241
|
}
|
|
6019
|
-
assertNoLegacyAiConfig("Opensteer constructor config", input);
|
|
6020
|
-
assertNoLegacyModeConfig("Opensteer constructor config", input);
|
|
6021
|
-
const rootDir = input.storage?.rootDir ?? DEFAULT_CONFIG.storage.rootDir ?? process.cwd();
|
|
6022
|
-
const fileConfig = loadConfigFile(rootDir);
|
|
6023
|
-
assertNoLegacyAiConfig(".opensteer/config.json", fileConfig);
|
|
6024
|
-
assertNoLegacyModeConfig(".opensteer/config.json", fileConfig);
|
|
6025
6242
|
const envConfig = {
|
|
6026
6243
|
browser: {
|
|
6027
|
-
headless: parseBool(
|
|
6028
|
-
executablePath:
|
|
6029
|
-
slowMo: parseNumber(
|
|
6030
|
-
connectUrl:
|
|
6031
|
-
channel:
|
|
6032
|
-
profileDir:
|
|
6244
|
+
headless: parseBool(env.OPENSTEER_HEADLESS),
|
|
6245
|
+
executablePath: env.OPENSTEER_BROWSER_PATH || void 0,
|
|
6246
|
+
slowMo: parseNumber(env.OPENSTEER_SLOW_MO),
|
|
6247
|
+
connectUrl: env.OPENSTEER_CONNECT_URL || void 0,
|
|
6248
|
+
channel: env.OPENSTEER_CHANNEL || void 0,
|
|
6249
|
+
profileDir: env.OPENSTEER_PROFILE_DIR || void 0
|
|
6033
6250
|
},
|
|
6034
|
-
model:
|
|
6035
|
-
debug: parseBool(
|
|
6251
|
+
model: env.OPENSTEER_MODEL || void 0,
|
|
6252
|
+
debug: parseBool(env.OPENSTEER_DEBUG)
|
|
6036
6253
|
};
|
|
6037
|
-
const mergedWithFile = mergeDeep(
|
|
6254
|
+
const mergedWithFile = mergeDeep(runtimeDefaults, fileConfig);
|
|
6038
6255
|
const mergedWithEnv = mergeDeep(mergedWithFile, envConfig);
|
|
6039
6256
|
const resolved = mergeDeep(mergedWithEnv, input);
|
|
6040
|
-
const envApiKey = resolveOpensteerApiKey();
|
|
6041
|
-
const envAuthScheme = resolveOpensteerAuthScheme();
|
|
6042
|
-
const
|
|
6257
|
+
const envApiKey = resolveOpensteerApiKey(env);
|
|
6258
|
+
const envAuthScheme = resolveOpensteerAuthScheme(env);
|
|
6259
|
+
const envCloudAnnounce = parseCloudAnnounce(
|
|
6260
|
+
env.OPENSTEER_REMOTE_ANNOUNCE,
|
|
6261
|
+
"OPENSTEER_REMOTE_ANNOUNCE"
|
|
6262
|
+
);
|
|
6263
|
+
const inputCloudOptions = normalizeCloudOptions(input.cloud);
|
|
6043
6264
|
const inputAuthScheme = parseAuthScheme(
|
|
6044
|
-
|
|
6045
|
-
"
|
|
6265
|
+
inputCloudOptions?.authScheme,
|
|
6266
|
+
"cloud.authScheme"
|
|
6046
6267
|
);
|
|
6047
|
-
const
|
|
6048
|
-
|
|
6268
|
+
const inputCloudAnnounce = parseCloudAnnounce(
|
|
6269
|
+
inputCloudOptions?.announce,
|
|
6270
|
+
"cloud.announce"
|
|
6049
6271
|
);
|
|
6050
|
-
const
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
|
|
6272
|
+
const inputHasCloudApiKey = Boolean(
|
|
6273
|
+
inputCloudOptions && Object.prototype.hasOwnProperty.call(inputCloudOptions, "apiKey")
|
|
6274
|
+
);
|
|
6275
|
+
const cloudSelection = resolveCloudSelection({
|
|
6276
|
+
cloud: resolved.cloud
|
|
6277
|
+
}, env);
|
|
6278
|
+
if (cloudSelection.cloud) {
|
|
6279
|
+
const resolvedCloud = normalizeCloudOptions(resolved.cloud) ?? {};
|
|
6280
|
+
const authScheme = inputAuthScheme ?? envAuthScheme ?? parseAuthScheme(resolvedCloud.authScheme, "cloud.authScheme") ?? "api-key";
|
|
6281
|
+
const announce = inputCloudAnnounce ?? envCloudAnnounce ?? parseCloudAnnounce(resolvedCloud.announce, "cloud.announce") ?? "always";
|
|
6282
|
+
resolved.cloud = {
|
|
6283
|
+
...resolvedCloud,
|
|
6284
|
+
authScheme,
|
|
6285
|
+
announce
|
|
6059
6286
|
};
|
|
6060
6287
|
}
|
|
6061
|
-
if (envApiKey &&
|
|
6062
|
-
resolved.
|
|
6063
|
-
...
|
|
6288
|
+
if (envApiKey && cloudSelection.cloud && !inputHasCloudApiKey) {
|
|
6289
|
+
resolved.cloud = {
|
|
6290
|
+
...normalizeCloudOptions(resolved.cloud) ?? {},
|
|
6064
6291
|
apiKey: envApiKey
|
|
6065
6292
|
};
|
|
6066
6293
|
}
|
|
@@ -7456,22 +7683,35 @@ function clonePersistedExtractNode(node) {
|
|
|
7456
7683
|
return JSON.parse(JSON.stringify(node));
|
|
7457
7684
|
}
|
|
7458
7685
|
|
|
7459
|
-
// src/
|
|
7460
|
-
var
|
|
7461
|
-
|
|
7686
|
+
// src/cloud/runtime.ts
|
|
7687
|
+
var DEFAULT_CLOUD_BASE_URL = "https://remote.opensteer.com";
|
|
7688
|
+
var DEFAULT_CLOUD_APP_URL = "https://opensteer.com";
|
|
7689
|
+
function createCloudRuntimeState(key, baseUrl = resolveCloudBaseUrl(), authScheme = "api-key", appUrl = resolveCloudAppUrl()) {
|
|
7462
7690
|
return {
|
|
7463
|
-
sessionClient: new
|
|
7464
|
-
cdpClient: new
|
|
7691
|
+
sessionClient: new CloudSessionClient(baseUrl, key, authScheme),
|
|
7692
|
+
cdpClient: new CloudCdpClient(),
|
|
7693
|
+
appUrl: normalizeCloudAppUrl(appUrl),
|
|
7465
7694
|
actionClient: null,
|
|
7466
|
-
sessionId: null
|
|
7695
|
+
sessionId: null,
|
|
7696
|
+
localRunId: null,
|
|
7697
|
+
cloudSessionUrl: null
|
|
7467
7698
|
};
|
|
7468
7699
|
}
|
|
7469
|
-
function
|
|
7700
|
+
function resolveCloudBaseUrl() {
|
|
7470
7701
|
const value = process.env.OPENSTEER_BASE_URL?.trim();
|
|
7471
|
-
if (!value) return
|
|
7702
|
+
if (!value) return DEFAULT_CLOUD_BASE_URL;
|
|
7472
7703
|
return value.replace(/\/+$/, "");
|
|
7473
7704
|
}
|
|
7474
|
-
function
|
|
7705
|
+
function resolveCloudAppUrl() {
|
|
7706
|
+
const value = process.env.OPENSTEER_APP_URL?.trim();
|
|
7707
|
+
if (!value) return DEFAULT_CLOUD_APP_URL;
|
|
7708
|
+
return normalizeCloudAppUrl(value);
|
|
7709
|
+
}
|
|
7710
|
+
function normalizeCloudAppUrl(value) {
|
|
7711
|
+
if (!value) return null;
|
|
7712
|
+
return value.replace(/\/+$/, "");
|
|
7713
|
+
}
|
|
7714
|
+
function readCloudActionDescription(payload) {
|
|
7475
7715
|
const description = payload.description;
|
|
7476
7716
|
if (typeof description !== "string") return void 0;
|
|
7477
7717
|
const normalized = description.trim();
|
|
@@ -7479,7 +7719,7 @@ function readRemoteActionDescription(payload) {
|
|
|
7479
7719
|
}
|
|
7480
7720
|
|
|
7481
7721
|
// src/opensteer.ts
|
|
7482
|
-
var
|
|
7722
|
+
var CLOUD_INTERACTION_METHODS = /* @__PURE__ */ new Set([
|
|
7483
7723
|
"click",
|
|
7484
7724
|
"dblclick",
|
|
7485
7725
|
"rightclick",
|
|
@@ -7496,7 +7736,7 @@ var Opensteer = class _Opensteer {
|
|
|
7496
7736
|
namespace;
|
|
7497
7737
|
storage;
|
|
7498
7738
|
pool;
|
|
7499
|
-
|
|
7739
|
+
cloud;
|
|
7500
7740
|
browser = null;
|
|
7501
7741
|
pageRef = null;
|
|
7502
7742
|
contextRef = null;
|
|
@@ -7504,8 +7744,8 @@ var Opensteer = class _Opensteer {
|
|
|
7504
7744
|
snapshotCache = null;
|
|
7505
7745
|
constructor(config = {}) {
|
|
7506
7746
|
const resolved = resolveConfig(config);
|
|
7507
|
-
const
|
|
7508
|
-
|
|
7747
|
+
const cloudSelection = resolveCloudSelection({
|
|
7748
|
+
cloud: resolved.cloud
|
|
7509
7749
|
});
|
|
7510
7750
|
const model = resolved.model;
|
|
7511
7751
|
this.config = resolved;
|
|
@@ -7515,21 +7755,22 @@ var Opensteer = class _Opensteer {
|
|
|
7515
7755
|
this.namespace = resolveNamespace(resolved, rootDir);
|
|
7516
7756
|
this.storage = new LocalSelectorStorage(rootDir, this.namespace);
|
|
7517
7757
|
this.pool = new BrowserPool(resolved.browser || {});
|
|
7518
|
-
if (
|
|
7519
|
-
const
|
|
7520
|
-
const apiKey =
|
|
7758
|
+
if (cloudSelection.cloud) {
|
|
7759
|
+
const cloudConfig = resolved.cloud && typeof resolved.cloud === "object" ? resolved.cloud : void 0;
|
|
7760
|
+
const apiKey = cloudConfig?.apiKey?.trim();
|
|
7521
7761
|
if (!apiKey) {
|
|
7522
7762
|
throw new Error(
|
|
7523
|
-
"
|
|
7763
|
+
"Cloud mode requires a non-empty API key via cloud.apiKey or OPENSTEER_API_KEY."
|
|
7524
7764
|
);
|
|
7525
7765
|
}
|
|
7526
|
-
this.
|
|
7766
|
+
this.cloud = createCloudRuntimeState(
|
|
7527
7767
|
apiKey,
|
|
7528
|
-
|
|
7529
|
-
|
|
7768
|
+
cloudConfig?.baseUrl,
|
|
7769
|
+
cloudConfig?.authScheme,
|
|
7770
|
+
cloudConfig?.appUrl
|
|
7530
7771
|
);
|
|
7531
7772
|
} else {
|
|
7532
|
-
this.
|
|
7773
|
+
this.cloud = null;
|
|
7533
7774
|
}
|
|
7534
7775
|
}
|
|
7535
7776
|
createLazyResolveCallback(model) {
|
|
@@ -7567,32 +7808,32 @@ var Opensteer = class _Opensteer {
|
|
|
7567
7808
|
};
|
|
7568
7809
|
return extract;
|
|
7569
7810
|
}
|
|
7570
|
-
async
|
|
7571
|
-
const result = await this.
|
|
7811
|
+
async invokeCloudActionAndResetCache(method, args) {
|
|
7812
|
+
const result = await this.invokeCloudAction(method, args);
|
|
7572
7813
|
this.snapshotCache = null;
|
|
7573
7814
|
return result;
|
|
7574
7815
|
}
|
|
7575
|
-
async
|
|
7576
|
-
const actionClient = this.
|
|
7577
|
-
const sessionId = this.
|
|
7816
|
+
async invokeCloudAction(method, args) {
|
|
7817
|
+
const actionClient = this.cloud?.actionClient;
|
|
7818
|
+
const sessionId = this.cloud?.sessionId;
|
|
7578
7819
|
if (!actionClient || !sessionId) {
|
|
7579
|
-
throw
|
|
7820
|
+
throw cloudNotLaunchedError();
|
|
7580
7821
|
}
|
|
7581
7822
|
const payload = args && typeof args === "object" ? args : {};
|
|
7582
7823
|
try {
|
|
7583
7824
|
return await actionClient.request(method, payload);
|
|
7584
7825
|
} catch (err) {
|
|
7585
|
-
if (err instanceof
|
|
7826
|
+
if (err instanceof OpensteerCloudError && err.code === "CLOUD_ACTION_FAILED" && CLOUD_INTERACTION_METHODS.has(method)) {
|
|
7586
7827
|
const detailsRecord = err.details && typeof err.details === "object" ? err.details : null;
|
|
7587
|
-
const
|
|
7828
|
+
const cloudFailure = normalizeActionFailure(
|
|
7588
7829
|
detailsRecord?.actionFailure
|
|
7589
7830
|
);
|
|
7590
|
-
const failure =
|
|
7831
|
+
const failure = cloudFailure || classifyActionFailure({
|
|
7591
7832
|
action: method,
|
|
7592
7833
|
error: err,
|
|
7593
7834
|
fallbackMessage: defaultActionFailureMessage(method)
|
|
7594
7835
|
});
|
|
7595
|
-
const description =
|
|
7836
|
+
const description = readCloudActionDescription(payload);
|
|
7596
7837
|
throw this.buildActionError(
|
|
7597
7838
|
method,
|
|
7598
7839
|
description,
|
|
@@ -7633,8 +7874,36 @@ var Opensteer = class _Opensteer {
|
|
|
7633
7874
|
}
|
|
7634
7875
|
return this.contextRef;
|
|
7635
7876
|
}
|
|
7636
|
-
|
|
7637
|
-
return this.
|
|
7877
|
+
getCloudSessionId() {
|
|
7878
|
+
return this.cloud?.sessionId ?? null;
|
|
7879
|
+
}
|
|
7880
|
+
getCloudSessionUrl() {
|
|
7881
|
+
return this.cloud?.cloudSessionUrl ?? null;
|
|
7882
|
+
}
|
|
7883
|
+
announceCloudSession(args) {
|
|
7884
|
+
if (!this.shouldAnnounceCloudSession()) {
|
|
7885
|
+
return;
|
|
7886
|
+
}
|
|
7887
|
+
const fields = [
|
|
7888
|
+
`sessionId=${args.sessionId}`,
|
|
7889
|
+
`workspaceId=${args.workspaceId}`
|
|
7890
|
+
];
|
|
7891
|
+
if (args.cloudSessionUrl) {
|
|
7892
|
+
fields.push(`url=${args.cloudSessionUrl}`);
|
|
7893
|
+
}
|
|
7894
|
+
process.stderr.write(`[opensteer] cloud session ready ${fields.join(" ")}
|
|
7895
|
+
`);
|
|
7896
|
+
}
|
|
7897
|
+
shouldAnnounceCloudSession() {
|
|
7898
|
+
const cloudConfig = this.config.cloud && typeof this.config.cloud === "object" ? this.config.cloud : null;
|
|
7899
|
+
const announce = cloudConfig?.announce ?? "always";
|
|
7900
|
+
if (announce === "off") {
|
|
7901
|
+
return false;
|
|
7902
|
+
}
|
|
7903
|
+
if (announce === "tty") {
|
|
7904
|
+
return Boolean(process.stderr.isTTY);
|
|
7905
|
+
}
|
|
7906
|
+
return true;
|
|
7638
7907
|
}
|
|
7639
7908
|
async launch(options = {}) {
|
|
7640
7909
|
if (this.pageRef && !this.ownsBrowser) {
|
|
@@ -7645,22 +7914,29 @@ var Opensteer = class _Opensteer {
|
|
|
7645
7914
|
if (this.pageRef && this.ownsBrowser) {
|
|
7646
7915
|
return;
|
|
7647
7916
|
}
|
|
7648
|
-
if (this.
|
|
7917
|
+
if (this.cloud) {
|
|
7649
7918
|
let actionClient = null;
|
|
7650
7919
|
let browser = null;
|
|
7651
7920
|
let sessionId = null;
|
|
7921
|
+
let localRunId = null;
|
|
7652
7922
|
try {
|
|
7653
7923
|
try {
|
|
7654
|
-
await this.
|
|
7924
|
+
await this.syncLocalSelectorCacheToCloud();
|
|
7655
7925
|
} catch (error) {
|
|
7656
7926
|
if (this.config.debug) {
|
|
7657
7927
|
const message = error instanceof Error ? error.message : String(error);
|
|
7658
7928
|
console.warn(
|
|
7659
|
-
`[opensteer]
|
|
7929
|
+
`[opensteer] cloud selector cache sync failed: ${message}`
|
|
7660
7930
|
);
|
|
7661
7931
|
}
|
|
7662
7932
|
}
|
|
7663
|
-
|
|
7933
|
+
localRunId = this.cloud.localRunId || buildLocalRunId(this.namespace);
|
|
7934
|
+
this.cloud.localRunId = localRunId;
|
|
7935
|
+
const session2 = await this.cloud.sessionClient.create({
|
|
7936
|
+
cloudSessionContractVersion,
|
|
7937
|
+
sourceType: "local-cloud",
|
|
7938
|
+
clientSessionHint: this.namespace,
|
|
7939
|
+
localRunId,
|
|
7664
7940
|
name: this.namespace,
|
|
7665
7941
|
model: this.config.model,
|
|
7666
7942
|
launchContext: options.context || void 0
|
|
@@ -7671,7 +7947,7 @@ var Opensteer = class _Opensteer {
|
|
|
7671
7947
|
token: session2.actionToken,
|
|
7672
7948
|
sessionId: session2.sessionId
|
|
7673
7949
|
});
|
|
7674
|
-
const cdpConnection = await this.
|
|
7950
|
+
const cdpConnection = await this.cloud.cdpClient.connect({
|
|
7675
7951
|
wsUrl: session2.cdpWsUrl,
|
|
7676
7952
|
token: session2.cdpToken
|
|
7677
7953
|
});
|
|
@@ -7681,8 +7957,17 @@ var Opensteer = class _Opensteer {
|
|
|
7681
7957
|
this.pageRef = cdpConnection.page;
|
|
7682
7958
|
this.ownsBrowser = true;
|
|
7683
7959
|
this.snapshotCache = null;
|
|
7684
|
-
this.
|
|
7685
|
-
this.
|
|
7960
|
+
this.cloud.actionClient = actionClient;
|
|
7961
|
+
this.cloud.sessionId = sessionId;
|
|
7962
|
+
this.cloud.cloudSessionUrl = buildCloudSessionUrl(
|
|
7963
|
+
this.cloud.appUrl,
|
|
7964
|
+
session2.cloudSession.sessionId
|
|
7965
|
+
);
|
|
7966
|
+
this.announceCloudSession({
|
|
7967
|
+
sessionId: session2.sessionId,
|
|
7968
|
+
workspaceId: session2.cloudSession.workspaceId,
|
|
7969
|
+
cloudSessionUrl: this.cloud.cloudSessionUrl
|
|
7970
|
+
});
|
|
7686
7971
|
return;
|
|
7687
7972
|
} catch (error) {
|
|
7688
7973
|
if (actionClient) {
|
|
@@ -7692,8 +7977,9 @@ var Opensteer = class _Opensteer {
|
|
|
7692
7977
|
await browser.close().catch(() => void 0);
|
|
7693
7978
|
}
|
|
7694
7979
|
if (sessionId) {
|
|
7695
|
-
await this.
|
|
7980
|
+
await this.cloud.sessionClient.close(sessionId).catch(() => void 0);
|
|
7696
7981
|
}
|
|
7982
|
+
this.cloud.cloudSessionUrl = null;
|
|
7697
7983
|
throw error;
|
|
7698
7984
|
}
|
|
7699
7985
|
}
|
|
@@ -7711,13 +7997,13 @@ var Opensteer = class _Opensteer {
|
|
|
7711
7997
|
}
|
|
7712
7998
|
static from(page, config = {}) {
|
|
7713
7999
|
const resolvedConfig = resolveConfig(config);
|
|
7714
|
-
const
|
|
7715
|
-
|
|
8000
|
+
const cloudSelection = resolveCloudSelection({
|
|
8001
|
+
cloud: resolvedConfig.cloud
|
|
7716
8002
|
});
|
|
7717
|
-
if (
|
|
7718
|
-
throw
|
|
8003
|
+
if (cloudSelection.cloud) {
|
|
8004
|
+
throw cloudUnsupportedMethodError(
|
|
7719
8005
|
"Opensteer.from(page)",
|
|
7720
|
-
"Opensteer.from(page) is not supported in
|
|
8006
|
+
"Opensteer.from(page) is not supported in cloud mode."
|
|
7721
8007
|
);
|
|
7722
8008
|
}
|
|
7723
8009
|
const instance = new _Opensteer(config);
|
|
@@ -7730,12 +8016,14 @@ var Opensteer = class _Opensteer {
|
|
|
7730
8016
|
}
|
|
7731
8017
|
async close() {
|
|
7732
8018
|
this.snapshotCache = null;
|
|
7733
|
-
if (this.
|
|
7734
|
-
const actionClient = this.
|
|
7735
|
-
const sessionId = this.
|
|
8019
|
+
if (this.cloud) {
|
|
8020
|
+
const actionClient = this.cloud.actionClient;
|
|
8021
|
+
const sessionId = this.cloud.sessionId;
|
|
7736
8022
|
const browser = this.browser;
|
|
7737
|
-
this.
|
|
7738
|
-
this.
|
|
8023
|
+
this.cloud.actionClient = null;
|
|
8024
|
+
this.cloud.sessionId = null;
|
|
8025
|
+
this.cloud.localRunId = null;
|
|
8026
|
+
this.cloud.cloudSessionUrl = null;
|
|
7739
8027
|
this.browser = null;
|
|
7740
8028
|
this.pageRef = null;
|
|
7741
8029
|
this.contextRef = null;
|
|
@@ -7747,7 +8035,7 @@ var Opensteer = class _Opensteer {
|
|
|
7747
8035
|
await browser.close().catch(() => void 0);
|
|
7748
8036
|
}
|
|
7749
8037
|
if (sessionId) {
|
|
7750
|
-
await this.
|
|
8038
|
+
await this.cloud.sessionClient.close(sessionId).catch(() => void 0);
|
|
7751
8039
|
}
|
|
7752
8040
|
return;
|
|
7753
8041
|
}
|
|
@@ -7759,17 +8047,17 @@ var Opensteer = class _Opensteer {
|
|
|
7759
8047
|
this.contextRef = null;
|
|
7760
8048
|
this.ownsBrowser = false;
|
|
7761
8049
|
}
|
|
7762
|
-
async
|
|
7763
|
-
if (!this.
|
|
8050
|
+
async syncLocalSelectorCacheToCloud() {
|
|
8051
|
+
if (!this.cloud) return;
|
|
7764
8052
|
const entries = collectLocalSelectorCacheEntries(this.storage);
|
|
7765
8053
|
if (!entries.length) return;
|
|
7766
|
-
await this.
|
|
8054
|
+
await this.cloud.sessionClient.importSelectorCache({
|
|
7767
8055
|
entries
|
|
7768
8056
|
});
|
|
7769
8057
|
}
|
|
7770
8058
|
async goto(url, options) {
|
|
7771
|
-
if (this.
|
|
7772
|
-
await this.
|
|
8059
|
+
if (this.cloud) {
|
|
8060
|
+
await this.invokeCloudActionAndResetCache("goto", { url, options });
|
|
7773
8061
|
return;
|
|
7774
8062
|
}
|
|
7775
8063
|
const { waitUntil = "domcontentloaded", ...rest } = options ?? {};
|
|
@@ -7778,8 +8066,8 @@ var Opensteer = class _Opensteer {
|
|
|
7778
8066
|
this.snapshotCache = null;
|
|
7779
8067
|
}
|
|
7780
8068
|
async snapshot(options = {}) {
|
|
7781
|
-
if (this.
|
|
7782
|
-
return await this.
|
|
8069
|
+
if (this.cloud) {
|
|
8070
|
+
return await this.invokeCloudActionAndResetCache("snapshot", {
|
|
7783
8071
|
options
|
|
7784
8072
|
});
|
|
7785
8073
|
}
|
|
@@ -7788,8 +8076,8 @@ var Opensteer = class _Opensteer {
|
|
|
7788
8076
|
return prepared.cleanedHtml;
|
|
7789
8077
|
}
|
|
7790
8078
|
async state() {
|
|
7791
|
-
if (this.
|
|
7792
|
-
return await this.
|
|
8079
|
+
if (this.cloud) {
|
|
8080
|
+
return await this.invokeCloudAction("state", {});
|
|
7793
8081
|
}
|
|
7794
8082
|
const html = await this.snapshot({ mode: "action" });
|
|
7795
8083
|
return {
|
|
@@ -7799,8 +8087,8 @@ var Opensteer = class _Opensteer {
|
|
|
7799
8087
|
};
|
|
7800
8088
|
}
|
|
7801
8089
|
async screenshot(options = {}) {
|
|
7802
|
-
if (this.
|
|
7803
|
-
const b64 = await this.
|
|
8090
|
+
if (this.cloud) {
|
|
8091
|
+
const b64 = await this.invokeCloudAction(
|
|
7804
8092
|
"screenshot",
|
|
7805
8093
|
options
|
|
7806
8094
|
);
|
|
@@ -7814,8 +8102,8 @@ var Opensteer = class _Opensteer {
|
|
|
7814
8102
|
});
|
|
7815
8103
|
}
|
|
7816
8104
|
async click(options) {
|
|
7817
|
-
if (this.
|
|
7818
|
-
return await this.
|
|
8105
|
+
if (this.cloud) {
|
|
8106
|
+
return await this.invokeCloudActionAndResetCache(
|
|
7819
8107
|
"click",
|
|
7820
8108
|
options
|
|
7821
8109
|
);
|
|
@@ -7827,8 +8115,8 @@ var Opensteer = class _Opensteer {
|
|
|
7827
8115
|
});
|
|
7828
8116
|
}
|
|
7829
8117
|
async dblclick(options) {
|
|
7830
|
-
if (this.
|
|
7831
|
-
return await this.
|
|
8118
|
+
if (this.cloud) {
|
|
8119
|
+
return await this.invokeCloudActionAndResetCache(
|
|
7832
8120
|
"dblclick",
|
|
7833
8121
|
options
|
|
7834
8122
|
);
|
|
@@ -7840,8 +8128,8 @@ var Opensteer = class _Opensteer {
|
|
|
7840
8128
|
});
|
|
7841
8129
|
}
|
|
7842
8130
|
async rightclick(options) {
|
|
7843
|
-
if (this.
|
|
7844
|
-
return await this.
|
|
8131
|
+
if (this.cloud) {
|
|
8132
|
+
return await this.invokeCloudActionAndResetCache(
|
|
7845
8133
|
"rightclick",
|
|
7846
8134
|
options
|
|
7847
8135
|
);
|
|
@@ -7853,8 +8141,8 @@ var Opensteer = class _Opensteer {
|
|
|
7853
8141
|
});
|
|
7854
8142
|
}
|
|
7855
8143
|
async hover(options) {
|
|
7856
|
-
if (this.
|
|
7857
|
-
return await this.
|
|
8144
|
+
if (this.cloud) {
|
|
8145
|
+
return await this.invokeCloudActionAndResetCache(
|
|
7858
8146
|
"hover",
|
|
7859
8147
|
options
|
|
7860
8148
|
);
|
|
@@ -7952,8 +8240,8 @@ var Opensteer = class _Opensteer {
|
|
|
7952
8240
|
);
|
|
7953
8241
|
}
|
|
7954
8242
|
async input(options) {
|
|
7955
|
-
if (this.
|
|
7956
|
-
return await this.
|
|
8243
|
+
if (this.cloud) {
|
|
8244
|
+
return await this.invokeCloudActionAndResetCache(
|
|
7957
8245
|
"input",
|
|
7958
8246
|
options
|
|
7959
8247
|
);
|
|
@@ -8055,8 +8343,8 @@ var Opensteer = class _Opensteer {
|
|
|
8055
8343
|
);
|
|
8056
8344
|
}
|
|
8057
8345
|
async select(options) {
|
|
8058
|
-
if (this.
|
|
8059
|
-
return await this.
|
|
8346
|
+
if (this.cloud) {
|
|
8347
|
+
return await this.invokeCloudActionAndResetCache(
|
|
8060
8348
|
"select",
|
|
8061
8349
|
options
|
|
8062
8350
|
);
|
|
@@ -8165,8 +8453,8 @@ var Opensteer = class _Opensteer {
|
|
|
8165
8453
|
);
|
|
8166
8454
|
}
|
|
8167
8455
|
async scroll(options = {}) {
|
|
8168
|
-
if (this.
|
|
8169
|
-
return await this.
|
|
8456
|
+
if (this.cloud) {
|
|
8457
|
+
return await this.invokeCloudActionAndResetCache(
|
|
8170
8458
|
"scroll",
|
|
8171
8459
|
options
|
|
8172
8460
|
);
|
|
@@ -8267,14 +8555,14 @@ var Opensteer = class _Opensteer {
|
|
|
8267
8555
|
}
|
|
8268
8556
|
// --- Tab Management ---
|
|
8269
8557
|
async tabs() {
|
|
8270
|
-
if (this.
|
|
8271
|
-
return await this.
|
|
8558
|
+
if (this.cloud) {
|
|
8559
|
+
return await this.invokeCloudAction("tabs", {});
|
|
8272
8560
|
}
|
|
8273
8561
|
return listTabs(this.context, this.page);
|
|
8274
8562
|
}
|
|
8275
8563
|
async newTab(url) {
|
|
8276
|
-
if (this.
|
|
8277
|
-
return await this.
|
|
8564
|
+
if (this.cloud) {
|
|
8565
|
+
return await this.invokeCloudActionAndResetCache("newTab", {
|
|
8278
8566
|
url
|
|
8279
8567
|
});
|
|
8280
8568
|
}
|
|
@@ -8284,8 +8572,8 @@ var Opensteer = class _Opensteer {
|
|
|
8284
8572
|
return info;
|
|
8285
8573
|
}
|
|
8286
8574
|
async switchTab(index) {
|
|
8287
|
-
if (this.
|
|
8288
|
-
await this.
|
|
8575
|
+
if (this.cloud) {
|
|
8576
|
+
await this.invokeCloudActionAndResetCache("switchTab", { index });
|
|
8289
8577
|
return;
|
|
8290
8578
|
}
|
|
8291
8579
|
const page = await switchTab(this.context, index);
|
|
@@ -8293,8 +8581,8 @@ var Opensteer = class _Opensteer {
|
|
|
8293
8581
|
this.snapshotCache = null;
|
|
8294
8582
|
}
|
|
8295
8583
|
async closeTab(index) {
|
|
8296
|
-
if (this.
|
|
8297
|
-
await this.
|
|
8584
|
+
if (this.cloud) {
|
|
8585
|
+
await this.invokeCloudActionAndResetCache("closeTab", { index });
|
|
8298
8586
|
return;
|
|
8299
8587
|
}
|
|
8300
8588
|
const newPage = await closeTab(this.context, this.page, index);
|
|
@@ -8305,8 +8593,8 @@ var Opensteer = class _Opensteer {
|
|
|
8305
8593
|
}
|
|
8306
8594
|
// --- Cookie Management ---
|
|
8307
8595
|
async getCookies(url) {
|
|
8308
|
-
if (this.
|
|
8309
|
-
return await this.
|
|
8596
|
+
if (this.cloud) {
|
|
8597
|
+
return await this.invokeCloudAction(
|
|
8310
8598
|
"getCookies",
|
|
8311
8599
|
{ url }
|
|
8312
8600
|
);
|
|
@@ -8314,41 +8602,41 @@ var Opensteer = class _Opensteer {
|
|
|
8314
8602
|
return getCookies(this.context, url);
|
|
8315
8603
|
}
|
|
8316
8604
|
async setCookie(cookie) {
|
|
8317
|
-
if (this.
|
|
8318
|
-
await this.
|
|
8605
|
+
if (this.cloud) {
|
|
8606
|
+
await this.invokeCloudAction("setCookie", cookie);
|
|
8319
8607
|
return;
|
|
8320
8608
|
}
|
|
8321
8609
|
return setCookie(this.context, cookie);
|
|
8322
8610
|
}
|
|
8323
8611
|
async clearCookies() {
|
|
8324
|
-
if (this.
|
|
8325
|
-
await this.
|
|
8612
|
+
if (this.cloud) {
|
|
8613
|
+
await this.invokeCloudAction("clearCookies", {});
|
|
8326
8614
|
return;
|
|
8327
8615
|
}
|
|
8328
8616
|
return clearCookies(this.context);
|
|
8329
8617
|
}
|
|
8330
8618
|
async exportCookies(filePath, url) {
|
|
8331
|
-
if (this.
|
|
8332
|
-
throw
|
|
8619
|
+
if (this.cloud) {
|
|
8620
|
+
throw cloudUnsupportedMethodError(
|
|
8333
8621
|
"exportCookies",
|
|
8334
|
-
"exportCookies() is not supported in
|
|
8622
|
+
"exportCookies() is not supported in cloud mode because it depends on local filesystem paths."
|
|
8335
8623
|
);
|
|
8336
8624
|
}
|
|
8337
8625
|
return exportCookies(this.context, filePath, url);
|
|
8338
8626
|
}
|
|
8339
8627
|
async importCookies(filePath) {
|
|
8340
|
-
if (this.
|
|
8341
|
-
throw
|
|
8628
|
+
if (this.cloud) {
|
|
8629
|
+
throw cloudUnsupportedMethodError(
|
|
8342
8630
|
"importCookies",
|
|
8343
|
-
"importCookies() is not supported in
|
|
8631
|
+
"importCookies() is not supported in cloud mode because it depends on local filesystem paths."
|
|
8344
8632
|
);
|
|
8345
8633
|
}
|
|
8346
8634
|
return importCookies(this.context, filePath);
|
|
8347
8635
|
}
|
|
8348
8636
|
// --- Keyboard Input ---
|
|
8349
8637
|
async pressKey(key) {
|
|
8350
|
-
if (this.
|
|
8351
|
-
await this.
|
|
8638
|
+
if (this.cloud) {
|
|
8639
|
+
await this.invokeCloudActionAndResetCache("pressKey", { key });
|
|
8352
8640
|
return;
|
|
8353
8641
|
}
|
|
8354
8642
|
await this.runWithPostActionWait("pressKey", void 0, async () => {
|
|
@@ -8357,8 +8645,8 @@ var Opensteer = class _Opensteer {
|
|
|
8357
8645
|
this.snapshotCache = null;
|
|
8358
8646
|
}
|
|
8359
8647
|
async type(text) {
|
|
8360
|
-
if (this.
|
|
8361
|
-
await this.
|
|
8648
|
+
if (this.cloud) {
|
|
8649
|
+
await this.invokeCloudActionAndResetCache("type", { text });
|
|
8362
8650
|
return;
|
|
8363
8651
|
}
|
|
8364
8652
|
await this.runWithPostActionWait("type", void 0, async () => {
|
|
@@ -8368,8 +8656,8 @@ var Opensteer = class _Opensteer {
|
|
|
8368
8656
|
}
|
|
8369
8657
|
// --- Element Info ---
|
|
8370
8658
|
async getElementText(options) {
|
|
8371
|
-
if (this.
|
|
8372
|
-
return await this.
|
|
8659
|
+
if (this.cloud) {
|
|
8660
|
+
return await this.invokeCloudAction("getElementText", options);
|
|
8373
8661
|
}
|
|
8374
8662
|
return this.executeElementInfoAction(
|
|
8375
8663
|
"getElementText",
|
|
@@ -8382,8 +8670,8 @@ var Opensteer = class _Opensteer {
|
|
|
8382
8670
|
);
|
|
8383
8671
|
}
|
|
8384
8672
|
async getElementValue(options) {
|
|
8385
|
-
if (this.
|
|
8386
|
-
return await this.
|
|
8673
|
+
if (this.cloud) {
|
|
8674
|
+
return await this.invokeCloudAction(
|
|
8387
8675
|
"getElementValue",
|
|
8388
8676
|
options
|
|
8389
8677
|
);
|
|
@@ -8398,8 +8686,8 @@ var Opensteer = class _Opensteer {
|
|
|
8398
8686
|
);
|
|
8399
8687
|
}
|
|
8400
8688
|
async getElementAttributes(options) {
|
|
8401
|
-
if (this.
|
|
8402
|
-
return await this.
|
|
8689
|
+
if (this.cloud) {
|
|
8690
|
+
return await this.invokeCloudAction(
|
|
8403
8691
|
"getElementAttributes",
|
|
8404
8692
|
options
|
|
8405
8693
|
);
|
|
@@ -8420,8 +8708,8 @@ var Opensteer = class _Opensteer {
|
|
|
8420
8708
|
);
|
|
8421
8709
|
}
|
|
8422
8710
|
async getElementBoundingBox(options) {
|
|
8423
|
-
if (this.
|
|
8424
|
-
return await this.
|
|
8711
|
+
if (this.cloud) {
|
|
8712
|
+
return await this.invokeCloudAction(
|
|
8425
8713
|
"getElementBoundingBox",
|
|
8426
8714
|
options
|
|
8427
8715
|
);
|
|
@@ -8436,14 +8724,14 @@ var Opensteer = class _Opensteer {
|
|
|
8436
8724
|
);
|
|
8437
8725
|
}
|
|
8438
8726
|
async getHtml(selector) {
|
|
8439
|
-
if (this.
|
|
8440
|
-
return await this.
|
|
8727
|
+
if (this.cloud) {
|
|
8728
|
+
return await this.invokeCloudAction("getHtml", { selector });
|
|
8441
8729
|
}
|
|
8442
8730
|
return getPageHtml(this.page, selector);
|
|
8443
8731
|
}
|
|
8444
8732
|
async getTitle() {
|
|
8445
|
-
if (this.
|
|
8446
|
-
return await this.
|
|
8733
|
+
if (this.cloud) {
|
|
8734
|
+
return await this.invokeCloudAction("getTitle", {});
|
|
8447
8735
|
}
|
|
8448
8736
|
return getPageTitle(this.page);
|
|
8449
8737
|
}
|
|
@@ -8481,10 +8769,10 @@ var Opensteer = class _Opensteer {
|
|
|
8481
8769
|
}
|
|
8482
8770
|
// --- File Upload ---
|
|
8483
8771
|
async uploadFile(options) {
|
|
8484
|
-
if (this.
|
|
8485
|
-
throw
|
|
8772
|
+
if (this.cloud) {
|
|
8773
|
+
throw cloudUnsupportedMethodError(
|
|
8486
8774
|
"uploadFile",
|
|
8487
|
-
"uploadFile() is not supported in
|
|
8775
|
+
"uploadFile() is not supported in cloud mode because file paths must be accessible on the cloud runtime."
|
|
8488
8776
|
);
|
|
8489
8777
|
}
|
|
8490
8778
|
const storageKey = this.resolveStorageKey(options.description);
|
|
@@ -8586,15 +8874,15 @@ var Opensteer = class _Opensteer {
|
|
|
8586
8874
|
}
|
|
8587
8875
|
// --- Wait for Text ---
|
|
8588
8876
|
async waitForText(text, options) {
|
|
8589
|
-
if (this.
|
|
8590
|
-
await this.
|
|
8877
|
+
if (this.cloud) {
|
|
8878
|
+
await this.invokeCloudAction("waitForText", { text, options });
|
|
8591
8879
|
return;
|
|
8592
8880
|
}
|
|
8593
8881
|
await this.page.getByText(text).first().waitFor({ timeout: options?.timeout ?? 3e4 });
|
|
8594
8882
|
}
|
|
8595
8883
|
async extract(options) {
|
|
8596
|
-
if (this.
|
|
8597
|
-
return await this.
|
|
8884
|
+
if (this.cloud) {
|
|
8885
|
+
return await this.invokeCloudAction("extract", options);
|
|
8598
8886
|
}
|
|
8599
8887
|
const storageKey = this.resolveStorageKey(options.description);
|
|
8600
8888
|
const schemaHash = options.schema ? computeSchemaHash(options.schema) : null;
|
|
@@ -8646,8 +8934,8 @@ var Opensteer = class _Opensteer {
|
|
|
8646
8934
|
return inflateDataPathObject(data);
|
|
8647
8935
|
}
|
|
8648
8936
|
async extractFromPlan(options) {
|
|
8649
|
-
if (this.
|
|
8650
|
-
return await this.
|
|
8937
|
+
if (this.cloud) {
|
|
8938
|
+
return await this.invokeCloudAction(
|
|
8651
8939
|
"extractFromPlan",
|
|
8652
8940
|
options
|
|
8653
8941
|
);
|
|
@@ -8696,10 +8984,10 @@ var Opensteer = class _Opensteer {
|
|
|
8696
8984
|
return this.storage;
|
|
8697
8985
|
}
|
|
8698
8986
|
clearCache() {
|
|
8699
|
-
if (this.
|
|
8987
|
+
if (this.cloud) {
|
|
8700
8988
|
this.snapshotCache = null;
|
|
8701
|
-
if (!this.
|
|
8702
|
-
void this.
|
|
8989
|
+
if (!this.cloud.actionClient) return;
|
|
8990
|
+
void this.invokeCloudAction("clearCache", {});
|
|
8703
8991
|
return;
|
|
8704
8992
|
}
|
|
8705
8993
|
this.storage.clearNamespace();
|
|
@@ -9727,6 +10015,16 @@ function getScrollDelta2(options) {
|
|
|
9727
10015
|
return { x: 0, y: absoluteAmount };
|
|
9728
10016
|
}
|
|
9729
10017
|
}
|
|
10018
|
+
function buildLocalRunId(namespace) {
|
|
10019
|
+
const normalized = namespace.trim() || "default";
|
|
10020
|
+
return `${normalized}-${Date.now().toString(36)}-${randomUUID2().slice(0, 8)}`;
|
|
10021
|
+
}
|
|
10022
|
+
function buildCloudSessionUrl(appUrl, sessionId) {
|
|
10023
|
+
if (!appUrl) {
|
|
10024
|
+
return null;
|
|
10025
|
+
}
|
|
10026
|
+
return `${appUrl}/browser/${encodeURIComponent(sessionId)}`;
|
|
10027
|
+
}
|
|
9730
10028
|
|
|
9731
10029
|
export {
|
|
9732
10030
|
normalizeNamespace,
|
|
@@ -9789,12 +10087,13 @@ export {
|
|
|
9789
10087
|
getPageTitle,
|
|
9790
10088
|
performFileUpload,
|
|
9791
10089
|
OpensteerActionError,
|
|
9792
|
-
|
|
9793
|
-
|
|
9794
|
-
|
|
10090
|
+
cloudSessionContractVersion,
|
|
10091
|
+
OpensteerCloudError,
|
|
10092
|
+
cloudUnsupportedMethodError,
|
|
10093
|
+
cloudNotLaunchedError,
|
|
9795
10094
|
ActionWsClient,
|
|
9796
10095
|
collectLocalSelectorCacheEntries,
|
|
9797
|
-
|
|
9798
|
-
|
|
10096
|
+
CloudCdpClient,
|
|
10097
|
+
CloudSessionClient,
|
|
9799
10098
|
Opensteer
|
|
9800
10099
|
};
|