@xbrowser/cli 1.23.0 → 1.24.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/README.md +13 -0
- package/dist/chunk-A7RZYSWM.js +8778 -0
- package/dist/chunk-BROEUPL3.js +9122 -0
- package/dist/{chunk-LPW6QS4M.js → chunk-FNXA6FDM.js} +39 -1
- package/dist/{chunk-FBQZ3PVD.js → chunk-PGKV24QN.js} +39 -1
- package/dist/{chunk-XTUAUFL3.js → chunk-SOPN4XDK.js} +41 -96
- package/dist/cli.js +255 -8918
- package/dist/daemon-main.js +50 -4
- package/dist/{human-interaction-MXST5ZQM.js → human-interaction-CTZ4IWXJ.js} +1 -1
- package/dist/{human-interaction-67K43B4O.js → human-interaction-HJCK45SL.js} +1 -1
- package/dist/{human-interaction-57VYIR56.js → human-interaction-V3VDGHHI.js} +2 -1
- package/dist/index.d.ts +16 -0
- package/dist/index.js +439 -9395
- package/dist/{recovery-LGY25LIM.js → recovery-5C4FBA5O.js} +1 -1
- package/dist/{recovery-6RI2FE3E.js → recovery-EBKORYEU.js} +1 -1
- package/dist/{recovery-LMJW537X.js → recovery-IMZUGWSS.js} +2 -1
- package/dist/server-NPINOVJS.js +243 -0
- package/dist/server-YVMWMNHD.js +240 -0
- package/package.json +2 -2
package/dist/daemon-main.js
CHANGED
|
@@ -69,6 +69,35 @@ import {
|
|
|
69
69
|
removeSession
|
|
70
70
|
} from "@dyyz1993/xcli-core";
|
|
71
71
|
|
|
72
|
+
// src/fail-codes.ts
|
|
73
|
+
var FAIL_CODES = {
|
|
74
|
+
selectorNotFound: "RETRYABLE: selector-not-found",
|
|
75
|
+
pageNotReady: "RETRYABLE: page-not-ready",
|
|
76
|
+
elementGone: "RETRYABLE: element-gone",
|
|
77
|
+
captcha: "HUMAN: captcha",
|
|
78
|
+
loginWall: "HUMAN: login-wall",
|
|
79
|
+
permissionDenied: "FATAL: permission-denied",
|
|
80
|
+
targetGone: "FATAL: target-gone",
|
|
81
|
+
unknown: "FATAL: unknown"
|
|
82
|
+
};
|
|
83
|
+
function classifyFailure(message) {
|
|
84
|
+
const msg = (message || "").toLowerCase();
|
|
85
|
+
const pick = (code) => ({
|
|
86
|
+
code,
|
|
87
|
+
level: code.split(":")[0],
|
|
88
|
+
message: message || code
|
|
89
|
+
});
|
|
90
|
+
if (/captcha|验证码|人机校验|recaptcha|hcaptcha|turnstile/.test(msg)) return pick(FAIL_CODES.captcha);
|
|
91
|
+
if (/login|登录|signin|sign in|未登录|login-required|LOGIN_REQUIRED/.test(msg)) return pick(FAIL_CODES.loginWall);
|
|
92
|
+
if (/permission|权限|not allowed|forbidden|EACCES/.test(msg)) return pick(FAIL_CODES.permissionDenied);
|
|
93
|
+
if (/selector|选择器|element not found|未找到元素|no such element|queryselector returned null/.test(msg))
|
|
94
|
+
return pick(FAIL_CODES.selectorNotFound);
|
|
95
|
+
if (/timeout|超时|timed out|waiting for/.test(msg)) return pick(FAIL_CODES.pageNotReady);
|
|
96
|
+
if (/net::err|404|navigation failed|页面不存在|target closed|element-gone/.test(msg))
|
|
97
|
+
return pick(FAIL_CODES.targetGone);
|
|
98
|
+
return pick(FAIL_CODES.unknown);
|
|
99
|
+
}
|
|
100
|
+
|
|
72
101
|
// src/executor.ts
|
|
73
102
|
import {
|
|
74
103
|
ok as ok30,
|
|
@@ -7966,7 +7995,16 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7966
7995
|
if (isSuccess) {
|
|
7967
7996
|
return { ...ok30(raw.data, merged.length > 0 ? merged : raw.tips), duration, ...hookOutputs ? { hookOutputs } : {} };
|
|
7968
7997
|
}
|
|
7969
|
-
|
|
7998
|
+
const fc = classifyFailure(raw.message);
|
|
7999
|
+
return {
|
|
8000
|
+
success: false,
|
|
8001
|
+
data: raw.data,
|
|
8002
|
+
message: raw.message,
|
|
8003
|
+
tips: mergedOrRaw,
|
|
8004
|
+
duration,
|
|
8005
|
+
error: { code: fc.code, level: fc.level },
|
|
8006
|
+
...hookOutputs ? { hookOutputs } : {}
|
|
8007
|
+
};
|
|
7970
8008
|
}
|
|
7971
8009
|
const smartTipNormalized = normalizeTips6(smartTips);
|
|
7972
8010
|
recordArchive(session?.id, sessionName, {
|
|
@@ -7985,7 +8023,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7985
8023
|
const errorMessage = errMsg(err);
|
|
7986
8024
|
if (session?.page && process.env.XBROWSER_RECOVERY && !extraOpts?._recoveryAttempted) {
|
|
7987
8025
|
try {
|
|
7988
|
-
const { attemptRecovery } = await import("./recovery-
|
|
8026
|
+
const { attemptRecovery } = await import("./recovery-5C4FBA5O.js");
|
|
7989
8027
|
const recovery = await attemptRecovery(
|
|
7990
8028
|
session.page,
|
|
7991
8029
|
sessionName,
|
|
@@ -8101,7 +8139,15 @@ async function executeChain(input, options) {
|
|
|
8101
8139
|
continue;
|
|
8102
8140
|
}
|
|
8103
8141
|
const pluginArgs = cmdArgs.slice(1);
|
|
8104
|
-
|
|
8142
|
+
let pluginParams = parsePluginParams(pluginArgs, cmdEntry.parameters);
|
|
8143
|
+
if (cmdEntry.parameters) {
|
|
8144
|
+
const schemaCheck = cmdEntry.parameters.safeParse(pluginParams);
|
|
8145
|
+
if (schemaCheck.success) {
|
|
8146
|
+
for (const [k, v] of Object.entries(schemaCheck.data)) {
|
|
8147
|
+
if (!(k in pluginParams)) pluginParams[k] = v;
|
|
8148
|
+
}
|
|
8149
|
+
}
|
|
8150
|
+
}
|
|
8105
8151
|
const pluginCtx = {
|
|
8106
8152
|
args: pluginArgs,
|
|
8107
8153
|
options: pluginParams,
|
|
@@ -9025,7 +9071,7 @@ function createRPCHandler() {
|
|
|
9025
9071
|
return result;
|
|
9026
9072
|
} catch (err) {
|
|
9027
9073
|
const errorMessage = errMsg(err);
|
|
9028
|
-
const { attemptRecovery } = await import("./recovery-
|
|
9074
|
+
const { attemptRecovery } = await import("./recovery-5C4FBA5O.js");
|
|
9029
9075
|
const recovery = await attemptRecovery(
|
|
9030
9076
|
session?.page,
|
|
9031
9077
|
sessionName,
|
package/dist/index.d.ts
CHANGED
|
@@ -836,6 +836,10 @@ interface ExecutionResult {
|
|
|
836
836
|
duration: number;
|
|
837
837
|
tips?: Tip[];
|
|
838
838
|
hookOutputs?: HookOutput[];
|
|
839
|
+
error?: {
|
|
840
|
+
code: string;
|
|
841
|
+
level: string;
|
|
842
|
+
};
|
|
839
843
|
}
|
|
840
844
|
/**
|
|
841
845
|
* Result of a single step within a command chain execution.
|
|
@@ -2488,6 +2492,10 @@ interface WebhookPayload {
|
|
|
2488
2492
|
previewUrl?: string;
|
|
2489
2493
|
targetUrl?: string;
|
|
2490
2494
|
timeout?: number;
|
|
2495
|
+
/** Drel 等推送服务的通知标题(可选;缺省由 event 推导) */
|
|
2496
|
+
title?: string;
|
|
2497
|
+
/** Drel 等推送服务的通知正文(可选;缺省由其余字段拼装) */
|
|
2498
|
+
body?: string;
|
|
2491
2499
|
}
|
|
2492
2500
|
/**
|
|
2493
2501
|
* Sends webhook notifications for browser automation lifecycle events.
|
|
@@ -2505,6 +2513,14 @@ declare class WebhookNotifier {
|
|
|
2505
2513
|
* @returns `true` if the request succeeded (HTTP 2xx), `false` otherwise.
|
|
2506
2514
|
*/
|
|
2507
2515
|
notify(payload: WebhookPayload): Promise<boolean>;
|
|
2516
|
+
/**
|
|
2517
|
+
* previewUrl 里的 localhost/127.0.0.1 替换为本机局域网 IPv4——
|
|
2518
|
+
* 推送目标是手机,localhost 在手机上不可达;同一 Wi-Fi 下局域网 IP 可达。
|
|
2519
|
+
*/
|
|
2520
|
+
private lanify;
|
|
2521
|
+
/** Drel 推送端点识别(api.drel.app/<token>) */
|
|
2522
|
+
private isDrelEndpoint;
|
|
2523
|
+
private toDrelPayload;
|
|
2508
2524
|
}
|
|
2509
2525
|
|
|
2510
2526
|
interface CaptchaConfig {
|