opensteer 0.8.10 → 0.8.11
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/dist/{chunk-F3X6UOEN.js → chunk-33FDEOQY.js} +315 -141
- package/dist/chunk-33FDEOQY.js.map +1 -0
- package/dist/cli/bin.cjs +445 -156
- package/dist/cli/bin.cjs.map +1 -1
- package/dist/cli/bin.js +127 -12
- package/dist/cli/bin.js.map +1 -1
- package/dist/index.cjs +64 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +63 -16
- package/dist/index.d.ts +63 -16
- package/dist/index.js +9 -3
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/dist/chunk-F3X6UOEN.js.map +0 -1
package/dist/cli/bin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { assertProviderSupportsEngine, createOpensteerSemanticRuntime, OpensteerBrowserManager, dispatchSemanticOperation, loadEnvironment, normalizeOpensteerProviderMode, discoverLocalCdpBrowsers, inspectCdpEndpoint, resolveOpensteerRuntimeConfig, resolveOpensteerEngineName, resolveOpensteerProvider, resolveFilesystemWorkspacePath, FlowRecorderCollector, generateReplayScript, pathExists, readPersistedLocalBrowserSessionRecord, readPersistedCloudSessionRecord, OpensteerCloudClient, isProcessRunning } from '../chunk-
|
|
2
|
+
import { assertProviderSupportsEngine, createOpensteerSemanticRuntime, OpensteerBrowserManager, dispatchSemanticOperation, loadEnvironment, normalizeOpensteerProviderMode, discoverLocalCdpBrowsers, inspectCdpEndpoint, resolveOpensteerRuntimeConfig, resolveOpensteerEngineName, resolveOpensteerProvider, resolveFilesystemWorkspacePath, CloudSessionProxy, FlowRecorderCollector, generateReplayScript, pathExists, readPersistedLocalBrowserSessionRecord, readPersistedCloudSessionRecord, OpensteerCloudClient, isProcessRunning } from '../chunk-33FDEOQY.js';
|
|
3
3
|
import process2 from 'process';
|
|
4
4
|
import { spawn } from 'child_process';
|
|
5
5
|
import { existsSync } from 'fs';
|
|
@@ -10,7 +10,7 @@ import { mkdir, writeFile } from 'fs/promises';
|
|
|
10
10
|
|
|
11
11
|
// package.json
|
|
12
12
|
var package_default = {
|
|
13
|
-
version: "0.8.
|
|
13
|
+
version: "0.8.10"};
|
|
14
14
|
|
|
15
15
|
// src/cli/env-loader.ts
|
|
16
16
|
async function loadCliEnvironment(cwd) {
|
|
@@ -313,6 +313,65 @@ async function runOpensteerRecordCommand(input) {
|
|
|
313
313
|
}
|
|
314
314
|
}
|
|
315
315
|
}
|
|
316
|
+
async function runOpensteerCloudRecordCommand(input) {
|
|
317
|
+
const stdout = input.stdout ?? process.stdout;
|
|
318
|
+
const stderr = input.stderr ?? process.stderr;
|
|
319
|
+
const outputPath = resolveRecordOutputPath({
|
|
320
|
+
rootDir: input.rootDir,
|
|
321
|
+
workspace: input.workspace,
|
|
322
|
+
...input.outputPath === void 0 ? {} : { outputPath: input.outputPath }
|
|
323
|
+
});
|
|
324
|
+
let cloud;
|
|
325
|
+
const resolveCloud = () => {
|
|
326
|
+
cloud ??= new OpensteerCloudClient(input.cloudConfig);
|
|
327
|
+
return cloud;
|
|
328
|
+
};
|
|
329
|
+
const runtime = input.runtime ?? new CloudSessionProxy(resolveCloud(), {
|
|
330
|
+
rootDir: input.rootDir,
|
|
331
|
+
workspace: input.workspace
|
|
332
|
+
});
|
|
333
|
+
const client = input.client ?? resolveCloud();
|
|
334
|
+
const sleep = input.sleep ?? delay;
|
|
335
|
+
let closed = false;
|
|
336
|
+
try {
|
|
337
|
+
await runtime.open({
|
|
338
|
+
url: input.url,
|
|
339
|
+
...input.browser === void 0 ? {} : { browser: input.browser },
|
|
340
|
+
...input.launch === void 0 ? {} : { launch: input.launch },
|
|
341
|
+
...input.context === void 0 ? {} : { context: input.context }
|
|
342
|
+
});
|
|
343
|
+
const sessionId = await resolveCloudRecordingSessionId(runtime);
|
|
344
|
+
const sessionUrl = buildCloudRecordingSessionUrl(input.cloudConfig, sessionId);
|
|
345
|
+
await client.startSessionRecording(sessionId);
|
|
346
|
+
stderr.write(
|
|
347
|
+
`Recording browser actions for workspace "${input.workspace}". Open ${sessionUrl} and click "Stop recording" in the browser session toolbar when you're done.
|
|
348
|
+
`
|
|
349
|
+
);
|
|
350
|
+
const completed = await waitForCloudRecordingCompletion({
|
|
351
|
+
client,
|
|
352
|
+
sessionId,
|
|
353
|
+
...input.pollIntervalMs === void 0 ? {} : { pollIntervalMs: input.pollIntervalMs },
|
|
354
|
+
sleep
|
|
355
|
+
});
|
|
356
|
+
if (completed.result === void 0) {
|
|
357
|
+
throw new Error("Cloud recording completed without a replay script.");
|
|
358
|
+
}
|
|
359
|
+
await mkdir(path.dirname(outputPath), { recursive: true });
|
|
360
|
+
await writeFile(outputPath, completed.result.script, "utf8");
|
|
361
|
+
await runtime.close();
|
|
362
|
+
closed = true;
|
|
363
|
+
stdout.write(`${outputPath}
|
|
364
|
+
`);
|
|
365
|
+
stderr.write(`Cloud browser session: ${sessionUrl}
|
|
366
|
+
`);
|
|
367
|
+
stderr.write(`Wrote replay script to ${outputPath}
|
|
368
|
+
`);
|
|
369
|
+
} finally {
|
|
370
|
+
if (!closed) {
|
|
371
|
+
await runtime.close().catch(() => void 0);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
316
375
|
function resolveRecordOutputPath(input) {
|
|
317
376
|
if (input.outputPath !== void 0) {
|
|
318
377
|
return path.resolve(input.rootDir, input.outputPath);
|
|
@@ -347,6 +406,35 @@ function createRecorderRuntimeAdapter(runtime) {
|
|
|
347
406
|
}
|
|
348
407
|
};
|
|
349
408
|
}
|
|
409
|
+
function buildCloudRecordingSessionUrl(cloudConfig, sessionId) {
|
|
410
|
+
const baseUrl = cloudConfig.appBaseUrl;
|
|
411
|
+
if (!baseUrl || baseUrl.trim().length === 0) {
|
|
412
|
+
throw new Error(
|
|
413
|
+
'record with provider=cloud requires OPENSTEER_CLOUD_APP_BASE_URL or "--cloud-app-base-url".'
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
return `${baseUrl.replace(/\/+$/, "")}/browsers/${encodeURIComponent(sessionId)}`;
|
|
417
|
+
}
|
|
418
|
+
async function resolveCloudRecordingSessionId(runtime) {
|
|
419
|
+
const info = await runtime.info();
|
|
420
|
+
if (typeof info.sessionId !== "string" || info.sessionId.length === 0) {
|
|
421
|
+
throw new Error("Cloud recording could not resolve the created session id.");
|
|
422
|
+
}
|
|
423
|
+
return info.sessionId;
|
|
424
|
+
}
|
|
425
|
+
async function waitForCloudRecordingCompletion(input) {
|
|
426
|
+
const pollIntervalMs = input.pollIntervalMs ?? 1e3;
|
|
427
|
+
for (; ; ) {
|
|
428
|
+
const state = await input.client.getSessionRecording(input.sessionId);
|
|
429
|
+
if (state.status === "completed") {
|
|
430
|
+
return state;
|
|
431
|
+
}
|
|
432
|
+
if (state.status === "failed") {
|
|
433
|
+
throw new Error(state.error ?? "Cloud recording failed.");
|
|
434
|
+
}
|
|
435
|
+
await input.sleep(pollIntervalMs);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
350
438
|
function formatRecordedAction(action) {
|
|
351
439
|
const time = new Date(action.timestamp).toISOString().slice(11, 19);
|
|
352
440
|
switch (action.kind) {
|
|
@@ -378,6 +466,11 @@ function formatRecordedAction(action) {
|
|
|
378
466
|
return `[${time}] reload ${action.pageId}`;
|
|
379
467
|
}
|
|
380
468
|
}
|
|
469
|
+
function delay(ms) {
|
|
470
|
+
return new Promise((resolve) => {
|
|
471
|
+
setTimeout(resolve, ms);
|
|
472
|
+
});
|
|
473
|
+
}
|
|
381
474
|
|
|
382
475
|
// src/cli/bin.ts
|
|
383
476
|
var OPERATION_ALIASES = /* @__PURE__ */ new Map([
|
|
@@ -627,22 +720,39 @@ async function handleRecordCommandEntry(parsed) {
|
|
|
627
720
|
}
|
|
628
721
|
const provider = resolveCliProvider(parsed);
|
|
629
722
|
assertCloudCliOptionsMatchProvider(parsed, provider.mode);
|
|
630
|
-
if (provider.mode !== "local") {
|
|
631
|
-
throw new Error(
|
|
632
|
-
'record requires provider=local. Set "--provider local" or clear OPENSTEER_PROVIDER.'
|
|
633
|
-
);
|
|
634
|
-
}
|
|
635
723
|
const engineName = resolveCliEngineName(parsed);
|
|
636
724
|
if (engineName !== "playwright") {
|
|
637
725
|
throw new Error("record requires engine=playwright.");
|
|
638
726
|
}
|
|
639
|
-
|
|
640
|
-
|
|
727
|
+
const rootDir = process2.cwd();
|
|
728
|
+
const recordBrowser = parsed.options.browser;
|
|
729
|
+
if (provider.mode === "cloud") {
|
|
730
|
+
if (typeof recordBrowser === "object") {
|
|
731
|
+
throw new Error('record does not support browser.mode="attach".');
|
|
732
|
+
}
|
|
733
|
+
const runtimeProvider = buildCliRuntimeProvider(parsed, provider.mode);
|
|
734
|
+
const runtimeConfig = resolveOpensteerRuntimeConfig({
|
|
735
|
+
...runtimeProvider === void 0 ? {} : { provider: runtimeProvider },
|
|
736
|
+
environment: process2.env
|
|
737
|
+
});
|
|
738
|
+
await runOpensteerCloudRecordCommand({
|
|
739
|
+
cloudConfig: runtimeConfig.cloud,
|
|
740
|
+
workspace: parsed.options.workspace,
|
|
741
|
+
url,
|
|
742
|
+
rootDir,
|
|
743
|
+
...recordBrowser === void 0 ? {} : { browser: recordBrowser },
|
|
744
|
+
...parsed.options.launch === void 0 ? {} : { launch: parsed.options.launch },
|
|
745
|
+
...parsed.options.context === void 0 ? {} : { context: parsed.options.context },
|
|
746
|
+
...parsed.options.output === void 0 ? {} : { outputPath: parsed.options.output }
|
|
747
|
+
});
|
|
748
|
+
return;
|
|
641
749
|
}
|
|
642
750
|
if (parsed.options.launch?.headless === true) {
|
|
643
751
|
throw new Error('record requires a headed browser. Remove "--headless true".');
|
|
644
752
|
}
|
|
645
|
-
|
|
753
|
+
if (recordBrowser !== void 0 && recordBrowser !== "persistent") {
|
|
754
|
+
throw new Error('record only supports "--browser persistent".');
|
|
755
|
+
}
|
|
646
756
|
const launch = {
|
|
647
757
|
...parsed.options.launch ?? {},
|
|
648
758
|
headless: false
|
|
@@ -782,6 +892,7 @@ var CLI_OPTION_SPECS = {
|
|
|
782
892
|
provider: { kind: "value" },
|
|
783
893
|
"cloud-base-url": { kind: "value" },
|
|
784
894
|
"cloud-api-key": { kind: "value" },
|
|
895
|
+
"cloud-app-base-url": { kind: "value" },
|
|
785
896
|
"cloud-profile-id": { kind: "value" },
|
|
786
897
|
"cloud-profile-reuse-if-active": { kind: "boolean" },
|
|
787
898
|
json: { kind: "boolean" },
|
|
@@ -911,6 +1022,7 @@ function parseCommandLine(argv) {
|
|
|
911
1022
|
const provider = providerValue === void 0 ? void 0 : normalizeOpensteerProviderMode(providerValue, "--provider");
|
|
912
1023
|
const cloudBaseUrl = readSingle(rawOptions, "cloud-base-url");
|
|
913
1024
|
const cloudApiKey = readSingle(rawOptions, "cloud-api-key");
|
|
1025
|
+
const cloudAppBaseUrl = readSingle(rawOptions, "cloud-app-base-url");
|
|
914
1026
|
const cloudProfileId = readSingle(rawOptions, "cloud-profile-id");
|
|
915
1027
|
const cloudProfileReuseIfActive = readOptionalBoolean(
|
|
916
1028
|
rawOptions,
|
|
@@ -932,6 +1044,7 @@ function parseCommandLine(argv) {
|
|
|
932
1044
|
...provider === void 0 ? {} : { provider },
|
|
933
1045
|
...cloudBaseUrl === void 0 ? {} : { cloudBaseUrl },
|
|
934
1046
|
...cloudApiKey === void 0 ? {} : { cloudApiKey },
|
|
1047
|
+
...cloudAppBaseUrl === void 0 ? {} : { cloudAppBaseUrl },
|
|
935
1048
|
...cloudProfileId === void 0 ? {} : { cloudProfileId },
|
|
936
1049
|
...cloudProfileReuseIfActive === void 0 ? {} : { cloudProfileReuseIfActive },
|
|
937
1050
|
...json === void 0 ? {} : { json },
|
|
@@ -1016,7 +1129,7 @@ function buildCliRuntimeProvider(parsed, providerMode) {
|
|
|
1016
1129
|
return explicitProvider?.mode === "local" ? explicitProvider : void 0;
|
|
1017
1130
|
}
|
|
1018
1131
|
const browserProfile = buildCliBrowserProfile(parsed);
|
|
1019
|
-
const hasCloudOverrides = parsed.options.cloudBaseUrl !== void 0 || parsed.options.cloudApiKey !== void 0 || browserProfile !== void 0;
|
|
1132
|
+
const hasCloudOverrides = parsed.options.cloudBaseUrl !== void 0 || parsed.options.cloudApiKey !== void 0 || parsed.options.cloudAppBaseUrl !== void 0 || browserProfile !== void 0;
|
|
1020
1133
|
if (!hasCloudOverrides && explicitProvider?.mode !== "cloud") {
|
|
1021
1134
|
return void 0;
|
|
1022
1135
|
}
|
|
@@ -1024,11 +1137,12 @@ function buildCliRuntimeProvider(parsed, providerMode) {
|
|
|
1024
1137
|
mode: "cloud",
|
|
1025
1138
|
...parsed.options.cloudBaseUrl === void 0 ? {} : { baseUrl: parsed.options.cloudBaseUrl },
|
|
1026
1139
|
...parsed.options.cloudApiKey === void 0 ? {} : { apiKey: parsed.options.cloudApiKey },
|
|
1140
|
+
...parsed.options.cloudAppBaseUrl === void 0 ? {} : { appBaseUrl: parsed.options.cloudAppBaseUrl },
|
|
1027
1141
|
...browserProfile === void 0 ? {} : { browserProfile }
|
|
1028
1142
|
};
|
|
1029
1143
|
}
|
|
1030
1144
|
function assertCloudCliOptionsMatchProvider(parsed, providerMode) {
|
|
1031
|
-
if (providerMode !== "cloud" && (parsed.options.cloudBaseUrl !== void 0 || parsed.options.cloudApiKey !== void 0 || parsed.options.cloudProfileId !== void 0 || parsed.options.cloudProfileReuseIfActive === true)) {
|
|
1145
|
+
if (providerMode !== "cloud" && (parsed.options.cloudBaseUrl !== void 0 || parsed.options.cloudApiKey !== void 0 || parsed.options.cloudAppBaseUrl !== void 0 || parsed.options.cloudProfileId !== void 0 || parsed.options.cloudProfileReuseIfActive === true)) {
|
|
1032
1146
|
throw new Error(
|
|
1033
1147
|
'Cloud-specific options require provider=cloud. Set "--provider cloud" or OPENSTEER_PROVIDER=cloud.'
|
|
1034
1148
|
);
|
|
@@ -1170,6 +1284,7 @@ Common options:
|
|
|
1170
1284
|
--provider local|cloud
|
|
1171
1285
|
--cloud-base-url <url>
|
|
1172
1286
|
--cloud-api-key <key>
|
|
1287
|
+
--cloud-app-base-url <url>
|
|
1173
1288
|
--cloud-profile-id <id>
|
|
1174
1289
|
--cloud-profile-reuse-if-active <true|false>
|
|
1175
1290
|
--json <true|false>
|