@xbrowser/cli 1.0.2 → 1.0.4
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-GITRHHFO.js → browser-5CTOA2WS.js} +3 -3
- package/dist/{browser-R56O3CW6.js → browser-ITLZZDHJ.js} +4 -2
- package/dist/{browser-ZJOZB5CR.js → browser-IUJXXNBT.js} +5 -4
- package/dist/{cdp-driver-BE3FOMRN.js → cdp-driver-4X3DK6PS.js} +19 -5
- package/dist/{cdp-driver-TOPYJIFL.js → cdp-driver-D6WMSMWX.js} +3 -2
- package/dist/{chunk-Q4IGYTKR.js → chunk-6WOSXSCQ.js} +6 -2
- package/dist/{chunk-ZZ2TFWIV.js → chunk-ABXMBNQ6.js} +1 -1
- package/dist/{chunk-JPHCY4TC.js → chunk-AMI64BSD.js} +9 -1
- package/dist/{chunk-CAFNSGYM.js → chunk-DKWR54XQ.js} +24 -8
- package/dist/chunk-GDKLH7ZY.js +8 -0
- package/dist/{chunk-QIK2I3VQ.js → chunk-LRBSUKUZ.js} +7 -4
- package/dist/{chunk-PPG4D2EW.js → chunk-N2JFPWMI.js} +21 -5
- package/dist/{chunk-BBMRDUYQ.js → chunk-TNEN6VQ2.js} +4 -1
- package/dist/{chunk-JPA2ZT2R.js → chunk-TWWOIJM7.js} +7 -4
- package/dist/cli.js +185 -107
- package/dist/{daemon-client-UZZEHHIV.js → daemon-client-3JOKX2L2.js} +2 -1
- package/dist/{daemon-client-DRCUMNHK.js → daemon-client-DIEHGP5B.js} +5 -2
- package/dist/daemon-main.js +154 -89
- package/dist/index.d.ts +1 -1
- package/dist/index.js +193 -116
- package/dist/{launcher-QUJ4M2VS.js → launcher-L2JNDB2H.js} +2 -1
- package/dist/{launcher-YARP45UY.js → launcher-OZXJQPNG.js} +1 -1
- package/dist/{proxy-LV4BJ5RC.js → proxy-C6CK3UH5.js} +1 -1
- package/dist/{session-replayer-GLTUICSD.js → session-replayer-MY27H4DX.js} +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
killAllDaemonProcesses,
|
|
26
26
|
startDaemonProcess,
|
|
27
27
|
stopDaemonProcess
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-6WOSXSCQ.js";
|
|
29
29
|
import {
|
|
30
30
|
CaptchaDetector,
|
|
31
31
|
HumanInteractionManager,
|
|
@@ -81,9 +81,12 @@ import {
|
|
|
81
81
|
resolveLaunchOpts,
|
|
82
82
|
saveSessionDiskMeta,
|
|
83
83
|
setActivePage
|
|
84
|
-
} from "./chunk-
|
|
85
|
-
import "./chunk-
|
|
86
|
-
import "./chunk-
|
|
84
|
+
} from "./chunk-TWWOIJM7.js";
|
|
85
|
+
import "./chunk-N2JFPWMI.js";
|
|
86
|
+
import "./chunk-TNEN6VQ2.js";
|
|
87
|
+
import {
|
|
88
|
+
errMsg
|
|
89
|
+
} from "./chunk-GDKLH7ZY.js";
|
|
87
90
|
import {
|
|
88
91
|
CDPInterceptorProxy,
|
|
89
92
|
advise,
|
|
@@ -97,7 +100,7 @@ import {
|
|
|
97
100
|
mouseTrajectoryRule,
|
|
98
101
|
networkAnomalyRule,
|
|
99
102
|
pageLifecycleRule
|
|
100
|
-
} from "./chunk-
|
|
103
|
+
} from "./chunk-ABXMBNQ6.js";
|
|
101
104
|
import {
|
|
102
105
|
__require
|
|
103
106
|
} from "./chunk-KFQGP6VL.js";
|
|
@@ -113,8 +116,8 @@ import {
|
|
|
113
116
|
ok as ok25,
|
|
114
117
|
fail as fail7,
|
|
115
118
|
isCommandResult,
|
|
116
|
-
CompositeStorage,
|
|
117
|
-
TipCollector,
|
|
119
|
+
CompositeStorage as CompositeStorage2,
|
|
120
|
+
TipCollector as TipCollector2,
|
|
118
121
|
normalizeTips as normalizeTips6,
|
|
119
122
|
configureArchiveStore,
|
|
120
123
|
appendCommandToArchive,
|
|
@@ -232,6 +235,69 @@ function parsePluginParams(args, schema, base = {}) {
|
|
|
232
235
|
return result;
|
|
233
236
|
}
|
|
234
237
|
|
|
238
|
+
// src/utils/stub-context.ts
|
|
239
|
+
import { join } from "path";
|
|
240
|
+
import { homedir } from "os";
|
|
241
|
+
import { TipCollector, CompositeStorage } from "@dyyz1993/xcli-core";
|
|
242
|
+
var CONFIG_DIR = join(homedir(), ".xbrowser");
|
|
243
|
+
var NoopSiteInstance = class {
|
|
244
|
+
name = "stub";
|
|
245
|
+
url = "";
|
|
246
|
+
config = { name: "stub" };
|
|
247
|
+
command() {
|
|
248
|
+
return this;
|
|
249
|
+
}
|
|
250
|
+
group() {
|
|
251
|
+
return this;
|
|
252
|
+
}
|
|
253
|
+
login() {
|
|
254
|
+
return this;
|
|
255
|
+
}
|
|
256
|
+
logout() {
|
|
257
|
+
return this;
|
|
258
|
+
}
|
|
259
|
+
async isLoggedIn() {
|
|
260
|
+
return true;
|
|
261
|
+
}
|
|
262
|
+
async requireLogin() {
|
|
263
|
+
}
|
|
264
|
+
getStorage() {
|
|
265
|
+
return new CompositeStorage("stub", CONFIG_DIR, "xbrowser");
|
|
266
|
+
}
|
|
267
|
+
getAllCommands() {
|
|
268
|
+
return [];
|
|
269
|
+
}
|
|
270
|
+
getCommand() {
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
getOriginalHandler() {
|
|
274
|
+
return void 0;
|
|
275
|
+
}
|
|
276
|
+
async executeLogin() {
|
|
277
|
+
}
|
|
278
|
+
async executeLogout() {
|
|
279
|
+
}
|
|
280
|
+
async restoreLogin() {
|
|
281
|
+
return false;
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
function createStubContext(pluginName) {
|
|
285
|
+
return {
|
|
286
|
+
args: [],
|
|
287
|
+
options: {},
|
|
288
|
+
cwd: process.cwd(),
|
|
289
|
+
storage: new CompositeStorage(pluginName, CONFIG_DIR, "xbrowser"),
|
|
290
|
+
output: { mode: "text", showTips: false, color: false, emoji: false },
|
|
291
|
+
error: (msg) => {
|
|
292
|
+
throw new Error(msg);
|
|
293
|
+
},
|
|
294
|
+
config: {},
|
|
295
|
+
site: new NoopSiteInstance(),
|
|
296
|
+
cliName: "xbrowser",
|
|
297
|
+
tips: new TipCollector()
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
|
|
235
301
|
// src/commands/navigation.ts
|
|
236
302
|
import { z } from "zod";
|
|
237
303
|
import { ok } from "@dyyz1993/xcli-core";
|
|
@@ -282,7 +348,7 @@ async function detectSsr(page) {
|
|
|
282
348
|
try {
|
|
283
349
|
const result = await page.evaluate((vars) => {
|
|
284
350
|
for (const varName of vars) {
|
|
285
|
-
const value = window
|
|
351
|
+
const value = Reflect.get(window, varName);
|
|
286
352
|
if (value != null && typeof value === "object") {
|
|
287
353
|
const keys = Object.keys(value).slice(0, 10);
|
|
288
354
|
return { variable: varName, keys };
|
|
@@ -998,9 +1064,9 @@ var clearLocalStorageCommand = registerCommand({
|
|
|
998
1064
|
import { z as z9 } from "zod";
|
|
999
1065
|
import { ok as ok9 } from "@dyyz1993/xcli-core";
|
|
1000
1066
|
import { writeFileSync, mkdirSync } from "fs";
|
|
1001
|
-
import { join } from "path";
|
|
1002
|
-
import { homedir } from "os";
|
|
1003
|
-
var SCREENSHOTS_DIR =
|
|
1067
|
+
import { join as join2 } from "path";
|
|
1068
|
+
import { homedir as homedir2 } from "os";
|
|
1069
|
+
var SCREENSHOTS_DIR = join2(homedir2(), ".xbrowser", "screenshots");
|
|
1004
1070
|
function ensureScreenshotsDir() {
|
|
1005
1071
|
mkdirSync(SCREENSHOTS_DIR, { recursive: true });
|
|
1006
1072
|
}
|
|
@@ -1008,7 +1074,7 @@ function generateScreenshotPath(format) {
|
|
|
1008
1074
|
const timestamp = Date.now();
|
|
1009
1075
|
const random = Math.random().toString(36).slice(2, 8);
|
|
1010
1076
|
const ext = format === "jpeg" ? "jpg" : "png";
|
|
1011
|
-
return
|
|
1077
|
+
return join2(SCREENSHOTS_DIR, `screenshot-${timestamp}-${random}.${ext}`);
|
|
1012
1078
|
}
|
|
1013
1079
|
var screenshotCommand = registerCommand({
|
|
1014
1080
|
name: "screenshot",
|
|
@@ -1631,7 +1697,7 @@ var healthCheckCommand = registerCommand({
|
|
|
1631
1697
|
issues.push({
|
|
1632
1698
|
severity: "error",
|
|
1633
1699
|
category: "links",
|
|
1634
|
-
message: `Broken link (fetch error): ${href} \u2014 ${err
|
|
1700
|
+
message: `Broken link (fetch error): ${href} \u2014 ${errMsg(err) || "unknown"}`
|
|
1635
1701
|
});
|
|
1636
1702
|
}
|
|
1637
1703
|
}
|
|
@@ -1665,9 +1731,9 @@ var healthCheckCommand = registerCommand({
|
|
|
1665
1731
|
import { z as z14 } from "zod";
|
|
1666
1732
|
import { ok as ok14 } from "@dyyz1993/xcli-core";
|
|
1667
1733
|
import { writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
|
|
1668
|
-
import { join as
|
|
1669
|
-
import { homedir as
|
|
1670
|
-
var SCREENSHOTS_DIR2 =
|
|
1734
|
+
import { join as join3 } from "path";
|
|
1735
|
+
import { homedir as homedir3 } from "os";
|
|
1736
|
+
var SCREENSHOTS_DIR2 = join3(homedir3(), ".xbrowser", "screenshots");
|
|
1671
1737
|
function ensureScreenshotsDir2() {
|
|
1672
1738
|
mkdirSync2(SCREENSHOTS_DIR2, { recursive: true });
|
|
1673
1739
|
}
|
|
@@ -1675,7 +1741,7 @@ function generateScreenshotPath2(format) {
|
|
|
1675
1741
|
const timestamp = Date.now();
|
|
1676
1742
|
const random = Math.random().toString(36).slice(2, 8);
|
|
1677
1743
|
const ext = format === "jpeg" ? "jpg" : "png";
|
|
1678
|
-
return
|
|
1744
|
+
return join3(SCREENSHOTS_DIR2, `screenshot-${timestamp}-${random}.${ext}`);
|
|
1679
1745
|
}
|
|
1680
1746
|
var waitActionSchema = z14.object({
|
|
1681
1747
|
type: z14.literal("wait"),
|
|
@@ -4454,8 +4520,8 @@ async function resolveRefParams(page, params, selectorKeys, cache, sessionId) {
|
|
|
4454
4520
|
|
|
4455
4521
|
// src/utils/site-semantics.ts
|
|
4456
4522
|
import { writeFileSync as writeFileSync3, mkdirSync as mkdirSync3, existsSync, readFileSync } from "fs";
|
|
4457
|
-
import { join as
|
|
4458
|
-
import { homedir as
|
|
4523
|
+
import { join as join4, dirname } from "path";
|
|
4524
|
+
import { homedir as homedir4 } from "os";
|
|
4459
4525
|
import { stringify, parse } from "yaml";
|
|
4460
4526
|
import { execFile } from "child_process";
|
|
4461
4527
|
var INTERACTIVE_ROLES = /* @__PURE__ */ new Set([
|
|
@@ -4532,10 +4598,10 @@ function inferAction(role, label) {
|
|
|
4532
4598
|
return {};
|
|
4533
4599
|
}
|
|
4534
4600
|
function getSemanticsDir() {
|
|
4535
|
-
return
|
|
4601
|
+
return join4(homedir4(), ".xbrowser", "site-semantics");
|
|
4536
4602
|
}
|
|
4537
4603
|
function getSemanticsPath(domain) {
|
|
4538
|
-
return
|
|
4604
|
+
return join4(getSemanticsDir(), `${domain}.yaml`);
|
|
4539
4605
|
}
|
|
4540
4606
|
function extractDomain2(url) {
|
|
4541
4607
|
try {
|
|
@@ -5007,7 +5073,7 @@ async function actOnPage(page, sessionId, input) {
|
|
|
5007
5073
|
ref: normalizedRef,
|
|
5008
5074
|
success: false,
|
|
5009
5075
|
reason: "browser_error",
|
|
5010
|
-
message: error
|
|
5076
|
+
message: errMsg(error),
|
|
5011
5077
|
stale,
|
|
5012
5078
|
screenHash: hash,
|
|
5013
5079
|
target: refMatch?.target
|
|
@@ -5091,7 +5157,7 @@ async function waitForPage(page, input) {
|
|
|
5091
5157
|
matched: input.selector ? "selector" : input.text ? "text" : input.url ? "url" : input.load ? "load" : input.fn ? "fn" : "screenHashChanged",
|
|
5092
5158
|
timeout,
|
|
5093
5159
|
elapsed: Date.now() - startedAt,
|
|
5094
|
-
message: error
|
|
5160
|
+
message: errMsg(error)
|
|
5095
5161
|
};
|
|
5096
5162
|
}
|
|
5097
5163
|
return {
|
|
@@ -6026,11 +6092,11 @@ async function detectWebdriverExposure(page) {
|
|
|
6026
6092
|
try {
|
|
6027
6093
|
const webdriver = await page.evaluate(() => {
|
|
6028
6094
|
return {
|
|
6029
|
-
webdriver:
|
|
6095
|
+
webdriver: navigator.webdriver,
|
|
6030
6096
|
webdriverScriptFn: !!window.__webdriver_script_fn,
|
|
6031
6097
|
webdriverEvaluate: !!window.__webdriver_evaluate,
|
|
6032
6098
|
chrome: !!window.chrome,
|
|
6033
|
-
permissions:
|
|
6099
|
+
permissions: navigator.permissions
|
|
6034
6100
|
};
|
|
6035
6101
|
}).catch(() => null);
|
|
6036
6102
|
if (!webdriver) {
|
|
@@ -6116,7 +6182,7 @@ import {
|
|
|
6116
6182
|
} from "@dyyz1993/xcli-core";
|
|
6117
6183
|
import { resolve as resolve2 } from "path";
|
|
6118
6184
|
import { existsSync as existsSync4, readdirSync } from "fs";
|
|
6119
|
-
import { homedir as
|
|
6185
|
+
import { homedir as homedir5 } from "os";
|
|
6120
6186
|
|
|
6121
6187
|
// src/plugin/metadata-parser.ts
|
|
6122
6188
|
import { existsSync as existsSync2 } from "fs";
|
|
@@ -6203,17 +6269,17 @@ var PluginMetadataParser = class {
|
|
|
6203
6269
|
|
|
6204
6270
|
// src/plugin/ensure-deps.ts
|
|
6205
6271
|
import { existsSync as existsSync3, mkdirSync as mkdirSync4, writeFileSync as writeFileSync5 } from "fs";
|
|
6206
|
-
import { join as
|
|
6272
|
+
import { join as join5 } from "path";
|
|
6207
6273
|
import { execSync } from "child_process";
|
|
6208
6274
|
var SHARED_PLUGIN_DEPENDENCIES = {
|
|
6209
6275
|
"zod": "^3.24.0",
|
|
6210
6276
|
"@dyyz1993/xcli-core": "^0.12.1"
|
|
6211
6277
|
};
|
|
6212
6278
|
function ensurePluginDependencies(pluginsDir) {
|
|
6213
|
-
const zodPath =
|
|
6279
|
+
const zodPath = join5(pluginsDir, "node_modules", "zod");
|
|
6214
6280
|
if (existsSync3(zodPath)) return;
|
|
6215
6281
|
mkdirSync4(pluginsDir, { recursive: true });
|
|
6216
|
-
const pkgPath =
|
|
6282
|
+
const pkgPath = join5(pluginsDir, "package.json");
|
|
6217
6283
|
let pkg2 = {};
|
|
6218
6284
|
if (existsSync3(pkgPath)) {
|
|
6219
6285
|
try {
|
|
@@ -6229,7 +6295,7 @@ function ensurePluginDependencies(pluginsDir) {
|
|
|
6229
6295
|
needsInstall = true;
|
|
6230
6296
|
}
|
|
6231
6297
|
}
|
|
6232
|
-
if (!needsInstall && existsSync3(
|
|
6298
|
+
if (!needsInstall && existsSync3(join5(pluginsDir, "node_modules"))) return;
|
|
6233
6299
|
pkg2.dependencies = existingDeps;
|
|
6234
6300
|
pkg2.private = true;
|
|
6235
6301
|
pkg2.description = pkg2.description || "xbrowser plugins \u2014 shared dependencies";
|
|
@@ -6390,19 +6456,26 @@ var patched = false;
|
|
|
6390
6456
|
function patchLoginRequired() {
|
|
6391
6457
|
if (patched) return;
|
|
6392
6458
|
patched = true;
|
|
6393
|
-
const
|
|
6394
|
-
const
|
|
6395
|
-
|
|
6396
|
-
const result =
|
|
6459
|
+
const target = SiteInstanceImpl.prototype;
|
|
6460
|
+
const originalCommand = target.command;
|
|
6461
|
+
const wrapped = function(...args) {
|
|
6462
|
+
const result = originalCommand.apply(this, args);
|
|
6463
|
+
const [name, cmd] = args;
|
|
6397
6464
|
const loginRequired = cmd.loginRequired;
|
|
6398
6465
|
if (loginRequired) {
|
|
6399
|
-
const
|
|
6466
|
+
const commands = this.commands;
|
|
6467
|
+
const entry = commands?.get(name);
|
|
6400
6468
|
if (entry) {
|
|
6401
6469
|
entry.loginRequired = loginRequired;
|
|
6402
6470
|
}
|
|
6403
6471
|
}
|
|
6404
6472
|
return result;
|
|
6405
6473
|
};
|
|
6474
|
+
Object.defineProperty(target, "command", {
|
|
6475
|
+
value: wrapped,
|
|
6476
|
+
writable: true,
|
|
6477
|
+
configurable: true
|
|
6478
|
+
});
|
|
6406
6479
|
}
|
|
6407
6480
|
|
|
6408
6481
|
// src/plugin/loader.ts
|
|
@@ -6469,12 +6542,12 @@ var XBrowserPluginLoader = class {
|
|
|
6469
6542
|
}
|
|
6470
6543
|
async scanAndLoad() {
|
|
6471
6544
|
const cwd = this.options.cwd || process.cwd();
|
|
6472
|
-
const globalDir = this.options.globalDir || resolve2(
|
|
6545
|
+
const globalDir = this.options.globalDir || resolve2(homedir5(), ".xbrowser/plugins");
|
|
6473
6546
|
ensurePluginDependencies(globalDir);
|
|
6474
6547
|
const dirs = [
|
|
6475
6548
|
resolve2(cwd, ".xcli/plugins"),
|
|
6476
6549
|
resolve2(cwd, "../.xcli/plugins"),
|
|
6477
|
-
this.options.userDir || resolve2(
|
|
6550
|
+
this.options.userDir || resolve2(homedir5(), ".xcli/plugins"),
|
|
6478
6551
|
globalDir
|
|
6479
6552
|
];
|
|
6480
6553
|
const loaded = [];
|
|
@@ -7096,15 +7169,14 @@ var HOOK_REGISTRY = {
|
|
|
7096
7169
|
recorder: {
|
|
7097
7170
|
name: "recorder",
|
|
7098
7171
|
onAfterCommand: async (ctx) => {
|
|
7099
|
-
const
|
|
7100
|
-
const logs = ctxAny.__commandLogs || [];
|
|
7172
|
+
const logs = ("__commandLogs" in ctx ? ctx.__commandLogs : void 0) || [];
|
|
7101
7173
|
logs.push({
|
|
7102
7174
|
timestamp: Date.now(),
|
|
7103
7175
|
command: ctx.command,
|
|
7104
7176
|
params: JSON.parse(JSON.stringify(ctx.params)),
|
|
7105
7177
|
duration: ctx.duration
|
|
7106
7178
|
});
|
|
7107
|
-
|
|
7179
|
+
Reflect.set(ctx, "__commandLogs", logs);
|
|
7108
7180
|
return void 0;
|
|
7109
7181
|
}
|
|
7110
7182
|
}
|
|
@@ -7132,15 +7204,15 @@ async function loadHooks() {
|
|
|
7132
7204
|
}
|
|
7133
7205
|
|
|
7134
7206
|
// src/executor.ts
|
|
7135
|
-
import { homedir as
|
|
7136
|
-
import { join as
|
|
7207
|
+
import { homedir as homedir6 } from "os";
|
|
7208
|
+
import { join as join6 } from "path";
|
|
7137
7209
|
var NAVIGATION_COMMANDS = /* @__PURE__ */ new Set(["goto", "back", "forward", "refresh"]);
|
|
7138
7210
|
var snapshotHintShown = /* @__PURE__ */ new WeakSet();
|
|
7139
|
-
var
|
|
7211
|
+
var CONFIG_DIR2 = join6(homedir6(), ".xbrowser");
|
|
7140
7212
|
var storageCache = /* @__PURE__ */ new Map();
|
|
7141
7213
|
function getPluginStorage(pluginName) {
|
|
7142
7214
|
if (!storageCache.has(pluginName)) {
|
|
7143
|
-
storageCache.set(pluginName, new
|
|
7215
|
+
storageCache.set(pluginName, new CompositeStorage2(pluginName, CONFIG_DIR2, "xbrowser"));
|
|
7144
7216
|
}
|
|
7145
7217
|
return storageCache.get(pluginName);
|
|
7146
7218
|
}
|
|
@@ -7148,7 +7220,7 @@ var archiveInitialized = false;
|
|
|
7148
7220
|
function ensureArchiveInit() {
|
|
7149
7221
|
if (!archiveInitialized) {
|
|
7150
7222
|
try {
|
|
7151
|
-
configureArchiveStore({ archiveDir:
|
|
7223
|
+
configureArchiveStore({ archiveDir: join6(homedir6(), ".xbrowser", "archives") });
|
|
7152
7224
|
} catch {
|
|
7153
7225
|
}
|
|
7154
7226
|
archiveInitialized = true;
|
|
@@ -7208,7 +7280,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7208
7280
|
}
|
|
7209
7281
|
let targetPageOverride = null;
|
|
7210
7282
|
if (_target && extraOpts?.cdpEndpoint) {
|
|
7211
|
-
const { findTargetPage } = await import("./browser-
|
|
7283
|
+
const { findTargetPage } = await import("./browser-IUJXXNBT.js");
|
|
7212
7284
|
targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
|
|
7213
7285
|
if (!targetPageOverride) {
|
|
7214
7286
|
return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
|
|
@@ -7225,7 +7297,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7225
7297
|
params = result.data;
|
|
7226
7298
|
}
|
|
7227
7299
|
if (command.scope !== "cli" && !process.env.XBROWSER_DAEMON_WORKER) {
|
|
7228
|
-
const { forwardExec } = await import("./daemon-client-
|
|
7300
|
+
const { forwardExec } = await import("./daemon-client-3JOKX2L2.js");
|
|
7229
7301
|
const result = await forwardExec(commandName, params, sessionName, extraOpts?.cdpEndpoint);
|
|
7230
7302
|
if (result) return result;
|
|
7231
7303
|
}
|
|
@@ -7276,9 +7348,9 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7276
7348
|
throw new Error(msg);
|
|
7277
7349
|
},
|
|
7278
7350
|
config: {},
|
|
7279
|
-
site:
|
|
7351
|
+
site: new NoopSiteInstance(),
|
|
7280
7352
|
cliName: "xbrowser",
|
|
7281
|
-
tips: new
|
|
7353
|
+
tips: new TipCollector2()
|
|
7282
7354
|
};
|
|
7283
7355
|
const start = Date.now();
|
|
7284
7356
|
if (session) {
|
|
@@ -7391,7 +7463,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7391
7463
|
} catch (err) {
|
|
7392
7464
|
const end = Date.now();
|
|
7393
7465
|
const duration = end - start;
|
|
7394
|
-
const errorMessage = err
|
|
7466
|
+
const errorMessage = errMsg(err);
|
|
7395
7467
|
if (session) {
|
|
7396
7468
|
streamCommandEvent(session.id, {
|
|
7397
7469
|
sessionId: session.id,
|
|
@@ -7504,7 +7576,7 @@ async function executeChain(input, options) {
|
|
|
7504
7576
|
config: {},
|
|
7505
7577
|
site,
|
|
7506
7578
|
cliName: "xbrowser",
|
|
7507
|
-
tips: new
|
|
7579
|
+
tips: new TipCollector2()
|
|
7508
7580
|
};
|
|
7509
7581
|
const start2 = Date.now();
|
|
7510
7582
|
try {
|
|
@@ -7591,7 +7663,7 @@ async function executeChain(input, options) {
|
|
|
7591
7663
|
}
|
|
7592
7664
|
} catch (err) {
|
|
7593
7665
|
const duration2 = Date.now() - start2;
|
|
7594
|
-
const errorMessage = err
|
|
7666
|
+
const errorMessage = errMsg(err);
|
|
7595
7667
|
recordArchive(session.id, sessionName, {
|
|
7596
7668
|
step: results.length,
|
|
7597
7669
|
command: `${cmdName} ${subCommand}`,
|
|
@@ -7731,7 +7803,12 @@ var BROWSER_SCOPE = {
|
|
|
7731
7803
|
};
|
|
7732
7804
|
|
|
7733
7805
|
// src/router.ts
|
|
7734
|
-
import { parseArgs, outputFormatter as outputFormatter2, isCommandResult as isCommandResult2, helpGenerator as helpGenerator2, TipCollector as
|
|
7806
|
+
import { parseArgs, outputFormatter as outputFormatter2, isCommandResult as isCommandResult2, helpGenerator as helpGenerator2, TipCollector as TipCollector3, normalizeTips as normalizeTips7, tip as makeTip } from "@dyyz1993/xcli-core";
|
|
7807
|
+
|
|
7808
|
+
// src/utils/zod-internal.ts
|
|
7809
|
+
function asZodSchema(value) {
|
|
7810
|
+
return value;
|
|
7811
|
+
}
|
|
7735
7812
|
|
|
7736
7813
|
// src/session/session-client.ts
|
|
7737
7814
|
function sessionToInfo(s) {
|
|
@@ -7924,7 +8001,7 @@ import {
|
|
|
7924
8001
|
rmSync as rmSync6
|
|
7925
8002
|
} from "fs";
|
|
7926
8003
|
import { resolve as resolve8, basename as basename2 } from "path";
|
|
7927
|
-
import { homedir as
|
|
8004
|
+
import { homedir as homedir7 } from "os";
|
|
7928
8005
|
|
|
7929
8006
|
// src/plugin/install-sources/local.ts
|
|
7930
8007
|
import { existsSync as existsSync5, cpSync, rmSync } from "fs";
|
|
@@ -7966,7 +8043,7 @@ async function installFromLocal(source, name, targetDir) {
|
|
|
7966
8043
|
|
|
7967
8044
|
// src/plugin/install-sources/npm.ts
|
|
7968
8045
|
import { existsSync as existsSync6, mkdirSync as mkdirSync5, readFileSync as readFileSync4, writeFileSync as writeFileSync6, rmSync as rmSync2, cpSync as cpSync2 } from "fs";
|
|
7969
|
-
import { resolve as resolve4, join as
|
|
8046
|
+
import { resolve as resolve4, join as join7 } from "path";
|
|
7970
8047
|
import { tmpdir } from "os";
|
|
7971
8048
|
import {
|
|
7972
8049
|
downloadToFile,
|
|
@@ -8004,7 +8081,8 @@ async function ensureProxyFetch() {
|
|
|
8004
8081
|
const body = init?.body;
|
|
8005
8082
|
if (body instanceof globalThis.FormData && !(body instanceof UFormData)) {
|
|
8006
8083
|
const ufd = new UFormData();
|
|
8007
|
-
|
|
8084
|
+
const domFormData = body;
|
|
8085
|
+
domFormData.forEach((value, key) => {
|
|
8008
8086
|
if (value instanceof Blob) {
|
|
8009
8087
|
ufd.append(key, value, value.name || "file");
|
|
8010
8088
|
} else {
|
|
@@ -8038,13 +8116,13 @@ async function installFromNpm(packageName, name, targetDir) {
|
|
|
8038
8116
|
throw new Error(`No tarball URL for ${packageName}@${latestVersion}`);
|
|
8039
8117
|
}
|
|
8040
8118
|
const tarballUrl = versionMeta.dist.tarball;
|
|
8041
|
-
const tmpDir =
|
|
8119
|
+
const tmpDir = join7(tmpdir(), `xbrowser-npm-${Date.now()}`);
|
|
8042
8120
|
mkdirSync5(tmpDir, { recursive: true });
|
|
8043
8121
|
let warnings = [];
|
|
8044
8122
|
try {
|
|
8045
|
-
const tarballPath =
|
|
8123
|
+
const tarballPath = join7(tmpDir, `${name}.tgz`);
|
|
8046
8124
|
await downloadToFile(tarballUrl, tarballPath);
|
|
8047
|
-
const extractDir =
|
|
8125
|
+
const extractDir = join7(tmpDir, "extracted");
|
|
8048
8126
|
extractTarGz(tarballPath, extractDir);
|
|
8049
8127
|
flattenPackageRoot(extractDir);
|
|
8050
8128
|
const verify = verifyPlugin2(extractDir, { metadataField: "xbrowser" });
|
|
@@ -8079,12 +8157,12 @@ async function installFromNpm(packageName, name, targetDir) {
|
|
|
8079
8157
|
|
|
8080
8158
|
// src/plugin/install-sources/git.ts
|
|
8081
8159
|
import { existsSync as existsSync7, readFileSync as readFileSync5, writeFileSync as writeFileSync7, rmSync as rmSync3, cpSync as cpSync3 } from "fs";
|
|
8082
|
-
import { resolve as resolve5, join as
|
|
8160
|
+
import { resolve as resolve5, join as join8 } from "path";
|
|
8083
8161
|
import { tmpdir as tmpdir2 } from "os";
|
|
8084
8162
|
import { execSync as execSync2 } from "child_process";
|
|
8085
8163
|
import { verifyPlugin as verifyPlugin3, safeCleanup as safeCleanup3 } from "@dyyz1993/xcli-core";
|
|
8086
8164
|
async function installFromGit(gitUrl, name, targetDir) {
|
|
8087
|
-
const tmpDir =
|
|
8165
|
+
const tmpDir = join8(tmpdir2(), `xbrowser-git-${Date.now()}`);
|
|
8088
8166
|
let warnings = [];
|
|
8089
8167
|
try {
|
|
8090
8168
|
execSync2(`git clone --depth 1 "${gitUrl}" "${tmpDir}"`, { stdio: "pipe" });
|
|
@@ -8121,7 +8199,7 @@ async function installFromGit(gitUrl, name, targetDir) {
|
|
|
8121
8199
|
|
|
8122
8200
|
// src/plugin/install-sources/url.ts
|
|
8123
8201
|
import { existsSync as existsSync8, mkdirSync as mkdirSync6, readFileSync as readFileSync6, writeFileSync as writeFileSync8, rmSync as rmSync4, cpSync as cpSync4 } from "fs";
|
|
8124
|
-
import { resolve as resolve6, join as
|
|
8202
|
+
import { resolve as resolve6, join as join9, basename } from "path";
|
|
8125
8203
|
import { tmpdir as tmpdir3 } from "os";
|
|
8126
8204
|
import {
|
|
8127
8205
|
downloadToFile as downloadToFile2,
|
|
@@ -8131,14 +8209,14 @@ import {
|
|
|
8131
8209
|
safeCleanup as safeCleanup4
|
|
8132
8210
|
} from "@dyyz1993/xcli-core";
|
|
8133
8211
|
async function installFromUrl(url, name, targetDir) {
|
|
8134
|
-
const tmpDir =
|
|
8212
|
+
const tmpDir = join9(tmpdir3(), `xbrowser-url-${Date.now()}`);
|
|
8135
8213
|
mkdirSync6(tmpDir, { recursive: true });
|
|
8136
8214
|
let warnings = [];
|
|
8137
8215
|
try {
|
|
8138
8216
|
const fileName = basename(new URL(url).pathname) || "plugin.tar.gz";
|
|
8139
|
-
const tarballPath =
|
|
8217
|
+
const tarballPath = join9(tmpDir, fileName);
|
|
8140
8218
|
await downloadToFile2(url, tarballPath);
|
|
8141
|
-
const extractDir =
|
|
8219
|
+
const extractDir = join9(tmpDir, "extracted");
|
|
8142
8220
|
extractTarGz2(tarballPath, extractDir);
|
|
8143
8221
|
flattenPackageRoot2(extractDir);
|
|
8144
8222
|
const verify = verifyPlugin4(extractDir, { metadataField: "xbrowser" });
|
|
@@ -8180,7 +8258,7 @@ import {
|
|
|
8180
8258
|
rmSync as rmSync5,
|
|
8181
8259
|
cpSync as cpSync5
|
|
8182
8260
|
} from "fs";
|
|
8183
|
-
import { resolve as resolve7, join as
|
|
8261
|
+
import { resolve as resolve7, join as join10, dirname as dirname2 } from "path";
|
|
8184
8262
|
import { tmpdir as tmpdir4 } from "os";
|
|
8185
8263
|
import { gunzipSync } from "zlib";
|
|
8186
8264
|
import {
|
|
@@ -8209,7 +8287,7 @@ async function installFromMarketplace(pluginsDir, slug, options) {
|
|
|
8209
8287
|
throw new Error(`Plugin "${name}" already exists. Use --force to overwrite.`);
|
|
8210
8288
|
}
|
|
8211
8289
|
mkdirSync7(targetDir, { recursive: true });
|
|
8212
|
-
const tmpDir =
|
|
8290
|
+
const tmpDir = join10(tmpdir4(), `xbrowser-marketplace-${Date.now()}`);
|
|
8213
8291
|
mkdirSync7(tmpDir, { recursive: true });
|
|
8214
8292
|
const realSlug = String(plugin.slug || slug);
|
|
8215
8293
|
try {
|
|
@@ -8272,7 +8350,7 @@ async function downloadAndExtractMarketplaceTarball(baseUrl, slug, tmpDir, targe
|
|
|
8272
8350
|
}
|
|
8273
8351
|
if (tarballRes.status === 302 || tarballRes.headers.get("location")) {
|
|
8274
8352
|
const redirectUrl = tarballRes.headers.get("location");
|
|
8275
|
-
const tarballPath =
|
|
8353
|
+
const tarballPath = join10(tmpDir, `${slug}.tar.gz`);
|
|
8276
8354
|
await downloadToFile3(redirectUrl, tarballPath);
|
|
8277
8355
|
const buffer = readFileSync7(tarballPath);
|
|
8278
8356
|
const manifest = tryParseAsGzippedManifest(buffer);
|
|
@@ -8280,7 +8358,7 @@ async function downloadAndExtractMarketplaceTarball(baseUrl, slug, tmpDir, targe
|
|
|
8280
8358
|
extractManifestToDir(manifest, targetDir);
|
|
8281
8359
|
return;
|
|
8282
8360
|
}
|
|
8283
|
-
const extractDir =
|
|
8361
|
+
const extractDir = join10(tmpDir, "extracted");
|
|
8284
8362
|
extractTarGz3(tarballPath, extractDir);
|
|
8285
8363
|
flattenPackageRoot3(extractDir);
|
|
8286
8364
|
if (existsSync9(targetDir)) {
|
|
@@ -8294,10 +8372,10 @@ async function downloadAndExtractMarketplaceTarball(baseUrl, slug, tmpDir, targe
|
|
|
8294
8372
|
extractManifestToDir(manifest, targetDir);
|
|
8295
8373
|
return;
|
|
8296
8374
|
}
|
|
8297
|
-
const tarballPath =
|
|
8375
|
+
const tarballPath = join10(tmpDir, `${slug}.tar.gz`);
|
|
8298
8376
|
writeFileSync9(tarballPath, buffer);
|
|
8299
8377
|
try {
|
|
8300
|
-
const extractDir =
|
|
8378
|
+
const extractDir = join10(tmpDir, "extracted");
|
|
8301
8379
|
extractTarGz3(tarballPath, extractDir);
|
|
8302
8380
|
flattenPackageRoot3(extractDir);
|
|
8303
8381
|
if (existsSync9(targetDir)) {
|
|
@@ -8390,7 +8468,7 @@ function ensureIndexFile(plugin, name, targetDir) {
|
|
|
8390
8468
|
var PluginInstaller = class {
|
|
8391
8469
|
pluginsDir;
|
|
8392
8470
|
constructor(pluginsDir) {
|
|
8393
|
-
this.pluginsDir = pluginsDir || resolve8(
|
|
8471
|
+
this.pluginsDir = pluginsDir || resolve8(homedir7(), ".xbrowser/plugins");
|
|
8394
8472
|
}
|
|
8395
8473
|
getPluginsDir() {
|
|
8396
8474
|
return this.pluginsDir;
|
|
@@ -8919,7 +8997,7 @@ async function searchFromMarketplacePlugin(options, loader) {
|
|
|
8919
8997
|
site: options.site,
|
|
8920
8998
|
limit: options.limit
|
|
8921
8999
|
},
|
|
8922
|
-
|
|
9000
|
+
createStubContext("marketplace")
|
|
8923
9001
|
);
|
|
8924
9002
|
const items = extractItems(result);
|
|
8925
9003
|
return items.map((item) => ({
|
|
@@ -9700,16 +9778,16 @@ async function handleBrowserCommand(command, args, options, sessionName, mode, c
|
|
|
9700
9778
|
if (cmdDef) {
|
|
9701
9779
|
if (mode === "json") {
|
|
9702
9780
|
const paramsList = [];
|
|
9703
|
-
const schema = cmdDef.parameters;
|
|
9781
|
+
const schema = asZodSchema(cmdDef.parameters);
|
|
9704
9782
|
const shape = schema?.shape ?? schema?._def?.shape;
|
|
9705
9783
|
if (shape) {
|
|
9706
9784
|
for (const [key, value] of Object.entries(shape)) {
|
|
9707
|
-
const fieldSchema = value;
|
|
9785
|
+
const fieldSchema = asZodSchema(value);
|
|
9708
9786
|
const fieldDef = fieldSchema._def;
|
|
9709
9787
|
const description = fieldSchema.description || fieldDef?.description || "";
|
|
9710
9788
|
const typeName = fieldDef?.typeName || "";
|
|
9711
9789
|
const isOptional = typeName === "ZodOptional" || typeof fieldSchema.isOptional === "function" && fieldSchema.isOptional();
|
|
9712
|
-
const innerType = fieldDef?.innerType;
|
|
9790
|
+
const innerType = asZodSchema(fieldDef?.innerType);
|
|
9713
9791
|
const innerTypeName = innerType?._def ? innerType._def.typeName : typeName;
|
|
9714
9792
|
let type = "unknown";
|
|
9715
9793
|
if (innerTypeName === "ZodString" || typeName === "ZodString") type = "string";
|
|
@@ -10027,15 +10105,15 @@ async function handleBrowserCommand(command, args, options, sessionName, mode, c
|
|
|
10027
10105
|
}
|
|
10028
10106
|
|
|
10029
10107
|
// src/cli/session-routes.ts
|
|
10030
|
-
import { homedir as
|
|
10031
|
-
import { join as
|
|
10108
|
+
import { homedir as homedir8 } from "os";
|
|
10109
|
+
import { join as join12 } from "path";
|
|
10032
10110
|
import { readdirSync as readdirSync3, rmSync as rmSync7 } from "fs";
|
|
10033
10111
|
function cleanSessionFiles() {
|
|
10034
|
-
const dir =
|
|
10112
|
+
const dir = join12(homedir8(), ".xbrowser", "sessions");
|
|
10035
10113
|
let count = 0;
|
|
10036
10114
|
try {
|
|
10037
10115
|
for (const entry of readdirSync3(dir, { withFileTypes: true })) {
|
|
10038
|
-
const p =
|
|
10116
|
+
const p = join12(dir, entry.name);
|
|
10039
10117
|
rmSync7(p, { recursive: true, force: true });
|
|
10040
10118
|
count++;
|
|
10041
10119
|
}
|
|
@@ -10119,8 +10197,7 @@ async function buildRuntimePluginInfo() {
|
|
|
10119
10197
|
const cmds = site.getAllCommands();
|
|
10120
10198
|
const commandNames = cmds.map((c) => c.name);
|
|
10121
10199
|
if (commandNames.length === 0) continue;
|
|
10122
|
-
const
|
|
10123
|
-
const hasLoginHandler = typeof anySite.hasLoginCommand === "function" && anySite.hasLoginCommand();
|
|
10200
|
+
const hasLoginHandler = "hasLoginCommand" in site && typeof site.hasLoginCommand === "function" && site.hasLoginCommand();
|
|
10124
10201
|
const configRequiresLogin = !!site.config.requiresLogin;
|
|
10125
10202
|
const hasLogin = hasLoginHandler || configRequiresLogin;
|
|
10126
10203
|
let loggedIn = null;
|
|
@@ -10170,7 +10247,7 @@ async function searchFromMarketplacePlugin2(options, loader) {
|
|
|
10170
10247
|
site: options.site,
|
|
10171
10248
|
limit: options.limit
|
|
10172
10249
|
},
|
|
10173
|
-
|
|
10250
|
+
createStubContext("marketplace")
|
|
10174
10251
|
);
|
|
10175
10252
|
const items = extractItems2(result);
|
|
10176
10253
|
return items.map((item) => ({ ...item, source: "marketplace" }));
|
|
@@ -10185,7 +10262,7 @@ async function infoFromMarketplacePlugin(slug, loader) {
|
|
|
10185
10262
|
const infoCmd = marketplaceSite.getCommand("info");
|
|
10186
10263
|
if (!infoCmd) return null;
|
|
10187
10264
|
try {
|
|
10188
|
-
const result = await infoCmd.handler({ slug },
|
|
10265
|
+
const result = await infoCmd.handler({ slug }, createStubContext("marketplace"));
|
|
10189
10266
|
if (!result || typeof result !== "object") return null;
|
|
10190
10267
|
const r = result;
|
|
10191
10268
|
let plugin = null;
|
|
@@ -10293,7 +10370,7 @@ async function handlePluginInfo(args, options, mode) {
|
|
|
10293
10370
|
}
|
|
10294
10371
|
console.error(`\u63D2\u4EF6 '${slug}' \u672A\u627E\u5230`);
|
|
10295
10372
|
} catch (err) {
|
|
10296
|
-
console.error("\u67E5\u8BE2\u5931\u8D25:", err
|
|
10373
|
+
console.error("\u67E5\u8BE2\u5931\u8D25:", errMsg(err));
|
|
10297
10374
|
}
|
|
10298
10375
|
}
|
|
10299
10376
|
async function handlePluginSchema(args, mode) {
|
|
@@ -10833,7 +10910,7 @@ async function handleGeneratePlugin(sessionName, pluginName, outputDir) {
|
|
|
10833
10910
|
const { SessionRecorder: SessionRecorder2 } = await import("./session-recorder-RTDGURIJ.js");
|
|
10834
10911
|
const { readSiteKnowledge: readSiteKnowledge2, toMarkdown } = await import("./site-knowledge-SYC6VCDB.js");
|
|
10835
10912
|
const { mkdirSync: mkdirSync11, writeFileSync: writeFileSync12 } = await import("fs");
|
|
10836
|
-
const { join:
|
|
10913
|
+
const { join: join14 } = await import("path");
|
|
10837
10914
|
const data = SessionRecorder2.readData(sessionName);
|
|
10838
10915
|
if (!data) {
|
|
10839
10916
|
outputError(`No recording found for session "${sessionName}". Run \`xbrowser record stop --session ${sessionName}\` first.`);
|
|
@@ -10845,14 +10922,14 @@ async function handleGeneratePlugin(sessionName, pluginName, outputDir) {
|
|
|
10845
10922
|
} catch {
|
|
10846
10923
|
}
|
|
10847
10924
|
const finalPluginName = pluginName || domain.split(".")[0] || "my-site";
|
|
10848
|
-
const finalOutputDir = outputDir ||
|
|
10925
|
+
const finalOutputDir = outputDir || join14(process.cwd(), ".xcli", "plugins", finalPluginName);
|
|
10849
10926
|
const knowledge = readSiteKnowledge2(domain);
|
|
10850
10927
|
const knowledgeMd = knowledge ? toMarkdown(knowledge) : "";
|
|
10851
10928
|
const pluginCode = generatePluginCode(finalPluginName, domain, data, knowledgeMd);
|
|
10852
|
-
mkdirSync11(
|
|
10853
|
-
writeFileSync12(
|
|
10929
|
+
mkdirSync11(join14(finalOutputDir), { recursive: true });
|
|
10930
|
+
writeFileSync12(join14(finalOutputDir, "index.ts"), pluginCode, "utf-8");
|
|
10854
10931
|
if (knowledgeMd) {
|
|
10855
|
-
writeFileSync12(
|
|
10932
|
+
writeFileSync12(join14(finalOutputDir, "SITE_KNOWLEDGE.md"), knowledgeMd, "utf-8");
|
|
10856
10933
|
}
|
|
10857
10934
|
console.log("");
|
|
10858
10935
|
console.log("=== Plugin Generated ===");
|
|
@@ -10984,9 +11061,9 @@ interface XBPage {
|
|
|
10984
11061
|
}
|
|
10985
11062
|
|
|
10986
11063
|
function ensurePage(ctx: CommandContext): XBPage {
|
|
10987
|
-
const page = (ctx as Record<string, unknown>).page;
|
|
11064
|
+
const page = 'page' in ctx ? (ctx as Record<string, unknown>).page : undefined;
|
|
10988
11065
|
if (!page) throw new Error('No active page. Start a session first.');
|
|
10989
|
-
return page as
|
|
11066
|
+
return page as XBPage;
|
|
10990
11067
|
}
|
|
10991
11068
|
|
|
10992
11069
|
export default createSite({
|
|
@@ -11019,7 +11096,7 @@ async function handleRun(filePath, options) {
|
|
|
11019
11096
|
try {
|
|
11020
11097
|
commands = readCommandFile(filePath);
|
|
11021
11098
|
} catch (e) {
|
|
11022
|
-
outputError(`Failed to read file '${filePath}': ${e
|
|
11099
|
+
outputError(`Failed to read file '${filePath}': ${errMsg(e)}`);
|
|
11023
11100
|
return;
|
|
11024
11101
|
}
|
|
11025
11102
|
if (commands.length === 0) {
|
|
@@ -11375,7 +11452,7 @@ async function handleNetCommand(args, options, mode, sessionName) {
|
|
|
11375
11452
|
outputError(`Unknown net sub-command: ${subCommand}. Use: list, clear, top, log, around, analyze, curl, replay, inspect, like, dislike, export`);
|
|
11376
11453
|
}
|
|
11377
11454
|
} catch (err) {
|
|
11378
|
-
outputError(err
|
|
11455
|
+
outputError(errMsg(err) || "Network command failed");
|
|
11379
11456
|
}
|
|
11380
11457
|
}
|
|
11381
11458
|
|
|
@@ -11900,7 +11977,7 @@ async function createSessionHandler(req) {
|
|
|
11900
11977
|
createdAt: session.createdAt
|
|
11901
11978
|
});
|
|
11902
11979
|
} catch (err) {
|
|
11903
|
-
return errorResponse(500, "INTERNAL_ERROR", err
|
|
11980
|
+
return errorResponse(500, "INTERNAL_ERROR", errMsg(err));
|
|
11904
11981
|
}
|
|
11905
11982
|
}
|
|
11906
11983
|
async function closeSession2(req) {
|
|
@@ -11995,7 +12072,7 @@ async function route(method, url, headers, body) {
|
|
|
11995
12072
|
try {
|
|
11996
12073
|
return await match.route.handler(req);
|
|
11997
12074
|
} catch (err) {
|
|
11998
|
-
return errorResponse(500, "INTERNAL_ERROR", err
|
|
12075
|
+
return errorResponse(500, "INTERNAL_ERROR", errMsg(err));
|
|
11999
12076
|
}
|
|
12000
12077
|
}
|
|
12001
12078
|
async function handleRequest(req, res, validateAuthFn) {
|
|
@@ -12153,8 +12230,9 @@ function showCommandHelp(siteName, cmd, siteConfig, mode) {
|
|
|
12153
12230
|
if (mode === "json") {
|
|
12154
12231
|
const paramsList = [];
|
|
12155
12232
|
if (c.parameters) {
|
|
12156
|
-
const def = c.parameters._def;
|
|
12157
|
-
const
|
|
12233
|
+
const def = asZodSchema(c.parameters)._def;
|
|
12234
|
+
const rawShape = def?.shape;
|
|
12235
|
+
const shape = typeof rawShape === "function" ? rawShape() : rawShape;
|
|
12158
12236
|
if (shape) {
|
|
12159
12237
|
for (const [key, value] of Object.entries(shape)) {
|
|
12160
12238
|
const info = extractZodFieldInfo(value);
|
|
@@ -12381,16 +12459,16 @@ async function routeCommand(argv, stdinCommands) {
|
|
|
12381
12459
|
if (builtinCmd) {
|
|
12382
12460
|
if (mode === "json") {
|
|
12383
12461
|
const paramsList = [];
|
|
12384
|
-
const schema = builtinCmd.parameters;
|
|
12462
|
+
const schema = asZodSchema(builtinCmd.parameters);
|
|
12385
12463
|
const shape = schema?.shape ?? schema?._def?.shape;
|
|
12386
12464
|
if (shape) {
|
|
12387
12465
|
for (const [key, value] of Object.entries(shape)) {
|
|
12388
|
-
const fieldSchema = value;
|
|
12466
|
+
const fieldSchema = asZodSchema(value);
|
|
12389
12467
|
const fieldDef = fieldSchema._def;
|
|
12390
12468
|
const description = fieldSchema.description || fieldDef?.description || "";
|
|
12391
12469
|
const typeName = fieldDef?.typeName || "";
|
|
12392
12470
|
const isOptional = typeName === "ZodOptional" || typeof fieldSchema.isOptional === "function" && fieldSchema.isOptional();
|
|
12393
|
-
const innerType = fieldDef?.innerType;
|
|
12471
|
+
const innerType = asZodSchema(fieldDef?.innerType);
|
|
12394
12472
|
const innerTypeName = innerType?._def ? innerType._def.typeName : typeName;
|
|
12395
12473
|
let type = "unknown";
|
|
12396
12474
|
if (innerTypeName === "ZodString" || typeName === "ZodString") type = "string";
|
|
@@ -12565,7 +12643,7 @@ Run "xbrowser ${command} --help" to see available commands.`
|
|
|
12565
12643
|
const rawPluginArgs = subCmdIdx >= 0 ? argv.slice(subCmdIdx + 1) : [];
|
|
12566
12644
|
const params = parsePluginParams(rawPluginArgs, cmdEntry.parameters);
|
|
12567
12645
|
if (cmdEntry.parameters) {
|
|
12568
|
-
const schemaAny = cmdEntry.parameters;
|
|
12646
|
+
const schemaAny = asZodSchema(cmdEntry.parameters);
|
|
12569
12647
|
const def = schemaAny._def;
|
|
12570
12648
|
const shapeOrFn = def?.shape ?? schemaAny.shape;
|
|
12571
12649
|
const shapeObj = typeof shapeOrFn === "function" ? shapeOrFn() : shapeOrFn;
|
|
@@ -12589,10 +12667,10 @@ Run "xbrowser ${command} ${subCommand} --help" to see available parameters.`
|
|
|
12589
12667
|
}
|
|
12590
12668
|
const needsBrowser = cmdEntry.scope === "page" || cmdEntry.scope === "browser";
|
|
12591
12669
|
if (needsBrowser && !process.env.XBROWSER_DAEMON_WORKER) {
|
|
12592
|
-
const { forwardExec } = await import("./daemon-client-
|
|
12670
|
+
const { forwardExec } = await import("./daemon-client-3JOKX2L2.js");
|
|
12593
12671
|
const userTimeout = typeof params.timeout === "number" && params.timeout > 0 ? params.timeout * 1e3 + 3e4 : void 0;
|
|
12594
12672
|
const result = await forwardExec(`${command}.${subCommand}`, params, sessionName, cdpEndpoint, userTimeout);
|
|
12595
|
-
const resultData = result && typeof result === "object" ? result.data : void 0;
|
|
12673
|
+
const resultData = result && typeof result === "object" && "data" in result ? result.data : void 0;
|
|
12596
12674
|
if (result && result.success === false && resultData?.code === "LOGIN_REQUIRED") {
|
|
12597
12675
|
outputLoginRequired(result, mode);
|
|
12598
12676
|
return;
|
|
@@ -12641,7 +12719,7 @@ Run "xbrowser ${command} ${subCommand} --help" to see available parameters.`
|
|
|
12641
12719
|
waitForHuman: async (_opts) => {
|
|
12642
12720
|
return { solved: false, timedOut: true };
|
|
12643
12721
|
},
|
|
12644
|
-
tips: new
|
|
12722
|
+
tips: new TipCollector3()
|
|
12645
12723
|
};
|
|
12646
12724
|
try {
|
|
12647
12725
|
const cmdStart = Date.now();
|
|
@@ -13084,7 +13162,7 @@ var PlaybackEngine = class _PlaybackEngine {
|
|
|
13084
13162
|
const content = fs4.readFileSync(filePath, "utf-8");
|
|
13085
13163
|
const raw = filePath.endsWith(".json") ? JSON.parse(content) : yaml2.parse(content);
|
|
13086
13164
|
let recording;
|
|
13087
|
-
const checkpoints = raw.checkpoints
|
|
13165
|
+
const checkpoints = "checkpoints" in raw ? raw.checkpoints : [];
|
|
13088
13166
|
if (raw.events && raw.events.length > 0) {
|
|
13089
13167
|
recording = raw;
|
|
13090
13168
|
} else if (raw.actions && raw.actions.length > 0) {
|
|
@@ -13157,7 +13235,7 @@ var PlaybackEngine = class _PlaybackEngine {
|
|
|
13157
13235
|
errors.push({
|
|
13158
13236
|
eventIndex: i,
|
|
13159
13237
|
event,
|
|
13160
|
-
error: err
|
|
13238
|
+
error: errMsg(err)
|
|
13161
13239
|
});
|
|
13162
13240
|
if (stopOnError) break;
|
|
13163
13241
|
}
|
|
@@ -13594,14 +13672,13 @@ var ElementMonitor = class {
|
|
|
13594
13672
|
document.addEventListener("focusin", (e) => {
|
|
13595
13673
|
const el = e.target;
|
|
13596
13674
|
if (el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.contentEditable === "true") {
|
|
13597
|
-
|
|
13598
|
-
w.__xb_focus_seq = (w.__xb_focus_seq || 0) + 1;
|
|
13675
|
+
window.__xb_focus_seq = (window.__xb_focus_seq || 0) + 1;
|
|
13599
13676
|
const info = {
|
|
13600
13677
|
selector: "",
|
|
13601
13678
|
tag: el.tagName,
|
|
13602
13679
|
value: el.value || "",
|
|
13603
13680
|
placeholder: el.placeholder || "",
|
|
13604
|
-
seq:
|
|
13681
|
+
seq: window.__xb_focus_seq
|
|
13605
13682
|
};
|
|
13606
13683
|
if (el.id) info.selector = "#" + el.id;
|
|
13607
13684
|
else if (el.getAttribute("name")) info.selector = '[name="' + el.getAttribute("name") + '"]';
|
|
@@ -13609,7 +13686,7 @@ var ElementMonitor = class {
|
|
|
13609
13686
|
if (el.tagName === "INPUT" && el.type === "file") {
|
|
13610
13687
|
info.isFileInput = true;
|
|
13611
13688
|
}
|
|
13612
|
-
|
|
13689
|
+
window.__xb_last_focused = info;
|
|
13613
13690
|
}
|
|
13614
13691
|
}, true);
|
|
13615
13692
|
document.addEventListener("focusout", () => {
|
|
@@ -14116,12 +14193,12 @@ var FileListHandler = class {
|
|
|
14116
14193
|
const msg = ctx.message;
|
|
14117
14194
|
try {
|
|
14118
14195
|
const { readdirSync: readdirSync4, statSync } = await import("fs");
|
|
14119
|
-
const { join:
|
|
14196
|
+
const { join: join14, resolve: resolve10 } = await import("path");
|
|
14120
14197
|
const targetPath = resolve10(msg.path);
|
|
14121
14198
|
const entries = readdirSync4(targetPath);
|
|
14122
14199
|
const files = entries.map((name) => {
|
|
14123
14200
|
try {
|
|
14124
|
-
const stat = statSync(
|
|
14201
|
+
const stat = statSync(join14(targetPath, name));
|
|
14125
14202
|
return { name, isDir: stat.isDirectory(), size: stat.size, modified: stat.mtime.toISOString() };
|
|
14126
14203
|
} catch {
|
|
14127
14204
|
return { name, isDir: false, size: 0, modified: "" };
|
|
@@ -15683,7 +15760,7 @@ var DataCollector = class {
|
|
|
15683
15760
|
return results;
|
|
15684
15761
|
}
|
|
15685
15762
|
async createBrowserContext() {
|
|
15686
|
-
const { launch } = await import("./cdp-driver-
|
|
15763
|
+
const { launch } = await import("./cdp-driver-D6WMSMWX.js");
|
|
15687
15764
|
const { browser } = await launch({
|
|
15688
15765
|
headless: true,
|
|
15689
15766
|
args: ["--no-sandbox", "--disable-setuid-sandbox"]
|
|
@@ -15692,7 +15769,7 @@ var DataCollector = class {
|
|
|
15692
15769
|
userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
|
|
15693
15770
|
viewport: { width: 1920, height: 1080 }
|
|
15694
15771
|
});
|
|
15695
|
-
context
|
|
15772
|
+
Reflect.set(context, "_browser", browser);
|
|
15696
15773
|
return context;
|
|
15697
15774
|
}
|
|
15698
15775
|
sleep(ms) {
|
|
@@ -15723,7 +15800,7 @@ var DataCollector = class {
|
|
|
15723
15800
|
|
|
15724
15801
|
// src/cdp-interceptor/index.ts
|
|
15725
15802
|
async function createCDPInterceptor(config) {
|
|
15726
|
-
const { CDPInterceptorProxy: CDPInterceptorProxy2 } = await import("./proxy-
|
|
15803
|
+
const { CDPInterceptorProxy: CDPInterceptorProxy2 } = await import("./proxy-C6CK3UH5.js");
|
|
15727
15804
|
const proxy = new CDPInterceptorProxy2(config);
|
|
15728
15805
|
await proxy.start();
|
|
15729
15806
|
return proxy;
|