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/index.cjs
CHANGED
|
@@ -338,6 +338,8 @@ var init_extractor = __esm({
|
|
|
338
338
|
var index_exports = {};
|
|
339
339
|
__export(index_exports, {
|
|
340
340
|
ActionWsClient: () => ActionWsClient,
|
|
341
|
+
CloudCdpClient: () => CloudCdpClient,
|
|
342
|
+
CloudSessionClient: () => CloudSessionClient,
|
|
341
343
|
CounterResolutionError: () => CounterResolutionError,
|
|
342
344
|
ElementPathError: () => ElementPathError,
|
|
343
345
|
LocalSelectorStorage: () => LocalSelectorStorage,
|
|
@@ -351,9 +353,7 @@ __export(index_exports, {
|
|
|
351
353
|
OS_UNAVAILABLE_ATTR: () => OS_UNAVAILABLE_ATTR,
|
|
352
354
|
Opensteer: () => Opensteer,
|
|
353
355
|
OpensteerActionError: () => OpensteerActionError,
|
|
354
|
-
|
|
355
|
-
RemoteCdpClient: () => RemoteCdpClient,
|
|
356
|
-
RemoteSessionClient: () => RemoteSessionClient,
|
|
356
|
+
OpensteerCloudError: () => OpensteerCloudError,
|
|
357
357
|
buildElementPathFromHandle: () => buildElementPathFromHandle,
|
|
358
358
|
buildElementPathFromSelector: () => buildElementPathFromSelector,
|
|
359
359
|
buildPathSelectorHint: () => buildPathSelectorHint,
|
|
@@ -365,6 +365,9 @@ __export(index_exports, {
|
|
|
365
365
|
clearCookies: () => clearCookies,
|
|
366
366
|
cloneElementPath: () => cloneElementPath,
|
|
367
367
|
closeTab: () => closeTab,
|
|
368
|
+
cloudNotLaunchedError: () => cloudNotLaunchedError,
|
|
369
|
+
cloudSessionContractVersion: () => cloudSessionContractVersion,
|
|
370
|
+
cloudUnsupportedMethodError: () => cloudUnsupportedMethodError,
|
|
368
371
|
collectLocalSelectorCacheEntries: () => collectLocalSelectorCacheEntries,
|
|
369
372
|
countArrayItemsWithPath: () => countArrayItemsWithPath,
|
|
370
373
|
createEmptyRegistry: () => createEmptyRegistry,
|
|
@@ -396,8 +399,6 @@ __export(index_exports, {
|
|
|
396
399
|
performSelect: () => performSelect,
|
|
397
400
|
prepareSnapshot: () => prepareSnapshot,
|
|
398
401
|
pressKey: () => pressKey,
|
|
399
|
-
remoteNotLaunchedError: () => remoteNotLaunchedError,
|
|
400
|
-
remoteUnsupportedMethodError: () => remoteUnsupportedMethodError,
|
|
401
402
|
resolveCounterElement: () => resolveCounterElement,
|
|
402
403
|
resolveCountersBatch: () => resolveCountersBatch,
|
|
403
404
|
resolveElementPath: () => resolveElementPath,
|
|
@@ -826,7 +827,7 @@ var BrowserPool = class {
|
|
|
826
827
|
const context = contexts[0];
|
|
827
828
|
const pages = context.pages();
|
|
828
829
|
const page = pages.length > 0 ? pages[0] : await context.newPage();
|
|
829
|
-
return { browser, context, page,
|
|
830
|
+
return { browser, context, page, isExternal: true };
|
|
830
831
|
} catch (error) {
|
|
831
832
|
if (browser) {
|
|
832
833
|
await browser.close().catch(() => void 0);
|
|
@@ -861,7 +862,7 @@ var BrowserPool = class {
|
|
|
861
862
|
context = await browser.newContext(options.context || {});
|
|
862
863
|
page = await context.newPage();
|
|
863
864
|
}
|
|
864
|
-
return { browser, context, page,
|
|
865
|
+
return { browser, context, page, isExternal: false };
|
|
865
866
|
}
|
|
866
867
|
async launchSandbox(options) {
|
|
867
868
|
const browser = await import_playwright.chromium.launch({
|
|
@@ -872,7 +873,7 @@ var BrowserPool = class {
|
|
|
872
873
|
const context = await browser.newContext(options.context || {});
|
|
873
874
|
const page = await context.newPage();
|
|
874
875
|
this.browser = browser;
|
|
875
|
-
return { browser, context, page,
|
|
876
|
+
return { browser, context, page, isExternal: false };
|
|
876
877
|
}
|
|
877
878
|
};
|
|
878
879
|
|
|
@@ -880,6 +881,7 @@ var BrowserPool = class {
|
|
|
880
881
|
var import_fs = __toESM(require("fs"), 1);
|
|
881
882
|
var import_path3 = __toESM(require("path"), 1);
|
|
882
883
|
var import_url = require("url");
|
|
884
|
+
var import_dotenv = require("dotenv");
|
|
883
885
|
|
|
884
886
|
// src/storage/namespace.ts
|
|
885
887
|
var import_path2 = __toESM(require("path"), 1);
|
|
@@ -929,6 +931,53 @@ var DEFAULT_CONFIG = {
|
|
|
929
931
|
model: "gpt-5.1",
|
|
930
932
|
debug: false
|
|
931
933
|
};
|
|
934
|
+
function dotenvFileOrder(nodeEnv) {
|
|
935
|
+
const normalized = nodeEnv?.trim() || "";
|
|
936
|
+
const files = [];
|
|
937
|
+
if (normalized) {
|
|
938
|
+
files.push(`.env.${normalized}.local`);
|
|
939
|
+
}
|
|
940
|
+
if (normalized !== "test") {
|
|
941
|
+
files.push(".env.local");
|
|
942
|
+
}
|
|
943
|
+
if (normalized) {
|
|
944
|
+
files.push(`.env.${normalized}`);
|
|
945
|
+
}
|
|
946
|
+
files.push(".env");
|
|
947
|
+
return files;
|
|
948
|
+
}
|
|
949
|
+
function loadDotenvValues(rootDir, baseEnv) {
|
|
950
|
+
const values = {};
|
|
951
|
+
if (parseBool(baseEnv.OPENSTEER_DISABLE_DOTENV_AUTOLOAD) === true) {
|
|
952
|
+
return values;
|
|
953
|
+
}
|
|
954
|
+
const baseDir = import_path3.default.resolve(rootDir);
|
|
955
|
+
const nodeEnv = baseEnv.NODE_ENV?.trim() || "";
|
|
956
|
+
for (const filename of dotenvFileOrder(nodeEnv)) {
|
|
957
|
+
const filePath = import_path3.default.join(baseDir, filename);
|
|
958
|
+
if (!import_fs.default.existsSync(filePath)) continue;
|
|
959
|
+
try {
|
|
960
|
+
const raw = import_fs.default.readFileSync(filePath, "utf8");
|
|
961
|
+
const parsed = (0, import_dotenv.parse)(raw);
|
|
962
|
+
for (const [key, value] of Object.entries(parsed)) {
|
|
963
|
+
if (values[key] === void 0) {
|
|
964
|
+
values[key] = value;
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
} catch {
|
|
968
|
+
continue;
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
return values;
|
|
972
|
+
}
|
|
973
|
+
function resolveEnv(rootDir) {
|
|
974
|
+
const baseEnv = process.env;
|
|
975
|
+
const dotenvValues = loadDotenvValues(rootDir, baseEnv);
|
|
976
|
+
return {
|
|
977
|
+
...dotenvValues,
|
|
978
|
+
...baseEnv
|
|
979
|
+
};
|
|
980
|
+
}
|
|
932
981
|
function hasOwn(config, key) {
|
|
933
982
|
if (!config || typeof config !== "object") return false;
|
|
934
983
|
return Object.prototype.hasOwnProperty.call(config, key);
|
|
@@ -943,28 +992,27 @@ function assertNoLegacyAiConfig(source, config) {
|
|
|
943
992
|
);
|
|
944
993
|
}
|
|
945
994
|
}
|
|
946
|
-
function
|
|
995
|
+
function assertNoLegacyRuntimeConfig(source, config) {
|
|
947
996
|
if (!config || typeof config !== "object") return;
|
|
948
997
|
const configRecord = config;
|
|
949
998
|
if (hasOwn(configRecord, "runtime")) {
|
|
950
999
|
throw new Error(
|
|
951
|
-
`Legacy "runtime" config is no longer supported in ${source}. Use top-level "
|
|
1000
|
+
`Legacy "runtime" config is no longer supported in ${source}. Use top-level "cloud" instead.`
|
|
952
1001
|
);
|
|
953
1002
|
}
|
|
954
|
-
if (hasOwn(configRecord, "
|
|
1003
|
+
if (hasOwn(configRecord, "mode")) {
|
|
955
1004
|
throw new Error(
|
|
956
|
-
`Top-level "
|
|
1005
|
+
`Top-level "mode" config is no longer supported in ${source}. Use "cloud: true" to enable cloud mode.`
|
|
957
1006
|
);
|
|
958
1007
|
}
|
|
959
|
-
|
|
960
|
-
if (typeof remoteValue === "boolean") {
|
|
1008
|
+
if (hasOwn(configRecord, "remote")) {
|
|
961
1009
|
throw new Error(
|
|
962
|
-
`
|
|
1010
|
+
`Top-level "remote" config is no longer supported in ${source}. Use "cloud" options instead.`
|
|
963
1011
|
);
|
|
964
1012
|
}
|
|
965
|
-
if (
|
|
1013
|
+
if (hasOwn(configRecord, "apiKey")) {
|
|
966
1014
|
throw new Error(
|
|
967
|
-
`
|
|
1015
|
+
`Top-level "apiKey" config is not supported in ${source}. Use "cloud.apiKey" instead.`
|
|
968
1016
|
);
|
|
969
1017
|
}
|
|
970
1018
|
}
|
|
@@ -1010,20 +1058,20 @@ function parseNumber(value) {
|
|
|
1010
1058
|
if (!Number.isFinite(parsed)) return void 0;
|
|
1011
1059
|
return parsed;
|
|
1012
1060
|
}
|
|
1013
|
-
function
|
|
1061
|
+
function parseRuntimeMode(value, source) {
|
|
1014
1062
|
if (value == null) return void 0;
|
|
1015
1063
|
if (typeof value !== "string") {
|
|
1016
1064
|
throw new Error(
|
|
1017
|
-
`Invalid ${source} value "${String(value)}". Use "local" or "
|
|
1065
|
+
`Invalid ${source} value "${String(value)}". Use "local" or "cloud".`
|
|
1018
1066
|
);
|
|
1019
1067
|
}
|
|
1020
1068
|
const normalized = value.trim().toLowerCase();
|
|
1021
1069
|
if (!normalized) return void 0;
|
|
1022
|
-
if (normalized === "local" || normalized === "
|
|
1070
|
+
if (normalized === "local" || normalized === "cloud") {
|
|
1023
1071
|
return normalized;
|
|
1024
1072
|
}
|
|
1025
1073
|
throw new Error(
|
|
1026
|
-
`Invalid ${source} value "${value}". Use "local" or "
|
|
1074
|
+
`Invalid ${source} value "${value}". Use "local" or "cloud".`
|
|
1027
1075
|
);
|
|
1028
1076
|
}
|
|
1029
1077
|
function parseAuthScheme(value, source) {
|
|
@@ -1042,99 +1090,138 @@ function parseAuthScheme(value, source) {
|
|
|
1042
1090
|
`Invalid ${source} value "${value}". Use "api-key" or "bearer".`
|
|
1043
1091
|
);
|
|
1044
1092
|
}
|
|
1045
|
-
function
|
|
1046
|
-
|
|
1093
|
+
function parseCloudAnnounce(value, source) {
|
|
1094
|
+
if (value == null) return void 0;
|
|
1095
|
+
if (typeof value !== "string") {
|
|
1096
|
+
throw new Error(
|
|
1097
|
+
`Invalid ${source} value "${String(value)}". Use "always", "off", or "tty".`
|
|
1098
|
+
);
|
|
1099
|
+
}
|
|
1100
|
+
const normalized = value.trim().toLowerCase();
|
|
1101
|
+
if (!normalized) return void 0;
|
|
1102
|
+
if (normalized === "always" || normalized === "off" || normalized === "tty") {
|
|
1103
|
+
return normalized;
|
|
1104
|
+
}
|
|
1105
|
+
throw new Error(
|
|
1106
|
+
`Invalid ${source} value "${value}". Use "always", "off", or "tty".`
|
|
1107
|
+
);
|
|
1108
|
+
}
|
|
1109
|
+
function resolveOpensteerApiKey(env) {
|
|
1110
|
+
const value = env.OPENSTEER_API_KEY?.trim();
|
|
1047
1111
|
if (!value) return void 0;
|
|
1048
1112
|
return value;
|
|
1049
1113
|
}
|
|
1050
|
-
function resolveOpensteerAuthScheme() {
|
|
1051
|
-
return parseAuthScheme(
|
|
1052
|
-
process.env.OPENSTEER_AUTH_SCHEME,
|
|
1053
|
-
"OPENSTEER_AUTH_SCHEME"
|
|
1054
|
-
);
|
|
1114
|
+
function resolveOpensteerAuthScheme(env) {
|
|
1115
|
+
return parseAuthScheme(env.OPENSTEER_AUTH_SCHEME, "OPENSTEER_AUTH_SCHEME");
|
|
1055
1116
|
}
|
|
1056
|
-
function
|
|
1117
|
+
function normalizeCloudOptions(value) {
|
|
1057
1118
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1058
1119
|
return void 0;
|
|
1059
1120
|
}
|
|
1060
1121
|
return value;
|
|
1061
1122
|
}
|
|
1062
|
-
function
|
|
1063
|
-
|
|
1064
|
-
if (
|
|
1123
|
+
function parseCloudEnabled(value, source) {
|
|
1124
|
+
if (value == null) return void 0;
|
|
1125
|
+
if (typeof value === "boolean") return value;
|
|
1126
|
+
if (typeof value === "object" && !Array.isArray(value)) return true;
|
|
1127
|
+
throw new Error(
|
|
1128
|
+
`Invalid ${source} value "${String(value)}". Use true, false, or a cloud options object.`
|
|
1129
|
+
);
|
|
1130
|
+
}
|
|
1131
|
+
function resolveCloudSelection(config, env = process.env) {
|
|
1132
|
+
const configCloud = parseCloudEnabled(config.cloud, "cloud");
|
|
1133
|
+
if (configCloud !== void 0) {
|
|
1065
1134
|
return {
|
|
1066
|
-
|
|
1067
|
-
source: "config.
|
|
1135
|
+
cloud: configCloud,
|
|
1136
|
+
source: "config.cloud"
|
|
1068
1137
|
};
|
|
1069
1138
|
}
|
|
1070
|
-
const envMode =
|
|
1139
|
+
const envMode = parseRuntimeMode(env.OPENSTEER_MODE, "OPENSTEER_MODE");
|
|
1071
1140
|
if (envMode) {
|
|
1072
1141
|
return {
|
|
1073
|
-
|
|
1142
|
+
cloud: envMode === "cloud",
|
|
1074
1143
|
source: "env.OPENSTEER_MODE"
|
|
1075
1144
|
};
|
|
1076
1145
|
}
|
|
1077
1146
|
return {
|
|
1078
|
-
|
|
1147
|
+
cloud: false,
|
|
1079
1148
|
source: "default"
|
|
1080
1149
|
};
|
|
1081
1150
|
}
|
|
1082
1151
|
function resolveConfig(input = {}) {
|
|
1083
|
-
|
|
1152
|
+
const initialRootDir = input.storage?.rootDir ?? process.cwd();
|
|
1153
|
+
const runtimeDefaults = mergeDeep(DEFAULT_CONFIG, {
|
|
1154
|
+
storage: {
|
|
1155
|
+
rootDir: initialRootDir
|
|
1156
|
+
}
|
|
1157
|
+
});
|
|
1158
|
+
assertNoLegacyAiConfig("Opensteer constructor config", input);
|
|
1159
|
+
assertNoLegacyRuntimeConfig("Opensteer constructor config", input);
|
|
1160
|
+
const fileConfig = loadConfigFile(initialRootDir);
|
|
1161
|
+
assertNoLegacyAiConfig(".opensteer/config.json", fileConfig);
|
|
1162
|
+
assertNoLegacyRuntimeConfig(".opensteer/config.json", fileConfig);
|
|
1163
|
+
const fileRootDir = typeof fileConfig.storage?.rootDir === "string" ? fileConfig.storage.rootDir : void 0;
|
|
1164
|
+
const envRootDir = input.storage?.rootDir ?? fileRootDir ?? initialRootDir;
|
|
1165
|
+
const env = resolveEnv(envRootDir);
|
|
1166
|
+
if (env.OPENSTEER_AI_MODEL) {
|
|
1084
1167
|
throw new Error(
|
|
1085
1168
|
"OPENSTEER_AI_MODEL is no longer supported. Use OPENSTEER_MODEL instead."
|
|
1086
1169
|
);
|
|
1087
1170
|
}
|
|
1088
|
-
if (
|
|
1171
|
+
if (env.OPENSTEER_RUNTIME != null) {
|
|
1089
1172
|
throw new Error(
|
|
1090
1173
|
"OPENSTEER_RUNTIME is no longer supported. Use OPENSTEER_MODE instead."
|
|
1091
1174
|
);
|
|
1092
1175
|
}
|
|
1093
|
-
assertNoLegacyAiConfig("Opensteer constructor config", input);
|
|
1094
|
-
assertNoLegacyModeConfig("Opensteer constructor config", input);
|
|
1095
|
-
const rootDir = input.storage?.rootDir ?? DEFAULT_CONFIG.storage.rootDir ?? process.cwd();
|
|
1096
|
-
const fileConfig = loadConfigFile(rootDir);
|
|
1097
|
-
assertNoLegacyAiConfig(".opensteer/config.json", fileConfig);
|
|
1098
|
-
assertNoLegacyModeConfig(".opensteer/config.json", fileConfig);
|
|
1099
1176
|
const envConfig = {
|
|
1100
1177
|
browser: {
|
|
1101
|
-
headless: parseBool(
|
|
1102
|
-
executablePath:
|
|
1103
|
-
slowMo: parseNumber(
|
|
1104
|
-
connectUrl:
|
|
1105
|
-
channel:
|
|
1106
|
-
profileDir:
|
|
1178
|
+
headless: parseBool(env.OPENSTEER_HEADLESS),
|
|
1179
|
+
executablePath: env.OPENSTEER_BROWSER_PATH || void 0,
|
|
1180
|
+
slowMo: parseNumber(env.OPENSTEER_SLOW_MO),
|
|
1181
|
+
connectUrl: env.OPENSTEER_CONNECT_URL || void 0,
|
|
1182
|
+
channel: env.OPENSTEER_CHANNEL || void 0,
|
|
1183
|
+
profileDir: env.OPENSTEER_PROFILE_DIR || void 0
|
|
1107
1184
|
},
|
|
1108
|
-
model:
|
|
1109
|
-
debug: parseBool(
|
|
1185
|
+
model: env.OPENSTEER_MODEL || void 0,
|
|
1186
|
+
debug: parseBool(env.OPENSTEER_DEBUG)
|
|
1110
1187
|
};
|
|
1111
|
-
const mergedWithFile = mergeDeep(
|
|
1188
|
+
const mergedWithFile = mergeDeep(runtimeDefaults, fileConfig);
|
|
1112
1189
|
const mergedWithEnv = mergeDeep(mergedWithFile, envConfig);
|
|
1113
1190
|
const resolved = mergeDeep(mergedWithEnv, input);
|
|
1114
|
-
const envApiKey = resolveOpensteerApiKey();
|
|
1115
|
-
const envAuthScheme = resolveOpensteerAuthScheme();
|
|
1116
|
-
const
|
|
1191
|
+
const envApiKey = resolveOpensteerApiKey(env);
|
|
1192
|
+
const envAuthScheme = resolveOpensteerAuthScheme(env);
|
|
1193
|
+
const envCloudAnnounce = parseCloudAnnounce(
|
|
1194
|
+
env.OPENSTEER_REMOTE_ANNOUNCE,
|
|
1195
|
+
"OPENSTEER_REMOTE_ANNOUNCE"
|
|
1196
|
+
);
|
|
1197
|
+
const inputCloudOptions = normalizeCloudOptions(input.cloud);
|
|
1117
1198
|
const inputAuthScheme = parseAuthScheme(
|
|
1118
|
-
|
|
1119
|
-
"
|
|
1199
|
+
inputCloudOptions?.authScheme,
|
|
1200
|
+
"cloud.authScheme"
|
|
1120
1201
|
);
|
|
1121
|
-
const
|
|
1122
|
-
|
|
1202
|
+
const inputCloudAnnounce = parseCloudAnnounce(
|
|
1203
|
+
inputCloudOptions?.announce,
|
|
1204
|
+
"cloud.announce"
|
|
1123
1205
|
);
|
|
1124
|
-
const
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1206
|
+
const inputHasCloudApiKey = Boolean(
|
|
1207
|
+
inputCloudOptions && Object.prototype.hasOwnProperty.call(inputCloudOptions, "apiKey")
|
|
1208
|
+
);
|
|
1209
|
+
const cloudSelection = resolveCloudSelection({
|
|
1210
|
+
cloud: resolved.cloud
|
|
1211
|
+
}, env);
|
|
1212
|
+
if (cloudSelection.cloud) {
|
|
1213
|
+
const resolvedCloud = normalizeCloudOptions(resolved.cloud) ?? {};
|
|
1214
|
+
const authScheme = inputAuthScheme ?? envAuthScheme ?? parseAuthScheme(resolvedCloud.authScheme, "cloud.authScheme") ?? "api-key";
|
|
1215
|
+
const announce = inputCloudAnnounce ?? envCloudAnnounce ?? parseCloudAnnounce(resolvedCloud.announce, "cloud.announce") ?? "always";
|
|
1216
|
+
resolved.cloud = {
|
|
1217
|
+
...resolvedCloud,
|
|
1218
|
+
authScheme,
|
|
1219
|
+
announce
|
|
1133
1220
|
};
|
|
1134
1221
|
}
|
|
1135
|
-
if (envApiKey &&
|
|
1136
|
-
resolved.
|
|
1137
|
-
...
|
|
1222
|
+
if (envApiKey && cloudSelection.cloud && !inputHasCloudApiKey) {
|
|
1223
|
+
resolved.cloud = {
|
|
1224
|
+
...normalizeCloudOptions(resolved.cloud) ?? {},
|
|
1138
1225
|
apiKey: envApiKey
|
|
1139
1226
|
};
|
|
1140
1227
|
}
|
|
@@ -7441,36 +7528,39 @@ function clonePersistedExtractNode(node) {
|
|
|
7441
7528
|
return JSON.parse(JSON.stringify(node));
|
|
7442
7529
|
}
|
|
7443
7530
|
|
|
7444
|
-
// src/
|
|
7531
|
+
// src/cloud/contracts.ts
|
|
7532
|
+
var cloudSessionContractVersion = "v3";
|
|
7533
|
+
|
|
7534
|
+
// src/cloud/action-ws-client.ts
|
|
7445
7535
|
var import_ws2 = __toESM(require("ws"), 1);
|
|
7446
7536
|
|
|
7447
|
-
// src/
|
|
7448
|
-
var
|
|
7537
|
+
// src/cloud/errors.ts
|
|
7538
|
+
var OpensteerCloudError = class extends Error {
|
|
7449
7539
|
code;
|
|
7450
7540
|
status;
|
|
7451
7541
|
details;
|
|
7452
7542
|
constructor(code, message, status, details) {
|
|
7453
7543
|
super(message);
|
|
7454
|
-
this.name = "
|
|
7544
|
+
this.name = "OpensteerCloudError";
|
|
7455
7545
|
this.code = code;
|
|
7456
7546
|
this.status = status;
|
|
7457
7547
|
this.details = details;
|
|
7458
7548
|
}
|
|
7459
7549
|
};
|
|
7460
|
-
function
|
|
7461
|
-
return new
|
|
7462
|
-
"
|
|
7463
|
-
message || `${method} is not supported in
|
|
7550
|
+
function cloudUnsupportedMethodError(method, message) {
|
|
7551
|
+
return new OpensteerCloudError(
|
|
7552
|
+
"CLOUD_UNSUPPORTED_METHOD",
|
|
7553
|
+
message || `${method} is not supported in cloud mode.`
|
|
7464
7554
|
);
|
|
7465
7555
|
}
|
|
7466
|
-
function
|
|
7467
|
-
return new
|
|
7468
|
-
"
|
|
7469
|
-
"
|
|
7556
|
+
function cloudNotLaunchedError() {
|
|
7557
|
+
return new OpensteerCloudError(
|
|
7558
|
+
"CLOUD_SESSION_NOT_FOUND",
|
|
7559
|
+
"Cloud session is not connected. Call launch() first."
|
|
7470
7560
|
);
|
|
7471
7561
|
}
|
|
7472
7562
|
|
|
7473
|
-
// src/
|
|
7563
|
+
// src/cloud/action-ws-client.ts
|
|
7474
7564
|
var ActionWsClient = class _ActionWsClient {
|
|
7475
7565
|
ws;
|
|
7476
7566
|
sessionId;
|
|
@@ -7487,18 +7577,18 @@ var ActionWsClient = class _ActionWsClient {
|
|
|
7487
7577
|
});
|
|
7488
7578
|
ws.on("error", (error) => {
|
|
7489
7579
|
this.rejectAll(
|
|
7490
|
-
new
|
|
7491
|
-
"
|
|
7492
|
-
`
|
|
7580
|
+
new OpensteerCloudError(
|
|
7581
|
+
"CLOUD_TRANSPORT_ERROR",
|
|
7582
|
+
`Cloud action websocket error: ${error.message}`
|
|
7493
7583
|
)
|
|
7494
7584
|
);
|
|
7495
7585
|
});
|
|
7496
7586
|
ws.on("close", () => {
|
|
7497
7587
|
this.closed = true;
|
|
7498
7588
|
this.rejectAll(
|
|
7499
|
-
new
|
|
7500
|
-
"
|
|
7501
|
-
"
|
|
7589
|
+
new OpensteerCloudError(
|
|
7590
|
+
"CLOUD_SESSION_CLOSED",
|
|
7591
|
+
"Cloud action websocket closed."
|
|
7502
7592
|
)
|
|
7503
7593
|
);
|
|
7504
7594
|
});
|
|
@@ -7510,8 +7600,8 @@ var ActionWsClient = class _ActionWsClient {
|
|
|
7510
7600
|
ws.once("open", () => resolve());
|
|
7511
7601
|
ws.once("error", (error) => {
|
|
7512
7602
|
reject(
|
|
7513
|
-
new
|
|
7514
|
-
"
|
|
7603
|
+
new OpensteerCloudError(
|
|
7604
|
+
"CLOUD_TRANSPORT_ERROR",
|
|
7515
7605
|
`Failed to connect action websocket: ${error.message}`
|
|
7516
7606
|
)
|
|
7517
7607
|
);
|
|
@@ -7521,9 +7611,9 @@ var ActionWsClient = class _ActionWsClient {
|
|
|
7521
7611
|
}
|
|
7522
7612
|
async request(method, args) {
|
|
7523
7613
|
if (this.closed || this.ws.readyState !== import_ws2.default.OPEN) {
|
|
7524
|
-
throw new
|
|
7525
|
-
"
|
|
7526
|
-
"
|
|
7614
|
+
throw new OpensteerCloudError(
|
|
7615
|
+
"CLOUD_SESSION_CLOSED",
|
|
7616
|
+
"Cloud action websocket is closed."
|
|
7527
7617
|
);
|
|
7528
7618
|
}
|
|
7529
7619
|
const id = this.nextRequestId;
|
|
@@ -7542,8 +7632,8 @@ var ActionWsClient = class _ActionWsClient {
|
|
|
7542
7632
|
this.ws.send(JSON.stringify(payload));
|
|
7543
7633
|
} catch (error) {
|
|
7544
7634
|
this.pending.delete(id);
|
|
7545
|
-
const message = error instanceof Error ? error.message : "Failed to send
|
|
7546
|
-
throw new
|
|
7635
|
+
const message = error instanceof Error ? error.message : "Failed to send cloud action request.";
|
|
7636
|
+
throw new OpensteerCloudError("CLOUD_TRANSPORT_ERROR", message);
|
|
7547
7637
|
}
|
|
7548
7638
|
return await resultPromise;
|
|
7549
7639
|
}
|
|
@@ -7561,9 +7651,9 @@ var ActionWsClient = class _ActionWsClient {
|
|
|
7561
7651
|
parsed = JSON.parse(rawDataToUtf8(raw));
|
|
7562
7652
|
} catch {
|
|
7563
7653
|
this.rejectAll(
|
|
7564
|
-
new
|
|
7565
|
-
"
|
|
7566
|
-
"Invalid
|
|
7654
|
+
new OpensteerCloudError(
|
|
7655
|
+
"CLOUD_TRANSPORT_ERROR",
|
|
7656
|
+
"Invalid cloud action response payload."
|
|
7567
7657
|
)
|
|
7568
7658
|
);
|
|
7569
7659
|
return;
|
|
@@ -7576,7 +7666,7 @@ var ActionWsClient = class _ActionWsClient {
|
|
|
7576
7666
|
return;
|
|
7577
7667
|
}
|
|
7578
7668
|
pending.reject(
|
|
7579
|
-
new
|
|
7669
|
+
new OpensteerCloudError(
|
|
7580
7670
|
parsed.code,
|
|
7581
7671
|
parsed.error,
|
|
7582
7672
|
void 0,
|
|
@@ -7604,7 +7694,7 @@ function withTokenQuery(wsUrl, token) {
|
|
|
7604
7694
|
return url.toString();
|
|
7605
7695
|
}
|
|
7606
7696
|
|
|
7607
|
-
// src/
|
|
7697
|
+
// src/cloud/local-cache-sync.ts
|
|
7608
7698
|
var import_fs3 = __toESM(require("fs"), 1);
|
|
7609
7699
|
var import_path5 = __toESM(require("path"), 1);
|
|
7610
7700
|
function collectLocalSelectorCacheEntries(storage) {
|
|
@@ -7728,24 +7818,24 @@ function dedupeNewest(entries) {
|
|
|
7728
7818
|
return [...byKey.values()];
|
|
7729
7819
|
}
|
|
7730
7820
|
|
|
7731
|
-
// src/
|
|
7821
|
+
// src/cloud/cdp-client.ts
|
|
7732
7822
|
var import_playwright2 = require("playwright");
|
|
7733
|
-
var
|
|
7823
|
+
var CloudCdpClient = class {
|
|
7734
7824
|
async connect(args) {
|
|
7735
7825
|
const endpoint = withTokenQuery2(args.wsUrl, args.token);
|
|
7736
7826
|
let browser;
|
|
7737
7827
|
try {
|
|
7738
7828
|
browser = await import_playwright2.chromium.connectOverCDP(endpoint);
|
|
7739
7829
|
} catch (error) {
|
|
7740
|
-
const message = error instanceof Error ? error.message : "Failed to connect to
|
|
7741
|
-
throw new
|
|
7830
|
+
const message = error instanceof Error ? error.message : "Failed to connect to cloud CDP endpoint.";
|
|
7831
|
+
throw new OpensteerCloudError("CLOUD_TRANSPORT_ERROR", message);
|
|
7742
7832
|
}
|
|
7743
7833
|
const context = browser.contexts()[0];
|
|
7744
7834
|
if (!context) {
|
|
7745
7835
|
await browser.close();
|
|
7746
|
-
throw new
|
|
7747
|
-
"
|
|
7748
|
-
"
|
|
7836
|
+
throw new OpensteerCloudError(
|
|
7837
|
+
"CLOUD_INTERNAL",
|
|
7838
|
+
"Cloud browser returned no context."
|
|
7749
7839
|
);
|
|
7750
7840
|
}
|
|
7751
7841
|
const page = context.pages()[0] || await context.newPage();
|
|
@@ -7758,9 +7848,9 @@ function withTokenQuery2(wsUrl, token) {
|
|
|
7758
7848
|
return url.toString();
|
|
7759
7849
|
}
|
|
7760
7850
|
|
|
7761
|
-
// src/
|
|
7851
|
+
// src/cloud/session-client.ts
|
|
7762
7852
|
var CACHE_IMPORT_BATCH_SIZE = 200;
|
|
7763
|
-
var
|
|
7853
|
+
var CloudSessionClient = class {
|
|
7764
7854
|
baseUrl;
|
|
7765
7855
|
key;
|
|
7766
7856
|
authScheme;
|
|
@@ -7781,7 +7871,17 @@ var RemoteSessionClient = class {
|
|
|
7781
7871
|
if (!response.ok) {
|
|
7782
7872
|
throw await parseHttpError(response);
|
|
7783
7873
|
}
|
|
7784
|
-
|
|
7874
|
+
let body;
|
|
7875
|
+
try {
|
|
7876
|
+
body = await response.json();
|
|
7877
|
+
} catch {
|
|
7878
|
+
throw new OpensteerCloudError(
|
|
7879
|
+
"CLOUD_CONTRACT_MISMATCH",
|
|
7880
|
+
"Invalid cloud session create response: expected a JSON object.",
|
|
7881
|
+
response.status
|
|
7882
|
+
);
|
|
7883
|
+
}
|
|
7884
|
+
return parseCreateResponse(body, response.status);
|
|
7785
7885
|
}
|
|
7786
7886
|
async close(sessionId) {
|
|
7787
7887
|
const response = await fetch(`${this.baseUrl}/sessions/${sessionId}`, {
|
|
@@ -7840,6 +7940,134 @@ var RemoteSessionClient = class {
|
|
|
7840
7940
|
function normalizeBaseUrl(baseUrl) {
|
|
7841
7941
|
return baseUrl.replace(/\/+$/, "");
|
|
7842
7942
|
}
|
|
7943
|
+
function parseCreateResponse(body, status) {
|
|
7944
|
+
const root = requireObject(
|
|
7945
|
+
body,
|
|
7946
|
+
"Invalid cloud session create response: expected a JSON object.",
|
|
7947
|
+
status
|
|
7948
|
+
);
|
|
7949
|
+
const sessionId = requireString(root, "sessionId", status);
|
|
7950
|
+
const actionWsUrl = requireString(root, "actionWsUrl", status);
|
|
7951
|
+
const cdpWsUrl = requireString(root, "cdpWsUrl", status);
|
|
7952
|
+
const actionToken = requireString(root, "actionToken", status);
|
|
7953
|
+
const cdpToken = requireString(root, "cdpToken", status);
|
|
7954
|
+
const cloudSessionUrl = requireString(root, "cloudSessionUrl", status);
|
|
7955
|
+
const cloudSessionRoot = requireObject(
|
|
7956
|
+
root.cloudSession,
|
|
7957
|
+
"Invalid cloud session create response: cloudSession must be an object.",
|
|
7958
|
+
status
|
|
7959
|
+
);
|
|
7960
|
+
const cloudSession = {
|
|
7961
|
+
sessionId: requireString(cloudSessionRoot, "sessionId", status, "cloudSession"),
|
|
7962
|
+
workspaceId: requireString(
|
|
7963
|
+
cloudSessionRoot,
|
|
7964
|
+
"workspaceId",
|
|
7965
|
+
status,
|
|
7966
|
+
"cloudSession"
|
|
7967
|
+
),
|
|
7968
|
+
state: requireString(cloudSessionRoot, "state", status, "cloudSession"),
|
|
7969
|
+
createdAt: requireNumber(cloudSessionRoot, "createdAt", status, "cloudSession"),
|
|
7970
|
+
sourceType: requireSourceType(cloudSessionRoot, "sourceType", status, "cloudSession"),
|
|
7971
|
+
sourceRef: optionalString(cloudSessionRoot, "sourceRef", status, "cloudSession"),
|
|
7972
|
+
label: optionalString(cloudSessionRoot, "label", status, "cloudSession")
|
|
7973
|
+
};
|
|
7974
|
+
const expiresAt = optionalNumber(root, "expiresAt", status);
|
|
7975
|
+
return {
|
|
7976
|
+
sessionId,
|
|
7977
|
+
actionWsUrl,
|
|
7978
|
+
cdpWsUrl,
|
|
7979
|
+
actionToken,
|
|
7980
|
+
cdpToken,
|
|
7981
|
+
expiresAt,
|
|
7982
|
+
cloudSessionUrl,
|
|
7983
|
+
cloudSession
|
|
7984
|
+
};
|
|
7985
|
+
}
|
|
7986
|
+
function requireObject(value, message, status) {
|
|
7987
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
7988
|
+
throw new OpensteerCloudError("CLOUD_CONTRACT_MISMATCH", message, status);
|
|
7989
|
+
}
|
|
7990
|
+
return value;
|
|
7991
|
+
}
|
|
7992
|
+
function requireString(source, field, status, parent) {
|
|
7993
|
+
const value = source[field];
|
|
7994
|
+
if (typeof value !== "string" || !value.trim()) {
|
|
7995
|
+
throw new OpensteerCloudError(
|
|
7996
|
+
"CLOUD_CONTRACT_MISMATCH",
|
|
7997
|
+
`Invalid cloud session create response: ${formatFieldPath(
|
|
7998
|
+
field,
|
|
7999
|
+
parent
|
|
8000
|
+
)} must be a non-empty string.`,
|
|
8001
|
+
status
|
|
8002
|
+
);
|
|
8003
|
+
}
|
|
8004
|
+
return value;
|
|
8005
|
+
}
|
|
8006
|
+
function requireNumber(source, field, status, parent) {
|
|
8007
|
+
const value = source[field];
|
|
8008
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
8009
|
+
throw new OpensteerCloudError(
|
|
8010
|
+
"CLOUD_CONTRACT_MISMATCH",
|
|
8011
|
+
`Invalid cloud session create response: ${formatFieldPath(
|
|
8012
|
+
field,
|
|
8013
|
+
parent
|
|
8014
|
+
)} must be a finite number.`,
|
|
8015
|
+
status
|
|
8016
|
+
);
|
|
8017
|
+
}
|
|
8018
|
+
return value;
|
|
8019
|
+
}
|
|
8020
|
+
function optionalString(source, field, status, parent) {
|
|
8021
|
+
const value = source[field];
|
|
8022
|
+
if (value == null) {
|
|
8023
|
+
return void 0;
|
|
8024
|
+
}
|
|
8025
|
+
if (typeof value !== "string") {
|
|
8026
|
+
throw new OpensteerCloudError(
|
|
8027
|
+
"CLOUD_CONTRACT_MISMATCH",
|
|
8028
|
+
`Invalid cloud session create response: ${formatFieldPath(
|
|
8029
|
+
field,
|
|
8030
|
+
parent
|
|
8031
|
+
)} must be a string when present.`,
|
|
8032
|
+
status
|
|
8033
|
+
);
|
|
8034
|
+
}
|
|
8035
|
+
return value;
|
|
8036
|
+
}
|
|
8037
|
+
function optionalNumber(source, field, status, parent) {
|
|
8038
|
+
const value = source[field];
|
|
8039
|
+
if (value == null) {
|
|
8040
|
+
return void 0;
|
|
8041
|
+
}
|
|
8042
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
8043
|
+
throw new OpensteerCloudError(
|
|
8044
|
+
"CLOUD_CONTRACT_MISMATCH",
|
|
8045
|
+
`Invalid cloud session create response: ${formatFieldPath(
|
|
8046
|
+
field,
|
|
8047
|
+
parent
|
|
8048
|
+
)} must be a finite number when present.`,
|
|
8049
|
+
status
|
|
8050
|
+
);
|
|
8051
|
+
}
|
|
8052
|
+
return value;
|
|
8053
|
+
}
|
|
8054
|
+
function requireSourceType(source, field, status, parent) {
|
|
8055
|
+
const value = source[field];
|
|
8056
|
+
if (value === "agent-thread" || value === "agent-run" || value === "local-cloud" || value === "manual") {
|
|
8057
|
+
return value;
|
|
8058
|
+
}
|
|
8059
|
+
throw new OpensteerCloudError(
|
|
8060
|
+
"CLOUD_CONTRACT_MISMATCH",
|
|
8061
|
+
`Invalid cloud session create response: ${formatFieldPath(
|
|
8062
|
+
field,
|
|
8063
|
+
parent
|
|
8064
|
+
)} must be one of "agent-thread", "agent-run", "local-cloud", or "manual".`,
|
|
8065
|
+
status
|
|
8066
|
+
);
|
|
8067
|
+
}
|
|
8068
|
+
function formatFieldPath(field, parent) {
|
|
8069
|
+
return parent ? `"${parent}.${field}"` : `"${field}"`;
|
|
8070
|
+
}
|
|
7843
8071
|
function zeroImportResponse() {
|
|
7844
8072
|
return {
|
|
7845
8073
|
imported: 0,
|
|
@@ -7863,33 +8091,46 @@ async function parseHttpError(response) {
|
|
|
7863
8091
|
} catch {
|
|
7864
8092
|
body = null;
|
|
7865
8093
|
}
|
|
7866
|
-
const code = typeof body?.code === "string" ?
|
|
7867
|
-
const message = typeof body?.error === "string" ? body.error : `
|
|
7868
|
-
return new
|
|
8094
|
+
const code = typeof body?.code === "string" ? toCloudErrorCode(body.code) : "CLOUD_TRANSPORT_ERROR";
|
|
8095
|
+
const message = typeof body?.error === "string" ? body.error : `Cloud request failed with status ${response.status}.`;
|
|
8096
|
+
return new OpensteerCloudError(code, message, response.status, body?.details);
|
|
7869
8097
|
}
|
|
7870
|
-
function
|
|
7871
|
-
if (code === "
|
|
8098
|
+
function toCloudErrorCode(code) {
|
|
8099
|
+
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") {
|
|
7872
8100
|
return code;
|
|
7873
8101
|
}
|
|
7874
|
-
return "
|
|
8102
|
+
return "CLOUD_TRANSPORT_ERROR";
|
|
7875
8103
|
}
|
|
7876
8104
|
|
|
7877
|
-
// src/
|
|
7878
|
-
var
|
|
7879
|
-
|
|
8105
|
+
// src/cloud/runtime.ts
|
|
8106
|
+
var DEFAULT_CLOUD_BASE_URL = "https://remote.opensteer.com";
|
|
8107
|
+
var DEFAULT_CLOUD_APP_URL = "https://opensteer.com";
|
|
8108
|
+
function createCloudRuntimeState(key, baseUrl = resolveCloudBaseUrl(), authScheme = "api-key", appUrl = resolveCloudAppUrl()) {
|
|
7880
8109
|
return {
|
|
7881
|
-
sessionClient: new
|
|
7882
|
-
cdpClient: new
|
|
8110
|
+
sessionClient: new CloudSessionClient(baseUrl, key, authScheme),
|
|
8111
|
+
cdpClient: new CloudCdpClient(),
|
|
8112
|
+
appUrl: normalizeCloudAppUrl(appUrl),
|
|
7883
8113
|
actionClient: null,
|
|
7884
|
-
sessionId: null
|
|
8114
|
+
sessionId: null,
|
|
8115
|
+
localRunId: null,
|
|
8116
|
+
cloudSessionUrl: null
|
|
7885
8117
|
};
|
|
7886
8118
|
}
|
|
7887
|
-
function
|
|
8119
|
+
function resolveCloudBaseUrl() {
|
|
7888
8120
|
const value = process.env.OPENSTEER_BASE_URL?.trim();
|
|
7889
|
-
if (!value) return
|
|
8121
|
+
if (!value) return DEFAULT_CLOUD_BASE_URL;
|
|
7890
8122
|
return value.replace(/\/+$/, "");
|
|
7891
8123
|
}
|
|
7892
|
-
function
|
|
8124
|
+
function resolveCloudAppUrl() {
|
|
8125
|
+
const value = process.env.OPENSTEER_APP_URL?.trim();
|
|
8126
|
+
if (!value) return DEFAULT_CLOUD_APP_URL;
|
|
8127
|
+
return normalizeCloudAppUrl(value);
|
|
8128
|
+
}
|
|
8129
|
+
function normalizeCloudAppUrl(value) {
|
|
8130
|
+
if (!value) return null;
|
|
8131
|
+
return value.replace(/\/+$/, "");
|
|
8132
|
+
}
|
|
8133
|
+
function readCloudActionDescription(payload) {
|
|
7893
8134
|
const description = payload.description;
|
|
7894
8135
|
if (typeof description !== "string") return void 0;
|
|
7895
8136
|
const normalized = description.trim();
|
|
@@ -7897,7 +8138,7 @@ function readRemoteActionDescription(payload) {
|
|
|
7897
8138
|
}
|
|
7898
8139
|
|
|
7899
8140
|
// src/opensteer.ts
|
|
7900
|
-
var
|
|
8141
|
+
var CLOUD_INTERACTION_METHODS = /* @__PURE__ */ new Set([
|
|
7901
8142
|
"click",
|
|
7902
8143
|
"dblclick",
|
|
7903
8144
|
"rightclick",
|
|
@@ -7914,7 +8155,7 @@ var Opensteer = class _Opensteer {
|
|
|
7914
8155
|
namespace;
|
|
7915
8156
|
storage;
|
|
7916
8157
|
pool;
|
|
7917
|
-
|
|
8158
|
+
cloud;
|
|
7918
8159
|
browser = null;
|
|
7919
8160
|
pageRef = null;
|
|
7920
8161
|
contextRef = null;
|
|
@@ -7922,8 +8163,8 @@ var Opensteer = class _Opensteer {
|
|
|
7922
8163
|
snapshotCache = null;
|
|
7923
8164
|
constructor(config = {}) {
|
|
7924
8165
|
const resolved = resolveConfig(config);
|
|
7925
|
-
const
|
|
7926
|
-
|
|
8166
|
+
const cloudSelection = resolveCloudSelection({
|
|
8167
|
+
cloud: resolved.cloud
|
|
7927
8168
|
});
|
|
7928
8169
|
const model = resolved.model;
|
|
7929
8170
|
this.config = resolved;
|
|
@@ -7933,21 +8174,22 @@ var Opensteer = class _Opensteer {
|
|
|
7933
8174
|
this.namespace = resolveNamespace(resolved, rootDir);
|
|
7934
8175
|
this.storage = new LocalSelectorStorage(rootDir, this.namespace);
|
|
7935
8176
|
this.pool = new BrowserPool(resolved.browser || {});
|
|
7936
|
-
if (
|
|
7937
|
-
const
|
|
7938
|
-
const apiKey =
|
|
8177
|
+
if (cloudSelection.cloud) {
|
|
8178
|
+
const cloudConfig = resolved.cloud && typeof resolved.cloud === "object" ? resolved.cloud : void 0;
|
|
8179
|
+
const apiKey = cloudConfig?.apiKey?.trim();
|
|
7939
8180
|
if (!apiKey) {
|
|
7940
8181
|
throw new Error(
|
|
7941
|
-
"
|
|
8182
|
+
"Cloud mode requires a non-empty API key via cloud.apiKey or OPENSTEER_API_KEY."
|
|
7942
8183
|
);
|
|
7943
8184
|
}
|
|
7944
|
-
this.
|
|
8185
|
+
this.cloud = createCloudRuntimeState(
|
|
7945
8186
|
apiKey,
|
|
7946
|
-
|
|
7947
|
-
|
|
8187
|
+
cloudConfig?.baseUrl,
|
|
8188
|
+
cloudConfig?.authScheme,
|
|
8189
|
+
cloudConfig?.appUrl
|
|
7948
8190
|
);
|
|
7949
8191
|
} else {
|
|
7950
|
-
this.
|
|
8192
|
+
this.cloud = null;
|
|
7951
8193
|
}
|
|
7952
8194
|
}
|
|
7953
8195
|
createLazyResolveCallback(model) {
|
|
@@ -7985,32 +8227,32 @@ var Opensteer = class _Opensteer {
|
|
|
7985
8227
|
};
|
|
7986
8228
|
return extract;
|
|
7987
8229
|
}
|
|
7988
|
-
async
|
|
7989
|
-
const result = await this.
|
|
8230
|
+
async invokeCloudActionAndResetCache(method, args) {
|
|
8231
|
+
const result = await this.invokeCloudAction(method, args);
|
|
7990
8232
|
this.snapshotCache = null;
|
|
7991
8233
|
return result;
|
|
7992
8234
|
}
|
|
7993
|
-
async
|
|
7994
|
-
const actionClient = this.
|
|
7995
|
-
const sessionId = this.
|
|
8235
|
+
async invokeCloudAction(method, args) {
|
|
8236
|
+
const actionClient = this.cloud?.actionClient;
|
|
8237
|
+
const sessionId = this.cloud?.sessionId;
|
|
7996
8238
|
if (!actionClient || !sessionId) {
|
|
7997
|
-
throw
|
|
8239
|
+
throw cloudNotLaunchedError();
|
|
7998
8240
|
}
|
|
7999
8241
|
const payload = args && typeof args === "object" ? args : {};
|
|
8000
8242
|
try {
|
|
8001
8243
|
return await actionClient.request(method, payload);
|
|
8002
8244
|
} catch (err) {
|
|
8003
|
-
if (err instanceof
|
|
8245
|
+
if (err instanceof OpensteerCloudError && err.code === "CLOUD_ACTION_FAILED" && CLOUD_INTERACTION_METHODS.has(method)) {
|
|
8004
8246
|
const detailsRecord = err.details && typeof err.details === "object" ? err.details : null;
|
|
8005
|
-
const
|
|
8247
|
+
const cloudFailure = normalizeActionFailure(
|
|
8006
8248
|
detailsRecord?.actionFailure
|
|
8007
8249
|
);
|
|
8008
|
-
const failure =
|
|
8250
|
+
const failure = cloudFailure || classifyActionFailure({
|
|
8009
8251
|
action: method,
|
|
8010
8252
|
error: err,
|
|
8011
8253
|
fallbackMessage: defaultActionFailureMessage(method)
|
|
8012
8254
|
});
|
|
8013
|
-
const description =
|
|
8255
|
+
const description = readCloudActionDescription(payload);
|
|
8014
8256
|
throw this.buildActionError(
|
|
8015
8257
|
method,
|
|
8016
8258
|
description,
|
|
@@ -8051,8 +8293,36 @@ var Opensteer = class _Opensteer {
|
|
|
8051
8293
|
}
|
|
8052
8294
|
return this.contextRef;
|
|
8053
8295
|
}
|
|
8054
|
-
|
|
8055
|
-
return this.
|
|
8296
|
+
getCloudSessionId() {
|
|
8297
|
+
return this.cloud?.sessionId ?? null;
|
|
8298
|
+
}
|
|
8299
|
+
getCloudSessionUrl() {
|
|
8300
|
+
return this.cloud?.cloudSessionUrl ?? null;
|
|
8301
|
+
}
|
|
8302
|
+
announceCloudSession(args) {
|
|
8303
|
+
if (!this.shouldAnnounceCloudSession()) {
|
|
8304
|
+
return;
|
|
8305
|
+
}
|
|
8306
|
+
const fields = [
|
|
8307
|
+
`sessionId=${args.sessionId}`,
|
|
8308
|
+
`workspaceId=${args.workspaceId}`
|
|
8309
|
+
];
|
|
8310
|
+
if (args.cloudSessionUrl) {
|
|
8311
|
+
fields.push(`url=${args.cloudSessionUrl}`);
|
|
8312
|
+
}
|
|
8313
|
+
process.stderr.write(`[opensteer] cloud session ready ${fields.join(" ")}
|
|
8314
|
+
`);
|
|
8315
|
+
}
|
|
8316
|
+
shouldAnnounceCloudSession() {
|
|
8317
|
+
const cloudConfig = this.config.cloud && typeof this.config.cloud === "object" ? this.config.cloud : null;
|
|
8318
|
+
const announce = cloudConfig?.announce ?? "always";
|
|
8319
|
+
if (announce === "off") {
|
|
8320
|
+
return false;
|
|
8321
|
+
}
|
|
8322
|
+
if (announce === "tty") {
|
|
8323
|
+
return Boolean(process.stderr.isTTY);
|
|
8324
|
+
}
|
|
8325
|
+
return true;
|
|
8056
8326
|
}
|
|
8057
8327
|
async launch(options = {}) {
|
|
8058
8328
|
if (this.pageRef && !this.ownsBrowser) {
|
|
@@ -8063,22 +8333,29 @@ var Opensteer = class _Opensteer {
|
|
|
8063
8333
|
if (this.pageRef && this.ownsBrowser) {
|
|
8064
8334
|
return;
|
|
8065
8335
|
}
|
|
8066
|
-
if (this.
|
|
8336
|
+
if (this.cloud) {
|
|
8067
8337
|
let actionClient = null;
|
|
8068
8338
|
let browser = null;
|
|
8069
8339
|
let sessionId = null;
|
|
8340
|
+
let localRunId = null;
|
|
8070
8341
|
try {
|
|
8071
8342
|
try {
|
|
8072
|
-
await this.
|
|
8343
|
+
await this.syncLocalSelectorCacheToCloud();
|
|
8073
8344
|
} catch (error) {
|
|
8074
8345
|
if (this.config.debug) {
|
|
8075
8346
|
const message = error instanceof Error ? error.message : String(error);
|
|
8076
8347
|
console.warn(
|
|
8077
|
-
`[opensteer]
|
|
8348
|
+
`[opensteer] cloud selector cache sync failed: ${message}`
|
|
8078
8349
|
);
|
|
8079
8350
|
}
|
|
8080
8351
|
}
|
|
8081
|
-
|
|
8352
|
+
localRunId = this.cloud.localRunId || buildLocalRunId(this.namespace);
|
|
8353
|
+
this.cloud.localRunId = localRunId;
|
|
8354
|
+
const session2 = await this.cloud.sessionClient.create({
|
|
8355
|
+
cloudSessionContractVersion,
|
|
8356
|
+
sourceType: "local-cloud",
|
|
8357
|
+
clientSessionHint: this.namespace,
|
|
8358
|
+
localRunId,
|
|
8082
8359
|
name: this.namespace,
|
|
8083
8360
|
model: this.config.model,
|
|
8084
8361
|
launchContext: options.context || void 0
|
|
@@ -8089,7 +8366,7 @@ var Opensteer = class _Opensteer {
|
|
|
8089
8366
|
token: session2.actionToken,
|
|
8090
8367
|
sessionId: session2.sessionId
|
|
8091
8368
|
});
|
|
8092
|
-
const cdpConnection = await this.
|
|
8369
|
+
const cdpConnection = await this.cloud.cdpClient.connect({
|
|
8093
8370
|
wsUrl: session2.cdpWsUrl,
|
|
8094
8371
|
token: session2.cdpToken
|
|
8095
8372
|
});
|
|
@@ -8099,8 +8376,17 @@ var Opensteer = class _Opensteer {
|
|
|
8099
8376
|
this.pageRef = cdpConnection.page;
|
|
8100
8377
|
this.ownsBrowser = true;
|
|
8101
8378
|
this.snapshotCache = null;
|
|
8102
|
-
this.
|
|
8103
|
-
this.
|
|
8379
|
+
this.cloud.actionClient = actionClient;
|
|
8380
|
+
this.cloud.sessionId = sessionId;
|
|
8381
|
+
this.cloud.cloudSessionUrl = buildCloudSessionUrl(
|
|
8382
|
+
this.cloud.appUrl,
|
|
8383
|
+
session2.cloudSession.sessionId
|
|
8384
|
+
);
|
|
8385
|
+
this.announceCloudSession({
|
|
8386
|
+
sessionId: session2.sessionId,
|
|
8387
|
+
workspaceId: session2.cloudSession.workspaceId,
|
|
8388
|
+
cloudSessionUrl: this.cloud.cloudSessionUrl
|
|
8389
|
+
});
|
|
8104
8390
|
return;
|
|
8105
8391
|
} catch (error) {
|
|
8106
8392
|
if (actionClient) {
|
|
@@ -8110,8 +8396,9 @@ var Opensteer = class _Opensteer {
|
|
|
8110
8396
|
await browser.close().catch(() => void 0);
|
|
8111
8397
|
}
|
|
8112
8398
|
if (sessionId) {
|
|
8113
|
-
await this.
|
|
8399
|
+
await this.cloud.sessionClient.close(sessionId).catch(() => void 0);
|
|
8114
8400
|
}
|
|
8401
|
+
this.cloud.cloudSessionUrl = null;
|
|
8115
8402
|
throw error;
|
|
8116
8403
|
}
|
|
8117
8404
|
}
|
|
@@ -8129,13 +8416,13 @@ var Opensteer = class _Opensteer {
|
|
|
8129
8416
|
}
|
|
8130
8417
|
static from(page, config = {}) {
|
|
8131
8418
|
const resolvedConfig = resolveConfig(config);
|
|
8132
|
-
const
|
|
8133
|
-
|
|
8419
|
+
const cloudSelection = resolveCloudSelection({
|
|
8420
|
+
cloud: resolvedConfig.cloud
|
|
8134
8421
|
});
|
|
8135
|
-
if (
|
|
8136
|
-
throw
|
|
8422
|
+
if (cloudSelection.cloud) {
|
|
8423
|
+
throw cloudUnsupportedMethodError(
|
|
8137
8424
|
"Opensteer.from(page)",
|
|
8138
|
-
"Opensteer.from(page) is not supported in
|
|
8425
|
+
"Opensteer.from(page) is not supported in cloud mode."
|
|
8139
8426
|
);
|
|
8140
8427
|
}
|
|
8141
8428
|
const instance = new _Opensteer(config);
|
|
@@ -8148,12 +8435,14 @@ var Opensteer = class _Opensteer {
|
|
|
8148
8435
|
}
|
|
8149
8436
|
async close() {
|
|
8150
8437
|
this.snapshotCache = null;
|
|
8151
|
-
if (this.
|
|
8152
|
-
const actionClient = this.
|
|
8153
|
-
const sessionId = this.
|
|
8438
|
+
if (this.cloud) {
|
|
8439
|
+
const actionClient = this.cloud.actionClient;
|
|
8440
|
+
const sessionId = this.cloud.sessionId;
|
|
8154
8441
|
const browser = this.browser;
|
|
8155
|
-
this.
|
|
8156
|
-
this.
|
|
8442
|
+
this.cloud.actionClient = null;
|
|
8443
|
+
this.cloud.sessionId = null;
|
|
8444
|
+
this.cloud.localRunId = null;
|
|
8445
|
+
this.cloud.cloudSessionUrl = null;
|
|
8157
8446
|
this.browser = null;
|
|
8158
8447
|
this.pageRef = null;
|
|
8159
8448
|
this.contextRef = null;
|
|
@@ -8165,7 +8454,7 @@ var Opensteer = class _Opensteer {
|
|
|
8165
8454
|
await browser.close().catch(() => void 0);
|
|
8166
8455
|
}
|
|
8167
8456
|
if (sessionId) {
|
|
8168
|
-
await this.
|
|
8457
|
+
await this.cloud.sessionClient.close(sessionId).catch(() => void 0);
|
|
8169
8458
|
}
|
|
8170
8459
|
return;
|
|
8171
8460
|
}
|
|
@@ -8177,17 +8466,17 @@ var Opensteer = class _Opensteer {
|
|
|
8177
8466
|
this.contextRef = null;
|
|
8178
8467
|
this.ownsBrowser = false;
|
|
8179
8468
|
}
|
|
8180
|
-
async
|
|
8181
|
-
if (!this.
|
|
8469
|
+
async syncLocalSelectorCacheToCloud() {
|
|
8470
|
+
if (!this.cloud) return;
|
|
8182
8471
|
const entries = collectLocalSelectorCacheEntries(this.storage);
|
|
8183
8472
|
if (!entries.length) return;
|
|
8184
|
-
await this.
|
|
8473
|
+
await this.cloud.sessionClient.importSelectorCache({
|
|
8185
8474
|
entries
|
|
8186
8475
|
});
|
|
8187
8476
|
}
|
|
8188
8477
|
async goto(url, options) {
|
|
8189
|
-
if (this.
|
|
8190
|
-
await this.
|
|
8478
|
+
if (this.cloud) {
|
|
8479
|
+
await this.invokeCloudActionAndResetCache("goto", { url, options });
|
|
8191
8480
|
return;
|
|
8192
8481
|
}
|
|
8193
8482
|
const { waitUntil = "domcontentloaded", ...rest } = options ?? {};
|
|
@@ -8196,8 +8485,8 @@ var Opensteer = class _Opensteer {
|
|
|
8196
8485
|
this.snapshotCache = null;
|
|
8197
8486
|
}
|
|
8198
8487
|
async snapshot(options = {}) {
|
|
8199
|
-
if (this.
|
|
8200
|
-
return await this.
|
|
8488
|
+
if (this.cloud) {
|
|
8489
|
+
return await this.invokeCloudActionAndResetCache("snapshot", {
|
|
8201
8490
|
options
|
|
8202
8491
|
});
|
|
8203
8492
|
}
|
|
@@ -8206,8 +8495,8 @@ var Opensteer = class _Opensteer {
|
|
|
8206
8495
|
return prepared.cleanedHtml;
|
|
8207
8496
|
}
|
|
8208
8497
|
async state() {
|
|
8209
|
-
if (this.
|
|
8210
|
-
return await this.
|
|
8498
|
+
if (this.cloud) {
|
|
8499
|
+
return await this.invokeCloudAction("state", {});
|
|
8211
8500
|
}
|
|
8212
8501
|
const html = await this.snapshot({ mode: "action" });
|
|
8213
8502
|
return {
|
|
@@ -8217,8 +8506,8 @@ var Opensteer = class _Opensteer {
|
|
|
8217
8506
|
};
|
|
8218
8507
|
}
|
|
8219
8508
|
async screenshot(options = {}) {
|
|
8220
|
-
if (this.
|
|
8221
|
-
const b64 = await this.
|
|
8509
|
+
if (this.cloud) {
|
|
8510
|
+
const b64 = await this.invokeCloudAction(
|
|
8222
8511
|
"screenshot",
|
|
8223
8512
|
options
|
|
8224
8513
|
);
|
|
@@ -8232,8 +8521,8 @@ var Opensteer = class _Opensteer {
|
|
|
8232
8521
|
});
|
|
8233
8522
|
}
|
|
8234
8523
|
async click(options) {
|
|
8235
|
-
if (this.
|
|
8236
|
-
return await this.
|
|
8524
|
+
if (this.cloud) {
|
|
8525
|
+
return await this.invokeCloudActionAndResetCache(
|
|
8237
8526
|
"click",
|
|
8238
8527
|
options
|
|
8239
8528
|
);
|
|
@@ -8245,8 +8534,8 @@ var Opensteer = class _Opensteer {
|
|
|
8245
8534
|
});
|
|
8246
8535
|
}
|
|
8247
8536
|
async dblclick(options) {
|
|
8248
|
-
if (this.
|
|
8249
|
-
return await this.
|
|
8537
|
+
if (this.cloud) {
|
|
8538
|
+
return await this.invokeCloudActionAndResetCache(
|
|
8250
8539
|
"dblclick",
|
|
8251
8540
|
options
|
|
8252
8541
|
);
|
|
@@ -8258,8 +8547,8 @@ var Opensteer = class _Opensteer {
|
|
|
8258
8547
|
});
|
|
8259
8548
|
}
|
|
8260
8549
|
async rightclick(options) {
|
|
8261
|
-
if (this.
|
|
8262
|
-
return await this.
|
|
8550
|
+
if (this.cloud) {
|
|
8551
|
+
return await this.invokeCloudActionAndResetCache(
|
|
8263
8552
|
"rightclick",
|
|
8264
8553
|
options
|
|
8265
8554
|
);
|
|
@@ -8271,8 +8560,8 @@ var Opensteer = class _Opensteer {
|
|
|
8271
8560
|
});
|
|
8272
8561
|
}
|
|
8273
8562
|
async hover(options) {
|
|
8274
|
-
if (this.
|
|
8275
|
-
return await this.
|
|
8563
|
+
if (this.cloud) {
|
|
8564
|
+
return await this.invokeCloudActionAndResetCache(
|
|
8276
8565
|
"hover",
|
|
8277
8566
|
options
|
|
8278
8567
|
);
|
|
@@ -8370,8 +8659,8 @@ var Opensteer = class _Opensteer {
|
|
|
8370
8659
|
);
|
|
8371
8660
|
}
|
|
8372
8661
|
async input(options) {
|
|
8373
|
-
if (this.
|
|
8374
|
-
return await this.
|
|
8662
|
+
if (this.cloud) {
|
|
8663
|
+
return await this.invokeCloudActionAndResetCache(
|
|
8375
8664
|
"input",
|
|
8376
8665
|
options
|
|
8377
8666
|
);
|
|
@@ -8473,8 +8762,8 @@ var Opensteer = class _Opensteer {
|
|
|
8473
8762
|
);
|
|
8474
8763
|
}
|
|
8475
8764
|
async select(options) {
|
|
8476
|
-
if (this.
|
|
8477
|
-
return await this.
|
|
8765
|
+
if (this.cloud) {
|
|
8766
|
+
return await this.invokeCloudActionAndResetCache(
|
|
8478
8767
|
"select",
|
|
8479
8768
|
options
|
|
8480
8769
|
);
|
|
@@ -8583,8 +8872,8 @@ var Opensteer = class _Opensteer {
|
|
|
8583
8872
|
);
|
|
8584
8873
|
}
|
|
8585
8874
|
async scroll(options = {}) {
|
|
8586
|
-
if (this.
|
|
8587
|
-
return await this.
|
|
8875
|
+
if (this.cloud) {
|
|
8876
|
+
return await this.invokeCloudActionAndResetCache(
|
|
8588
8877
|
"scroll",
|
|
8589
8878
|
options
|
|
8590
8879
|
);
|
|
@@ -8685,14 +8974,14 @@ var Opensteer = class _Opensteer {
|
|
|
8685
8974
|
}
|
|
8686
8975
|
// --- Tab Management ---
|
|
8687
8976
|
async tabs() {
|
|
8688
|
-
if (this.
|
|
8689
|
-
return await this.
|
|
8977
|
+
if (this.cloud) {
|
|
8978
|
+
return await this.invokeCloudAction("tabs", {});
|
|
8690
8979
|
}
|
|
8691
8980
|
return listTabs(this.context, this.page);
|
|
8692
8981
|
}
|
|
8693
8982
|
async newTab(url) {
|
|
8694
|
-
if (this.
|
|
8695
|
-
return await this.
|
|
8983
|
+
if (this.cloud) {
|
|
8984
|
+
return await this.invokeCloudActionAndResetCache("newTab", {
|
|
8696
8985
|
url
|
|
8697
8986
|
});
|
|
8698
8987
|
}
|
|
@@ -8702,8 +8991,8 @@ var Opensteer = class _Opensteer {
|
|
|
8702
8991
|
return info;
|
|
8703
8992
|
}
|
|
8704
8993
|
async switchTab(index) {
|
|
8705
|
-
if (this.
|
|
8706
|
-
await this.
|
|
8994
|
+
if (this.cloud) {
|
|
8995
|
+
await this.invokeCloudActionAndResetCache("switchTab", { index });
|
|
8707
8996
|
return;
|
|
8708
8997
|
}
|
|
8709
8998
|
const page = await switchTab(this.context, index);
|
|
@@ -8711,8 +9000,8 @@ var Opensteer = class _Opensteer {
|
|
|
8711
9000
|
this.snapshotCache = null;
|
|
8712
9001
|
}
|
|
8713
9002
|
async closeTab(index) {
|
|
8714
|
-
if (this.
|
|
8715
|
-
await this.
|
|
9003
|
+
if (this.cloud) {
|
|
9004
|
+
await this.invokeCloudActionAndResetCache("closeTab", { index });
|
|
8716
9005
|
return;
|
|
8717
9006
|
}
|
|
8718
9007
|
const newPage = await closeTab(this.context, this.page, index);
|
|
@@ -8723,8 +9012,8 @@ var Opensteer = class _Opensteer {
|
|
|
8723
9012
|
}
|
|
8724
9013
|
// --- Cookie Management ---
|
|
8725
9014
|
async getCookies(url) {
|
|
8726
|
-
if (this.
|
|
8727
|
-
return await this.
|
|
9015
|
+
if (this.cloud) {
|
|
9016
|
+
return await this.invokeCloudAction(
|
|
8728
9017
|
"getCookies",
|
|
8729
9018
|
{ url }
|
|
8730
9019
|
);
|
|
@@ -8732,41 +9021,41 @@ var Opensteer = class _Opensteer {
|
|
|
8732
9021
|
return getCookies(this.context, url);
|
|
8733
9022
|
}
|
|
8734
9023
|
async setCookie(cookie) {
|
|
8735
|
-
if (this.
|
|
8736
|
-
await this.
|
|
9024
|
+
if (this.cloud) {
|
|
9025
|
+
await this.invokeCloudAction("setCookie", cookie);
|
|
8737
9026
|
return;
|
|
8738
9027
|
}
|
|
8739
9028
|
return setCookie(this.context, cookie);
|
|
8740
9029
|
}
|
|
8741
9030
|
async clearCookies() {
|
|
8742
|
-
if (this.
|
|
8743
|
-
await this.
|
|
9031
|
+
if (this.cloud) {
|
|
9032
|
+
await this.invokeCloudAction("clearCookies", {});
|
|
8744
9033
|
return;
|
|
8745
9034
|
}
|
|
8746
9035
|
return clearCookies(this.context);
|
|
8747
9036
|
}
|
|
8748
9037
|
async exportCookies(filePath, url) {
|
|
8749
|
-
if (this.
|
|
8750
|
-
throw
|
|
9038
|
+
if (this.cloud) {
|
|
9039
|
+
throw cloudUnsupportedMethodError(
|
|
8751
9040
|
"exportCookies",
|
|
8752
|
-
"exportCookies() is not supported in
|
|
9041
|
+
"exportCookies() is not supported in cloud mode because it depends on local filesystem paths."
|
|
8753
9042
|
);
|
|
8754
9043
|
}
|
|
8755
9044
|
return exportCookies(this.context, filePath, url);
|
|
8756
9045
|
}
|
|
8757
9046
|
async importCookies(filePath) {
|
|
8758
|
-
if (this.
|
|
8759
|
-
throw
|
|
9047
|
+
if (this.cloud) {
|
|
9048
|
+
throw cloudUnsupportedMethodError(
|
|
8760
9049
|
"importCookies",
|
|
8761
|
-
"importCookies() is not supported in
|
|
9050
|
+
"importCookies() is not supported in cloud mode because it depends on local filesystem paths."
|
|
8762
9051
|
);
|
|
8763
9052
|
}
|
|
8764
9053
|
return importCookies(this.context, filePath);
|
|
8765
9054
|
}
|
|
8766
9055
|
// --- Keyboard Input ---
|
|
8767
9056
|
async pressKey(key) {
|
|
8768
|
-
if (this.
|
|
8769
|
-
await this.
|
|
9057
|
+
if (this.cloud) {
|
|
9058
|
+
await this.invokeCloudActionAndResetCache("pressKey", { key });
|
|
8770
9059
|
return;
|
|
8771
9060
|
}
|
|
8772
9061
|
await this.runWithPostActionWait("pressKey", void 0, async () => {
|
|
@@ -8775,8 +9064,8 @@ var Opensteer = class _Opensteer {
|
|
|
8775
9064
|
this.snapshotCache = null;
|
|
8776
9065
|
}
|
|
8777
9066
|
async type(text) {
|
|
8778
|
-
if (this.
|
|
8779
|
-
await this.
|
|
9067
|
+
if (this.cloud) {
|
|
9068
|
+
await this.invokeCloudActionAndResetCache("type", { text });
|
|
8780
9069
|
return;
|
|
8781
9070
|
}
|
|
8782
9071
|
await this.runWithPostActionWait("type", void 0, async () => {
|
|
@@ -8786,8 +9075,8 @@ var Opensteer = class _Opensteer {
|
|
|
8786
9075
|
}
|
|
8787
9076
|
// --- Element Info ---
|
|
8788
9077
|
async getElementText(options) {
|
|
8789
|
-
if (this.
|
|
8790
|
-
return await this.
|
|
9078
|
+
if (this.cloud) {
|
|
9079
|
+
return await this.invokeCloudAction("getElementText", options);
|
|
8791
9080
|
}
|
|
8792
9081
|
return this.executeElementInfoAction(
|
|
8793
9082
|
"getElementText",
|
|
@@ -8800,8 +9089,8 @@ var Opensteer = class _Opensteer {
|
|
|
8800
9089
|
);
|
|
8801
9090
|
}
|
|
8802
9091
|
async getElementValue(options) {
|
|
8803
|
-
if (this.
|
|
8804
|
-
return await this.
|
|
9092
|
+
if (this.cloud) {
|
|
9093
|
+
return await this.invokeCloudAction(
|
|
8805
9094
|
"getElementValue",
|
|
8806
9095
|
options
|
|
8807
9096
|
);
|
|
@@ -8816,8 +9105,8 @@ var Opensteer = class _Opensteer {
|
|
|
8816
9105
|
);
|
|
8817
9106
|
}
|
|
8818
9107
|
async getElementAttributes(options) {
|
|
8819
|
-
if (this.
|
|
8820
|
-
return await this.
|
|
9108
|
+
if (this.cloud) {
|
|
9109
|
+
return await this.invokeCloudAction(
|
|
8821
9110
|
"getElementAttributes",
|
|
8822
9111
|
options
|
|
8823
9112
|
);
|
|
@@ -8838,8 +9127,8 @@ var Opensteer = class _Opensteer {
|
|
|
8838
9127
|
);
|
|
8839
9128
|
}
|
|
8840
9129
|
async getElementBoundingBox(options) {
|
|
8841
|
-
if (this.
|
|
8842
|
-
return await this.
|
|
9130
|
+
if (this.cloud) {
|
|
9131
|
+
return await this.invokeCloudAction(
|
|
8843
9132
|
"getElementBoundingBox",
|
|
8844
9133
|
options
|
|
8845
9134
|
);
|
|
@@ -8854,14 +9143,14 @@ var Opensteer = class _Opensteer {
|
|
|
8854
9143
|
);
|
|
8855
9144
|
}
|
|
8856
9145
|
async getHtml(selector) {
|
|
8857
|
-
if (this.
|
|
8858
|
-
return await this.
|
|
9146
|
+
if (this.cloud) {
|
|
9147
|
+
return await this.invokeCloudAction("getHtml", { selector });
|
|
8859
9148
|
}
|
|
8860
9149
|
return getPageHtml(this.page, selector);
|
|
8861
9150
|
}
|
|
8862
9151
|
async getTitle() {
|
|
8863
|
-
if (this.
|
|
8864
|
-
return await this.
|
|
9152
|
+
if (this.cloud) {
|
|
9153
|
+
return await this.invokeCloudAction("getTitle", {});
|
|
8865
9154
|
}
|
|
8866
9155
|
return getPageTitle(this.page);
|
|
8867
9156
|
}
|
|
@@ -8899,10 +9188,10 @@ var Opensteer = class _Opensteer {
|
|
|
8899
9188
|
}
|
|
8900
9189
|
// --- File Upload ---
|
|
8901
9190
|
async uploadFile(options) {
|
|
8902
|
-
if (this.
|
|
8903
|
-
throw
|
|
9191
|
+
if (this.cloud) {
|
|
9192
|
+
throw cloudUnsupportedMethodError(
|
|
8904
9193
|
"uploadFile",
|
|
8905
|
-
"uploadFile() is not supported in
|
|
9194
|
+
"uploadFile() is not supported in cloud mode because file paths must be accessible on the cloud runtime."
|
|
8906
9195
|
);
|
|
8907
9196
|
}
|
|
8908
9197
|
const storageKey = this.resolveStorageKey(options.description);
|
|
@@ -9004,15 +9293,15 @@ var Opensteer = class _Opensteer {
|
|
|
9004
9293
|
}
|
|
9005
9294
|
// --- Wait for Text ---
|
|
9006
9295
|
async waitForText(text, options) {
|
|
9007
|
-
if (this.
|
|
9008
|
-
await this.
|
|
9296
|
+
if (this.cloud) {
|
|
9297
|
+
await this.invokeCloudAction("waitForText", { text, options });
|
|
9009
9298
|
return;
|
|
9010
9299
|
}
|
|
9011
9300
|
await this.page.getByText(text).first().waitFor({ timeout: options?.timeout ?? 3e4 });
|
|
9012
9301
|
}
|
|
9013
9302
|
async extract(options) {
|
|
9014
|
-
if (this.
|
|
9015
|
-
return await this.
|
|
9303
|
+
if (this.cloud) {
|
|
9304
|
+
return await this.invokeCloudAction("extract", options);
|
|
9016
9305
|
}
|
|
9017
9306
|
const storageKey = this.resolveStorageKey(options.description);
|
|
9018
9307
|
const schemaHash = options.schema ? computeSchemaHash(options.schema) : null;
|
|
@@ -9064,8 +9353,8 @@ var Opensteer = class _Opensteer {
|
|
|
9064
9353
|
return inflateDataPathObject(data);
|
|
9065
9354
|
}
|
|
9066
9355
|
async extractFromPlan(options) {
|
|
9067
|
-
if (this.
|
|
9068
|
-
return await this.
|
|
9356
|
+
if (this.cloud) {
|
|
9357
|
+
return await this.invokeCloudAction(
|
|
9069
9358
|
"extractFromPlan",
|
|
9070
9359
|
options
|
|
9071
9360
|
);
|
|
@@ -9114,10 +9403,10 @@ var Opensteer = class _Opensteer {
|
|
|
9114
9403
|
return this.storage;
|
|
9115
9404
|
}
|
|
9116
9405
|
clearCache() {
|
|
9117
|
-
if (this.
|
|
9406
|
+
if (this.cloud) {
|
|
9118
9407
|
this.snapshotCache = null;
|
|
9119
|
-
if (!this.
|
|
9120
|
-
void this.
|
|
9408
|
+
if (!this.cloud.actionClient) return;
|
|
9409
|
+
void this.invokeCloudAction("clearCache", {});
|
|
9121
9410
|
return;
|
|
9122
9411
|
}
|
|
9123
9412
|
this.storage.clearNamespace();
|
|
@@ -10145,6 +10434,16 @@ function getScrollDelta2(options) {
|
|
|
10145
10434
|
return { x: 0, y: absoluteAmount };
|
|
10146
10435
|
}
|
|
10147
10436
|
}
|
|
10437
|
+
function buildLocalRunId(namespace) {
|
|
10438
|
+
const normalized = namespace.trim() || "default";
|
|
10439
|
+
return `${normalized}-${Date.now().toString(36)}-${(0, import_crypto2.randomUUID)().slice(0, 8)}`;
|
|
10440
|
+
}
|
|
10441
|
+
function buildCloudSessionUrl(appUrl, sessionId) {
|
|
10442
|
+
if (!appUrl) {
|
|
10443
|
+
return null;
|
|
10444
|
+
}
|
|
10445
|
+
return `${appUrl}/browser/${encodeURIComponent(sessionId)}`;
|
|
10446
|
+
}
|
|
10148
10447
|
|
|
10149
10448
|
// src/ai/index.ts
|
|
10150
10449
|
init_resolver();
|
|
@@ -10153,6 +10452,8 @@ init_model();
|
|
|
10153
10452
|
// Annotate the CommonJS export names for ESM import in node:
|
|
10154
10453
|
0 && (module.exports = {
|
|
10155
10454
|
ActionWsClient,
|
|
10455
|
+
CloudCdpClient,
|
|
10456
|
+
CloudSessionClient,
|
|
10156
10457
|
CounterResolutionError,
|
|
10157
10458
|
ElementPathError,
|
|
10158
10459
|
LocalSelectorStorage,
|
|
@@ -10166,9 +10467,7 @@ init_model();
|
|
|
10166
10467
|
OS_UNAVAILABLE_ATTR,
|
|
10167
10468
|
Opensteer,
|
|
10168
10469
|
OpensteerActionError,
|
|
10169
|
-
|
|
10170
|
-
RemoteCdpClient,
|
|
10171
|
-
RemoteSessionClient,
|
|
10470
|
+
OpensteerCloudError,
|
|
10172
10471
|
buildElementPathFromHandle,
|
|
10173
10472
|
buildElementPathFromSelector,
|
|
10174
10473
|
buildPathSelectorHint,
|
|
@@ -10180,6 +10479,9 @@ init_model();
|
|
|
10180
10479
|
clearCookies,
|
|
10181
10480
|
cloneElementPath,
|
|
10182
10481
|
closeTab,
|
|
10482
|
+
cloudNotLaunchedError,
|
|
10483
|
+
cloudSessionContractVersion,
|
|
10484
|
+
cloudUnsupportedMethodError,
|
|
10183
10485
|
collectLocalSelectorCacheEntries,
|
|
10184
10486
|
countArrayItemsWithPath,
|
|
10185
10487
|
createEmptyRegistry,
|
|
@@ -10211,8 +10513,6 @@ init_model();
|
|
|
10211
10513
|
performSelect,
|
|
10212
10514
|
prepareSnapshot,
|
|
10213
10515
|
pressKey,
|
|
10214
|
-
remoteNotLaunchedError,
|
|
10215
|
-
remoteUnsupportedMethodError,
|
|
10216
10516
|
resolveCounterElement,
|
|
10217
10517
|
resolveCountersBatch,
|
|
10218
10518
|
resolveElementPath,
|