@xbrowser/cli 1.8.6 → 1.9.0
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/{browser-XPKM344Y.js → browser-4KRHALJ3.js} +1 -1
- package/dist/{browser-LW2MDJE4.js → browser-6WJHQDPV.js} +1 -1
- package/dist/{browser-TLIDFFEG.js → browser-C63PFGPT.js} +1 -1
- package/dist/{chunk-CJJ564VK.js → chunk-MSQIPXKE.js} +1 -1
- package/dist/{chunk-HXLMMSU3.js → chunk-OOJ2H7IL.js} +1 -1
- package/dist/{chunk-FL6DOSWV.js → chunk-TTZNR3QP.js} +30 -2
- package/dist/{chunk-RMYEHTLS.js → chunk-YSCY52UJ.js} +30 -2
- package/dist/{chunk-SJLRCE6N.js → chunk-Z7WC4P2M.js} +1 -1
- package/dist/cli.js +42 -34
- package/dist/daemon-main.js +57 -171
- package/dist/index.d.ts +11 -1
- package/dist/index.js +41 -33
- package/dist/{session-recorder-33UKWCIR.js → session-recorder-KPU4YQAE.js} +1 -1
- package/dist/{session-recorder-BMIJ3ZJM.js → session-recorder-UTULJFTE.js} +1 -1
- package/package.json +1 -1
|
@@ -656,7 +656,7 @@ async function closeSessionByName(name) {
|
|
|
656
656
|
} catch {
|
|
657
657
|
}
|
|
658
658
|
try {
|
|
659
|
-
const { SessionRecorder } = await import("./session-recorder-
|
|
659
|
+
const { SessionRecorder } = await import("./session-recorder-KPU4YQAE.js");
|
|
660
660
|
SessionRecorder.cleanup(session.name);
|
|
661
661
|
} catch {
|
|
662
662
|
}
|
|
@@ -2021,7 +2021,7 @@ async function closeSessionByName(name) {
|
|
|
2021
2021
|
} catch {
|
|
2022
2022
|
}
|
|
2023
2023
|
try {
|
|
2024
|
-
const { SessionRecorder } = await import("./session-recorder-
|
|
2024
|
+
const { SessionRecorder } = await import("./session-recorder-UTULJFTE.js");
|
|
2025
2025
|
SessionRecorder.cleanup(session.name);
|
|
2026
2026
|
} catch {
|
|
2027
2027
|
}
|
|
@@ -1639,7 +1639,7 @@ var SessionRecorder = class _SessionRecorder {
|
|
|
1639
1639
|
return this.actions.length;
|
|
1640
1640
|
}
|
|
1641
1641
|
/** Record an action triggered by a CDP command (e.g. xbrowser fill/click/goto) */
|
|
1642
|
-
recordCommandAction(action) {
|
|
1642
|
+
async recordCommandAction(action) {
|
|
1643
1643
|
const normalizedType = action.type === "cdp-fill" ? "input" : action.type === "cdp-click" ? "click" : action.type;
|
|
1644
1644
|
const recent = this.actions[this.actions.length - 1];
|
|
1645
1645
|
if (recent && Date.now() - recent.timestamp < 1500) {
|
|
@@ -1653,7 +1653,7 @@ var SessionRecorder = class _SessionRecorder {
|
|
|
1653
1653
|
this.actionCounter++;
|
|
1654
1654
|
const ts = Date.now();
|
|
1655
1655
|
const actionUrl = action.url && action.url !== "about:blank" ? action.url : this.lastKnownUrl || this.page.url();
|
|
1656
|
-
|
|
1656
|
+
const actionToPush = {
|
|
1657
1657
|
id: this.actionCounter,
|
|
1658
1658
|
type: action.type,
|
|
1659
1659
|
timestamp: ts,
|
|
@@ -1661,6 +1661,11 @@ var SessionRecorder = class _SessionRecorder {
|
|
|
1661
1661
|
pageTitle: "",
|
|
1662
1662
|
element: action.element || (action.selector ? { tag: "", selector: action.selector, text: "" } : void 0),
|
|
1663
1663
|
value: action.value
|
|
1664
|
+
};
|
|
1665
|
+
this.actions.push(actionToPush);
|
|
1666
|
+
actionToPush.elementScreenshot = await this.captureElementScreenshot(this.page, {
|
|
1667
|
+
type: action.type,
|
|
1668
|
+
element: actionToPush.element
|
|
1664
1669
|
});
|
|
1665
1670
|
this.lastActionTs = ts;
|
|
1666
1671
|
this.cdpActionDedup = {
|
|
@@ -2319,6 +2324,8 @@ var SessionRecorder = class _SessionRecorder {
|
|
|
2319
2324
|
clickContext,
|
|
2320
2325
|
files: raw.files
|
|
2321
2326
|
});
|
|
2327
|
+
const pushed = this.actions[this.actions.length - 1];
|
|
2328
|
+
pushed.elementScreenshot = await this.captureElementScreenshot(page, raw);
|
|
2322
2329
|
this.lastActionTs = raw.ts;
|
|
2323
2330
|
if (raw.type === "click" || raw.type === "navigate" || raw.type === "submit") {
|
|
2324
2331
|
const detected = await this.detectCheckpoints(page);
|
|
@@ -2329,6 +2336,27 @@ var SessionRecorder = class _SessionRecorder {
|
|
|
2329
2336
|
}
|
|
2330
2337
|
}
|
|
2331
2338
|
}
|
|
2339
|
+
/**
|
|
2340
|
+
* Capture a screenshot of the target element for key action types.
|
|
2341
|
+
* Returns a base64-encoded PNG string, or undefined if the element has no
|
|
2342
|
+
* selector or the screenshot fails (non-critical — never blocks recording).
|
|
2343
|
+
*
|
|
2344
|
+
* Only captures for: click, input, change, dblclick, and their CDP counterparts.
|
|
2345
|
+
*/
|
|
2346
|
+
async captureElementScreenshot(page, action) {
|
|
2347
|
+
const keyTypes = ["click", "input", "change", "dblclick", "cdp-click", "cdp-fill", "filechooser"];
|
|
2348
|
+
if (!keyTypes.includes(action.type)) return;
|
|
2349
|
+
if (!action.element?.selector) return;
|
|
2350
|
+
try {
|
|
2351
|
+
const buffer = await page.locator(action.element.selector).first().screenshot({
|
|
2352
|
+
type: "png",
|
|
2353
|
+
timeout: 2e3
|
|
2354
|
+
});
|
|
2355
|
+
return buffer.toString("base64");
|
|
2356
|
+
} catch {
|
|
2357
|
+
return;
|
|
2358
|
+
}
|
|
2359
|
+
}
|
|
2332
2360
|
/**
|
|
2333
2361
|
* After a click, wait 300ms then scan for popover/dropdown/menu elements
|
|
2334
2362
|
* near the click position. This runs server-side to avoid race conditions
|
|
@@ -1242,7 +1242,7 @@ var SessionRecorder = class _SessionRecorder {
|
|
|
1242
1242
|
return this.actions.length;
|
|
1243
1243
|
}
|
|
1244
1244
|
/** Record an action triggered by a CDP command (e.g. xbrowser fill/click/goto) */
|
|
1245
|
-
recordCommandAction(action) {
|
|
1245
|
+
async recordCommandAction(action) {
|
|
1246
1246
|
const normalizedType = action.type === "cdp-fill" ? "input" : action.type === "cdp-click" ? "click" : action.type;
|
|
1247
1247
|
const recent = this.actions[this.actions.length - 1];
|
|
1248
1248
|
if (recent && Date.now() - recent.timestamp < 1500) {
|
|
@@ -1256,7 +1256,7 @@ var SessionRecorder = class _SessionRecorder {
|
|
|
1256
1256
|
this.actionCounter++;
|
|
1257
1257
|
const ts = Date.now();
|
|
1258
1258
|
const actionUrl = action.url && action.url !== "about:blank" ? action.url : this.lastKnownUrl || this.page.url();
|
|
1259
|
-
|
|
1259
|
+
const actionToPush = {
|
|
1260
1260
|
id: this.actionCounter,
|
|
1261
1261
|
type: action.type,
|
|
1262
1262
|
timestamp: ts,
|
|
@@ -1264,6 +1264,11 @@ var SessionRecorder = class _SessionRecorder {
|
|
|
1264
1264
|
pageTitle: "",
|
|
1265
1265
|
element: action.element || (action.selector ? { tag: "", selector: action.selector, text: "" } : void 0),
|
|
1266
1266
|
value: action.value
|
|
1267
|
+
};
|
|
1268
|
+
this.actions.push(actionToPush);
|
|
1269
|
+
actionToPush.elementScreenshot = await this.captureElementScreenshot(this.page, {
|
|
1270
|
+
type: action.type,
|
|
1271
|
+
element: actionToPush.element
|
|
1267
1272
|
});
|
|
1268
1273
|
this.lastActionTs = ts;
|
|
1269
1274
|
this.cdpActionDedup = {
|
|
@@ -1922,6 +1927,8 @@ var SessionRecorder = class _SessionRecorder {
|
|
|
1922
1927
|
clickContext,
|
|
1923
1928
|
files: raw.files
|
|
1924
1929
|
});
|
|
1930
|
+
const pushed = this.actions[this.actions.length - 1];
|
|
1931
|
+
pushed.elementScreenshot = await this.captureElementScreenshot(page, raw);
|
|
1925
1932
|
this.lastActionTs = raw.ts;
|
|
1926
1933
|
if (raw.type === "click" || raw.type === "navigate" || raw.type === "submit") {
|
|
1927
1934
|
const detected = await this.detectCheckpoints(page);
|
|
@@ -1932,6 +1939,27 @@ var SessionRecorder = class _SessionRecorder {
|
|
|
1932
1939
|
}
|
|
1933
1940
|
}
|
|
1934
1941
|
}
|
|
1942
|
+
/**
|
|
1943
|
+
* Capture a screenshot of the target element for key action types.
|
|
1944
|
+
* Returns a base64-encoded PNG string, or undefined if the element has no
|
|
1945
|
+
* selector or the screenshot fails (non-critical — never blocks recording).
|
|
1946
|
+
*
|
|
1947
|
+
* Only captures for: click, input, change, dblclick, and their CDP counterparts.
|
|
1948
|
+
*/
|
|
1949
|
+
async captureElementScreenshot(page, action) {
|
|
1950
|
+
const keyTypes = ["click", "input", "change", "dblclick", "cdp-click", "cdp-fill", "filechooser"];
|
|
1951
|
+
if (!keyTypes.includes(action.type)) return;
|
|
1952
|
+
if (!action.element?.selector) return;
|
|
1953
|
+
try {
|
|
1954
|
+
const buffer = await page.locator(action.element.selector).first().screenshot({
|
|
1955
|
+
type: "png",
|
|
1956
|
+
timeout: 2e3
|
|
1957
|
+
});
|
|
1958
|
+
return buffer.toString("base64");
|
|
1959
|
+
} catch {
|
|
1960
|
+
return;
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1935
1963
|
/**
|
|
1936
1964
|
* After a click, wait 300ms then scan for popover/dropdown/menu elements
|
|
1937
1965
|
* near the click position. This runs server-side to avoid race conditions
|
|
@@ -4965,7 +4965,7 @@ async function closeSessionByName(name) {
|
|
|
4965
4965
|
} catch {
|
|
4966
4966
|
}
|
|
4967
4967
|
try {
|
|
4968
|
-
const { SessionRecorder } = await import("./session-recorder-
|
|
4968
|
+
const { SessionRecorder } = await import("./session-recorder-KPU4YQAE.js");
|
|
4969
4969
|
SessionRecorder.cleanup(session.name);
|
|
4970
4970
|
} catch {
|
|
4971
4971
|
}
|
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
SessionRecorder
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-YSCY52UJ.js";
|
|
5
5
|
import {
|
|
6
6
|
addKnownIssue,
|
|
7
7
|
getKnowledgePath,
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
resolveLaunchOpts,
|
|
26
26
|
saveSessionDiskMeta,
|
|
27
27
|
setActivePage
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-Z7WC4P2M.js";
|
|
29
29
|
import "./chunk-TNEN6VQ2.js";
|
|
30
30
|
import {
|
|
31
31
|
forwardCommandLog,
|
|
@@ -182,7 +182,7 @@ function asZodSchema(value) {
|
|
|
182
182
|
// src/executor.ts
|
|
183
183
|
import {
|
|
184
184
|
ok as ok25,
|
|
185
|
-
fail as
|
|
185
|
+
fail as fail9,
|
|
186
186
|
isCommandResult,
|
|
187
187
|
CompositeStorage as CompositeStorage2,
|
|
188
188
|
TipCollector as TipCollector2,
|
|
@@ -2316,7 +2316,7 @@ var scrapeCommand = registerCommand({
|
|
|
2316
2316
|
scope: "project",
|
|
2317
2317
|
selectorParams: ["selector"],
|
|
2318
2318
|
parameters: z15.object({
|
|
2319
|
-
url: z15.string(),
|
|
2319
|
+
url: z15.string().optional(),
|
|
2320
2320
|
selector: z15.string().optional(),
|
|
2321
2321
|
timeout: z15.number().default(3e4),
|
|
2322
2322
|
format: z15.enum(["markdown", "html", "text"]).default("markdown"),
|
|
@@ -2329,10 +2329,14 @@ var scrapeCommand = registerCommand({
|
|
|
2329
2329
|
const { context, page } = await createEphemeralContext(resolveLaunchOpts(ctx));
|
|
2330
2330
|
const maxAttempts = p.retries + 1;
|
|
2331
2331
|
try {
|
|
2332
|
+
const targetUrl = p.url || page.url();
|
|
2333
|
+
if (!targetUrl || targetUrl === "about:blank") {
|
|
2334
|
+
return fail3("URL is required. Provide a URL or connect to a browser (--cdp) with a non-blank page.");
|
|
2335
|
+
}
|
|
2332
2336
|
let lastError;
|
|
2333
2337
|
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
2334
2338
|
try {
|
|
2335
|
-
await page.goto(
|
|
2339
|
+
await page.goto(targetUrl, { waitUntil: "commit", timeout: p.timeout });
|
|
2336
2340
|
await page.waitForSelector("body", { timeout: p.timeout }).catch(() => {
|
|
2337
2341
|
});
|
|
2338
2342
|
await page.waitForLoadState("networkidle", Math.min(p.timeout, 8e3)).catch(() => {
|
|
@@ -2393,7 +2397,7 @@ var scrapeCommand = registerCommand({
|
|
|
2393
2397
|
return { url: location.href, title: document.title, navigation, tables, forms: forms.slice(0, 20), links: links.slice(0, 30), mainText };
|
|
2394
2398
|
});
|
|
2395
2399
|
try {
|
|
2396
|
-
persistFromScrape(
|
|
2400
|
+
persistFromScrape(targetUrl, structured);
|
|
2397
2401
|
} catch {
|
|
2398
2402
|
}
|
|
2399
2403
|
if (p.mode === "smart") {
|
|
@@ -2494,7 +2498,7 @@ var scrapeCommand = registerCommand({
|
|
|
2494
2498
|
|
|
2495
2499
|
// src/commands/map.ts
|
|
2496
2500
|
import { z as z16 } from "zod";
|
|
2497
|
-
import { ok as ok16 } from "@dyyz1993/xcli-core";
|
|
2501
|
+
import { ok as ok16, fail as fail4 } from "@dyyz1993/xcli-core";
|
|
2498
2502
|
|
|
2499
2503
|
// src/utils/url.ts
|
|
2500
2504
|
var SKIP_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
@@ -2730,7 +2734,7 @@ var mapCommand = registerCommand({
|
|
|
2730
2734
|
description: "Discover all URLs on a website via sitemap and page link extraction",
|
|
2731
2735
|
scope: "project",
|
|
2732
2736
|
parameters: z16.object({
|
|
2733
|
-
url: z16.string(),
|
|
2737
|
+
url: z16.string().optional(),
|
|
2734
2738
|
search: z16.string().optional(),
|
|
2735
2739
|
sitemap: z16.enum(["include", "only"]).optional(),
|
|
2736
2740
|
includeSubdomains: z16.boolean().optional(),
|
|
@@ -2741,7 +2745,11 @@ var mapCommand = registerCommand({
|
|
|
2741
2745
|
handler: async (p, ctx) => {
|
|
2742
2746
|
const { context, page } = await createEphemeralContext(resolveLaunchOpts(ctx));
|
|
2743
2747
|
try {
|
|
2744
|
-
const
|
|
2748
|
+
const targetUrl = p.url || page.url();
|
|
2749
|
+
if (!targetUrl || targetUrl === "about:blank") {
|
|
2750
|
+
return fail4("URL is required. Provide a URL or connect to a browser (--cdp) with a non-blank page.");
|
|
2751
|
+
}
|
|
2752
|
+
const links = await discoverUrls(page, targetUrl, {
|
|
2745
2753
|
sitemap: p.sitemap,
|
|
2746
2754
|
includeSubdomains: p.includeSubdomains,
|
|
2747
2755
|
allowExternalLinks: p.allowExternalLinks,
|
|
@@ -3584,7 +3592,7 @@ ${errors.map((e) => ` - ${e.engine}: ${e.error}`).join("\n")}`
|
|
|
3584
3592
|
|
|
3585
3593
|
// src/commands/network.ts
|
|
3586
3594
|
import { z as z19 } from "zod";
|
|
3587
|
-
import { ok as ok19, fail as
|
|
3595
|
+
import { ok as ok19, fail as fail5 } from "@dyyz1993/xcli-core";
|
|
3588
3596
|
function extractPath2(url) {
|
|
3589
3597
|
try {
|
|
3590
3598
|
const u = new URL(url);
|
|
@@ -3749,7 +3757,7 @@ var networkCommand = registerCommand({
|
|
|
3749
3757
|
};
|
|
3750
3758
|
if (p.listen) {
|
|
3751
3759
|
const page2 = ctx.page;
|
|
3752
|
-
if (!page2) return
|
|
3760
|
+
if (!page2) return fail5("No active page. Use --cdp to connect first.");
|
|
3753
3761
|
const captures = [];
|
|
3754
3762
|
const consoleMessages = [];
|
|
3755
3763
|
const wsCaptures = [];
|
|
@@ -4129,7 +4137,7 @@ var ENGINE_KEY_ENUM = z20.enum(ALL_ENGINE_KEYS);
|
|
|
4129
4137
|
|
|
4130
4138
|
// src/commands/snapshot.ts
|
|
4131
4139
|
import { z as z21 } from "zod";
|
|
4132
|
-
import { ok as ok20, fail as
|
|
4140
|
+
import { ok as ok20, fail as fail6, normalizeTips as normalizeTips3 } from "@dyyz1993/xcli-core";
|
|
4133
4141
|
|
|
4134
4142
|
// src/runtime/ref-store.ts
|
|
4135
4143
|
var sessions = /* @__PURE__ */ new Map();
|
|
@@ -5100,7 +5108,7 @@ var snapshotCommand = registerCommand({
|
|
|
5100
5108
|
persistSemantics(url, aria);
|
|
5101
5109
|
return ok20({ url, title, aria, text, dom }, normalizeTips3(tips));
|
|
5102
5110
|
}
|
|
5103
|
-
return
|
|
5111
|
+
return fail6(`Unknown snapshot type: ${p.type}`);
|
|
5104
5112
|
}
|
|
5105
5113
|
});
|
|
5106
5114
|
function persistSemantics(url, aria) {
|
|
@@ -5269,7 +5277,7 @@ var waitForCommand = registerCommand({
|
|
|
5269
5277
|
|
|
5270
5278
|
// src/commands/tab.ts
|
|
5271
5279
|
import { z as z23 } from "zod";
|
|
5272
|
-
import { ok as ok22, fail as
|
|
5280
|
+
import { ok as ok22, fail as fail7 } from "@dyyz1993/xcli-core";
|
|
5273
5281
|
var TabParams = z23.object({
|
|
5274
5282
|
subcommand: z23.enum(["list", "new", "close", "switch"]),
|
|
5275
5283
|
url: z23.string().optional(),
|
|
@@ -5286,7 +5294,7 @@ var tabCommand = registerCommand({
|
|
|
5286
5294
|
}),
|
|
5287
5295
|
handler: async (p, ctx) => {
|
|
5288
5296
|
if (!ctx.browserContext) {
|
|
5289
|
-
return
|
|
5297
|
+
return fail7("No browser context available. Use --cdp to connect to a browser first.");
|
|
5290
5298
|
}
|
|
5291
5299
|
const pages = ctx.browserContext.pages();
|
|
5292
5300
|
switch (p.subcommand) {
|
|
@@ -5299,7 +5307,7 @@ var tabCommand = registerCommand({
|
|
|
5299
5307
|
case "switch":
|
|
5300
5308
|
return handleSwitch(p, pages, ctx);
|
|
5301
5309
|
default:
|
|
5302
|
-
return
|
|
5310
|
+
return fail7(`Unknown subcommand: ${p.subcommand}`);
|
|
5303
5311
|
}
|
|
5304
5312
|
}
|
|
5305
5313
|
});
|
|
@@ -5356,11 +5364,11 @@ async function handleNew(p, _pages, ctx) {
|
|
|
5356
5364
|
}
|
|
5357
5365
|
async function handleClose(p, pages, ctx) {
|
|
5358
5366
|
if (pages.length <= 1) {
|
|
5359
|
-
return
|
|
5367
|
+
return fail7("Cannot close the last remaining tab");
|
|
5360
5368
|
}
|
|
5361
5369
|
const closeIndex = p.index ?? pages.indexOf(ctx.page);
|
|
5362
5370
|
if (closeIndex < 0 || closeIndex >= pages.length) {
|
|
5363
|
-
return
|
|
5371
|
+
return fail7(`Invalid tab index: ${closeIndex}. Valid range: 0-${pages.length - 1}`);
|
|
5364
5372
|
}
|
|
5365
5373
|
const pageToClose = pages[closeIndex];
|
|
5366
5374
|
const isActivePage = pageToClose === ctx.page;
|
|
@@ -5383,10 +5391,10 @@ async function handleClose(p, pages, ctx) {
|
|
|
5383
5391
|
}
|
|
5384
5392
|
async function handleSwitch(p, pages, ctx) {
|
|
5385
5393
|
if (p.index === void 0) {
|
|
5386
|
-
return
|
|
5394
|
+
return fail7("Parameter --index is required for switch subcommand");
|
|
5387
5395
|
}
|
|
5388
5396
|
if (p.index < 0 || p.index >= pages.length) {
|
|
5389
|
-
return
|
|
5397
|
+
return fail7(`Invalid tab index: ${p.index}. Valid range: 0-${pages.length - 1}`);
|
|
5390
5398
|
}
|
|
5391
5399
|
const targetPage = pages[p.index];
|
|
5392
5400
|
await targetPage.bringToFront().catch(() => {
|
|
@@ -5638,7 +5646,7 @@ registerCommandDefinition("addinitscript", ["script"]);
|
|
|
5638
5646
|
|
|
5639
5647
|
// src/commands/find.ts
|
|
5640
5648
|
import { z as z25 } from "zod";
|
|
5641
|
-
import { ok as ok24, fail as
|
|
5649
|
+
import { ok as ok24, fail as fail8, normalizeTips as normalizeTips5 } from "@dyyz1993/xcli-core";
|
|
5642
5650
|
var actionSchema2 = z25.enum(["click", "fill", "type", "select", "hover", "check"]);
|
|
5643
5651
|
var findCommand = registerCommand({
|
|
5644
5652
|
name: "find",
|
|
@@ -5679,7 +5687,7 @@ var findCommand = registerCommand({
|
|
|
5679
5687
|
});
|
|
5680
5688
|
const count = await locator.count();
|
|
5681
5689
|
if (count === 0) {
|
|
5682
|
-
return
|
|
5690
|
+
return fail8(`No element found with ${p.strategy}="${p.value}"`);
|
|
5683
5691
|
}
|
|
5684
5692
|
const tips = [];
|
|
5685
5693
|
const target = selectTarget(locator, p.strategy);
|
|
@@ -5691,15 +5699,15 @@ var findCommand = registerCommand({
|
|
|
5691
5699
|
await target.click({ timeout: p.timeout, force: true });
|
|
5692
5700
|
return okWithTips({ matched: count, selector, action: "click" }, tips);
|
|
5693
5701
|
} else if (actionName === "fill") {
|
|
5694
|
-
if (actionValue === void 0) return
|
|
5702
|
+
if (actionValue === void 0) return fail8("find fill requires a value");
|
|
5695
5703
|
await target.fill(actionValue, { timeout: p.timeout, force: true });
|
|
5696
5704
|
return okWithTips({ matched: count, selector, action: `fill("${actionValue}")` }, tips);
|
|
5697
5705
|
} else if (actionName === "type") {
|
|
5698
|
-
if (actionValue === void 0) return
|
|
5706
|
+
if (actionValue === void 0) return fail8("find type requires a value");
|
|
5699
5707
|
await target.type(actionValue, { delay: 10, timeout: p.timeout });
|
|
5700
5708
|
return okWithTips({ matched: count, selector, action: `type("${actionValue}")` }, tips);
|
|
5701
5709
|
} else if (actionName === "select") {
|
|
5702
|
-
if (actionValue === void 0) return
|
|
5710
|
+
if (actionValue === void 0) return fail8("find select requires a value");
|
|
5703
5711
|
await target.selectOption(actionValue);
|
|
5704
5712
|
return okWithTips({ matched: count, selector, action: `select("${actionValue}")` }, tips);
|
|
5705
5713
|
} else if (actionName === "hover") {
|
|
@@ -7135,7 +7143,7 @@ async function guardCheck(commandName) {
|
|
|
7135
7143
|
}
|
|
7136
7144
|
}
|
|
7137
7145
|
function errorResult(message) {
|
|
7138
|
-
return { ...
|
|
7146
|
+
return { ...fail9(message), duration: 0 };
|
|
7139
7147
|
}
|
|
7140
7148
|
function tipsToMessages(tips) {
|
|
7141
7149
|
if (!tips || tips.length === 0) return [];
|
|
@@ -7212,7 +7220,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7212
7220
|
}
|
|
7213
7221
|
let targetPageOverride = null;
|
|
7214
7222
|
if (_target && extraOpts?.cdpEndpoint) {
|
|
7215
|
-
const { findTargetPage } = await import("./browser-
|
|
7223
|
+
const { findTargetPage } = await import("./browser-4KRHALJ3.js");
|
|
7216
7224
|
targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
|
|
7217
7225
|
if (!targetPageOverride) {
|
|
7218
7226
|
return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
|
|
@@ -7436,7 +7444,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7436
7444
|
duration,
|
|
7437
7445
|
timestamp: start
|
|
7438
7446
|
});
|
|
7439
|
-
return { ...
|
|
7447
|
+
return { ...fail9(errorMessage), duration };
|
|
7440
7448
|
} finally {
|
|
7441
7449
|
}
|
|
7442
7450
|
}
|
|
@@ -7477,7 +7485,7 @@ async function executeChain(input, options) {
|
|
|
7477
7485
|
results.push({
|
|
7478
7486
|
command: cmdName,
|
|
7479
7487
|
raw: cmdStr,
|
|
7480
|
-
...
|
|
7488
|
+
...fail9(`Plugin "${cmdName}" requires a sub-command`),
|
|
7481
7489
|
duration: 0
|
|
7482
7490
|
});
|
|
7483
7491
|
if (type === "and") {
|
|
@@ -7496,7 +7504,7 @@ async function executeChain(input, options) {
|
|
|
7496
7504
|
results.push({
|
|
7497
7505
|
command: cmdName,
|
|
7498
7506
|
raw: cmdStr,
|
|
7499
|
-
...
|
|
7507
|
+
...fail9(`Unknown command "${subCommand}" for plugin "${cmdName}"`),
|
|
7500
7508
|
duration: 0
|
|
7501
7509
|
});
|
|
7502
7510
|
if (type === "and") {
|
|
@@ -7628,7 +7636,7 @@ async function executeChain(input, options) {
|
|
|
7628
7636
|
results.push({
|
|
7629
7637
|
command: `${cmdName} ${subCommand}`,
|
|
7630
7638
|
raw: cmdStr,
|
|
7631
|
-
...
|
|
7639
|
+
...fail9(errorMessage),
|
|
7632
7640
|
duration: duration2
|
|
7633
7641
|
});
|
|
7634
7642
|
if (type === "and") {
|
|
@@ -11226,7 +11234,7 @@ async function handleFilter(args, _mode, options) {
|
|
|
11226
11234
|
console.log(` Original: ${result.originalCount}, After: ${result.filteredCount}, Removed: ${result.removed} (${result.percentage}%)`);
|
|
11227
11235
|
}
|
|
11228
11236
|
async function handleGeneratePlugin(sessionName, pluginName, outputDir) {
|
|
11229
|
-
const { SessionRecorder: SessionRecorder2 } = await import("./session-recorder-
|
|
11237
|
+
const { SessionRecorder: SessionRecorder2 } = await import("./session-recorder-KPU4YQAE.js");
|
|
11230
11238
|
const { readSiteKnowledge: readSiteKnowledge2, toMarkdown } = await import("./site-knowledge-SYC6VCDB.js");
|
|
11231
11239
|
const { mkdirSync: mkdirSync10, writeFileSync: writeFileSync12 } = await import("fs");
|
|
11232
11240
|
const { join: join14 } = await import("path");
|
|
@@ -13188,7 +13196,7 @@ Run "xbrowser ${command} ${subCommand} --help" to see available parameters.`
|
|
|
13188
13196
|
const targetPage = pages[cmdTabIndex];
|
|
13189
13197
|
await targetPage.bringToFront().catch(() => {
|
|
13190
13198
|
});
|
|
13191
|
-
const { setActivePage: setActivePage2 } = await import("./browser-
|
|
13199
|
+
const { setActivePage: setActivePage2 } = await import("./browser-4KRHALJ3.js");
|
|
13192
13200
|
setActivePage2(session, targetPage);
|
|
13193
13201
|
}
|
|
13194
13202
|
}
|
|
@@ -13461,7 +13469,7 @@ async function main() {
|
|
|
13461
13469
|
const command = process.argv[2];
|
|
13462
13470
|
const isLongRunning = command === "preview" || command === "serve";
|
|
13463
13471
|
if (!isLongRunning) {
|
|
13464
|
-
const { ensureProcessCanExit } = await import("./browser-
|
|
13472
|
+
const { ensureProcessCanExit } = await import("./browser-4KRHALJ3.js");
|
|
13465
13473
|
await ensureProcessCanExit().catch(() => {
|
|
13466
13474
|
});
|
|
13467
13475
|
process.exit(exitCode);
|