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
package/dist/cli/server.cjs
CHANGED
|
@@ -752,7 +752,7 @@ var BrowserPool = class {
|
|
|
752
752
|
const context = contexts[0];
|
|
753
753
|
const pages = context.pages();
|
|
754
754
|
const page = pages.length > 0 ? pages[0] : await context.newPage();
|
|
755
|
-
return { browser, context, page,
|
|
755
|
+
return { browser, context, page, isExternal: true };
|
|
756
756
|
} catch (error) {
|
|
757
757
|
if (browser) {
|
|
758
758
|
await browser.close().catch(() => void 0);
|
|
@@ -787,7 +787,7 @@ var BrowserPool = class {
|
|
|
787
787
|
context = await browser.newContext(options.context || {});
|
|
788
788
|
page = await context.newPage();
|
|
789
789
|
}
|
|
790
|
-
return { browser, context, page,
|
|
790
|
+
return { browser, context, page, isExternal: false };
|
|
791
791
|
}
|
|
792
792
|
async launchSandbox(options) {
|
|
793
793
|
const browser = await import_playwright.chromium.launch({
|
|
@@ -798,7 +798,7 @@ var BrowserPool = class {
|
|
|
798
798
|
const context = await browser.newContext(options.context || {});
|
|
799
799
|
const page = await context.newPage();
|
|
800
800
|
this.browser = browser;
|
|
801
|
-
return { browser, context, page,
|
|
801
|
+
return { browser, context, page, isExternal: false };
|
|
802
802
|
}
|
|
803
803
|
};
|
|
804
804
|
|
|
@@ -806,6 +806,7 @@ var BrowserPool = class {
|
|
|
806
806
|
var import_fs = __toESM(require("fs"), 1);
|
|
807
807
|
var import_path3 = __toESM(require("path"), 1);
|
|
808
808
|
var import_url = require("url");
|
|
809
|
+
var import_dotenv = require("dotenv");
|
|
809
810
|
|
|
810
811
|
// src/storage/namespace.ts
|
|
811
812
|
var import_path2 = __toESM(require("path"), 1);
|
|
@@ -855,6 +856,53 @@ var DEFAULT_CONFIG = {
|
|
|
855
856
|
model: "gpt-5.1",
|
|
856
857
|
debug: false
|
|
857
858
|
};
|
|
859
|
+
function dotenvFileOrder(nodeEnv) {
|
|
860
|
+
const normalized = nodeEnv?.trim() || "";
|
|
861
|
+
const files = [];
|
|
862
|
+
if (normalized) {
|
|
863
|
+
files.push(`.env.${normalized}.local`);
|
|
864
|
+
}
|
|
865
|
+
if (normalized !== "test") {
|
|
866
|
+
files.push(".env.local");
|
|
867
|
+
}
|
|
868
|
+
if (normalized) {
|
|
869
|
+
files.push(`.env.${normalized}`);
|
|
870
|
+
}
|
|
871
|
+
files.push(".env");
|
|
872
|
+
return files;
|
|
873
|
+
}
|
|
874
|
+
function loadDotenvValues(rootDir, baseEnv) {
|
|
875
|
+
const values = {};
|
|
876
|
+
if (parseBool(baseEnv.OPENSTEER_DISABLE_DOTENV_AUTOLOAD) === true) {
|
|
877
|
+
return values;
|
|
878
|
+
}
|
|
879
|
+
const baseDir = import_path3.default.resolve(rootDir);
|
|
880
|
+
const nodeEnv = baseEnv.NODE_ENV?.trim() || "";
|
|
881
|
+
for (const filename of dotenvFileOrder(nodeEnv)) {
|
|
882
|
+
const filePath = import_path3.default.join(baseDir, filename);
|
|
883
|
+
if (!import_fs.default.existsSync(filePath)) continue;
|
|
884
|
+
try {
|
|
885
|
+
const raw = import_fs.default.readFileSync(filePath, "utf8");
|
|
886
|
+
const parsed = (0, import_dotenv.parse)(raw);
|
|
887
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
888
|
+
if (values[key] === void 0) {
|
|
889
|
+
values[key] = value;
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
} catch {
|
|
893
|
+
continue;
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
return values;
|
|
897
|
+
}
|
|
898
|
+
function resolveEnv(rootDir) {
|
|
899
|
+
const baseEnv = process.env;
|
|
900
|
+
const dotenvValues = loadDotenvValues(rootDir, baseEnv);
|
|
901
|
+
return {
|
|
902
|
+
...dotenvValues,
|
|
903
|
+
...baseEnv
|
|
904
|
+
};
|
|
905
|
+
}
|
|
858
906
|
function hasOwn(config, key) {
|
|
859
907
|
if (!config || typeof config !== "object") return false;
|
|
860
908
|
return Object.prototype.hasOwnProperty.call(config, key);
|
|
@@ -869,28 +917,27 @@ function assertNoLegacyAiConfig(source, config) {
|
|
|
869
917
|
);
|
|
870
918
|
}
|
|
871
919
|
}
|
|
872
|
-
function
|
|
920
|
+
function assertNoLegacyRuntimeConfig(source, config) {
|
|
873
921
|
if (!config || typeof config !== "object") return;
|
|
874
922
|
const configRecord = config;
|
|
875
923
|
if (hasOwn(configRecord, "runtime")) {
|
|
876
924
|
throw new Error(
|
|
877
|
-
`Legacy "runtime" config is no longer supported in ${source}. Use top-level "
|
|
925
|
+
`Legacy "runtime" config is no longer supported in ${source}. Use top-level "cloud" instead.`
|
|
878
926
|
);
|
|
879
927
|
}
|
|
880
|
-
if (hasOwn(configRecord, "
|
|
928
|
+
if (hasOwn(configRecord, "mode")) {
|
|
881
929
|
throw new Error(
|
|
882
|
-
`Top-level "
|
|
930
|
+
`Top-level "mode" config is no longer supported in ${source}. Use "cloud: true" to enable cloud mode.`
|
|
883
931
|
);
|
|
884
932
|
}
|
|
885
|
-
|
|
886
|
-
if (typeof remoteValue === "boolean") {
|
|
933
|
+
if (hasOwn(configRecord, "remote")) {
|
|
887
934
|
throw new Error(
|
|
888
|
-
`
|
|
935
|
+
`Top-level "remote" config is no longer supported in ${source}. Use "cloud" options instead.`
|
|
889
936
|
);
|
|
890
937
|
}
|
|
891
|
-
if (
|
|
938
|
+
if (hasOwn(configRecord, "apiKey")) {
|
|
892
939
|
throw new Error(
|
|
893
|
-
`
|
|
940
|
+
`Top-level "apiKey" config is not supported in ${source}. Use "cloud.apiKey" instead.`
|
|
894
941
|
);
|
|
895
942
|
}
|
|
896
943
|
}
|
|
@@ -936,20 +983,20 @@ function parseNumber(value) {
|
|
|
936
983
|
if (!Number.isFinite(parsed)) return void 0;
|
|
937
984
|
return parsed;
|
|
938
985
|
}
|
|
939
|
-
function
|
|
986
|
+
function parseRuntimeMode(value, source) {
|
|
940
987
|
if (value == null) return void 0;
|
|
941
988
|
if (typeof value !== "string") {
|
|
942
989
|
throw new Error(
|
|
943
|
-
`Invalid ${source} value "${String(value)}". Use "local" or "
|
|
990
|
+
`Invalid ${source} value "${String(value)}". Use "local" or "cloud".`
|
|
944
991
|
);
|
|
945
992
|
}
|
|
946
993
|
const normalized = value.trim().toLowerCase();
|
|
947
994
|
if (!normalized) return void 0;
|
|
948
|
-
if (normalized === "local" || normalized === "
|
|
995
|
+
if (normalized === "local" || normalized === "cloud") {
|
|
949
996
|
return normalized;
|
|
950
997
|
}
|
|
951
998
|
throw new Error(
|
|
952
|
-
`Invalid ${source} value "${value}". Use "local" or "
|
|
999
|
+
`Invalid ${source} value "${value}". Use "local" or "cloud".`
|
|
953
1000
|
);
|
|
954
1001
|
}
|
|
955
1002
|
function parseAuthScheme(value, source) {
|
|
@@ -968,99 +1015,138 @@ function parseAuthScheme(value, source) {
|
|
|
968
1015
|
`Invalid ${source} value "${value}". Use "api-key" or "bearer".`
|
|
969
1016
|
);
|
|
970
1017
|
}
|
|
971
|
-
function
|
|
972
|
-
|
|
1018
|
+
function parseCloudAnnounce(value, source) {
|
|
1019
|
+
if (value == null) return void 0;
|
|
1020
|
+
if (typeof value !== "string") {
|
|
1021
|
+
throw new Error(
|
|
1022
|
+
`Invalid ${source} value "${String(value)}". Use "always", "off", or "tty".`
|
|
1023
|
+
);
|
|
1024
|
+
}
|
|
1025
|
+
const normalized = value.trim().toLowerCase();
|
|
1026
|
+
if (!normalized) return void 0;
|
|
1027
|
+
if (normalized === "always" || normalized === "off" || normalized === "tty") {
|
|
1028
|
+
return normalized;
|
|
1029
|
+
}
|
|
1030
|
+
throw new Error(
|
|
1031
|
+
`Invalid ${source} value "${value}". Use "always", "off", or "tty".`
|
|
1032
|
+
);
|
|
1033
|
+
}
|
|
1034
|
+
function resolveOpensteerApiKey(env) {
|
|
1035
|
+
const value = env.OPENSTEER_API_KEY?.trim();
|
|
973
1036
|
if (!value) return void 0;
|
|
974
1037
|
return value;
|
|
975
1038
|
}
|
|
976
|
-
function resolveOpensteerAuthScheme() {
|
|
977
|
-
return parseAuthScheme(
|
|
978
|
-
process.env.OPENSTEER_AUTH_SCHEME,
|
|
979
|
-
"OPENSTEER_AUTH_SCHEME"
|
|
980
|
-
);
|
|
1039
|
+
function resolveOpensteerAuthScheme(env) {
|
|
1040
|
+
return parseAuthScheme(env.OPENSTEER_AUTH_SCHEME, "OPENSTEER_AUTH_SCHEME");
|
|
981
1041
|
}
|
|
982
|
-
function
|
|
1042
|
+
function normalizeCloudOptions(value) {
|
|
983
1043
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
984
1044
|
return void 0;
|
|
985
1045
|
}
|
|
986
1046
|
return value;
|
|
987
1047
|
}
|
|
988
|
-
function
|
|
989
|
-
|
|
990
|
-
if (
|
|
1048
|
+
function parseCloudEnabled(value, source) {
|
|
1049
|
+
if (value == null) return void 0;
|
|
1050
|
+
if (typeof value === "boolean") return value;
|
|
1051
|
+
if (typeof value === "object" && !Array.isArray(value)) return true;
|
|
1052
|
+
throw new Error(
|
|
1053
|
+
`Invalid ${source} value "${String(value)}". Use true, false, or a cloud options object.`
|
|
1054
|
+
);
|
|
1055
|
+
}
|
|
1056
|
+
function resolveCloudSelection(config, env = process.env) {
|
|
1057
|
+
const configCloud = parseCloudEnabled(config.cloud, "cloud");
|
|
1058
|
+
if (configCloud !== void 0) {
|
|
991
1059
|
return {
|
|
992
|
-
|
|
993
|
-
source: "config.
|
|
1060
|
+
cloud: configCloud,
|
|
1061
|
+
source: "config.cloud"
|
|
994
1062
|
};
|
|
995
1063
|
}
|
|
996
|
-
const envMode =
|
|
1064
|
+
const envMode = parseRuntimeMode(env.OPENSTEER_MODE, "OPENSTEER_MODE");
|
|
997
1065
|
if (envMode) {
|
|
998
1066
|
return {
|
|
999
|
-
|
|
1067
|
+
cloud: envMode === "cloud",
|
|
1000
1068
|
source: "env.OPENSTEER_MODE"
|
|
1001
1069
|
};
|
|
1002
1070
|
}
|
|
1003
1071
|
return {
|
|
1004
|
-
|
|
1072
|
+
cloud: false,
|
|
1005
1073
|
source: "default"
|
|
1006
1074
|
};
|
|
1007
1075
|
}
|
|
1008
1076
|
function resolveConfig(input = {}) {
|
|
1009
|
-
|
|
1077
|
+
const initialRootDir = input.storage?.rootDir ?? process.cwd();
|
|
1078
|
+
const runtimeDefaults = mergeDeep(DEFAULT_CONFIG, {
|
|
1079
|
+
storage: {
|
|
1080
|
+
rootDir: initialRootDir
|
|
1081
|
+
}
|
|
1082
|
+
});
|
|
1083
|
+
assertNoLegacyAiConfig("Opensteer constructor config", input);
|
|
1084
|
+
assertNoLegacyRuntimeConfig("Opensteer constructor config", input);
|
|
1085
|
+
const fileConfig = loadConfigFile(initialRootDir);
|
|
1086
|
+
assertNoLegacyAiConfig(".opensteer/config.json", fileConfig);
|
|
1087
|
+
assertNoLegacyRuntimeConfig(".opensteer/config.json", fileConfig);
|
|
1088
|
+
const fileRootDir = typeof fileConfig.storage?.rootDir === "string" ? fileConfig.storage.rootDir : void 0;
|
|
1089
|
+
const envRootDir = input.storage?.rootDir ?? fileRootDir ?? initialRootDir;
|
|
1090
|
+
const env = resolveEnv(envRootDir);
|
|
1091
|
+
if (env.OPENSTEER_AI_MODEL) {
|
|
1010
1092
|
throw new Error(
|
|
1011
1093
|
"OPENSTEER_AI_MODEL is no longer supported. Use OPENSTEER_MODEL instead."
|
|
1012
1094
|
);
|
|
1013
1095
|
}
|
|
1014
|
-
if (
|
|
1096
|
+
if (env.OPENSTEER_RUNTIME != null) {
|
|
1015
1097
|
throw new Error(
|
|
1016
1098
|
"OPENSTEER_RUNTIME is no longer supported. Use OPENSTEER_MODE instead."
|
|
1017
1099
|
);
|
|
1018
1100
|
}
|
|
1019
|
-
assertNoLegacyAiConfig("Opensteer constructor config", input);
|
|
1020
|
-
assertNoLegacyModeConfig("Opensteer constructor config", input);
|
|
1021
|
-
const rootDir = input.storage?.rootDir ?? DEFAULT_CONFIG.storage.rootDir ?? process.cwd();
|
|
1022
|
-
const fileConfig = loadConfigFile(rootDir);
|
|
1023
|
-
assertNoLegacyAiConfig(".opensteer/config.json", fileConfig);
|
|
1024
|
-
assertNoLegacyModeConfig(".opensteer/config.json", fileConfig);
|
|
1025
1101
|
const envConfig = {
|
|
1026
1102
|
browser: {
|
|
1027
|
-
headless: parseBool(
|
|
1028
|
-
executablePath:
|
|
1029
|
-
slowMo: parseNumber(
|
|
1030
|
-
connectUrl:
|
|
1031
|
-
channel:
|
|
1032
|
-
profileDir:
|
|
1103
|
+
headless: parseBool(env.OPENSTEER_HEADLESS),
|
|
1104
|
+
executablePath: env.OPENSTEER_BROWSER_PATH || void 0,
|
|
1105
|
+
slowMo: parseNumber(env.OPENSTEER_SLOW_MO),
|
|
1106
|
+
connectUrl: env.OPENSTEER_CONNECT_URL || void 0,
|
|
1107
|
+
channel: env.OPENSTEER_CHANNEL || void 0,
|
|
1108
|
+
profileDir: env.OPENSTEER_PROFILE_DIR || void 0
|
|
1033
1109
|
},
|
|
1034
|
-
model:
|
|
1035
|
-
debug: parseBool(
|
|
1110
|
+
model: env.OPENSTEER_MODEL || void 0,
|
|
1111
|
+
debug: parseBool(env.OPENSTEER_DEBUG)
|
|
1036
1112
|
};
|
|
1037
|
-
const mergedWithFile = mergeDeep(
|
|
1113
|
+
const mergedWithFile = mergeDeep(runtimeDefaults, fileConfig);
|
|
1038
1114
|
const mergedWithEnv = mergeDeep(mergedWithFile, envConfig);
|
|
1039
1115
|
const resolved = mergeDeep(mergedWithEnv, input);
|
|
1040
|
-
const envApiKey = resolveOpensteerApiKey();
|
|
1041
|
-
const envAuthScheme = resolveOpensteerAuthScheme();
|
|
1042
|
-
const
|
|
1116
|
+
const envApiKey = resolveOpensteerApiKey(env);
|
|
1117
|
+
const envAuthScheme = resolveOpensteerAuthScheme(env);
|
|
1118
|
+
const envCloudAnnounce = parseCloudAnnounce(
|
|
1119
|
+
env.OPENSTEER_REMOTE_ANNOUNCE,
|
|
1120
|
+
"OPENSTEER_REMOTE_ANNOUNCE"
|
|
1121
|
+
);
|
|
1122
|
+
const inputCloudOptions = normalizeCloudOptions(input.cloud);
|
|
1043
1123
|
const inputAuthScheme = parseAuthScheme(
|
|
1044
|
-
|
|
1045
|
-
"
|
|
1124
|
+
inputCloudOptions?.authScheme,
|
|
1125
|
+
"cloud.authScheme"
|
|
1046
1126
|
);
|
|
1047
|
-
const
|
|
1048
|
-
|
|
1127
|
+
const inputCloudAnnounce = parseCloudAnnounce(
|
|
1128
|
+
inputCloudOptions?.announce,
|
|
1129
|
+
"cloud.announce"
|
|
1049
1130
|
);
|
|
1050
|
-
const
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1131
|
+
const inputHasCloudApiKey = Boolean(
|
|
1132
|
+
inputCloudOptions && Object.prototype.hasOwnProperty.call(inputCloudOptions, "apiKey")
|
|
1133
|
+
);
|
|
1134
|
+
const cloudSelection = resolveCloudSelection({
|
|
1135
|
+
cloud: resolved.cloud
|
|
1136
|
+
}, env);
|
|
1137
|
+
if (cloudSelection.cloud) {
|
|
1138
|
+
const resolvedCloud = normalizeCloudOptions(resolved.cloud) ?? {};
|
|
1139
|
+
const authScheme = inputAuthScheme ?? envAuthScheme ?? parseAuthScheme(resolvedCloud.authScheme, "cloud.authScheme") ?? "api-key";
|
|
1140
|
+
const announce = inputCloudAnnounce ?? envCloudAnnounce ?? parseCloudAnnounce(resolvedCloud.announce, "cloud.announce") ?? "always";
|
|
1141
|
+
resolved.cloud = {
|
|
1142
|
+
...resolvedCloud,
|
|
1143
|
+
authScheme,
|
|
1144
|
+
announce
|
|
1059
1145
|
};
|
|
1060
1146
|
}
|
|
1061
|
-
if (envApiKey &&
|
|
1062
|
-
resolved.
|
|
1063
|
-
...
|
|
1147
|
+
if (envApiKey && cloudSelection.cloud && !inputHasCloudApiKey) {
|
|
1148
|
+
resolved.cloud = {
|
|
1149
|
+
...normalizeCloudOptions(resolved.cloud) ?? {},
|
|
1064
1150
|
apiKey: envApiKey
|
|
1065
1151
|
};
|
|
1066
1152
|
}
|
|
@@ -7357,36 +7443,39 @@ function clonePersistedExtractNode(node) {
|
|
|
7357
7443
|
return JSON.parse(JSON.stringify(node));
|
|
7358
7444
|
}
|
|
7359
7445
|
|
|
7360
|
-
// src/
|
|
7446
|
+
// src/cloud/contracts.ts
|
|
7447
|
+
var cloudSessionContractVersion = "v3";
|
|
7448
|
+
|
|
7449
|
+
// src/cloud/action-ws-client.ts
|
|
7361
7450
|
var import_ws2 = __toESM(require("ws"), 1);
|
|
7362
7451
|
|
|
7363
|
-
// src/
|
|
7364
|
-
var
|
|
7452
|
+
// src/cloud/errors.ts
|
|
7453
|
+
var OpensteerCloudError = class extends Error {
|
|
7365
7454
|
code;
|
|
7366
7455
|
status;
|
|
7367
7456
|
details;
|
|
7368
7457
|
constructor(code, message, status, details) {
|
|
7369
7458
|
super(message);
|
|
7370
|
-
this.name = "
|
|
7459
|
+
this.name = "OpensteerCloudError";
|
|
7371
7460
|
this.code = code;
|
|
7372
7461
|
this.status = status;
|
|
7373
7462
|
this.details = details;
|
|
7374
7463
|
}
|
|
7375
7464
|
};
|
|
7376
|
-
function
|
|
7377
|
-
return new
|
|
7378
|
-
"
|
|
7379
|
-
message || `${method} is not supported in
|
|
7465
|
+
function cloudUnsupportedMethodError(method, message) {
|
|
7466
|
+
return new OpensteerCloudError(
|
|
7467
|
+
"CLOUD_UNSUPPORTED_METHOD",
|
|
7468
|
+
message || `${method} is not supported in cloud mode.`
|
|
7380
7469
|
);
|
|
7381
7470
|
}
|
|
7382
|
-
function
|
|
7383
|
-
return new
|
|
7384
|
-
"
|
|
7385
|
-
"
|
|
7471
|
+
function cloudNotLaunchedError() {
|
|
7472
|
+
return new OpensteerCloudError(
|
|
7473
|
+
"CLOUD_SESSION_NOT_FOUND",
|
|
7474
|
+
"Cloud session is not connected. Call launch() first."
|
|
7386
7475
|
);
|
|
7387
7476
|
}
|
|
7388
7477
|
|
|
7389
|
-
// src/
|
|
7478
|
+
// src/cloud/action-ws-client.ts
|
|
7390
7479
|
var ActionWsClient = class _ActionWsClient {
|
|
7391
7480
|
ws;
|
|
7392
7481
|
sessionId;
|
|
@@ -7403,18 +7492,18 @@ var ActionWsClient = class _ActionWsClient {
|
|
|
7403
7492
|
});
|
|
7404
7493
|
ws.on("error", (error) => {
|
|
7405
7494
|
this.rejectAll(
|
|
7406
|
-
new
|
|
7407
|
-
"
|
|
7408
|
-
`
|
|
7495
|
+
new OpensteerCloudError(
|
|
7496
|
+
"CLOUD_TRANSPORT_ERROR",
|
|
7497
|
+
`Cloud action websocket error: ${error.message}`
|
|
7409
7498
|
)
|
|
7410
7499
|
);
|
|
7411
7500
|
});
|
|
7412
7501
|
ws.on("close", () => {
|
|
7413
7502
|
this.closed = true;
|
|
7414
7503
|
this.rejectAll(
|
|
7415
|
-
new
|
|
7416
|
-
"
|
|
7417
|
-
"
|
|
7504
|
+
new OpensteerCloudError(
|
|
7505
|
+
"CLOUD_SESSION_CLOSED",
|
|
7506
|
+
"Cloud action websocket closed."
|
|
7418
7507
|
)
|
|
7419
7508
|
);
|
|
7420
7509
|
});
|
|
@@ -7426,8 +7515,8 @@ var ActionWsClient = class _ActionWsClient {
|
|
|
7426
7515
|
ws.once("open", () => resolve());
|
|
7427
7516
|
ws.once("error", (error) => {
|
|
7428
7517
|
reject(
|
|
7429
|
-
new
|
|
7430
|
-
"
|
|
7518
|
+
new OpensteerCloudError(
|
|
7519
|
+
"CLOUD_TRANSPORT_ERROR",
|
|
7431
7520
|
`Failed to connect action websocket: ${error.message}`
|
|
7432
7521
|
)
|
|
7433
7522
|
);
|
|
@@ -7437,9 +7526,9 @@ var ActionWsClient = class _ActionWsClient {
|
|
|
7437
7526
|
}
|
|
7438
7527
|
async request(method, args) {
|
|
7439
7528
|
if (this.closed || this.ws.readyState !== import_ws2.default.OPEN) {
|
|
7440
|
-
throw new
|
|
7441
|
-
"
|
|
7442
|
-
"
|
|
7529
|
+
throw new OpensteerCloudError(
|
|
7530
|
+
"CLOUD_SESSION_CLOSED",
|
|
7531
|
+
"Cloud action websocket is closed."
|
|
7443
7532
|
);
|
|
7444
7533
|
}
|
|
7445
7534
|
const id = this.nextRequestId;
|
|
@@ -7458,8 +7547,8 @@ var ActionWsClient = class _ActionWsClient {
|
|
|
7458
7547
|
this.ws.send(JSON.stringify(payload));
|
|
7459
7548
|
} catch (error) {
|
|
7460
7549
|
this.pending.delete(id);
|
|
7461
|
-
const message = error instanceof Error ? error.message : "Failed to send
|
|
7462
|
-
throw new
|
|
7550
|
+
const message = error instanceof Error ? error.message : "Failed to send cloud action request.";
|
|
7551
|
+
throw new OpensteerCloudError("CLOUD_TRANSPORT_ERROR", message);
|
|
7463
7552
|
}
|
|
7464
7553
|
return await resultPromise;
|
|
7465
7554
|
}
|
|
@@ -7477,9 +7566,9 @@ var ActionWsClient = class _ActionWsClient {
|
|
|
7477
7566
|
parsed = JSON.parse(rawDataToUtf8(raw));
|
|
7478
7567
|
} catch {
|
|
7479
7568
|
this.rejectAll(
|
|
7480
|
-
new
|
|
7481
|
-
"
|
|
7482
|
-
"Invalid
|
|
7569
|
+
new OpensteerCloudError(
|
|
7570
|
+
"CLOUD_TRANSPORT_ERROR",
|
|
7571
|
+
"Invalid cloud action response payload."
|
|
7483
7572
|
)
|
|
7484
7573
|
);
|
|
7485
7574
|
return;
|
|
@@ -7492,7 +7581,7 @@ var ActionWsClient = class _ActionWsClient {
|
|
|
7492
7581
|
return;
|
|
7493
7582
|
}
|
|
7494
7583
|
pending.reject(
|
|
7495
|
-
new
|
|
7584
|
+
new OpensteerCloudError(
|
|
7496
7585
|
parsed.code,
|
|
7497
7586
|
parsed.error,
|
|
7498
7587
|
void 0,
|
|
@@ -7520,7 +7609,7 @@ function withTokenQuery(wsUrl, token) {
|
|
|
7520
7609
|
return url.toString();
|
|
7521
7610
|
}
|
|
7522
7611
|
|
|
7523
|
-
// src/
|
|
7612
|
+
// src/cloud/local-cache-sync.ts
|
|
7524
7613
|
var import_fs3 = __toESM(require("fs"), 1);
|
|
7525
7614
|
var import_path5 = __toESM(require("path"), 1);
|
|
7526
7615
|
function collectLocalSelectorCacheEntries(storage) {
|
|
@@ -7644,24 +7733,24 @@ function dedupeNewest(entries) {
|
|
|
7644
7733
|
return [...byKey.values()];
|
|
7645
7734
|
}
|
|
7646
7735
|
|
|
7647
|
-
// src/
|
|
7736
|
+
// src/cloud/cdp-client.ts
|
|
7648
7737
|
var import_playwright2 = require("playwright");
|
|
7649
|
-
var
|
|
7738
|
+
var CloudCdpClient = class {
|
|
7650
7739
|
async connect(args) {
|
|
7651
7740
|
const endpoint = withTokenQuery2(args.wsUrl, args.token);
|
|
7652
7741
|
let browser;
|
|
7653
7742
|
try {
|
|
7654
7743
|
browser = await import_playwright2.chromium.connectOverCDP(endpoint);
|
|
7655
7744
|
} catch (error) {
|
|
7656
|
-
const message = error instanceof Error ? error.message : "Failed to connect to
|
|
7657
|
-
throw new
|
|
7745
|
+
const message = error instanceof Error ? error.message : "Failed to connect to cloud CDP endpoint.";
|
|
7746
|
+
throw new OpensteerCloudError("CLOUD_TRANSPORT_ERROR", message);
|
|
7658
7747
|
}
|
|
7659
7748
|
const context = browser.contexts()[0];
|
|
7660
7749
|
if (!context) {
|
|
7661
7750
|
await browser.close();
|
|
7662
|
-
throw new
|
|
7663
|
-
"
|
|
7664
|
-
"
|
|
7751
|
+
throw new OpensteerCloudError(
|
|
7752
|
+
"CLOUD_INTERNAL",
|
|
7753
|
+
"Cloud browser returned no context."
|
|
7665
7754
|
);
|
|
7666
7755
|
}
|
|
7667
7756
|
const page = context.pages()[0] || await context.newPage();
|
|
@@ -7674,9 +7763,9 @@ function withTokenQuery2(wsUrl, token) {
|
|
|
7674
7763
|
return url.toString();
|
|
7675
7764
|
}
|
|
7676
7765
|
|
|
7677
|
-
// src/
|
|
7766
|
+
// src/cloud/session-client.ts
|
|
7678
7767
|
var CACHE_IMPORT_BATCH_SIZE = 200;
|
|
7679
|
-
var
|
|
7768
|
+
var CloudSessionClient = class {
|
|
7680
7769
|
baseUrl;
|
|
7681
7770
|
key;
|
|
7682
7771
|
authScheme;
|
|
@@ -7697,7 +7786,17 @@ var RemoteSessionClient = class {
|
|
|
7697
7786
|
if (!response.ok) {
|
|
7698
7787
|
throw await parseHttpError(response);
|
|
7699
7788
|
}
|
|
7700
|
-
|
|
7789
|
+
let body;
|
|
7790
|
+
try {
|
|
7791
|
+
body = await response.json();
|
|
7792
|
+
} catch {
|
|
7793
|
+
throw new OpensteerCloudError(
|
|
7794
|
+
"CLOUD_CONTRACT_MISMATCH",
|
|
7795
|
+
"Invalid cloud session create response: expected a JSON object.",
|
|
7796
|
+
response.status
|
|
7797
|
+
);
|
|
7798
|
+
}
|
|
7799
|
+
return parseCreateResponse(body, response.status);
|
|
7701
7800
|
}
|
|
7702
7801
|
async close(sessionId) {
|
|
7703
7802
|
const response = await fetch(`${this.baseUrl}/sessions/${sessionId}`, {
|
|
@@ -7756,6 +7855,134 @@ var RemoteSessionClient = class {
|
|
|
7756
7855
|
function normalizeBaseUrl(baseUrl) {
|
|
7757
7856
|
return baseUrl.replace(/\/+$/, "");
|
|
7758
7857
|
}
|
|
7858
|
+
function parseCreateResponse(body, status) {
|
|
7859
|
+
const root = requireObject(
|
|
7860
|
+
body,
|
|
7861
|
+
"Invalid cloud session create response: expected a JSON object.",
|
|
7862
|
+
status
|
|
7863
|
+
);
|
|
7864
|
+
const sessionId = requireString(root, "sessionId", status);
|
|
7865
|
+
const actionWsUrl = requireString(root, "actionWsUrl", status);
|
|
7866
|
+
const cdpWsUrl = requireString(root, "cdpWsUrl", status);
|
|
7867
|
+
const actionToken = requireString(root, "actionToken", status);
|
|
7868
|
+
const cdpToken = requireString(root, "cdpToken", status);
|
|
7869
|
+
const cloudSessionUrl = requireString(root, "cloudSessionUrl", status);
|
|
7870
|
+
const cloudSessionRoot = requireObject(
|
|
7871
|
+
root.cloudSession,
|
|
7872
|
+
"Invalid cloud session create response: cloudSession must be an object.",
|
|
7873
|
+
status
|
|
7874
|
+
);
|
|
7875
|
+
const cloudSession = {
|
|
7876
|
+
sessionId: requireString(cloudSessionRoot, "sessionId", status, "cloudSession"),
|
|
7877
|
+
workspaceId: requireString(
|
|
7878
|
+
cloudSessionRoot,
|
|
7879
|
+
"workspaceId",
|
|
7880
|
+
status,
|
|
7881
|
+
"cloudSession"
|
|
7882
|
+
),
|
|
7883
|
+
state: requireString(cloudSessionRoot, "state", status, "cloudSession"),
|
|
7884
|
+
createdAt: requireNumber(cloudSessionRoot, "createdAt", status, "cloudSession"),
|
|
7885
|
+
sourceType: requireSourceType(cloudSessionRoot, "sourceType", status, "cloudSession"),
|
|
7886
|
+
sourceRef: optionalString(cloudSessionRoot, "sourceRef", status, "cloudSession"),
|
|
7887
|
+
label: optionalString(cloudSessionRoot, "label", status, "cloudSession")
|
|
7888
|
+
};
|
|
7889
|
+
const expiresAt = optionalNumber(root, "expiresAt", status);
|
|
7890
|
+
return {
|
|
7891
|
+
sessionId,
|
|
7892
|
+
actionWsUrl,
|
|
7893
|
+
cdpWsUrl,
|
|
7894
|
+
actionToken,
|
|
7895
|
+
cdpToken,
|
|
7896
|
+
expiresAt,
|
|
7897
|
+
cloudSessionUrl,
|
|
7898
|
+
cloudSession
|
|
7899
|
+
};
|
|
7900
|
+
}
|
|
7901
|
+
function requireObject(value, message, status) {
|
|
7902
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
7903
|
+
throw new OpensteerCloudError("CLOUD_CONTRACT_MISMATCH", message, status);
|
|
7904
|
+
}
|
|
7905
|
+
return value;
|
|
7906
|
+
}
|
|
7907
|
+
function requireString(source, field, status, parent) {
|
|
7908
|
+
const value = source[field];
|
|
7909
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
7910
|
+
throw new OpensteerCloudError(
|
|
7911
|
+
"CLOUD_CONTRACT_MISMATCH",
|
|
7912
|
+
`Invalid cloud session create response: ${formatFieldPath(
|
|
7913
|
+
field,
|
|
7914
|
+
parent
|
|
7915
|
+
)} must be a non-empty string.`,
|
|
7916
|
+
status
|
|
7917
|
+
);
|
|
7918
|
+
}
|
|
7919
|
+
return value;
|
|
7920
|
+
}
|
|
7921
|
+
function requireNumber(source, field, status, parent) {
|
|
7922
|
+
const value = source[field];
|
|
7923
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
7924
|
+
throw new OpensteerCloudError(
|
|
7925
|
+
"CLOUD_CONTRACT_MISMATCH",
|
|
7926
|
+
`Invalid cloud session create response: ${formatFieldPath(
|
|
7927
|
+
field,
|
|
7928
|
+
parent
|
|
7929
|
+
)} must be a finite number.`,
|
|
7930
|
+
status
|
|
7931
|
+
);
|
|
7932
|
+
}
|
|
7933
|
+
return value;
|
|
7934
|
+
}
|
|
7935
|
+
function optionalString(source, field, status, parent) {
|
|
7936
|
+
const value = source[field];
|
|
7937
|
+
if (value == null) {
|
|
7938
|
+
return void 0;
|
|
7939
|
+
}
|
|
7940
|
+
if (typeof value !== "string") {
|
|
7941
|
+
throw new OpensteerCloudError(
|
|
7942
|
+
"CLOUD_CONTRACT_MISMATCH",
|
|
7943
|
+
`Invalid cloud session create response: ${formatFieldPath(
|
|
7944
|
+
field,
|
|
7945
|
+
parent
|
|
7946
|
+
)} must be a string when present.`,
|
|
7947
|
+
status
|
|
7948
|
+
);
|
|
7949
|
+
}
|
|
7950
|
+
return value;
|
|
7951
|
+
}
|
|
7952
|
+
function optionalNumber(source, field, status, parent) {
|
|
7953
|
+
const value = source[field];
|
|
7954
|
+
if (value == null) {
|
|
7955
|
+
return void 0;
|
|
7956
|
+
}
|
|
7957
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
7958
|
+
throw new OpensteerCloudError(
|
|
7959
|
+
"CLOUD_CONTRACT_MISMATCH",
|
|
7960
|
+
`Invalid cloud session create response: ${formatFieldPath(
|
|
7961
|
+
field,
|
|
7962
|
+
parent
|
|
7963
|
+
)} must be a finite number when present.`,
|
|
7964
|
+
status
|
|
7965
|
+
);
|
|
7966
|
+
}
|
|
7967
|
+
return value;
|
|
7968
|
+
}
|
|
7969
|
+
function requireSourceType(source, field, status, parent) {
|
|
7970
|
+
const value = source[field];
|
|
7971
|
+
if (value === "agent-thread" || value === "agent-run" || value === "local-cloud" || value === "manual") {
|
|
7972
|
+
return value;
|
|
7973
|
+
}
|
|
7974
|
+
throw new OpensteerCloudError(
|
|
7975
|
+
"CLOUD_CONTRACT_MISMATCH",
|
|
7976
|
+
`Invalid cloud session create response: ${formatFieldPath(
|
|
7977
|
+
field,
|
|
7978
|
+
parent
|
|
7979
|
+
)} must be one of "agent-thread", "agent-run", "local-cloud", or "manual".`,
|
|
7980
|
+
status
|
|
7981
|
+
);
|
|
7982
|
+
}
|
|
7983
|
+
function formatFieldPath(field, parent) {
|
|
7984
|
+
return parent ? `"${parent}.${field}"` : `"${field}"`;
|
|
7985
|
+
}
|
|
7759
7986
|
function zeroImportResponse() {
|
|
7760
7987
|
return {
|
|
7761
7988
|
imported: 0,
|
|
@@ -7779,33 +8006,46 @@ async function parseHttpError(response) {
|
|
|
7779
8006
|
} catch {
|
|
7780
8007
|
body = null;
|
|
7781
8008
|
}
|
|
7782
|
-
const code = typeof body?.code === "string" ?
|
|
7783
|
-
const message = typeof body?.error === "string" ? body.error : `
|
|
7784
|
-
return new
|
|
8009
|
+
const code = typeof body?.code === "string" ? toCloudErrorCode(body.code) : "CLOUD_TRANSPORT_ERROR";
|
|
8010
|
+
const message = typeof body?.error === "string" ? body.error : `Cloud request failed with status ${response.status}.`;
|
|
8011
|
+
return new OpensteerCloudError(code, message, response.status, body?.details);
|
|
7785
8012
|
}
|
|
7786
|
-
function
|
|
7787
|
-
if (code === "
|
|
8013
|
+
function toCloudErrorCode(code) {
|
|
8014
|
+
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") {
|
|
7788
8015
|
return code;
|
|
7789
8016
|
}
|
|
7790
|
-
return "
|
|
8017
|
+
return "CLOUD_TRANSPORT_ERROR";
|
|
7791
8018
|
}
|
|
7792
8019
|
|
|
7793
|
-
// src/
|
|
7794
|
-
var
|
|
7795
|
-
|
|
8020
|
+
// src/cloud/runtime.ts
|
|
8021
|
+
var DEFAULT_CLOUD_BASE_URL = "https://remote.opensteer.com";
|
|
8022
|
+
var DEFAULT_CLOUD_APP_URL = "https://opensteer.com";
|
|
8023
|
+
function createCloudRuntimeState(key, baseUrl = resolveCloudBaseUrl(), authScheme = "api-key", appUrl = resolveCloudAppUrl()) {
|
|
7796
8024
|
return {
|
|
7797
|
-
sessionClient: new
|
|
7798
|
-
cdpClient: new
|
|
8025
|
+
sessionClient: new CloudSessionClient(baseUrl, key, authScheme),
|
|
8026
|
+
cdpClient: new CloudCdpClient(),
|
|
8027
|
+
appUrl: normalizeCloudAppUrl(appUrl),
|
|
7799
8028
|
actionClient: null,
|
|
7800
|
-
sessionId: null
|
|
8029
|
+
sessionId: null,
|
|
8030
|
+
localRunId: null,
|
|
8031
|
+
cloudSessionUrl: null
|
|
7801
8032
|
};
|
|
7802
8033
|
}
|
|
7803
|
-
function
|
|
8034
|
+
function resolveCloudBaseUrl() {
|
|
7804
8035
|
const value = process.env.OPENSTEER_BASE_URL?.trim();
|
|
7805
|
-
if (!value) return
|
|
8036
|
+
if (!value) return DEFAULT_CLOUD_BASE_URL;
|
|
7806
8037
|
return value.replace(/\/+$/, "");
|
|
7807
8038
|
}
|
|
7808
|
-
function
|
|
8039
|
+
function resolveCloudAppUrl() {
|
|
8040
|
+
const value = process.env.OPENSTEER_APP_URL?.trim();
|
|
8041
|
+
if (!value) return DEFAULT_CLOUD_APP_URL;
|
|
8042
|
+
return normalizeCloudAppUrl(value);
|
|
8043
|
+
}
|
|
8044
|
+
function normalizeCloudAppUrl(value) {
|
|
8045
|
+
if (!value) return null;
|
|
8046
|
+
return value.replace(/\/+$/, "");
|
|
8047
|
+
}
|
|
8048
|
+
function readCloudActionDescription(payload) {
|
|
7809
8049
|
const description = payload.description;
|
|
7810
8050
|
if (typeof description !== "string") return void 0;
|
|
7811
8051
|
const normalized = description.trim();
|
|
@@ -7813,7 +8053,7 @@ function readRemoteActionDescription(payload) {
|
|
|
7813
8053
|
}
|
|
7814
8054
|
|
|
7815
8055
|
// src/opensteer.ts
|
|
7816
|
-
var
|
|
8056
|
+
var CLOUD_INTERACTION_METHODS = /* @__PURE__ */ new Set([
|
|
7817
8057
|
"click",
|
|
7818
8058
|
"dblclick",
|
|
7819
8059
|
"rightclick",
|
|
@@ -7830,7 +8070,7 @@ var Opensteer = class _Opensteer {
|
|
|
7830
8070
|
namespace;
|
|
7831
8071
|
storage;
|
|
7832
8072
|
pool;
|
|
7833
|
-
|
|
8073
|
+
cloud;
|
|
7834
8074
|
browser = null;
|
|
7835
8075
|
pageRef = null;
|
|
7836
8076
|
contextRef = null;
|
|
@@ -7838,8 +8078,8 @@ var Opensteer = class _Opensteer {
|
|
|
7838
8078
|
snapshotCache = null;
|
|
7839
8079
|
constructor(config = {}) {
|
|
7840
8080
|
const resolved = resolveConfig(config);
|
|
7841
|
-
const
|
|
7842
|
-
|
|
8081
|
+
const cloudSelection = resolveCloudSelection({
|
|
8082
|
+
cloud: resolved.cloud
|
|
7843
8083
|
});
|
|
7844
8084
|
const model = resolved.model;
|
|
7845
8085
|
this.config = resolved;
|
|
@@ -7849,21 +8089,22 @@ var Opensteer = class _Opensteer {
|
|
|
7849
8089
|
this.namespace = resolveNamespace(resolved, rootDir);
|
|
7850
8090
|
this.storage = new LocalSelectorStorage(rootDir, this.namespace);
|
|
7851
8091
|
this.pool = new BrowserPool(resolved.browser || {});
|
|
7852
|
-
if (
|
|
7853
|
-
const
|
|
7854
|
-
const apiKey =
|
|
8092
|
+
if (cloudSelection.cloud) {
|
|
8093
|
+
const cloudConfig = resolved.cloud && typeof resolved.cloud === "object" ? resolved.cloud : void 0;
|
|
8094
|
+
const apiKey = cloudConfig?.apiKey?.trim();
|
|
7855
8095
|
if (!apiKey) {
|
|
7856
8096
|
throw new Error(
|
|
7857
|
-
"
|
|
8097
|
+
"Cloud mode requires a non-empty API key via cloud.apiKey or OPENSTEER_API_KEY."
|
|
7858
8098
|
);
|
|
7859
8099
|
}
|
|
7860
|
-
this.
|
|
8100
|
+
this.cloud = createCloudRuntimeState(
|
|
7861
8101
|
apiKey,
|
|
7862
|
-
|
|
7863
|
-
|
|
8102
|
+
cloudConfig?.baseUrl,
|
|
8103
|
+
cloudConfig?.authScheme,
|
|
8104
|
+
cloudConfig?.appUrl
|
|
7864
8105
|
);
|
|
7865
8106
|
} else {
|
|
7866
|
-
this.
|
|
8107
|
+
this.cloud = null;
|
|
7867
8108
|
}
|
|
7868
8109
|
}
|
|
7869
8110
|
createLazyResolveCallback(model) {
|
|
@@ -7901,32 +8142,32 @@ var Opensteer = class _Opensteer {
|
|
|
7901
8142
|
};
|
|
7902
8143
|
return extract;
|
|
7903
8144
|
}
|
|
7904
|
-
async
|
|
7905
|
-
const result = await this.
|
|
8145
|
+
async invokeCloudActionAndResetCache(method, args) {
|
|
8146
|
+
const result = await this.invokeCloudAction(method, args);
|
|
7906
8147
|
this.snapshotCache = null;
|
|
7907
8148
|
return result;
|
|
7908
8149
|
}
|
|
7909
|
-
async
|
|
7910
|
-
const actionClient = this.
|
|
7911
|
-
const sessionId = this.
|
|
8150
|
+
async invokeCloudAction(method, args) {
|
|
8151
|
+
const actionClient = this.cloud?.actionClient;
|
|
8152
|
+
const sessionId = this.cloud?.sessionId;
|
|
7912
8153
|
if (!actionClient || !sessionId) {
|
|
7913
|
-
throw
|
|
8154
|
+
throw cloudNotLaunchedError();
|
|
7914
8155
|
}
|
|
7915
8156
|
const payload = args && typeof args === "object" ? args : {};
|
|
7916
8157
|
try {
|
|
7917
8158
|
return await actionClient.request(method, payload);
|
|
7918
8159
|
} catch (err) {
|
|
7919
|
-
if (err instanceof
|
|
8160
|
+
if (err instanceof OpensteerCloudError && err.code === "CLOUD_ACTION_FAILED" && CLOUD_INTERACTION_METHODS.has(method)) {
|
|
7920
8161
|
const detailsRecord = err.details && typeof err.details === "object" ? err.details : null;
|
|
7921
|
-
const
|
|
8162
|
+
const cloudFailure = normalizeActionFailure(
|
|
7922
8163
|
detailsRecord?.actionFailure
|
|
7923
8164
|
);
|
|
7924
|
-
const failure =
|
|
8165
|
+
const failure = cloudFailure || classifyActionFailure({
|
|
7925
8166
|
action: method,
|
|
7926
8167
|
error: err,
|
|
7927
8168
|
fallbackMessage: defaultActionFailureMessage(method)
|
|
7928
8169
|
});
|
|
7929
|
-
const description =
|
|
8170
|
+
const description = readCloudActionDescription(payload);
|
|
7930
8171
|
throw this.buildActionError(
|
|
7931
8172
|
method,
|
|
7932
8173
|
description,
|
|
@@ -7967,8 +8208,36 @@ var Opensteer = class _Opensteer {
|
|
|
7967
8208
|
}
|
|
7968
8209
|
return this.contextRef;
|
|
7969
8210
|
}
|
|
7970
|
-
|
|
7971
|
-
return this.
|
|
8211
|
+
getCloudSessionId() {
|
|
8212
|
+
return this.cloud?.sessionId ?? null;
|
|
8213
|
+
}
|
|
8214
|
+
getCloudSessionUrl() {
|
|
8215
|
+
return this.cloud?.cloudSessionUrl ?? null;
|
|
8216
|
+
}
|
|
8217
|
+
announceCloudSession(args) {
|
|
8218
|
+
if (!this.shouldAnnounceCloudSession()) {
|
|
8219
|
+
return;
|
|
8220
|
+
}
|
|
8221
|
+
const fields = [
|
|
8222
|
+
`sessionId=${args.sessionId}`,
|
|
8223
|
+
`workspaceId=${args.workspaceId}`
|
|
8224
|
+
];
|
|
8225
|
+
if (args.cloudSessionUrl) {
|
|
8226
|
+
fields.push(`url=${args.cloudSessionUrl}`);
|
|
8227
|
+
}
|
|
8228
|
+
process.stderr.write(`[opensteer] cloud session ready ${fields.join(" ")}
|
|
8229
|
+
`);
|
|
8230
|
+
}
|
|
8231
|
+
shouldAnnounceCloudSession() {
|
|
8232
|
+
const cloudConfig = this.config.cloud && typeof this.config.cloud === "object" ? this.config.cloud : null;
|
|
8233
|
+
const announce = cloudConfig?.announce ?? "always";
|
|
8234
|
+
if (announce === "off") {
|
|
8235
|
+
return false;
|
|
8236
|
+
}
|
|
8237
|
+
if (announce === "tty") {
|
|
8238
|
+
return Boolean(process.stderr.isTTY);
|
|
8239
|
+
}
|
|
8240
|
+
return true;
|
|
7972
8241
|
}
|
|
7973
8242
|
async launch(options = {}) {
|
|
7974
8243
|
if (this.pageRef && !this.ownsBrowser) {
|
|
@@ -7979,22 +8248,29 @@ var Opensteer = class _Opensteer {
|
|
|
7979
8248
|
if (this.pageRef && this.ownsBrowser) {
|
|
7980
8249
|
return;
|
|
7981
8250
|
}
|
|
7982
|
-
if (this.
|
|
8251
|
+
if (this.cloud) {
|
|
7983
8252
|
let actionClient = null;
|
|
7984
8253
|
let browser = null;
|
|
7985
8254
|
let sessionId = null;
|
|
8255
|
+
let localRunId = null;
|
|
7986
8256
|
try {
|
|
7987
8257
|
try {
|
|
7988
|
-
await this.
|
|
8258
|
+
await this.syncLocalSelectorCacheToCloud();
|
|
7989
8259
|
} catch (error) {
|
|
7990
8260
|
if (this.config.debug) {
|
|
7991
8261
|
const message = error instanceof Error ? error.message : String(error);
|
|
7992
8262
|
console.warn(
|
|
7993
|
-
`[opensteer]
|
|
8263
|
+
`[opensteer] cloud selector cache sync failed: ${message}`
|
|
7994
8264
|
);
|
|
7995
8265
|
}
|
|
7996
8266
|
}
|
|
7997
|
-
|
|
8267
|
+
localRunId = this.cloud.localRunId || buildLocalRunId(this.namespace);
|
|
8268
|
+
this.cloud.localRunId = localRunId;
|
|
8269
|
+
const session3 = await this.cloud.sessionClient.create({
|
|
8270
|
+
cloudSessionContractVersion,
|
|
8271
|
+
sourceType: "local-cloud",
|
|
8272
|
+
clientSessionHint: this.namespace,
|
|
8273
|
+
localRunId,
|
|
7998
8274
|
name: this.namespace,
|
|
7999
8275
|
model: this.config.model,
|
|
8000
8276
|
launchContext: options.context || void 0
|
|
@@ -8005,7 +8281,7 @@ var Opensteer = class _Opensteer {
|
|
|
8005
8281
|
token: session3.actionToken,
|
|
8006
8282
|
sessionId: session3.sessionId
|
|
8007
8283
|
});
|
|
8008
|
-
const cdpConnection = await this.
|
|
8284
|
+
const cdpConnection = await this.cloud.cdpClient.connect({
|
|
8009
8285
|
wsUrl: session3.cdpWsUrl,
|
|
8010
8286
|
token: session3.cdpToken
|
|
8011
8287
|
});
|
|
@@ -8015,8 +8291,17 @@ var Opensteer = class _Opensteer {
|
|
|
8015
8291
|
this.pageRef = cdpConnection.page;
|
|
8016
8292
|
this.ownsBrowser = true;
|
|
8017
8293
|
this.snapshotCache = null;
|
|
8018
|
-
this.
|
|
8019
|
-
this.
|
|
8294
|
+
this.cloud.actionClient = actionClient;
|
|
8295
|
+
this.cloud.sessionId = sessionId;
|
|
8296
|
+
this.cloud.cloudSessionUrl = buildCloudSessionUrl(
|
|
8297
|
+
this.cloud.appUrl,
|
|
8298
|
+
session3.cloudSession.sessionId
|
|
8299
|
+
);
|
|
8300
|
+
this.announceCloudSession({
|
|
8301
|
+
sessionId: session3.sessionId,
|
|
8302
|
+
workspaceId: session3.cloudSession.workspaceId,
|
|
8303
|
+
cloudSessionUrl: this.cloud.cloudSessionUrl
|
|
8304
|
+
});
|
|
8020
8305
|
return;
|
|
8021
8306
|
} catch (error) {
|
|
8022
8307
|
if (actionClient) {
|
|
@@ -8026,8 +8311,9 @@ var Opensteer = class _Opensteer {
|
|
|
8026
8311
|
await browser.close().catch(() => void 0);
|
|
8027
8312
|
}
|
|
8028
8313
|
if (sessionId) {
|
|
8029
|
-
await this.
|
|
8314
|
+
await this.cloud.sessionClient.close(sessionId).catch(() => void 0);
|
|
8030
8315
|
}
|
|
8316
|
+
this.cloud.cloudSessionUrl = null;
|
|
8031
8317
|
throw error;
|
|
8032
8318
|
}
|
|
8033
8319
|
}
|
|
@@ -8045,13 +8331,13 @@ var Opensteer = class _Opensteer {
|
|
|
8045
8331
|
}
|
|
8046
8332
|
static from(page, config = {}) {
|
|
8047
8333
|
const resolvedConfig = resolveConfig(config);
|
|
8048
|
-
const
|
|
8049
|
-
|
|
8334
|
+
const cloudSelection = resolveCloudSelection({
|
|
8335
|
+
cloud: resolvedConfig.cloud
|
|
8050
8336
|
});
|
|
8051
|
-
if (
|
|
8052
|
-
throw
|
|
8337
|
+
if (cloudSelection.cloud) {
|
|
8338
|
+
throw cloudUnsupportedMethodError(
|
|
8053
8339
|
"Opensteer.from(page)",
|
|
8054
|
-
"Opensteer.from(page) is not supported in
|
|
8340
|
+
"Opensteer.from(page) is not supported in cloud mode."
|
|
8055
8341
|
);
|
|
8056
8342
|
}
|
|
8057
8343
|
const instance2 = new _Opensteer(config);
|
|
@@ -8064,12 +8350,14 @@ var Opensteer = class _Opensteer {
|
|
|
8064
8350
|
}
|
|
8065
8351
|
async close() {
|
|
8066
8352
|
this.snapshotCache = null;
|
|
8067
|
-
if (this.
|
|
8068
|
-
const actionClient = this.
|
|
8069
|
-
const sessionId = this.
|
|
8353
|
+
if (this.cloud) {
|
|
8354
|
+
const actionClient = this.cloud.actionClient;
|
|
8355
|
+
const sessionId = this.cloud.sessionId;
|
|
8070
8356
|
const browser = this.browser;
|
|
8071
|
-
this.
|
|
8072
|
-
this.
|
|
8357
|
+
this.cloud.actionClient = null;
|
|
8358
|
+
this.cloud.sessionId = null;
|
|
8359
|
+
this.cloud.localRunId = null;
|
|
8360
|
+
this.cloud.cloudSessionUrl = null;
|
|
8073
8361
|
this.browser = null;
|
|
8074
8362
|
this.pageRef = null;
|
|
8075
8363
|
this.contextRef = null;
|
|
@@ -8081,7 +8369,7 @@ var Opensteer = class _Opensteer {
|
|
|
8081
8369
|
await browser.close().catch(() => void 0);
|
|
8082
8370
|
}
|
|
8083
8371
|
if (sessionId) {
|
|
8084
|
-
await this.
|
|
8372
|
+
await this.cloud.sessionClient.close(sessionId).catch(() => void 0);
|
|
8085
8373
|
}
|
|
8086
8374
|
return;
|
|
8087
8375
|
}
|
|
@@ -8093,17 +8381,17 @@ var Opensteer = class _Opensteer {
|
|
|
8093
8381
|
this.contextRef = null;
|
|
8094
8382
|
this.ownsBrowser = false;
|
|
8095
8383
|
}
|
|
8096
|
-
async
|
|
8097
|
-
if (!this.
|
|
8384
|
+
async syncLocalSelectorCacheToCloud() {
|
|
8385
|
+
if (!this.cloud) return;
|
|
8098
8386
|
const entries = collectLocalSelectorCacheEntries(this.storage);
|
|
8099
8387
|
if (!entries.length) return;
|
|
8100
|
-
await this.
|
|
8388
|
+
await this.cloud.sessionClient.importSelectorCache({
|
|
8101
8389
|
entries
|
|
8102
8390
|
});
|
|
8103
8391
|
}
|
|
8104
8392
|
async goto(url, options) {
|
|
8105
|
-
if (this.
|
|
8106
|
-
await this.
|
|
8393
|
+
if (this.cloud) {
|
|
8394
|
+
await this.invokeCloudActionAndResetCache("goto", { url, options });
|
|
8107
8395
|
return;
|
|
8108
8396
|
}
|
|
8109
8397
|
const { waitUntil = "domcontentloaded", ...rest } = options ?? {};
|
|
@@ -8112,8 +8400,8 @@ var Opensteer = class _Opensteer {
|
|
|
8112
8400
|
this.snapshotCache = null;
|
|
8113
8401
|
}
|
|
8114
8402
|
async snapshot(options = {}) {
|
|
8115
|
-
if (this.
|
|
8116
|
-
return await this.
|
|
8403
|
+
if (this.cloud) {
|
|
8404
|
+
return await this.invokeCloudActionAndResetCache("snapshot", {
|
|
8117
8405
|
options
|
|
8118
8406
|
});
|
|
8119
8407
|
}
|
|
@@ -8122,8 +8410,8 @@ var Opensteer = class _Opensteer {
|
|
|
8122
8410
|
return prepared.cleanedHtml;
|
|
8123
8411
|
}
|
|
8124
8412
|
async state() {
|
|
8125
|
-
if (this.
|
|
8126
|
-
return await this.
|
|
8413
|
+
if (this.cloud) {
|
|
8414
|
+
return await this.invokeCloudAction("state", {});
|
|
8127
8415
|
}
|
|
8128
8416
|
const html = await this.snapshot({ mode: "action" });
|
|
8129
8417
|
return {
|
|
@@ -8133,8 +8421,8 @@ var Opensteer = class _Opensteer {
|
|
|
8133
8421
|
};
|
|
8134
8422
|
}
|
|
8135
8423
|
async screenshot(options = {}) {
|
|
8136
|
-
if (this.
|
|
8137
|
-
const b64 = await this.
|
|
8424
|
+
if (this.cloud) {
|
|
8425
|
+
const b64 = await this.invokeCloudAction(
|
|
8138
8426
|
"screenshot",
|
|
8139
8427
|
options
|
|
8140
8428
|
);
|
|
@@ -8148,8 +8436,8 @@ var Opensteer = class _Opensteer {
|
|
|
8148
8436
|
});
|
|
8149
8437
|
}
|
|
8150
8438
|
async click(options) {
|
|
8151
|
-
if (this.
|
|
8152
|
-
return await this.
|
|
8439
|
+
if (this.cloud) {
|
|
8440
|
+
return await this.invokeCloudActionAndResetCache(
|
|
8153
8441
|
"click",
|
|
8154
8442
|
options
|
|
8155
8443
|
);
|
|
@@ -8161,8 +8449,8 @@ var Opensteer = class _Opensteer {
|
|
|
8161
8449
|
});
|
|
8162
8450
|
}
|
|
8163
8451
|
async dblclick(options) {
|
|
8164
|
-
if (this.
|
|
8165
|
-
return await this.
|
|
8452
|
+
if (this.cloud) {
|
|
8453
|
+
return await this.invokeCloudActionAndResetCache(
|
|
8166
8454
|
"dblclick",
|
|
8167
8455
|
options
|
|
8168
8456
|
);
|
|
@@ -8174,8 +8462,8 @@ var Opensteer = class _Opensteer {
|
|
|
8174
8462
|
});
|
|
8175
8463
|
}
|
|
8176
8464
|
async rightclick(options) {
|
|
8177
|
-
if (this.
|
|
8178
|
-
return await this.
|
|
8465
|
+
if (this.cloud) {
|
|
8466
|
+
return await this.invokeCloudActionAndResetCache(
|
|
8179
8467
|
"rightclick",
|
|
8180
8468
|
options
|
|
8181
8469
|
);
|
|
@@ -8187,8 +8475,8 @@ var Opensteer = class _Opensteer {
|
|
|
8187
8475
|
});
|
|
8188
8476
|
}
|
|
8189
8477
|
async hover(options) {
|
|
8190
|
-
if (this.
|
|
8191
|
-
return await this.
|
|
8478
|
+
if (this.cloud) {
|
|
8479
|
+
return await this.invokeCloudActionAndResetCache(
|
|
8192
8480
|
"hover",
|
|
8193
8481
|
options
|
|
8194
8482
|
);
|
|
@@ -8286,8 +8574,8 @@ var Opensteer = class _Opensteer {
|
|
|
8286
8574
|
);
|
|
8287
8575
|
}
|
|
8288
8576
|
async input(options) {
|
|
8289
|
-
if (this.
|
|
8290
|
-
return await this.
|
|
8577
|
+
if (this.cloud) {
|
|
8578
|
+
return await this.invokeCloudActionAndResetCache(
|
|
8291
8579
|
"input",
|
|
8292
8580
|
options
|
|
8293
8581
|
);
|
|
@@ -8389,8 +8677,8 @@ var Opensteer = class _Opensteer {
|
|
|
8389
8677
|
);
|
|
8390
8678
|
}
|
|
8391
8679
|
async select(options) {
|
|
8392
|
-
if (this.
|
|
8393
|
-
return await this.
|
|
8680
|
+
if (this.cloud) {
|
|
8681
|
+
return await this.invokeCloudActionAndResetCache(
|
|
8394
8682
|
"select",
|
|
8395
8683
|
options
|
|
8396
8684
|
);
|
|
@@ -8499,8 +8787,8 @@ var Opensteer = class _Opensteer {
|
|
|
8499
8787
|
);
|
|
8500
8788
|
}
|
|
8501
8789
|
async scroll(options = {}) {
|
|
8502
|
-
if (this.
|
|
8503
|
-
return await this.
|
|
8790
|
+
if (this.cloud) {
|
|
8791
|
+
return await this.invokeCloudActionAndResetCache(
|
|
8504
8792
|
"scroll",
|
|
8505
8793
|
options
|
|
8506
8794
|
);
|
|
@@ -8601,14 +8889,14 @@ var Opensteer = class _Opensteer {
|
|
|
8601
8889
|
}
|
|
8602
8890
|
// --- Tab Management ---
|
|
8603
8891
|
async tabs() {
|
|
8604
|
-
if (this.
|
|
8605
|
-
return await this.
|
|
8892
|
+
if (this.cloud) {
|
|
8893
|
+
return await this.invokeCloudAction("tabs", {});
|
|
8606
8894
|
}
|
|
8607
8895
|
return listTabs(this.context, this.page);
|
|
8608
8896
|
}
|
|
8609
8897
|
async newTab(url) {
|
|
8610
|
-
if (this.
|
|
8611
|
-
return await this.
|
|
8898
|
+
if (this.cloud) {
|
|
8899
|
+
return await this.invokeCloudActionAndResetCache("newTab", {
|
|
8612
8900
|
url
|
|
8613
8901
|
});
|
|
8614
8902
|
}
|
|
@@ -8618,8 +8906,8 @@ var Opensteer = class _Opensteer {
|
|
|
8618
8906
|
return info;
|
|
8619
8907
|
}
|
|
8620
8908
|
async switchTab(index) {
|
|
8621
|
-
if (this.
|
|
8622
|
-
await this.
|
|
8909
|
+
if (this.cloud) {
|
|
8910
|
+
await this.invokeCloudActionAndResetCache("switchTab", { index });
|
|
8623
8911
|
return;
|
|
8624
8912
|
}
|
|
8625
8913
|
const page = await switchTab(this.context, index);
|
|
@@ -8627,8 +8915,8 @@ var Opensteer = class _Opensteer {
|
|
|
8627
8915
|
this.snapshotCache = null;
|
|
8628
8916
|
}
|
|
8629
8917
|
async closeTab(index) {
|
|
8630
|
-
if (this.
|
|
8631
|
-
await this.
|
|
8918
|
+
if (this.cloud) {
|
|
8919
|
+
await this.invokeCloudActionAndResetCache("closeTab", { index });
|
|
8632
8920
|
return;
|
|
8633
8921
|
}
|
|
8634
8922
|
const newPage = await closeTab(this.context, this.page, index);
|
|
@@ -8639,8 +8927,8 @@ var Opensteer = class _Opensteer {
|
|
|
8639
8927
|
}
|
|
8640
8928
|
// --- Cookie Management ---
|
|
8641
8929
|
async getCookies(url) {
|
|
8642
|
-
if (this.
|
|
8643
|
-
return await this.
|
|
8930
|
+
if (this.cloud) {
|
|
8931
|
+
return await this.invokeCloudAction(
|
|
8644
8932
|
"getCookies",
|
|
8645
8933
|
{ url }
|
|
8646
8934
|
);
|
|
@@ -8648,41 +8936,41 @@ var Opensteer = class _Opensteer {
|
|
|
8648
8936
|
return getCookies(this.context, url);
|
|
8649
8937
|
}
|
|
8650
8938
|
async setCookie(cookie) {
|
|
8651
|
-
if (this.
|
|
8652
|
-
await this.
|
|
8939
|
+
if (this.cloud) {
|
|
8940
|
+
await this.invokeCloudAction("setCookie", cookie);
|
|
8653
8941
|
return;
|
|
8654
8942
|
}
|
|
8655
8943
|
return setCookie(this.context, cookie);
|
|
8656
8944
|
}
|
|
8657
8945
|
async clearCookies() {
|
|
8658
|
-
if (this.
|
|
8659
|
-
await this.
|
|
8946
|
+
if (this.cloud) {
|
|
8947
|
+
await this.invokeCloudAction("clearCookies", {});
|
|
8660
8948
|
return;
|
|
8661
8949
|
}
|
|
8662
8950
|
return clearCookies(this.context);
|
|
8663
8951
|
}
|
|
8664
8952
|
async exportCookies(filePath, url) {
|
|
8665
|
-
if (this.
|
|
8666
|
-
throw
|
|
8953
|
+
if (this.cloud) {
|
|
8954
|
+
throw cloudUnsupportedMethodError(
|
|
8667
8955
|
"exportCookies",
|
|
8668
|
-
"exportCookies() is not supported in
|
|
8956
|
+
"exportCookies() is not supported in cloud mode because it depends on local filesystem paths."
|
|
8669
8957
|
);
|
|
8670
8958
|
}
|
|
8671
8959
|
return exportCookies(this.context, filePath, url);
|
|
8672
8960
|
}
|
|
8673
8961
|
async importCookies(filePath) {
|
|
8674
|
-
if (this.
|
|
8675
|
-
throw
|
|
8962
|
+
if (this.cloud) {
|
|
8963
|
+
throw cloudUnsupportedMethodError(
|
|
8676
8964
|
"importCookies",
|
|
8677
|
-
"importCookies() is not supported in
|
|
8965
|
+
"importCookies() is not supported in cloud mode because it depends on local filesystem paths."
|
|
8678
8966
|
);
|
|
8679
8967
|
}
|
|
8680
8968
|
return importCookies(this.context, filePath);
|
|
8681
8969
|
}
|
|
8682
8970
|
// --- Keyboard Input ---
|
|
8683
8971
|
async pressKey(key) {
|
|
8684
|
-
if (this.
|
|
8685
|
-
await this.
|
|
8972
|
+
if (this.cloud) {
|
|
8973
|
+
await this.invokeCloudActionAndResetCache("pressKey", { key });
|
|
8686
8974
|
return;
|
|
8687
8975
|
}
|
|
8688
8976
|
await this.runWithPostActionWait("pressKey", void 0, async () => {
|
|
@@ -8691,8 +8979,8 @@ var Opensteer = class _Opensteer {
|
|
|
8691
8979
|
this.snapshotCache = null;
|
|
8692
8980
|
}
|
|
8693
8981
|
async type(text) {
|
|
8694
|
-
if (this.
|
|
8695
|
-
await this.
|
|
8982
|
+
if (this.cloud) {
|
|
8983
|
+
await this.invokeCloudActionAndResetCache("type", { text });
|
|
8696
8984
|
return;
|
|
8697
8985
|
}
|
|
8698
8986
|
await this.runWithPostActionWait("type", void 0, async () => {
|
|
@@ -8702,8 +8990,8 @@ var Opensteer = class _Opensteer {
|
|
|
8702
8990
|
}
|
|
8703
8991
|
// --- Element Info ---
|
|
8704
8992
|
async getElementText(options) {
|
|
8705
|
-
if (this.
|
|
8706
|
-
return await this.
|
|
8993
|
+
if (this.cloud) {
|
|
8994
|
+
return await this.invokeCloudAction("getElementText", options);
|
|
8707
8995
|
}
|
|
8708
8996
|
return this.executeElementInfoAction(
|
|
8709
8997
|
"getElementText",
|
|
@@ -8716,8 +9004,8 @@ var Opensteer = class _Opensteer {
|
|
|
8716
9004
|
);
|
|
8717
9005
|
}
|
|
8718
9006
|
async getElementValue(options) {
|
|
8719
|
-
if (this.
|
|
8720
|
-
return await this.
|
|
9007
|
+
if (this.cloud) {
|
|
9008
|
+
return await this.invokeCloudAction(
|
|
8721
9009
|
"getElementValue",
|
|
8722
9010
|
options
|
|
8723
9011
|
);
|
|
@@ -8732,8 +9020,8 @@ var Opensteer = class _Opensteer {
|
|
|
8732
9020
|
);
|
|
8733
9021
|
}
|
|
8734
9022
|
async getElementAttributes(options) {
|
|
8735
|
-
if (this.
|
|
8736
|
-
return await this.
|
|
9023
|
+
if (this.cloud) {
|
|
9024
|
+
return await this.invokeCloudAction(
|
|
8737
9025
|
"getElementAttributes",
|
|
8738
9026
|
options
|
|
8739
9027
|
);
|
|
@@ -8754,8 +9042,8 @@ var Opensteer = class _Opensteer {
|
|
|
8754
9042
|
);
|
|
8755
9043
|
}
|
|
8756
9044
|
async getElementBoundingBox(options) {
|
|
8757
|
-
if (this.
|
|
8758
|
-
return await this.
|
|
9045
|
+
if (this.cloud) {
|
|
9046
|
+
return await this.invokeCloudAction(
|
|
8759
9047
|
"getElementBoundingBox",
|
|
8760
9048
|
options
|
|
8761
9049
|
);
|
|
@@ -8770,14 +9058,14 @@ var Opensteer = class _Opensteer {
|
|
|
8770
9058
|
);
|
|
8771
9059
|
}
|
|
8772
9060
|
async getHtml(selector) {
|
|
8773
|
-
if (this.
|
|
8774
|
-
return await this.
|
|
9061
|
+
if (this.cloud) {
|
|
9062
|
+
return await this.invokeCloudAction("getHtml", { selector });
|
|
8775
9063
|
}
|
|
8776
9064
|
return getPageHtml(this.page, selector);
|
|
8777
9065
|
}
|
|
8778
9066
|
async getTitle() {
|
|
8779
|
-
if (this.
|
|
8780
|
-
return await this.
|
|
9067
|
+
if (this.cloud) {
|
|
9068
|
+
return await this.invokeCloudAction("getTitle", {});
|
|
8781
9069
|
}
|
|
8782
9070
|
return getPageTitle(this.page);
|
|
8783
9071
|
}
|
|
@@ -8815,10 +9103,10 @@ var Opensteer = class _Opensteer {
|
|
|
8815
9103
|
}
|
|
8816
9104
|
// --- File Upload ---
|
|
8817
9105
|
async uploadFile(options) {
|
|
8818
|
-
if (this.
|
|
8819
|
-
throw
|
|
9106
|
+
if (this.cloud) {
|
|
9107
|
+
throw cloudUnsupportedMethodError(
|
|
8820
9108
|
"uploadFile",
|
|
8821
|
-
"uploadFile() is not supported in
|
|
9109
|
+
"uploadFile() is not supported in cloud mode because file paths must be accessible on the cloud runtime."
|
|
8822
9110
|
);
|
|
8823
9111
|
}
|
|
8824
9112
|
const storageKey = this.resolveStorageKey(options.description);
|
|
@@ -8920,15 +9208,15 @@ var Opensteer = class _Opensteer {
|
|
|
8920
9208
|
}
|
|
8921
9209
|
// --- Wait for Text ---
|
|
8922
9210
|
async waitForText(text, options) {
|
|
8923
|
-
if (this.
|
|
8924
|
-
await this.
|
|
9211
|
+
if (this.cloud) {
|
|
9212
|
+
await this.invokeCloudAction("waitForText", { text, options });
|
|
8925
9213
|
return;
|
|
8926
9214
|
}
|
|
8927
9215
|
await this.page.getByText(text).first().waitFor({ timeout: options?.timeout ?? 3e4 });
|
|
8928
9216
|
}
|
|
8929
9217
|
async extract(options) {
|
|
8930
|
-
if (this.
|
|
8931
|
-
return await this.
|
|
9218
|
+
if (this.cloud) {
|
|
9219
|
+
return await this.invokeCloudAction("extract", options);
|
|
8932
9220
|
}
|
|
8933
9221
|
const storageKey = this.resolveStorageKey(options.description);
|
|
8934
9222
|
const schemaHash = options.schema ? computeSchemaHash(options.schema) : null;
|
|
@@ -8980,8 +9268,8 @@ var Opensteer = class _Opensteer {
|
|
|
8980
9268
|
return inflateDataPathObject(data);
|
|
8981
9269
|
}
|
|
8982
9270
|
async extractFromPlan(options) {
|
|
8983
|
-
if (this.
|
|
8984
|
-
return await this.
|
|
9271
|
+
if (this.cloud) {
|
|
9272
|
+
return await this.invokeCloudAction(
|
|
8985
9273
|
"extractFromPlan",
|
|
8986
9274
|
options
|
|
8987
9275
|
);
|
|
@@ -9030,10 +9318,10 @@ var Opensteer = class _Opensteer {
|
|
|
9030
9318
|
return this.storage;
|
|
9031
9319
|
}
|
|
9032
9320
|
clearCache() {
|
|
9033
|
-
if (this.
|
|
9321
|
+
if (this.cloud) {
|
|
9034
9322
|
this.snapshotCache = null;
|
|
9035
|
-
if (!this.
|
|
9036
|
-
void this.
|
|
9323
|
+
if (!this.cloud.actionClient) return;
|
|
9324
|
+
void this.invokeCloudAction("clearCache", {});
|
|
9037
9325
|
return;
|
|
9038
9326
|
}
|
|
9039
9327
|
this.storage.clearNamespace();
|
|
@@ -10061,6 +10349,16 @@ function getScrollDelta2(options) {
|
|
|
10061
10349
|
return { x: 0, y: absoluteAmount };
|
|
10062
10350
|
}
|
|
10063
10351
|
}
|
|
10352
|
+
function buildLocalRunId(namespace) {
|
|
10353
|
+
const normalized = namespace.trim() || "default";
|
|
10354
|
+
return `${normalized}-${Date.now().toString(36)}-${(0, import_crypto2.randomUUID)().slice(0, 8)}`;
|
|
10355
|
+
}
|
|
10356
|
+
function buildCloudSessionUrl(appUrl, sessionId) {
|
|
10357
|
+
if (!appUrl) {
|
|
10358
|
+
return null;
|
|
10359
|
+
}
|
|
10360
|
+
return `${appUrl}/browser/${encodeURIComponent(sessionId)}`;
|
|
10361
|
+
}
|
|
10064
10362
|
|
|
10065
10363
|
// src/cli/paths.ts
|
|
10066
10364
|
var import_os2 = require("os");
|
|
@@ -10462,7 +10760,8 @@ async function handleRequest(request, socket) {
|
|
|
10462
10760
|
url: instance.page.url(),
|
|
10463
10761
|
session,
|
|
10464
10762
|
name: activeNamespace,
|
|
10465
|
-
|
|
10763
|
+
cloudSessionId: instance.getCloudSessionId() ?? void 0,
|
|
10764
|
+
cloudSessionUrl: instance.getCloudSessionUrl() ?? void 0
|
|
10466
10765
|
}
|
|
10467
10766
|
});
|
|
10468
10767
|
} catch (err) {
|