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.cjs
CHANGED
|
@@ -59,7 +59,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
59
59
|
|
|
60
60
|
// package.json
|
|
61
61
|
var package_default = {
|
|
62
|
-
version: "0.8.
|
|
62
|
+
version: "0.8.10"};
|
|
63
63
|
util.promisify(child_process.execFile);
|
|
64
64
|
Math.floor(Date.now() - process.uptime() * 1e3);
|
|
65
65
|
({ ...process.env});
|
|
@@ -2283,6 +2283,9 @@ function isBrowserCoreError(value) {
|
|
|
2283
2283
|
// ../browser-core/src/cdp-visual-stability.ts
|
|
2284
2284
|
var DEFAULT_VISUAL_STABILITY_SETTLE_MS = 750;
|
|
2285
2285
|
|
|
2286
|
+
// ../browser-core/src/post-load-tracker.ts
|
|
2287
|
+
var DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS = 400;
|
|
2288
|
+
|
|
2286
2289
|
// ../protocol/src/identity.ts
|
|
2287
2290
|
var refPrefixes = [
|
|
2288
2291
|
"session",
|
|
@@ -7472,9 +7475,23 @@ var opensteerInspectStorageInputSchema = objectSchema(
|
|
|
7472
7475
|
title: "OpensteerInspectStorageInput"
|
|
7473
7476
|
}
|
|
7474
7477
|
);
|
|
7478
|
+
var opensteerComputerMouseButtonSchema = enumSchema(["left", "middle", "right"], {
|
|
7479
|
+
title: "OpensteerComputerMouseButton"
|
|
7480
|
+
});
|
|
7481
|
+
var opensteerComputerKeyModifierSchema = enumSchema(
|
|
7482
|
+
["Shift", "Control", "Alt", "Meta"],
|
|
7483
|
+
{
|
|
7484
|
+
title: "OpensteerComputerKeyModifier"
|
|
7485
|
+
}
|
|
7486
|
+
);
|
|
7475
7487
|
var opensteerDomClickInputSchema = objectSchema(
|
|
7476
7488
|
{
|
|
7477
7489
|
target: opensteerTargetInputSchema,
|
|
7490
|
+
button: opensteerComputerMouseButtonSchema,
|
|
7491
|
+
clickCount: integerSchema({ minimum: 1 }),
|
|
7492
|
+
modifiers: arraySchema(opensteerComputerKeyModifierSchema, {
|
|
7493
|
+
uniqueItems: true
|
|
7494
|
+
}),
|
|
7478
7495
|
persistAsDescription: stringSchema(),
|
|
7479
7496
|
captureNetwork: stringSchema({ minLength: 1 })
|
|
7480
7497
|
},
|
|
@@ -7574,18 +7591,6 @@ var opensteerSessionCloseOutputSchema = objectSchema(
|
|
|
7574
7591
|
required: ["closed"]
|
|
7575
7592
|
}
|
|
7576
7593
|
);
|
|
7577
|
-
var opensteerComputerMouseButtonSchema = enumSchema(
|
|
7578
|
-
["left", "middle", "right"],
|
|
7579
|
-
{
|
|
7580
|
-
title: "OpensteerComputerMouseButton"
|
|
7581
|
-
}
|
|
7582
|
-
);
|
|
7583
|
-
var opensteerComputerKeyModifierSchema = enumSchema(
|
|
7584
|
-
["Shift", "Control", "Alt", "Meta"],
|
|
7585
|
-
{
|
|
7586
|
-
title: "OpensteerComputerKeyModifier"
|
|
7587
|
-
}
|
|
7588
|
-
);
|
|
7589
7594
|
var opensteerComputerAnnotationSchema = enumSchema(opensteerComputerAnnotationNames, {
|
|
7590
7595
|
title: "OpensteerComputerAnnotation"
|
|
7591
7596
|
});
|
|
@@ -12126,6 +12131,30 @@ var OpensteerCloudClient = class {
|
|
|
12126
12131
|
});
|
|
12127
12132
|
return await response.json();
|
|
12128
12133
|
}
|
|
12134
|
+
async getSessionRecording(sessionId) {
|
|
12135
|
+
const response = await this.request(`/v1/sessions/${encodeURIComponent(sessionId)}/recording`, {
|
|
12136
|
+
method: "GET"
|
|
12137
|
+
});
|
|
12138
|
+
return await response.json();
|
|
12139
|
+
}
|
|
12140
|
+
async startSessionRecording(sessionId) {
|
|
12141
|
+
const response = await this.request(
|
|
12142
|
+
`/v1/sessions/${encodeURIComponent(sessionId)}/recording/start`,
|
|
12143
|
+
{
|
|
12144
|
+
method: "POST"
|
|
12145
|
+
}
|
|
12146
|
+
);
|
|
12147
|
+
return await response.json();
|
|
12148
|
+
}
|
|
12149
|
+
async stopSessionRecording(sessionId) {
|
|
12150
|
+
const response = await this.request(
|
|
12151
|
+
`/v1/sessions/${encodeURIComponent(sessionId)}/recording/stop`,
|
|
12152
|
+
{
|
|
12153
|
+
method: "POST"
|
|
12154
|
+
}
|
|
12155
|
+
);
|
|
12156
|
+
return await response.json();
|
|
12157
|
+
}
|
|
12129
12158
|
async closeSession(sessionId) {
|
|
12130
12159
|
const response = await this.request(`/v1/sessions/${encodeURIComponent(sessionId)}`, {
|
|
12131
12160
|
method: "DELETE"
|
|
@@ -12316,9 +12345,11 @@ function resolveCloudConfig(input = {}) {
|
|
|
12316
12345
|
if (!baseUrl || baseUrl.trim().length === 0) {
|
|
12317
12346
|
throw new Error("provider=cloud requires OPENSTEER_BASE_URL or provider.baseUrl.");
|
|
12318
12347
|
}
|
|
12348
|
+
const appBaseUrl = cloudProvider?.appBaseUrl ?? input.environment?.OPENSTEER_CLOUD_APP_BASE_URL;
|
|
12319
12349
|
return {
|
|
12320
12350
|
apiKey: apiKey.trim(),
|
|
12321
12351
|
baseUrl: baseUrl.trim().replace(/\/+$/, ""),
|
|
12352
|
+
...appBaseUrl === void 0 || appBaseUrl.trim().length === 0 ? {} : { appBaseUrl: appBaseUrl.trim().replace(/\/+$/, "") },
|
|
12322
12353
|
...cloudProvider?.browserProfile === void 0 ? {} : { browserProfile: cloudProvider.browserProfile }
|
|
12323
12354
|
};
|
|
12324
12355
|
}
|
|
@@ -12333,16 +12364,7 @@ var OPENSTEER_RUNTIME_CORE_VERSION = package_default2.version;
|
|
|
12333
12364
|
// ../runtime-core/src/action-boundary.ts
|
|
12334
12365
|
var actionBoundaryDiagnosticsBySignal = /* @__PURE__ */ new WeakMap();
|
|
12335
12366
|
async function captureActionBoundarySnapshot(engine, pageRef) {
|
|
12336
|
-
|
|
12337
|
-
const mainFrame = frames.find((frame) => frame.isMainFrame);
|
|
12338
|
-
if (!mainFrame) {
|
|
12339
|
-
throw new Error(`page ${pageRef} does not expose a main frame`);
|
|
12340
|
-
}
|
|
12341
|
-
return {
|
|
12342
|
-
pageRef,
|
|
12343
|
-
documentRef: mainFrame.documentRef,
|
|
12344
|
-
url: mainFrame.url
|
|
12345
|
-
};
|
|
12367
|
+
return engine.getActionBoundarySnapshot({ pageRef });
|
|
12346
12368
|
}
|
|
12347
12369
|
function createActionBoundaryDiagnostics(input) {
|
|
12348
12370
|
return {
|
|
@@ -12459,6 +12481,7 @@ var NAVIGATION_VISUAL_STABILITY_PROFILE = {
|
|
|
12459
12481
|
scope: "visible-frames",
|
|
12460
12482
|
timeoutMs: 7e3
|
|
12461
12483
|
};
|
|
12484
|
+
var NAVIGATION_POST_LOAD_CAPTURE_WINDOW_MS = 1e3;
|
|
12462
12485
|
var defaultDomActionSettleObserver = {
|
|
12463
12486
|
async settle(input) {
|
|
12464
12487
|
if (input.trigger !== "dom-action") {
|
|
@@ -12494,6 +12517,13 @@ var defaultNavigationSettleObserver = {
|
|
|
12494
12517
|
return false;
|
|
12495
12518
|
}
|
|
12496
12519
|
try {
|
|
12520
|
+
await input.engine.waitForPostLoadQuiet({
|
|
12521
|
+
pageRef: input.pageRef,
|
|
12522
|
+
timeoutMs: effectiveTimeout,
|
|
12523
|
+
quietMs: DEFAULT_POST_LOAD_TRACKER_QUIET_WINDOW_MS,
|
|
12524
|
+
captureWindowMs: Math.min(NAVIGATION_POST_LOAD_CAPTURE_WINDOW_MS, effectiveTimeout),
|
|
12525
|
+
signal: input.signal
|
|
12526
|
+
});
|
|
12497
12527
|
await input.engine.waitForVisualStability({
|
|
12498
12528
|
pageRef: input.pageRef,
|
|
12499
12529
|
timeoutMs: effectiveTimeout,
|
|
@@ -23274,11 +23304,11 @@ var SandboxClock = class {
|
|
|
23274
23304
|
performanceNow() {
|
|
23275
23305
|
return this.mode === "manual" ? this.manualNow - this.startedAt : (globalThis.performance?.now() ?? 0) - this.performanceStartedAt;
|
|
23276
23306
|
}
|
|
23277
|
-
setTimeout(callback,
|
|
23278
|
-
return this.registerTimer(false, callback,
|
|
23307
|
+
setTimeout(callback, delay4 = 0, ...args) {
|
|
23308
|
+
return this.registerTimer(false, callback, delay4, args);
|
|
23279
23309
|
}
|
|
23280
|
-
setInterval(callback,
|
|
23281
|
-
return this.registerTimer(true, callback,
|
|
23310
|
+
setInterval(callback, delay4 = 0, ...args) {
|
|
23311
|
+
return this.registerTimer(true, callback, delay4, args);
|
|
23282
23312
|
}
|
|
23283
23313
|
clearTimeout(timerId) {
|
|
23284
23314
|
this.clearTimer(timerId);
|
|
@@ -23299,9 +23329,9 @@ var SandboxClock = class {
|
|
|
23299
23329
|
this.clearTimer(timerId);
|
|
23300
23330
|
}
|
|
23301
23331
|
}
|
|
23302
|
-
registerTimer(repeat, callback,
|
|
23332
|
+
registerTimer(repeat, callback, delay4, args) {
|
|
23303
23333
|
const timerId = this.nextTimerId++;
|
|
23304
|
-
const normalizedDelay = Math.max(0,
|
|
23334
|
+
const normalizedDelay = Math.max(0, delay4);
|
|
23305
23335
|
const record = {
|
|
23306
23336
|
callback,
|
|
23307
23337
|
args,
|
|
@@ -24472,6 +24502,9 @@ var OpensteerSessionRuntime = class {
|
|
|
24472
24502
|
const result = await this.requireDom().click({
|
|
24473
24503
|
pageRef,
|
|
24474
24504
|
target,
|
|
24505
|
+
...input.button === void 0 ? {} : { button: input.button },
|
|
24506
|
+
...input.clickCount === void 0 ? {} : { clickCount: input.clickCount },
|
|
24507
|
+
...input.modifiers === void 0 ? {} : { modifiers: input.modifiers },
|
|
24475
24508
|
timeout
|
|
24476
24509
|
});
|
|
24477
24510
|
return {
|
|
@@ -33191,7 +33224,11 @@ function screenshotMediaType(format2) {
|
|
|
33191
33224
|
var SINGLE_ATTRIBUTE_PRIORITY = Array.from(
|
|
33192
33225
|
/* @__PURE__ */ new Set(["data-testid", "data-test", "data-qa", "data-cy", "id", ...STABLE_PRIMARY_ATTR_KEYS])
|
|
33193
33226
|
);
|
|
33194
|
-
|
|
33227
|
+
function createFlowRecorderInstallScript(options = {}) {
|
|
33228
|
+
const normalizedOptions = {
|
|
33229
|
+
showStopButton: options.showStopButton ?? true
|
|
33230
|
+
};
|
|
33231
|
+
return String.raw`(() => {
|
|
33195
33232
|
const TOP_LEVEL_ONLY = (() => {
|
|
33196
33233
|
try {
|
|
33197
33234
|
return window.top === window.self;
|
|
@@ -33216,6 +33253,7 @@ var FLOW_RECORDER_INSTALL_SOURCE = String.raw`(() => {
|
|
|
33216
33253
|
const volatileLazyLoadingAttrs = new Set(${JSON.stringify([...VOLATILE_LAZY_LOADING_ATTRS])});
|
|
33217
33254
|
const volatileClassTokens = new Set(${JSON.stringify([...VOLATILE_CLASS_TOKENS])});
|
|
33218
33255
|
const volatileLazyClassTokens = new Set(${JSON.stringify([...VOLATILE_LAZY_CLASS_TOKENS])});
|
|
33256
|
+
const options = ${JSON.stringify(normalizedOptions)};
|
|
33219
33257
|
|
|
33220
33258
|
const previous = globalScope[recorderKey];
|
|
33221
33259
|
if (previous && typeof previous.dispose === "function") {
|
|
@@ -33226,6 +33264,7 @@ var FLOW_RECORDER_INSTALL_SOURCE = String.raw`(() => {
|
|
|
33226
33264
|
const cleanup = [];
|
|
33227
33265
|
const inputFlushTimers = new Map();
|
|
33228
33266
|
const pendingInputs = new Map();
|
|
33267
|
+
let historyStateCache = undefined;
|
|
33229
33268
|
let stopRequested = false;
|
|
33230
33269
|
let pendingWheel = undefined;
|
|
33231
33270
|
|
|
@@ -33546,44 +33585,76 @@ var FLOW_RECORDER_INSTALL_SOURCE = String.raw`(() => {
|
|
|
33546
33585
|
inputFlushTimers.set(selector, timerId);
|
|
33547
33586
|
}
|
|
33548
33587
|
|
|
33549
|
-
function
|
|
33550
|
-
|
|
33551
|
-
|
|
33552
|
-
|
|
33553
|
-
|
|
33554
|
-
|
|
33555
|
-
|
|
33588
|
+
function createDefaultHistoryState(currentUrl) {
|
|
33589
|
+
return {
|
|
33590
|
+
entries: [currentUrl],
|
|
33591
|
+
index: 0,
|
|
33592
|
+
};
|
|
33593
|
+
}
|
|
33594
|
+
|
|
33595
|
+
function normalizeHistoryState(state) {
|
|
33596
|
+
if (
|
|
33597
|
+
!state ||
|
|
33598
|
+
!Array.isArray(state.entries) ||
|
|
33599
|
+
!state.entries.every((entry) => typeof entry === "string") ||
|
|
33600
|
+
!Number.isInteger(state.index)
|
|
33601
|
+
) {
|
|
33602
|
+
return undefined;
|
|
33556
33603
|
}
|
|
33557
|
-
|
|
33558
|
-
|
|
33604
|
+
const entries = state.entries.slice();
|
|
33605
|
+
if (entries.length === 0) {
|
|
33606
|
+
return createDefaultHistoryState(location.href);
|
|
33559
33607
|
}
|
|
33608
|
+
return {
|
|
33609
|
+
entries,
|
|
33610
|
+
index: Math.min(entries.length - 1, Math.max(0, state.index)),
|
|
33611
|
+
};
|
|
33612
|
+
}
|
|
33613
|
+
|
|
33614
|
+
function writeHistoryState(state) {
|
|
33615
|
+
const normalized = normalizeHistoryState(state) ?? createDefaultHistoryState(location.href);
|
|
33616
|
+
historyStateCache = normalized;
|
|
33617
|
+
try {
|
|
33618
|
+
sessionStorage.setItem(historyStateKey, JSON.stringify(normalized));
|
|
33619
|
+
} catch {}
|
|
33620
|
+
return normalized;
|
|
33621
|
+
}
|
|
33622
|
+
|
|
33623
|
+
function applyHistoryState(state, mode, nextUrl) {
|
|
33624
|
+
const current = normalizeHistoryState(state) ?? createDefaultHistoryState(location.href);
|
|
33625
|
+
const nextState = {
|
|
33626
|
+
entries: current.entries.slice(),
|
|
33627
|
+
index: current.index,
|
|
33628
|
+
};
|
|
33560
33629
|
if (mode === "replace") {
|
|
33561
|
-
|
|
33630
|
+
nextState.entries[nextState.index] = nextUrl;
|
|
33562
33631
|
} else if (mode === "push") {
|
|
33563
|
-
|
|
33564
|
-
|
|
33565
|
-
|
|
33632
|
+
nextState.entries = nextState.entries.slice(0, nextState.index + 1);
|
|
33633
|
+
nextState.entries.push(nextUrl);
|
|
33634
|
+
nextState.index = nextState.entries.length - 1;
|
|
33566
33635
|
} else if (mode === "back") {
|
|
33567
|
-
|
|
33636
|
+
nextState.index = Math.max(0, nextState.index - 1);
|
|
33568
33637
|
} else if (mode === "forward") {
|
|
33569
|
-
|
|
33638
|
+
nextState.index = Math.min(nextState.entries.length - 1, nextState.index + 1);
|
|
33570
33639
|
}
|
|
33571
|
-
|
|
33572
|
-
|
|
33573
|
-
|
|
33574
|
-
|
|
33640
|
+
return nextState;
|
|
33641
|
+
}
|
|
33642
|
+
|
|
33643
|
+
function updateHistoryState(mode, nextUrl) {
|
|
33644
|
+
return writeHistoryState(applyHistoryState(readHistoryState(), mode, nextUrl));
|
|
33575
33645
|
}
|
|
33576
33646
|
|
|
33577
33647
|
function readHistoryState() {
|
|
33648
|
+
const cached = normalizeHistoryState(historyStateCache);
|
|
33649
|
+
if (cached) {
|
|
33650
|
+
historyStateCache = cached;
|
|
33651
|
+
return cached;
|
|
33652
|
+
}
|
|
33578
33653
|
try {
|
|
33579
33654
|
const raw = sessionStorage.getItem(historyStateKey);
|
|
33580
|
-
const parsed = raw ? JSON.parse(raw) : undefined;
|
|
33581
|
-
if (
|
|
33582
|
-
parsed
|
|
33583
|
-
Array.isArray(parsed.entries) &&
|
|
33584
|
-
parsed.entries.every((entry) => typeof entry === "string") &&
|
|
33585
|
-
typeof parsed.index === "number"
|
|
33586
|
-
) {
|
|
33655
|
+
const parsed = normalizeHistoryState(raw ? JSON.parse(raw) : undefined);
|
|
33656
|
+
if (parsed) {
|
|
33657
|
+
historyStateCache = parsed;
|
|
33587
33658
|
return parsed;
|
|
33588
33659
|
}
|
|
33589
33660
|
} catch {}
|
|
@@ -33595,28 +33666,30 @@ var FLOW_RECORDER_INSTALL_SOURCE = String.raw`(() => {
|
|
|
33595
33666
|
if (!state) {
|
|
33596
33667
|
return undefined;
|
|
33597
33668
|
}
|
|
33669
|
+
if (state.entries[state.index] === currentUrl) {
|
|
33670
|
+
return undefined;
|
|
33671
|
+
}
|
|
33598
33672
|
if (state.entries[state.index - 1] === currentUrl) {
|
|
33599
|
-
|
|
33673
|
+
writeHistoryState({
|
|
33674
|
+
entries: state.entries,
|
|
33675
|
+
index: state.index - 1,
|
|
33676
|
+
});
|
|
33600
33677
|
return "go-back";
|
|
33601
33678
|
}
|
|
33602
33679
|
if (state.entries[state.index + 1] === currentUrl) {
|
|
33603
|
-
|
|
33680
|
+
writeHistoryState({
|
|
33681
|
+
entries: state.entries,
|
|
33682
|
+
index: state.index + 1,
|
|
33683
|
+
});
|
|
33604
33684
|
return "go-forward";
|
|
33605
33685
|
}
|
|
33606
33686
|
const existingIndex = state.entries.lastIndexOf(currentUrl);
|
|
33607
|
-
if (existingIndex !== -1) {
|
|
33608
|
-
|
|
33609
|
-
|
|
33610
|
-
|
|
33611
|
-
|
|
33612
|
-
|
|
33613
|
-
}
|
|
33614
|
-
if (existingIndex > state.index) {
|
|
33615
|
-
while (readHistoryState()?.index < existingIndex) {
|
|
33616
|
-
updateHistoryState("forward", currentUrl);
|
|
33617
|
-
}
|
|
33618
|
-
return "go-forward";
|
|
33619
|
-
}
|
|
33687
|
+
if (existingIndex !== -1 && existingIndex !== state.index) {
|
|
33688
|
+
writeHistoryState({
|
|
33689
|
+
entries: state.entries,
|
|
33690
|
+
index: existingIndex,
|
|
33691
|
+
});
|
|
33692
|
+
return existingIndex < state.index ? "go-back" : "go-forward";
|
|
33620
33693
|
}
|
|
33621
33694
|
return undefined;
|
|
33622
33695
|
}
|
|
@@ -33743,10 +33816,6 @@ var FLOW_RECORDER_INSTALL_SOURCE = String.raw`(() => {
|
|
|
33743
33816
|
" outline: 2px solid #2563eb;",
|
|
33744
33817
|
" outline-offset: 2px;",
|
|
33745
33818
|
"}",
|
|
33746
|
-
"button:disabled {",
|
|
33747
|
-
" cursor: wait;",
|
|
33748
|
-
" opacity: 0.8;",
|
|
33749
|
-
"}",
|
|
33750
33819
|
].join("\n");
|
|
33751
33820
|
const button = document.createElement("button");
|
|
33752
33821
|
button.type = "button";
|
|
@@ -33979,7 +34048,8 @@ var FLOW_RECORDER_INSTALL_SOURCE = String.raw`(() => {
|
|
|
33979
34048
|
});
|
|
33980
34049
|
return;
|
|
33981
34050
|
}
|
|
33982
|
-
|
|
34051
|
+
const state = readHistoryState();
|
|
34052
|
+
if (state?.entries[state.index] !== currentUrl) {
|
|
33983
34053
|
updateHistoryState("push", currentUrl);
|
|
33984
34054
|
enqueue({
|
|
33985
34055
|
kind: "navigate",
|
|
@@ -34033,10 +34103,13 @@ var FLOW_RECORDER_INSTALL_SOURCE = String.raw`(() => {
|
|
|
34033
34103
|
},
|
|
34034
34104
|
};
|
|
34035
34105
|
|
|
34036
|
-
|
|
34106
|
+
if (options.showStopButton) {
|
|
34107
|
+
ensureStopButtonMounted();
|
|
34108
|
+
}
|
|
34037
34109
|
onInstall();
|
|
34038
34110
|
})();`;
|
|
34039
|
-
|
|
34111
|
+
}
|
|
34112
|
+
var FLOW_RECORDER_INSTALL_SCRIPT = createFlowRecorderInstallScript();
|
|
34040
34113
|
var FLOW_RECORDER_DRAIN_SCRIPT = String.raw`(() => {
|
|
34041
34114
|
const recorder = globalThis.__opensteerFlowRecorder;
|
|
34042
34115
|
if (!recorder || typeof recorder.drain !== "function") {
|
|
@@ -34056,6 +34129,7 @@ var FlowRecorderCollector = class {
|
|
|
34056
34129
|
runtime;
|
|
34057
34130
|
pollIntervalMs;
|
|
34058
34131
|
onAction;
|
|
34132
|
+
installScript;
|
|
34059
34133
|
pages = /* @__PURE__ */ new Map();
|
|
34060
34134
|
actions = [];
|
|
34061
34135
|
nextPageOrdinal = 0;
|
|
@@ -34068,10 +34142,11 @@ var FlowRecorderCollector = class {
|
|
|
34068
34142
|
this.runtime = runtime;
|
|
34069
34143
|
this.pollIntervalMs = options.pollIntervalMs ?? 250;
|
|
34070
34144
|
this.onAction = options.onAction;
|
|
34145
|
+
this.installScript = options.installScript ?? FLOW_RECORDER_INSTALL_SCRIPT;
|
|
34071
34146
|
}
|
|
34072
34147
|
async install() {
|
|
34073
34148
|
await this.runtime.addInitScript({
|
|
34074
|
-
script:
|
|
34149
|
+
script: this.installScript
|
|
34075
34150
|
});
|
|
34076
34151
|
const { pages } = await this.runtime.listPages();
|
|
34077
34152
|
for (const page of pages) {
|
|
@@ -34080,7 +34155,7 @@ var FlowRecorderCollector = class {
|
|
|
34080
34155
|
await Promise.all(
|
|
34081
34156
|
pages.map(
|
|
34082
34157
|
(page) => this.runtime.evaluate({
|
|
34083
|
-
script:
|
|
34158
|
+
script: this.installScript,
|
|
34084
34159
|
pageRef: page.pageRef
|
|
34085
34160
|
}).catch(() => void 0)
|
|
34086
34161
|
)
|
|
@@ -34112,6 +34187,18 @@ var FlowRecorderCollector = class {
|
|
|
34112
34187
|
getActions() {
|
|
34113
34188
|
return this.actions.slice();
|
|
34114
34189
|
}
|
|
34190
|
+
getPages() {
|
|
34191
|
+
return [...this.pages.values()].map((page) => ({
|
|
34192
|
+
pageId: page.pageId,
|
|
34193
|
+
pageRef: page.pageRef,
|
|
34194
|
+
...page.openerPageRef === void 0 ? {} : { openerPageRef: page.openerPageRef },
|
|
34195
|
+
...page.openerPageId === void 0 ? {} : { openerPageId: page.openerPageId },
|
|
34196
|
+
currentUrl: page.currentUrl
|
|
34197
|
+
})).sort((left, right) => comparePageIds(left.pageId, right.pageId));
|
|
34198
|
+
}
|
|
34199
|
+
getFocusedPageId() {
|
|
34200
|
+
return this.focusedPageId;
|
|
34201
|
+
}
|
|
34115
34202
|
async waitForStop() {
|
|
34116
34203
|
if (this.stopDetected) {
|
|
34117
34204
|
return;
|
|
@@ -34208,10 +34295,17 @@ var FlowRecorderCollector = class {
|
|
|
34208
34295
|
}
|
|
34209
34296
|
for (const listedPage of input.listedPages) {
|
|
34210
34297
|
if (!input.previousPageRefs.has(listedPage.pageRef)) {
|
|
34211
|
-
const created = this.ensureKnownPage(
|
|
34298
|
+
const created = this.ensureKnownPage(
|
|
34299
|
+
listedPage.pageRef,
|
|
34300
|
+
listedPage.url,
|
|
34301
|
+
listedPage.openerPageRef
|
|
34302
|
+
);
|
|
34212
34303
|
actions.push({
|
|
34213
34304
|
kind: "new-tab",
|
|
34214
|
-
timestamp: Math.max(
|
|
34305
|
+
timestamp: Math.max(
|
|
34306
|
+
0,
|
|
34307
|
+
(firstEventTimestampByPage.get(listedPage.pageRef) ?? input.pollTimestamp) - 1
|
|
34308
|
+
),
|
|
34215
34309
|
pageId: created.pageId,
|
|
34216
34310
|
pageUrl: listedPage.url,
|
|
34217
34311
|
detail: {
|
|
@@ -34265,7 +34359,11 @@ var FlowRecorderCollector = class {
|
|
|
34265
34359
|
(event) => this.normalizeRawEvent(event, knownPage, evaluatedPage.currentUrl)
|
|
34266
34360
|
)
|
|
34267
34361
|
);
|
|
34268
|
-
this.updateKnownPage(
|
|
34362
|
+
this.updateKnownPage(
|
|
34363
|
+
evaluatedPage.pageRef,
|
|
34364
|
+
evaluatedPage.currentUrl,
|
|
34365
|
+
evaluatedPage.openerPageRef
|
|
34366
|
+
);
|
|
34269
34367
|
}
|
|
34270
34368
|
const focusedPage = input.evaluatedPages.find((page) => page.focused);
|
|
34271
34369
|
if (focusedPage !== void 0 && focusedPage.pageId !== this.focusedPageId) {
|
|
@@ -34516,6 +34614,14 @@ function actionSortPriority(kind) {
|
|
|
34516
34614
|
return 6;
|
|
34517
34615
|
}
|
|
34518
34616
|
}
|
|
34617
|
+
function comparePageIds(left, right) {
|
|
34618
|
+
const leftMatch = /^page(\d+)$/u.exec(left);
|
|
34619
|
+
const rightMatch = /^page(\d+)$/u.exec(right);
|
|
34620
|
+
if (leftMatch && rightMatch) {
|
|
34621
|
+
return Number(leftMatch[1]) - Number(rightMatch[1]);
|
|
34622
|
+
}
|
|
34623
|
+
return left.localeCompare(right);
|
|
34624
|
+
}
|
|
34519
34625
|
function delay2(ms) {
|
|
34520
34626
|
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
34521
34627
|
}
|
|
@@ -34565,17 +34671,16 @@ var WINDOW_SCROLL_SCRIPT = String.raw`(deltaX, deltaY) => {
|
|
|
34565
34671
|
window.scrollBy(Number(deltaX), Number(deltaY));
|
|
34566
34672
|
}`;
|
|
34567
34673
|
function generateReplayScript(options) {
|
|
34568
|
-
const
|
|
34569
|
-
const
|
|
34674
|
+
const replayTarget = resolveReplayTarget(options);
|
|
34675
|
+
const initialPages = orderInitialPages(resolveInitialPages(options));
|
|
34676
|
+
const activeInitialPageId = resolveActiveInitialPageId(options, initialPages);
|
|
34677
|
+
const initialPageId = initialPages[0]?.pageId ?? "page0";
|
|
34570
34678
|
const lines = [
|
|
34571
34679
|
`import { Opensteer } from "opensteer";`,
|
|
34572
34680
|
``,
|
|
34573
|
-
|
|
34574
|
-
` workspace: ${JSON.stringify(options.workspace)},`,
|
|
34575
|
-
` browser: "persistent",`,
|
|
34576
|
-
`});`,
|
|
34681
|
+
...renderOpensteerBootstrap(replayTarget),
|
|
34577
34682
|
``,
|
|
34578
|
-
`const ${initialPageId} = (await opensteer.open(${JSON.stringify(
|
|
34683
|
+
`const ${initialPageId} = (await opensteer.open(${JSON.stringify(initialPages[0]?.initialUrl ?? "")})).pageRef;`,
|
|
34579
34684
|
`let activePageRef: string | undefined = ${initialPageId};`,
|
|
34580
34685
|
``,
|
|
34581
34686
|
`async function ensureActive(pageRef: string): Promise<void> {`,
|
|
@@ -34616,6 +34721,17 @@ function generateReplayScript(options) {
|
|
|
34616
34721
|
`try {`
|
|
34617
34722
|
];
|
|
34618
34723
|
const declaredPages = /* @__PURE__ */ new Set([initialPageId]);
|
|
34724
|
+
for (const page of initialPages.slice(1)) {
|
|
34725
|
+
const openerPageId = page.openerPageId !== void 0 && declaredPages.has(page.openerPageId) ? page.openerPageId : void 0;
|
|
34726
|
+
lines.push(
|
|
34727
|
+
` const ${page.pageId} = (await opensteer.newPage(${renderNewPageInput(openerPageId, page.initialUrl)})).pageRef;`
|
|
34728
|
+
);
|
|
34729
|
+
lines.push(` activePageRef = ${page.pageId};`);
|
|
34730
|
+
declaredPages.add(page.pageId);
|
|
34731
|
+
}
|
|
34732
|
+
if (activeInitialPageId !== void 0 && activeInitialPageId !== initialPageId) {
|
|
34733
|
+
lines.push(` await ensureActive(${activeInitialPageId});`);
|
|
34734
|
+
}
|
|
34619
34735
|
for (let index = 0; index < options.actions.length; index += 1) {
|
|
34620
34736
|
const action = options.actions[index];
|
|
34621
34737
|
const pageVar = action.pageId;
|
|
@@ -34648,16 +34764,11 @@ function generateReplayScript(options) {
|
|
|
34648
34764
|
case "dblclick":
|
|
34649
34765
|
lines.push(` await ensureActive(${pageVar});`);
|
|
34650
34766
|
lines.push(
|
|
34651
|
-
` await opensteer.click({ selector: ${JSON.stringify(requireSelector(action))} });`
|
|
34652
|
-
);
|
|
34653
|
-
lines.push(
|
|
34654
|
-
` await opensteer.click({ selector: ${JSON.stringify(requireSelector(action))} });`
|
|
34767
|
+
` await opensteer.click({ selector: ${JSON.stringify(requireSelector(action))}, clickCount: 2 });`
|
|
34655
34768
|
);
|
|
34656
34769
|
break;
|
|
34657
34770
|
case "keypress":
|
|
34658
|
-
lines.push(
|
|
34659
|
-
` await dispatchKey(${pageVar}, ${JSON.stringify(action.detail.key)});`
|
|
34660
|
-
);
|
|
34771
|
+
lines.push(` await dispatchKey(${pageVar}, ${JSON.stringify(action.detail.key)});`);
|
|
34661
34772
|
break;
|
|
34662
34773
|
case "scroll": {
|
|
34663
34774
|
const { direction, amount, isWindowScroll } = normalizeScrollAction(action);
|
|
@@ -34685,7 +34796,7 @@ function generateReplayScript(options) {
|
|
|
34685
34796
|
case "new-tab": {
|
|
34686
34797
|
const openerPageVar = action.detail.openerPageId;
|
|
34687
34798
|
const shouldUseWaitForPage = shouldUsePopupWait(options.actions, index, openerPageVar);
|
|
34688
|
-
const creationLine = shouldUseWaitForPage && openerPageVar !== void 0 ? ` const ${pageVar} = (await opensteer.waitForPage({ openerPageRef: ${openerPageVar}, timeoutMs: 30_000 })).pageRef;` : ` const ${pageVar} = (await opensteer.newPage(
|
|
34799
|
+
const creationLine = shouldUseWaitForPage && openerPageVar !== void 0 ? ` const ${pageVar} = (await opensteer.waitForPage({ openerPageRef: ${openerPageVar}, timeoutMs: 30_000 })).pageRef;` : ` const ${pageVar} = (await opensteer.newPage(${renderNewPageInput(action.detail.openerPageId, action.detail.initialUrl)})).pageRef;`;
|
|
34689
34800
|
lines.push(creationLine);
|
|
34690
34801
|
lines.push(` activePageRef = ${pageVar};`);
|
|
34691
34802
|
declaredPages.add(pageVar);
|
|
@@ -34718,29 +34829,114 @@ function generateReplayScript(options) {
|
|
|
34718
34829
|
return `${lines.join("\n")}
|
|
34719
34830
|
`;
|
|
34720
34831
|
}
|
|
34721
|
-
function
|
|
34722
|
-
|
|
34723
|
-
|
|
34724
|
-
|
|
34725
|
-
|
|
34726
|
-
|
|
34727
|
-
|
|
34728
|
-
|
|
34729
|
-
|
|
34730
|
-
|
|
34731
|
-
|
|
34732
|
-
|
|
34832
|
+
function resolveReplayTarget(options) {
|
|
34833
|
+
if (options.replayTarget !== void 0) {
|
|
34834
|
+
return options.replayTarget;
|
|
34835
|
+
}
|
|
34836
|
+
if (options.workspace !== void 0) {
|
|
34837
|
+
return {
|
|
34838
|
+
kind: "local",
|
|
34839
|
+
workspace: options.workspace
|
|
34840
|
+
};
|
|
34841
|
+
}
|
|
34842
|
+
throw new Error("Replay codegen requires either replayTarget or workspace.");
|
|
34843
|
+
}
|
|
34844
|
+
function resolveInitialPages(options) {
|
|
34845
|
+
if (options.initialPages !== void 0 && options.initialPages.length > 0) {
|
|
34846
|
+
const unique = /* @__PURE__ */ new Set();
|
|
34847
|
+
return options.initialPages.map((page) => {
|
|
34848
|
+
if (unique.has(page.pageId)) {
|
|
34849
|
+
throw new Error(`Duplicate initial page id "${page.pageId}" in recording bootstrap.`);
|
|
34850
|
+
}
|
|
34851
|
+
unique.add(page.pageId);
|
|
34852
|
+
return page;
|
|
34853
|
+
});
|
|
34854
|
+
}
|
|
34855
|
+
const startUrl = options.startUrl;
|
|
34856
|
+
if (startUrl === void 0) {
|
|
34857
|
+
throw new Error("Replay codegen requires startUrl when initialPages is not provided.");
|
|
34858
|
+
}
|
|
34859
|
+
return [
|
|
34860
|
+
{
|
|
34861
|
+
pageId: "page0",
|
|
34862
|
+
initialUrl: startUrl
|
|
34733
34863
|
}
|
|
34864
|
+
];
|
|
34865
|
+
}
|
|
34866
|
+
function resolveActiveInitialPageId(options, initialPages) {
|
|
34867
|
+
if (options.activePageId !== void 0) {
|
|
34868
|
+
return options.activePageId;
|
|
34734
34869
|
}
|
|
34735
|
-
return [
|
|
34870
|
+
return initialPages[0]?.pageId;
|
|
34736
34871
|
}
|
|
34737
|
-
function
|
|
34738
|
-
|
|
34739
|
-
|
|
34740
|
-
|
|
34741
|
-
|
|
34872
|
+
function renderOpensteerBootstrap(replayTarget) {
|
|
34873
|
+
if (replayTarget.kind === "local") {
|
|
34874
|
+
return [
|
|
34875
|
+
`const opensteer = new Opensteer({`,
|
|
34876
|
+
` workspace: ${JSON.stringify(replayTarget.workspace)},`,
|
|
34877
|
+
` browser: "persistent",`,
|
|
34878
|
+
`});`
|
|
34879
|
+
];
|
|
34742
34880
|
}
|
|
34743
|
-
return
|
|
34881
|
+
return [
|
|
34882
|
+
renderRequireEnvHelper(replayTarget),
|
|
34883
|
+
``,
|
|
34884
|
+
`const opensteer = new Opensteer({`,
|
|
34885
|
+
` provider: {`,
|
|
34886
|
+
` mode: "cloud",`,
|
|
34887
|
+
` baseUrl: requireEnv(${JSON.stringify(replayTarget.baseUrlEnvVar ?? "OPENSTEER_BASE_URL")}),`,
|
|
34888
|
+
` apiKey: requireEnv(${JSON.stringify(replayTarget.apiKeyEnvVar ?? "OPENSTEER_API_KEY")}),`,
|
|
34889
|
+
...renderCloudBrowserProfile(replayTarget),
|
|
34890
|
+
` },`,
|
|
34891
|
+
`});`
|
|
34892
|
+
];
|
|
34893
|
+
}
|
|
34894
|
+
function renderRequireEnvHelper(replayTarget) {
|
|
34895
|
+
const baseUrlEnvVar = replayTarget.baseUrlEnvVar ?? "OPENSTEER_BASE_URL";
|
|
34896
|
+
const apiKeyEnvVar = replayTarget.apiKeyEnvVar ?? "OPENSTEER_API_KEY";
|
|
34897
|
+
return [
|
|
34898
|
+
`function requireEnv(name: string): string {`,
|
|
34899
|
+
` const value = process.env[name];`,
|
|
34900
|
+
` if (typeof value === "string" && value.trim().length > 0) {`,
|
|
34901
|
+
` return value;`,
|
|
34902
|
+
` }`,
|
|
34903
|
+
` throw new Error(\`Missing environment variable \${name}. Set ${baseUrlEnvVar} and ${apiKeyEnvVar} before replaying this recording.\`);`,
|
|
34904
|
+
`}`
|
|
34905
|
+
].join("\n");
|
|
34906
|
+
}
|
|
34907
|
+
function renderCloudBrowserProfile(replayTarget) {
|
|
34908
|
+
if (replayTarget.browserProfileId === void 0) {
|
|
34909
|
+
return [];
|
|
34910
|
+
}
|
|
34911
|
+
return [
|
|
34912
|
+
` browserProfile: {`,
|
|
34913
|
+
` profileId: ${JSON.stringify(replayTarget.browserProfileId)},`,
|
|
34914
|
+
...replayTarget.reuseBrowserProfileIfActive ? [` reuseIfActive: true,`] : [],
|
|
34915
|
+
` },`
|
|
34916
|
+
];
|
|
34917
|
+
}
|
|
34918
|
+
function orderInitialPages(initialPages) {
|
|
34919
|
+
const ordered = [];
|
|
34920
|
+
const declared = /* @__PURE__ */ new Set();
|
|
34921
|
+
const remaining = [...initialPages];
|
|
34922
|
+
while (remaining.length > 0) {
|
|
34923
|
+
let advanced = false;
|
|
34924
|
+
for (let index = 0; index < remaining.length; index += 1) {
|
|
34925
|
+
const page = remaining[index];
|
|
34926
|
+
if (page.openerPageId !== void 0 && !declared.has(page.openerPageId)) {
|
|
34927
|
+
continue;
|
|
34928
|
+
}
|
|
34929
|
+
ordered.push(page);
|
|
34930
|
+
declared.add(page.pageId);
|
|
34931
|
+
remaining.splice(index, 1);
|
|
34932
|
+
advanced = true;
|
|
34933
|
+
break;
|
|
34934
|
+
}
|
|
34935
|
+
if (!advanced) {
|
|
34936
|
+
ordered.push(...remaining.splice(0, remaining.length));
|
|
34937
|
+
}
|
|
34938
|
+
}
|
|
34939
|
+
return ordered;
|
|
34744
34940
|
}
|
|
34745
34941
|
function requireSelector(action) {
|
|
34746
34942
|
if (action.selector === void 0) {
|
|
@@ -34774,18 +34970,18 @@ function shouldUsePopupWait(actions, newTabIndex, openerPageId) {
|
|
|
34774
34970
|
}
|
|
34775
34971
|
return previousAction.kind === "click" || previousAction.kind === "dblclick" || previousAction.kind === "keypress";
|
|
34776
34972
|
}
|
|
34777
|
-
function
|
|
34973
|
+
function renderNewPageInput(openerPageId, initialUrl) {
|
|
34778
34974
|
const argumentsList = [];
|
|
34779
34975
|
if (openerPageId !== void 0) {
|
|
34780
|
-
argumentsList.push(`
|
|
34976
|
+
argumentsList.push(`openerPageRef: ${openerPageId}`);
|
|
34781
34977
|
}
|
|
34782
34978
|
if (initialUrl.length > 0 && initialUrl !== "about:blank") {
|
|
34783
|
-
argumentsList.push(`
|
|
34979
|
+
argumentsList.push(`url: ${JSON.stringify(initialUrl)}`);
|
|
34784
34980
|
}
|
|
34785
34981
|
if (argumentsList.length === 0) {
|
|
34786
|
-
return
|
|
34982
|
+
return `{}`;
|
|
34787
34983
|
}
|
|
34788
|
-
return ` ${argumentsList.join(",")}
|
|
34984
|
+
return `{ ${argumentsList.join(", ")} }`;
|
|
34789
34985
|
}
|
|
34790
34986
|
var OpensteerSemanticRestError = class extends Error {
|
|
34791
34987
|
opensteerError;
|
|
@@ -35934,18 +36130,6 @@ function resolveOwnership(browser) {
|
|
|
35934
36130
|
}
|
|
35935
36131
|
|
|
35936
36132
|
// src/sdk/runtime-resolution.ts
|
|
35937
|
-
var LOCAL_ONLY_RUNTIME_OPTION_KEYS = [
|
|
35938
|
-
"launch",
|
|
35939
|
-
"context",
|
|
35940
|
-
"engine",
|
|
35941
|
-
"engineFactory",
|
|
35942
|
-
"policy",
|
|
35943
|
-
"descriptorStore",
|
|
35944
|
-
"extractionDescriptorStore",
|
|
35945
|
-
"registryOverrides",
|
|
35946
|
-
"observationSessionId",
|
|
35947
|
-
"observationSink"
|
|
35948
|
-
];
|
|
35949
36133
|
function resolveOpensteerRuntimeConfig(input = {}) {
|
|
35950
36134
|
const environment = input.environment ?? process.env;
|
|
35951
36135
|
const provider = resolveOpensteerProvider({
|
|
@@ -35970,15 +36154,8 @@ function createOpensteerSemanticRuntime(input = {}) {
|
|
|
35970
36154
|
...input.provider === void 0 ? {} : { provider: input.provider },
|
|
35971
36155
|
...input.environment === void 0 ? {} : { environment: input.environment }
|
|
35972
36156
|
});
|
|
35973
|
-
|
|
35974
|
-
|
|
35975
|
-
if (config.provider.mode === "cloud" && config.provider.source === "explicit" && localOnlyRuntimeOptions.length > 0) {
|
|
35976
|
-
throw new Error(
|
|
35977
|
-
`provider=cloud does not support local runtime options: ${localOnlyRuntimeOptions.join(", ")}.`
|
|
35978
|
-
);
|
|
35979
|
-
}
|
|
35980
|
-
assertProviderSupportsEngine(providerMode, engine);
|
|
35981
|
-
if (providerMode === "cloud") {
|
|
36157
|
+
assertProviderSupportsEngine(config.provider.mode, engine);
|
|
36158
|
+
if (config.provider.mode === "cloud") {
|
|
35982
36159
|
return new CloudSessionProxy(new OpensteerCloudClient(config.cloud), {
|
|
35983
36160
|
...runtimeOptions.rootDir === void 0 ? {} : { rootDir: runtimeOptions.rootDir },
|
|
35984
36161
|
...runtimeOptions.rootPath === void 0 ? {} : { rootPath: runtimeOptions.rootPath },
|
|
@@ -35992,9 +36169,6 @@ function createOpensteerSemanticRuntime(input = {}) {
|
|
|
35992
36169
|
engineName: engine
|
|
35993
36170
|
});
|
|
35994
36171
|
}
|
|
35995
|
-
function listLocalOnlyRuntimeOptions(runtimeOptions) {
|
|
35996
|
-
return LOCAL_ONLY_RUNTIME_OPTION_KEYS.filter((key) => runtimeOptions[key] !== void 0);
|
|
35997
|
-
}
|
|
35998
36172
|
async function collectOpensteerStatus(input) {
|
|
35999
36173
|
const output = {
|
|
36000
36174
|
provider: {
|
|
@@ -36202,6 +36376,65 @@ async function runOpensteerRecordCommand(input) {
|
|
|
36202
36376
|
}
|
|
36203
36377
|
}
|
|
36204
36378
|
}
|
|
36379
|
+
async function runOpensteerCloudRecordCommand(input) {
|
|
36380
|
+
const stdout = input.stdout ?? process.stdout;
|
|
36381
|
+
const stderr = input.stderr ?? process.stderr;
|
|
36382
|
+
const outputPath = resolveRecordOutputPath({
|
|
36383
|
+
rootDir: input.rootDir,
|
|
36384
|
+
workspace: input.workspace,
|
|
36385
|
+
...input.outputPath === void 0 ? {} : { outputPath: input.outputPath }
|
|
36386
|
+
});
|
|
36387
|
+
let cloud;
|
|
36388
|
+
const resolveCloud = () => {
|
|
36389
|
+
cloud ??= new OpensteerCloudClient(input.cloudConfig);
|
|
36390
|
+
return cloud;
|
|
36391
|
+
};
|
|
36392
|
+
const runtime = input.runtime ?? new CloudSessionProxy(resolveCloud(), {
|
|
36393
|
+
rootDir: input.rootDir,
|
|
36394
|
+
workspace: input.workspace
|
|
36395
|
+
});
|
|
36396
|
+
const client = input.client ?? resolveCloud();
|
|
36397
|
+
const sleep5 = input.sleep ?? delay3;
|
|
36398
|
+
let closed = false;
|
|
36399
|
+
try {
|
|
36400
|
+
await runtime.open({
|
|
36401
|
+
url: input.url,
|
|
36402
|
+
...input.browser === void 0 ? {} : { browser: input.browser },
|
|
36403
|
+
...input.launch === void 0 ? {} : { launch: input.launch },
|
|
36404
|
+
...input.context === void 0 ? {} : { context: input.context }
|
|
36405
|
+
});
|
|
36406
|
+
const sessionId = await resolveCloudRecordingSessionId(runtime);
|
|
36407
|
+
const sessionUrl = buildCloudRecordingSessionUrl(input.cloudConfig, sessionId);
|
|
36408
|
+
await client.startSessionRecording(sessionId);
|
|
36409
|
+
stderr.write(
|
|
36410
|
+
`Recording browser actions for workspace "${input.workspace}". Open ${sessionUrl} and click "Stop recording" in the browser session toolbar when you're done.
|
|
36411
|
+
`
|
|
36412
|
+
);
|
|
36413
|
+
const completed = await waitForCloudRecordingCompletion({
|
|
36414
|
+
client,
|
|
36415
|
+
sessionId,
|
|
36416
|
+
...input.pollIntervalMs === void 0 ? {} : { pollIntervalMs: input.pollIntervalMs },
|
|
36417
|
+
sleep: sleep5
|
|
36418
|
+
});
|
|
36419
|
+
if (completed.result === void 0) {
|
|
36420
|
+
throw new Error("Cloud recording completed without a replay script.");
|
|
36421
|
+
}
|
|
36422
|
+
await promises.mkdir(path7__default.default.dirname(outputPath), { recursive: true });
|
|
36423
|
+
await promises.writeFile(outputPath, completed.result.script, "utf8");
|
|
36424
|
+
await runtime.close();
|
|
36425
|
+
closed = true;
|
|
36426
|
+
stdout.write(`${outputPath}
|
|
36427
|
+
`);
|
|
36428
|
+
stderr.write(`Cloud browser session: ${sessionUrl}
|
|
36429
|
+
`);
|
|
36430
|
+
stderr.write(`Wrote replay script to ${outputPath}
|
|
36431
|
+
`);
|
|
36432
|
+
} finally {
|
|
36433
|
+
if (!closed) {
|
|
36434
|
+
await runtime.close().catch(() => void 0);
|
|
36435
|
+
}
|
|
36436
|
+
}
|
|
36437
|
+
}
|
|
36205
36438
|
function resolveRecordOutputPath(input) {
|
|
36206
36439
|
if (input.outputPath !== void 0) {
|
|
36207
36440
|
return path7__default.default.resolve(input.rootDir, input.outputPath);
|
|
@@ -36236,6 +36469,35 @@ function createRecorderRuntimeAdapter(runtime) {
|
|
|
36236
36469
|
}
|
|
36237
36470
|
};
|
|
36238
36471
|
}
|
|
36472
|
+
function buildCloudRecordingSessionUrl(cloudConfig, sessionId) {
|
|
36473
|
+
const baseUrl = cloudConfig.appBaseUrl;
|
|
36474
|
+
if (!baseUrl || baseUrl.trim().length === 0) {
|
|
36475
|
+
throw new Error(
|
|
36476
|
+
'record with provider=cloud requires OPENSTEER_CLOUD_APP_BASE_URL or "--cloud-app-base-url".'
|
|
36477
|
+
);
|
|
36478
|
+
}
|
|
36479
|
+
return `${baseUrl.replace(/\/+$/, "")}/browsers/${encodeURIComponent(sessionId)}`;
|
|
36480
|
+
}
|
|
36481
|
+
async function resolveCloudRecordingSessionId(runtime) {
|
|
36482
|
+
const info = await runtime.info();
|
|
36483
|
+
if (typeof info.sessionId !== "string" || info.sessionId.length === 0) {
|
|
36484
|
+
throw new Error("Cloud recording could not resolve the created session id.");
|
|
36485
|
+
}
|
|
36486
|
+
return info.sessionId;
|
|
36487
|
+
}
|
|
36488
|
+
async function waitForCloudRecordingCompletion(input) {
|
|
36489
|
+
const pollIntervalMs = input.pollIntervalMs ?? 1e3;
|
|
36490
|
+
for (; ; ) {
|
|
36491
|
+
const state = await input.client.getSessionRecording(input.sessionId);
|
|
36492
|
+
if (state.status === "completed") {
|
|
36493
|
+
return state;
|
|
36494
|
+
}
|
|
36495
|
+
if (state.status === "failed") {
|
|
36496
|
+
throw new Error(state.error ?? "Cloud recording failed.");
|
|
36497
|
+
}
|
|
36498
|
+
await input.sleep(pollIntervalMs);
|
|
36499
|
+
}
|
|
36500
|
+
}
|
|
36239
36501
|
function formatRecordedAction(action) {
|
|
36240
36502
|
const time = new Date(action.timestamp).toISOString().slice(11, 19);
|
|
36241
36503
|
switch (action.kind) {
|
|
@@ -36267,6 +36529,11 @@ function formatRecordedAction(action) {
|
|
|
36267
36529
|
return `[${time}] reload ${action.pageId}`;
|
|
36268
36530
|
}
|
|
36269
36531
|
}
|
|
36532
|
+
function delay3(ms) {
|
|
36533
|
+
return new Promise((resolve4) => {
|
|
36534
|
+
setTimeout(resolve4, ms);
|
|
36535
|
+
});
|
|
36536
|
+
}
|
|
36270
36537
|
|
|
36271
36538
|
// src/cli/bin.ts
|
|
36272
36539
|
var OPERATION_ALIASES = /* @__PURE__ */ new Map([
|
|
@@ -36516,22 +36783,39 @@ async function handleRecordCommandEntry(parsed) {
|
|
|
36516
36783
|
}
|
|
36517
36784
|
const provider = resolveCliProvider(parsed);
|
|
36518
36785
|
assertCloudCliOptionsMatchProvider(parsed, provider.mode);
|
|
36519
|
-
if (provider.mode !== "local") {
|
|
36520
|
-
throw new Error(
|
|
36521
|
-
'record requires provider=local. Set "--provider local" or clear OPENSTEER_PROVIDER.'
|
|
36522
|
-
);
|
|
36523
|
-
}
|
|
36524
36786
|
const engineName = resolveCliEngineName(parsed);
|
|
36525
36787
|
if (engineName !== "playwright") {
|
|
36526
36788
|
throw new Error("record requires engine=playwright.");
|
|
36527
36789
|
}
|
|
36528
|
-
|
|
36529
|
-
|
|
36790
|
+
const rootDir = process2__default.default.cwd();
|
|
36791
|
+
const recordBrowser = parsed.options.browser;
|
|
36792
|
+
if (provider.mode === "cloud") {
|
|
36793
|
+
if (typeof recordBrowser === "object") {
|
|
36794
|
+
throw new Error('record does not support browser.mode="attach".');
|
|
36795
|
+
}
|
|
36796
|
+
const runtimeProvider = buildCliRuntimeProvider(parsed, provider.mode);
|
|
36797
|
+
const runtimeConfig = resolveOpensteerRuntimeConfig({
|
|
36798
|
+
...runtimeProvider === void 0 ? {} : { provider: runtimeProvider },
|
|
36799
|
+
environment: process2__default.default.env
|
|
36800
|
+
});
|
|
36801
|
+
await runOpensteerCloudRecordCommand({
|
|
36802
|
+
cloudConfig: runtimeConfig.cloud,
|
|
36803
|
+
workspace: parsed.options.workspace,
|
|
36804
|
+
url,
|
|
36805
|
+
rootDir,
|
|
36806
|
+
...recordBrowser === void 0 ? {} : { browser: recordBrowser },
|
|
36807
|
+
...parsed.options.launch === void 0 ? {} : { launch: parsed.options.launch },
|
|
36808
|
+
...parsed.options.context === void 0 ? {} : { context: parsed.options.context },
|
|
36809
|
+
...parsed.options.output === void 0 ? {} : { outputPath: parsed.options.output }
|
|
36810
|
+
});
|
|
36811
|
+
return;
|
|
36530
36812
|
}
|
|
36531
36813
|
if (parsed.options.launch?.headless === true) {
|
|
36532
36814
|
throw new Error('record requires a headed browser. Remove "--headless true".');
|
|
36533
36815
|
}
|
|
36534
|
-
|
|
36816
|
+
if (recordBrowser !== void 0 && recordBrowser !== "persistent") {
|
|
36817
|
+
throw new Error('record only supports "--browser persistent".');
|
|
36818
|
+
}
|
|
36535
36819
|
const launch = {
|
|
36536
36820
|
...parsed.options.launch ?? {},
|
|
36537
36821
|
headless: false
|
|
@@ -36671,6 +36955,7 @@ var CLI_OPTION_SPECS = {
|
|
|
36671
36955
|
provider: { kind: "value" },
|
|
36672
36956
|
"cloud-base-url": { kind: "value" },
|
|
36673
36957
|
"cloud-api-key": { kind: "value" },
|
|
36958
|
+
"cloud-app-base-url": { kind: "value" },
|
|
36674
36959
|
"cloud-profile-id": { kind: "value" },
|
|
36675
36960
|
"cloud-profile-reuse-if-active": { kind: "boolean" },
|
|
36676
36961
|
json: { kind: "boolean" },
|
|
@@ -36800,6 +37085,7 @@ function parseCommandLine(argv) {
|
|
|
36800
37085
|
const provider = providerValue === void 0 ? void 0 : normalizeOpensteerProviderMode(providerValue, "--provider");
|
|
36801
37086
|
const cloudBaseUrl = readSingle(rawOptions, "cloud-base-url");
|
|
36802
37087
|
const cloudApiKey = readSingle(rawOptions, "cloud-api-key");
|
|
37088
|
+
const cloudAppBaseUrl = readSingle(rawOptions, "cloud-app-base-url");
|
|
36803
37089
|
const cloudProfileId = readSingle(rawOptions, "cloud-profile-id");
|
|
36804
37090
|
const cloudProfileReuseIfActive = readOptionalBoolean(
|
|
36805
37091
|
rawOptions,
|
|
@@ -36821,6 +37107,7 @@ function parseCommandLine(argv) {
|
|
|
36821
37107
|
...provider === void 0 ? {} : { provider },
|
|
36822
37108
|
...cloudBaseUrl === void 0 ? {} : { cloudBaseUrl },
|
|
36823
37109
|
...cloudApiKey === void 0 ? {} : { cloudApiKey },
|
|
37110
|
+
...cloudAppBaseUrl === void 0 ? {} : { cloudAppBaseUrl },
|
|
36824
37111
|
...cloudProfileId === void 0 ? {} : { cloudProfileId },
|
|
36825
37112
|
...cloudProfileReuseIfActive === void 0 ? {} : { cloudProfileReuseIfActive },
|
|
36826
37113
|
...json === void 0 ? {} : { json },
|
|
@@ -36905,7 +37192,7 @@ function buildCliRuntimeProvider(parsed, providerMode) {
|
|
|
36905
37192
|
return explicitProvider?.mode === "local" ? explicitProvider : void 0;
|
|
36906
37193
|
}
|
|
36907
37194
|
const browserProfile = buildCliBrowserProfile(parsed);
|
|
36908
|
-
const hasCloudOverrides = parsed.options.cloudBaseUrl !== void 0 || parsed.options.cloudApiKey !== void 0 || browserProfile !== void 0;
|
|
37195
|
+
const hasCloudOverrides = parsed.options.cloudBaseUrl !== void 0 || parsed.options.cloudApiKey !== void 0 || parsed.options.cloudAppBaseUrl !== void 0 || browserProfile !== void 0;
|
|
36909
37196
|
if (!hasCloudOverrides && explicitProvider?.mode !== "cloud") {
|
|
36910
37197
|
return void 0;
|
|
36911
37198
|
}
|
|
@@ -36913,11 +37200,12 @@ function buildCliRuntimeProvider(parsed, providerMode) {
|
|
|
36913
37200
|
mode: "cloud",
|
|
36914
37201
|
...parsed.options.cloudBaseUrl === void 0 ? {} : { baseUrl: parsed.options.cloudBaseUrl },
|
|
36915
37202
|
...parsed.options.cloudApiKey === void 0 ? {} : { apiKey: parsed.options.cloudApiKey },
|
|
37203
|
+
...parsed.options.cloudAppBaseUrl === void 0 ? {} : { appBaseUrl: parsed.options.cloudAppBaseUrl },
|
|
36916
37204
|
...browserProfile === void 0 ? {} : { browserProfile }
|
|
36917
37205
|
};
|
|
36918
37206
|
}
|
|
36919
37207
|
function assertCloudCliOptionsMatchProvider(parsed, providerMode) {
|
|
36920
|
-
if (providerMode !== "cloud" && (parsed.options.cloudBaseUrl !== void 0 || parsed.options.cloudApiKey !== void 0 || parsed.options.cloudProfileId !== void 0 || parsed.options.cloudProfileReuseIfActive === true)) {
|
|
37208
|
+
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)) {
|
|
36921
37209
|
throw new Error(
|
|
36922
37210
|
'Cloud-specific options require provider=cloud. Set "--provider cloud" or OPENSTEER_PROVIDER=cloud.'
|
|
36923
37211
|
);
|
|
@@ -37059,6 +37347,7 @@ Common options:
|
|
|
37059
37347
|
--provider local|cloud
|
|
37060
37348
|
--cloud-base-url <url>
|
|
37061
37349
|
--cloud-api-key <key>
|
|
37350
|
+
--cloud-app-base-url <url>
|
|
37062
37351
|
--cloud-profile-id <id>
|
|
37063
37352
|
--cloud-profile-reuse-if-active <true|false>
|
|
37064
37353
|
--json <true|false>
|