@xbrowser/cli 1.26.0 → 1.27.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/{chunk-6OWOICQ3.js → chunk-IDXOIXQR.js} +306 -139
- package/dist/{chunk-HDFQRDBC.js → chunk-YITK42HZ.js} +306 -139
- package/dist/cli.js +2 -2
- package/dist/daemon-main.js +309 -142
- package/dist/index.js +2 -2
- package/dist/{server-6KZ5NT6L.js → server-WDDGIV3C.js} +1 -1
- package/dist/{server-65LCP6S6.js → server-YKMRFDEM.js} +1 -1
- package/package.json +1 -1
package/dist/daemon-main.js
CHANGED
|
@@ -102,12 +102,12 @@ function classifyFailure(message) {
|
|
|
102
102
|
|
|
103
103
|
// src/executor.ts
|
|
104
104
|
import {
|
|
105
|
-
ok as
|
|
106
|
-
fail as
|
|
105
|
+
ok as ok32,
|
|
106
|
+
fail as fail17,
|
|
107
107
|
isCommandResult,
|
|
108
108
|
CompositeStorage as CompositeStorage2,
|
|
109
109
|
TipCollector as TipCollector2,
|
|
110
|
-
normalizeTips as
|
|
110
|
+
normalizeTips as normalizeTips7,
|
|
111
111
|
configureArchiveStore,
|
|
112
112
|
appendCommandToArchive,
|
|
113
113
|
checkGuard,
|
|
@@ -5879,26 +5879,193 @@ var waitForCommand = registerCommand({
|
|
|
5879
5879
|
}
|
|
5880
5880
|
});
|
|
5881
5881
|
|
|
5882
|
-
// src/commands/
|
|
5882
|
+
// src/commands/task.ts
|
|
5883
5883
|
import { z as z27 } from "zod";
|
|
5884
|
-
import { ok as ok26, fail as fail12 } from "@dyyz1993/xcli-core";
|
|
5885
|
-
var
|
|
5886
|
-
|
|
5887
|
-
|
|
5888
|
-
|
|
5884
|
+
import { ok as ok26, fail as fail12, normalizeTips as normalizeTips5 } from "@dyyz1993/xcli-core";
|
|
5885
|
+
var DECISION_SYSTEM = `\u4F60\u662F\u6D4F\u89C8\u5668\u4EFB\u52A1\u51B3\u7B56\u5668\u3002\u6839\u636E\u76EE\u6807\u3001\u5F53\u524D\u9875\u9762\u5143\u7D20\u6E05\u5355\uFF08\u6BCF\u9879\u5E26 @eN \u7F16\u53F7\uFF09\u548C\u5DF2\u6267\u884C\u5386\u53F2\uFF0C\u8F93\u51FA\u4E0B\u4E00\u6B65\u52A8\u4F5C\u3002
|
|
5886
|
+
|
|
5887
|
+
\u53EF\u7528\u52A8\u4F5C\uFF08\u53EA\u80FD\u8F93\u51FA\u4E00\u4E2A JSON \u5BF9\u8C61\uFF0C\u4E0D\u8981\u8F93\u51FA\u4EFB\u4F55\u5176\u4ED6\u6587\u5B57\uFF09\uFF1A
|
|
5888
|
+
{"action":"click","ref":"@eN","thought":"\u4E3A\u4EC0\u4E48"}
|
|
5889
|
+
{"action":"fill","ref":"@eN","value":"\u6587\u672C","thought":"\u4E3A\u4EC0\u4E48"}
|
|
5890
|
+
{"action":"select","ref":"@eN","value":"\u9009\u9879\u503C","thought":"\u4E3A\u4EC0\u4E48"}
|
|
5891
|
+
{"action":"press","value":"Enter","thought":"\u4E3A\u4EC0\u4E48"}
|
|
5892
|
+
{"action":"scroll","value":"down \u6216 up","thought":"\u4E3A\u4EC0\u4E48"}
|
|
5893
|
+
{"action":"done","value":"\u5B8C\u6210\u6458\u8981","thought":"\u4E3A\u4EC0\u4E48"}
|
|
5894
|
+
{"action":"blocked","value":"\u5361\u4F4F\u539F\u56E0","thought":"\u4E3A\u4EC0\u4E48"}
|
|
5895
|
+
|
|
5896
|
+
\u89C4\u5219\uFF1A
|
|
5897
|
+
1. ref \u5FC5\u987B\u539F\u6837\u6765\u81EA\u672C\u6B21\u5143\u7D20\u6E05\u5355\uFF1B\u6E05\u5355\u91CC\u6CA1\u6709\u80FD\u63A8\u8FDB\u76EE\u6807\u7684\u5143\u7D20\u5C31\u8F93\u51FA blocked\u3002
|
|
5898
|
+
2. \u76EE\u6807\u5DF2\u5B8C\u6210\uFF08\u9875\u9762\u4E0A\u80FD\u786E\u8BA4\u7ED3\u679C\uFF09\u5C31\u8F93\u51FA done\uFF0Cvalue \u5199\u5B8C\u6210\u6458\u8981\u3002
|
|
5899
|
+
3. \u4E0D\u8981\u91CD\u590D\u521A\u5931\u8D25\u8FC7\u7684\u540C\u4E00\u52A8\u4F5C\uFF1B\u8FDE\u7EED\u5931\u8D25\u6362\u601D\u8DEF\u6216 blocked\u3002`;
|
|
5900
|
+
function extractDecision(raw) {
|
|
5901
|
+
let s = raw.trim().replace(/^```(?:json)?\s*/i, "").replace(/\s*```$/, "");
|
|
5902
|
+
const start = s.indexOf("{");
|
|
5903
|
+
if (start < 0) return null;
|
|
5904
|
+
let depth = 0;
|
|
5905
|
+
for (let i = start; i < s.length; i++) {
|
|
5906
|
+
if (s[i] === "{") depth++;
|
|
5907
|
+
else if (s[i] === "}") {
|
|
5908
|
+
depth--;
|
|
5909
|
+
if (depth === 0) {
|
|
5910
|
+
try {
|
|
5911
|
+
return JSON.parse(s.slice(start, i + 1));
|
|
5912
|
+
} catch {
|
|
5913
|
+
return null;
|
|
5914
|
+
}
|
|
5915
|
+
}
|
|
5916
|
+
}
|
|
5917
|
+
}
|
|
5918
|
+
return null;
|
|
5919
|
+
}
|
|
5920
|
+
var taskCommand = registerCommand({
|
|
5921
|
+
name: "task",
|
|
5922
|
+
description: "Autonomous goal loop: observe refs \u2192 LLM decides \u2192 act, until done/blocked (budget-capped)",
|
|
5923
|
+
scope: "page",
|
|
5924
|
+
parameters: z27.object({
|
|
5925
|
+
goal: z27.string().describe("Natural-language goal"),
|
|
5926
|
+
maxSteps: z27.number().int().positive().max(50).optional().default(15).describe("Hard action budget"),
|
|
5927
|
+
timeout: z27.number().optional().default(18e4).describe("Wall clock budget in ms"),
|
|
5928
|
+
limit: z27.number().int().positive().max(300).optional().default(80).describe("Max targets per observe")
|
|
5929
|
+
}),
|
|
5930
|
+
result: z27.object({
|
|
5931
|
+
status: z27.enum(["done", "blocked", "max_steps", "error"]),
|
|
5932
|
+
summary: z27.string().optional(),
|
|
5933
|
+
steps: z27.array(z27.record(z27.unknown())),
|
|
5934
|
+
finalUrl: z27.string().optional(),
|
|
5935
|
+
usage: z27.object({ llmCalls: z27.number(), steps: z27.number() }).passthrough().optional()
|
|
5936
|
+
}).passthrough(),
|
|
5937
|
+
handler: async (p, ctx) => {
|
|
5938
|
+
const creds = loadVLMCredentials2();
|
|
5939
|
+
if (!creds) {
|
|
5940
|
+
return fail12("task \u9700\u8981\u51B3\u7B56\u6A21\u578B\u51ED\u8BC1\uFF1A\u8BBE\u7F6E XBROWSER_VLM_CONFIG \u6216 ~/.zcode/v2/config.json");
|
|
5941
|
+
}
|
|
5942
|
+
const model = process.env.XBROWSER_TASK_MODEL || creds.model;
|
|
5943
|
+
const started = Date.now();
|
|
5944
|
+
const steps = [];
|
|
5945
|
+
const history = [];
|
|
5946
|
+
let llmCalls = 0;
|
|
5947
|
+
let status = "max_steps";
|
|
5948
|
+
let summary = "";
|
|
5949
|
+
let lastError = "";
|
|
5950
|
+
for (let step = 1; step <= p.maxSteps; step++) {
|
|
5951
|
+
if (Date.now() - started > p.timeout) {
|
|
5952
|
+
status = "blocked";
|
|
5953
|
+
summary = `timeout after ${step - 1} steps`;
|
|
5954
|
+
break;
|
|
5955
|
+
}
|
|
5956
|
+
const obs = await observePage(ctx.page, ctx.sessionId, { limit: p.limit, includeHidden: false });
|
|
5957
|
+
const compact = obs.compact ?? obs.targets.map((t, i) => `@e${i + 1} [${t.tag ?? ""}] ${t.name ?? ""}`).join("\n");
|
|
5958
|
+
const screenHash = obs.screenHash;
|
|
5959
|
+
const userPayload = [
|
|
5960
|
+
`\u76EE\u6807\uFF1A${p.goal}`,
|
|
5961
|
+
`\u5F53\u524D\u9875\u9762\uFF08URL: ${obs.url ?? ""}\uFF09\uFF1A`,
|
|
5962
|
+
compact,
|
|
5963
|
+
history.length ? `
|
|
5964
|
+
\u5DF2\u6267\u884C\uFF08\u52FF\u91CD\u590D\u5931\u8D25\u52A8\u4F5C\uFF09\uFF1A
|
|
5965
|
+
${history.slice(-6).join("\n")}` : ""
|
|
5966
|
+
].filter(Boolean).join("\n");
|
|
5967
|
+
let raw = "";
|
|
5968
|
+
try {
|
|
5969
|
+
raw = await vlmAsk({ ...creds, model }, [{ type: "text", text: `${DECISION_SYSTEM}
|
|
5970
|
+
|
|
5971
|
+
---
|
|
5972
|
+
|
|
5973
|
+
${userPayload}` }], 900);
|
|
5974
|
+
llmCalls++;
|
|
5975
|
+
} catch (e) {
|
|
5976
|
+
lastError = e instanceof Error ? e.message : String(e);
|
|
5977
|
+
status = "error";
|
|
5978
|
+
summary = `LLM call failed: ${lastError}`;
|
|
5979
|
+
break;
|
|
5980
|
+
}
|
|
5981
|
+
const decision = extractDecision(raw);
|
|
5982
|
+
if (!decision || typeof decision.action !== "string") {
|
|
5983
|
+
status = "blocked";
|
|
5984
|
+
summary = `LLM returned unparsable decision: ${raw.slice(0, 120)}`;
|
|
5985
|
+
break;
|
|
5986
|
+
}
|
|
5987
|
+
const action = decision.action;
|
|
5988
|
+
const ref = typeof decision.ref === "string" ? decision.ref : void 0;
|
|
5989
|
+
const value = typeof decision.value === "string" ? decision.value : void 0;
|
|
5990
|
+
const thought = typeof decision.thought === "string" ? decision.thought : void 0;
|
|
5991
|
+
if (action === "done") {
|
|
5992
|
+
status = "done";
|
|
5993
|
+
summary = value || thought || "task done";
|
|
5994
|
+
steps.push({ step, thought, action: "done", ok: true, screenHash });
|
|
5995
|
+
break;
|
|
5996
|
+
}
|
|
5997
|
+
if (action === "blocked") {
|
|
5998
|
+
status = "blocked";
|
|
5999
|
+
summary = value || thought || "LLM judged blocked";
|
|
6000
|
+
steps.push({ step, thought, action: "blocked", ok: true, screenHash });
|
|
6001
|
+
break;
|
|
6002
|
+
}
|
|
6003
|
+
const legalRefs = new Set(obs.targets.map((t, i) => t.ref ?? `e${i + 1}`));
|
|
6004
|
+
const normalizedRef = ref ? legalRefs.has(ref.replace("@", "")) || legalRefs.has(ref) ? ref : void 0 : void 0;
|
|
6005
|
+
if (ref && !normalizedRef && action !== "scroll" && action !== "press") {
|
|
6006
|
+
history.push(`step${step}: ${action} ${ref} REJECTED (ref not in current list)`);
|
|
6007
|
+
steps.push({ step, thought, action, ref, ok: false, error: "ref not in current list", screenHash });
|
|
6008
|
+
continue;
|
|
6009
|
+
}
|
|
6010
|
+
const res = await actOnPage(ctx.page, ctx.sessionId, {
|
|
6011
|
+
action,
|
|
6012
|
+
ref: normalizedRef,
|
|
6013
|
+
value,
|
|
6014
|
+
selector: void 0,
|
|
6015
|
+
force: false,
|
|
6016
|
+
timeout: 1e4
|
|
6017
|
+
});
|
|
6018
|
+
const record = {
|
|
6019
|
+
step,
|
|
6020
|
+
thought,
|
|
6021
|
+
action,
|
|
6022
|
+
ref: normalizedRef,
|
|
6023
|
+
value,
|
|
6024
|
+
ok: res.success === true,
|
|
6025
|
+
stale: res.stale,
|
|
6026
|
+
error: res.success ? void 0 : res.message || res.reason,
|
|
6027
|
+
screenHash
|
|
6028
|
+
};
|
|
6029
|
+
steps.push(record);
|
|
6030
|
+
history.push(`step${step}: ${action} ${normalizedRef ?? ""} ${value ?? ""} -> ${res.success ? "ok" : `failed(${res.reason || res.message})`}`);
|
|
6031
|
+
const sig = (s) => `${s.action}|${s.ref ?? ""}|${s.value ?? ""}`;
|
|
6032
|
+
const last3 = steps.slice(-3);
|
|
6033
|
+
if (last3.length === 3 && new Set(last3.map(sig)).size === 1) {
|
|
6034
|
+
status = "blocked";
|
|
6035
|
+
summary = "dead loop: identical action repeated 3 times";
|
|
6036
|
+
break;
|
|
6037
|
+
}
|
|
6038
|
+
}
|
|
6039
|
+
if (status === "max_steps") summary = summary || `hit maxSteps=${p.maxSteps}`;
|
|
6040
|
+
const finalUrl = ctx.page ? ctx.page.url() : void 0;
|
|
6041
|
+
const data = { status, summary, steps, finalUrl, usage: { llmCalls, steps: steps.length } };
|
|
6042
|
+
if (status === "error") return fail12(summary || lastError, normalizeTips5([`completed steps: ${steps.length}`]));
|
|
6043
|
+
return ok26(data, normalizeTips5([
|
|
6044
|
+
status === "done" ? `\u2705 task done (${steps.length} steps, ${llmCalls} LLM calls)` : `\u26A0\uFE0F task ${status}: ${summary.slice(0, 80)}`
|
|
6045
|
+
]));
|
|
6046
|
+
}
|
|
6047
|
+
});
|
|
6048
|
+
|
|
6049
|
+
// src/commands/tab.ts
|
|
6050
|
+
import { z as z28 } from "zod";
|
|
6051
|
+
import { ok as ok27, fail as fail13 } from "@dyyz1993/xcli-core";
|
|
6052
|
+
var TabParams = z28.object({
|
|
6053
|
+
subcommand: z28.enum(["list", "new", "close", "switch"]),
|
|
6054
|
+
url: z28.string().optional(),
|
|
6055
|
+
index: z28.number().int().min(0).optional()
|
|
5889
6056
|
});
|
|
5890
6057
|
var tabCommand = registerCommand({
|
|
5891
6058
|
name: "tab",
|
|
5892
6059
|
description: "Manage browser tabs: list, new, close, switch",
|
|
5893
6060
|
scope: "page",
|
|
5894
6061
|
parameters: TabParams,
|
|
5895
|
-
result:
|
|
5896
|
-
success:
|
|
5897
|
-
data:
|
|
6062
|
+
result: z28.object({
|
|
6063
|
+
success: z28.boolean(),
|
|
6064
|
+
data: z28.unknown()
|
|
5898
6065
|
}),
|
|
5899
6066
|
handler: async (p, ctx) => {
|
|
5900
6067
|
if (!ctx.browserContext) {
|
|
5901
|
-
return
|
|
6068
|
+
return fail13("No browser context available. Use --cdp to connect to a browser first.");
|
|
5902
6069
|
}
|
|
5903
6070
|
const pages = ctx.browserContext.pages();
|
|
5904
6071
|
switch (p.subcommand) {
|
|
@@ -5911,7 +6078,7 @@ var tabCommand = registerCommand({
|
|
|
5911
6078
|
case "switch":
|
|
5912
6079
|
return handleSwitch(p, pages, ctx);
|
|
5913
6080
|
default:
|
|
5914
|
-
return
|
|
6081
|
+
return fail13(`Unknown subcommand: ${p.subcommand}`);
|
|
5915
6082
|
}
|
|
5916
6083
|
}
|
|
5917
6084
|
});
|
|
@@ -5926,7 +6093,7 @@ async function handleList(pages, ctx) {
|
|
|
5926
6093
|
if (isActive) activeIndex = i;
|
|
5927
6094
|
tabs.push({ index: i, url, title, active: isActive });
|
|
5928
6095
|
}
|
|
5929
|
-
return
|
|
6096
|
+
return ok27({ tabs, total: tabs.length, activeIndex });
|
|
5930
6097
|
}
|
|
5931
6098
|
async function handleNew(p, _pages, ctx) {
|
|
5932
6099
|
const newPage = await ctx.browserContext.newPage();
|
|
@@ -5954,7 +6121,7 @@ async function handleNew(p, _pages, ctx) {
|
|
|
5954
6121
|
const title = await newPage.title().catch(() => "");
|
|
5955
6122
|
const allPages = ctx.browserContext.pages();
|
|
5956
6123
|
const newIndex = allPages.indexOf(newPage);
|
|
5957
|
-
return
|
|
6124
|
+
return ok27({
|
|
5958
6125
|
index: newIndex >= 0 ? newIndex : allPages.length - 1,
|
|
5959
6126
|
url: newPage.url(),
|
|
5960
6127
|
title,
|
|
@@ -5965,11 +6132,11 @@ async function handleNew(p, _pages, ctx) {
|
|
|
5965
6132
|
async function handleClose(p, ctx) {
|
|
5966
6133
|
const currentPages = ctx.browserContext.pages();
|
|
5967
6134
|
if (currentPages.length <= 1) {
|
|
5968
|
-
return
|
|
6135
|
+
return fail13("Cannot close the last remaining tab");
|
|
5969
6136
|
}
|
|
5970
6137
|
const closeIndex = p.index ?? currentPages.findIndex((pg) => pg === ctx.page);
|
|
5971
6138
|
if (closeIndex < 0 || closeIndex >= currentPages.length) {
|
|
5972
|
-
return
|
|
6139
|
+
return fail13(`Invalid tab index: ${closeIndex}. Valid range: 0-${currentPages.length - 1}`);
|
|
5973
6140
|
}
|
|
5974
6141
|
const pageToClose = currentPages[closeIndex];
|
|
5975
6142
|
const isActivePage = pageToClose === ctx.page;
|
|
@@ -5984,7 +6151,7 @@ async function handleClose(p, ctx) {
|
|
|
5984
6151
|
}
|
|
5985
6152
|
ctx.page = newActivePage;
|
|
5986
6153
|
}
|
|
5987
|
-
return
|
|
6154
|
+
return ok27({
|
|
5988
6155
|
closedIndex: closeIndex,
|
|
5989
6156
|
total: remainingPages.length,
|
|
5990
6157
|
activeIndex: isActivePage ? closeIndex < remainingPages.length ? closeIndex : remainingPages.length - 1 : remainingPages.findIndex((pg) => pg === ctx.page)
|
|
@@ -5992,10 +6159,10 @@ async function handleClose(p, ctx) {
|
|
|
5992
6159
|
}
|
|
5993
6160
|
async function handleSwitch(p, pages, ctx) {
|
|
5994
6161
|
if (p.index === void 0) {
|
|
5995
|
-
return
|
|
6162
|
+
return fail13("Parameter --index is required for switch subcommand");
|
|
5996
6163
|
}
|
|
5997
6164
|
if (p.index < 0 || p.index >= pages.length) {
|
|
5998
|
-
return
|
|
6165
|
+
return fail13(`Invalid tab index: ${p.index}. Valid range: 0-${pages.length - 1}`);
|
|
5999
6166
|
}
|
|
6000
6167
|
const targetPage = pages[p.index];
|
|
6001
6168
|
await targetPage.bringToFront().catch(() => {
|
|
@@ -6017,7 +6184,7 @@ async function handleSwitch(p, pages, ctx) {
|
|
|
6017
6184
|
}
|
|
6018
6185
|
ctx.page = targetPage;
|
|
6019
6186
|
const title = await targetPage.title().catch(() => "");
|
|
6020
|
-
return
|
|
6187
|
+
return ok27({
|
|
6021
6188
|
index: p.index,
|
|
6022
6189
|
url: targetPage.url(),
|
|
6023
6190
|
title,
|
|
@@ -6026,8 +6193,8 @@ async function handleSwitch(p, pages, ctx) {
|
|
|
6026
6193
|
}
|
|
6027
6194
|
|
|
6028
6195
|
// src/commands/addinitscript.ts
|
|
6029
|
-
import { z as
|
|
6030
|
-
import { ok as
|
|
6196
|
+
import { z as z29 } from "zod";
|
|
6197
|
+
import { ok as ok28 } from "@dyyz1993/xcli-core";
|
|
6031
6198
|
import { readFileSync as readFileSync4 } from "fs";
|
|
6032
6199
|
|
|
6033
6200
|
// src/chain-parser.ts
|
|
@@ -6168,14 +6335,14 @@ registerCommandDefinition("tab", ["subcommand"]);
|
|
|
6168
6335
|
registerCommandDefinition("mouse", ["action", "x", "y"]);
|
|
6169
6336
|
|
|
6170
6337
|
// src/commands/addinitscript.ts
|
|
6171
|
-
var InitScriptParams =
|
|
6172
|
-
script:
|
|
6173
|
-
file:
|
|
6174
|
-
stdin:
|
|
6175
|
-
name:
|
|
6176
|
-
list:
|
|
6177
|
-
remove:
|
|
6178
|
-
base64:
|
|
6338
|
+
var InitScriptParams = z29.object({
|
|
6339
|
+
script: z29.string().optional(),
|
|
6340
|
+
file: z29.string().optional(),
|
|
6341
|
+
stdin: z29.boolean().optional(),
|
|
6342
|
+
name: z29.string().optional(),
|
|
6343
|
+
list: z29.boolean().optional(),
|
|
6344
|
+
remove: z29.union([z29.string(), z29.boolean()]).optional(),
|
|
6345
|
+
base64: z29.string().optional()
|
|
6179
6346
|
});
|
|
6180
6347
|
var registeredScripts = /* @__PURE__ */ new Map();
|
|
6181
6348
|
function resolveScriptContent(params) {
|
|
@@ -6209,14 +6376,14 @@ var addInitScriptCommand = registerCommand({
|
|
|
6209
6376
|
description: "Add an initialization script that runs on every page load",
|
|
6210
6377
|
scope: "page",
|
|
6211
6378
|
parameters: InitScriptParams,
|
|
6212
|
-
result:
|
|
6213
|
-
scripts:
|
|
6214
|
-
removed:
|
|
6215
|
-
existed:
|
|
6216
|
-
error:
|
|
6217
|
-
registered:
|
|
6218
|
-
hint:
|
|
6219
|
-
executedImmediately:
|
|
6379
|
+
result: z29.object({
|
|
6380
|
+
scripts: z29.array(z29.object({ name: z29.string(), size: z29.number(), preview: z29.string() })).optional(),
|
|
6381
|
+
removed: z29.string().optional(),
|
|
6382
|
+
existed: z29.boolean().optional(),
|
|
6383
|
+
error: z29.string().optional(),
|
|
6384
|
+
registered: z29.string().optional(),
|
|
6385
|
+
hint: z29.string().optional(),
|
|
6386
|
+
executedImmediately: z29.boolean().optional()
|
|
6220
6387
|
}).passthrough(),
|
|
6221
6388
|
handler: async (params, ctx) => {
|
|
6222
6389
|
if (params.list) {
|
|
@@ -6225,20 +6392,20 @@ var addInitScriptCommand = registerCommand({
|
|
|
6225
6392
|
size: content2.length,
|
|
6226
6393
|
preview: content2.slice(0, 80)
|
|
6227
6394
|
}));
|
|
6228
|
-
return
|
|
6395
|
+
return ok28({ scripts });
|
|
6229
6396
|
}
|
|
6230
6397
|
if (params.remove && typeof params.remove === "string") {
|
|
6231
6398
|
const existed = registeredScripts.delete(params.remove);
|
|
6232
|
-
return
|
|
6399
|
+
return ok28({ removed: params.remove, existed });
|
|
6233
6400
|
}
|
|
6234
6401
|
const removeTarget = (typeof params.remove === "string" ? params.remove : null) || (params.name && !resolveScriptContent(params) ? params.name : null);
|
|
6235
6402
|
if (removeTarget && !resolveScriptContent(params)) {
|
|
6236
6403
|
const existed = registeredScripts.delete(removeTarget);
|
|
6237
|
-
return
|
|
6404
|
+
return ok28({ removed: removeTarget, existed });
|
|
6238
6405
|
}
|
|
6239
6406
|
let content = params.stdin ? await readStdin() : resolveScriptContent(params);
|
|
6240
6407
|
if (!content) {
|
|
6241
|
-
return
|
|
6408
|
+
return ok28({ error: "No script content provided. Use --script, --file, --stdin, or --base64" });
|
|
6242
6409
|
}
|
|
6243
6410
|
const scriptName = params.name ?? `script-${Date.now()}`;
|
|
6244
6411
|
registeredScripts.set(scriptName, content);
|
|
@@ -6246,45 +6413,45 @@ var addInitScriptCommand = registerCommand({
|
|
|
6246
6413
|
try {
|
|
6247
6414
|
await ctx.page.evaluate(content);
|
|
6248
6415
|
} catch {
|
|
6249
|
-
return
|
|
6416
|
+
return ok28({
|
|
6250
6417
|
registered: scriptName,
|
|
6251
6418
|
hint: "Script registered for future page loads; immediate execution skipped (page may not be ready)"
|
|
6252
6419
|
});
|
|
6253
6420
|
}
|
|
6254
|
-
return
|
|
6421
|
+
return ok28({ registered: scriptName, executedImmediately: true });
|
|
6255
6422
|
}
|
|
6256
6423
|
});
|
|
6257
6424
|
registerCommandDefinition("addinitscript", ["script"]);
|
|
6258
6425
|
|
|
6259
6426
|
// src/commands/find.ts
|
|
6260
|
-
import { z as
|
|
6261
|
-
import { ok as
|
|
6262
|
-
var actionSchema2 =
|
|
6427
|
+
import { z as z30 } from "zod";
|
|
6428
|
+
import { ok as ok29, fail as fail14, normalizeTips as normalizeTips6 } from "@dyyz1993/xcli-core";
|
|
6429
|
+
var actionSchema2 = z30.enum(["click", "fill", "type", "select", "hover", "check"]);
|
|
6263
6430
|
var findCommand = registerCommand({
|
|
6264
6431
|
name: "find",
|
|
6265
6432
|
description: "Find elements by semantic strategy (text/role/label/placeholder/testid) and optionally perform an action",
|
|
6266
6433
|
scope: "page",
|
|
6267
|
-
parameters:
|
|
6268
|
-
strategy:
|
|
6269
|
-
value:
|
|
6270
|
-
name:
|
|
6271
|
-
exact:
|
|
6272
|
-
operation:
|
|
6434
|
+
parameters: z30.object({
|
|
6435
|
+
strategy: z30.enum(["text", "role", "label", "placeholder", "testid", "alt", "title", "first", "last", "nth"]),
|
|
6436
|
+
value: z30.string(),
|
|
6437
|
+
name: z30.string().optional(),
|
|
6438
|
+
exact: z30.boolean().optional().default(false),
|
|
6439
|
+
operation: z30.string().optional().describe('Trailing operation syntax, e.g. click, fill "text", type "text"'),
|
|
6273
6440
|
action: actionSchema2.optional().describe("Action to perform when not using trailing operation syntax"),
|
|
6274
|
-
actionValue:
|
|
6275
|
-
index:
|
|
6276
|
-
click:
|
|
6277
|
-
fill:
|
|
6278
|
-
type:
|
|
6279
|
-
select:
|
|
6280
|
-
hover:
|
|
6281
|
-
check:
|
|
6282
|
-
timeout:
|
|
6441
|
+
actionValue: z30.string().optional().describe("Value for fill/type/select when using action"),
|
|
6442
|
+
index: z30.number().int().optional().describe("Index for nth strategy"),
|
|
6443
|
+
click: z30.boolean().optional().default(false),
|
|
6444
|
+
fill: z30.string().optional(),
|
|
6445
|
+
type: z30.string().optional(),
|
|
6446
|
+
select: z30.string().optional(),
|
|
6447
|
+
hover: z30.boolean().optional().default(false),
|
|
6448
|
+
check: z30.boolean().optional().default(false),
|
|
6449
|
+
timeout: z30.number().optional().default(1e4)
|
|
6283
6450
|
}),
|
|
6284
|
-
result:
|
|
6285
|
-
matched:
|
|
6286
|
-
selector:
|
|
6287
|
-
action:
|
|
6451
|
+
result: z30.object({
|
|
6452
|
+
matched: z30.number(),
|
|
6453
|
+
selector: z30.string(),
|
|
6454
|
+
action: z30.string().optional()
|
|
6288
6455
|
}),
|
|
6289
6456
|
handler: async (p, ctx) => {
|
|
6290
6457
|
const page = ctx.page;
|
|
@@ -6299,7 +6466,7 @@ var findCommand = registerCommand({
|
|
|
6299
6466
|
});
|
|
6300
6467
|
const count = await locator.count();
|
|
6301
6468
|
if (count === 0) {
|
|
6302
|
-
return
|
|
6469
|
+
return fail14(`No element found with ${p.strategy}="${p.value}"`);
|
|
6303
6470
|
}
|
|
6304
6471
|
const tips = [];
|
|
6305
6472
|
const target = selectTarget(locator, p.strategy);
|
|
@@ -6311,15 +6478,15 @@ var findCommand = registerCommand({
|
|
|
6311
6478
|
await target.click({ timeout: p.timeout, force: true });
|
|
6312
6479
|
return okWithTips({ matched: count, selector, action: "click" }, tips);
|
|
6313
6480
|
} else if (actionName === "fill") {
|
|
6314
|
-
if (actionValue === void 0) return
|
|
6481
|
+
if (actionValue === void 0) return fail14("find fill requires a value");
|
|
6315
6482
|
await target.fill(actionValue, { timeout: p.timeout, force: true });
|
|
6316
6483
|
return okWithTips({ matched: count, selector, action: `fill("${actionValue}")` }, tips);
|
|
6317
6484
|
} else if (actionName === "type") {
|
|
6318
|
-
if (actionValue === void 0) return
|
|
6485
|
+
if (actionValue === void 0) return fail14("find type requires a value");
|
|
6319
6486
|
await target.type(actionValue, { delay: 10, timeout: p.timeout });
|
|
6320
6487
|
return okWithTips({ matched: count, selector, action: `type("${actionValue}")` }, tips);
|
|
6321
6488
|
} else if (actionName === "select") {
|
|
6322
|
-
if (actionValue === void 0) return
|
|
6489
|
+
if (actionValue === void 0) return fail14("find select requires a value");
|
|
6323
6490
|
await target.selectOption(actionValue);
|
|
6324
6491
|
return okWithTips({ matched: count, selector, action: `select("${actionValue}")` }, tips);
|
|
6325
6492
|
} else if (actionName === "hover") {
|
|
@@ -6333,8 +6500,8 @@ var findCommand = registerCommand({
|
|
|
6333
6500
|
}
|
|
6334
6501
|
});
|
|
6335
6502
|
function okWithTips(data, tips) {
|
|
6336
|
-
const result =
|
|
6337
|
-
if (tips.length > 0) result.tips =
|
|
6503
|
+
const result = ok29(data);
|
|
6504
|
+
if (tips.length > 0) result.tips = normalizeTips6(tips);
|
|
6338
6505
|
return result;
|
|
6339
6506
|
}
|
|
6340
6507
|
function parseOperation(operation) {
|
|
@@ -6432,8 +6599,8 @@ function describeSelector(strategy, value, name) {
|
|
|
6432
6599
|
}
|
|
6433
6600
|
|
|
6434
6601
|
// src/commands/visual-tag.ts
|
|
6435
|
-
import { z as
|
|
6436
|
-
import { ok as
|
|
6602
|
+
import { z as z31 } from "zod";
|
|
6603
|
+
import { ok as ok30, fail as fail15 } from "@dyyz1993/xcli-core";
|
|
6437
6604
|
var SAFE_SET = "ahjkmnprtw3479".split("");
|
|
6438
6605
|
var TAG_SCRIPT = `
|
|
6439
6606
|
(function() {
|
|
@@ -6524,49 +6691,49 @@ var visualTagCommand = registerCommand({
|
|
|
6524
6691
|
name: "visual-tag",
|
|
6525
6692
|
description: "\u5728\u9875\u9762\u4E0A\u7ED9\u53EF\u4EA4\u4E92\u5143\u7D20\u53E0\u52A0\u9632\u6DF7\u6DC6\u77ED ID \u6807\u7B7E\uFF08\u89C6\u89C9\u5B9A\u4F4D\u7528\uFF09",
|
|
6526
6693
|
scope: "page",
|
|
6527
|
-
parameters:
|
|
6528
|
-
action:
|
|
6529
|
-
id:
|
|
6694
|
+
parameters: z31.object({
|
|
6695
|
+
action: z31.enum(["tag", "lookup", "clear", "list"]),
|
|
6696
|
+
id: z31.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID")
|
|
6530
6697
|
}),
|
|
6531
|
-
result:
|
|
6532
|
-
action:
|
|
6533
|
-
tagged:
|
|
6534
|
-
id:
|
|
6535
|
-
element:
|
|
6698
|
+
result: z31.object({
|
|
6699
|
+
action: z31.string(),
|
|
6700
|
+
tagged: z31.number().optional(),
|
|
6701
|
+
id: z31.string().optional(),
|
|
6702
|
+
element: z31.record(z31.unknown()).optional()
|
|
6536
6703
|
}),
|
|
6537
6704
|
handler: async (p, ctx) => {
|
|
6538
6705
|
switch (p.action) {
|
|
6539
6706
|
case "tag": {
|
|
6540
6707
|
const result = await ctx.page.evaluate(TAG_SCRIPT);
|
|
6541
6708
|
const parsed = JSON.parse(result);
|
|
6542
|
-
return
|
|
6709
|
+
return ok30({ action: "tag", tagged: parsed.tagged });
|
|
6543
6710
|
}
|
|
6544
6711
|
case "lookup": {
|
|
6545
|
-
if (!p.id) return
|
|
6712
|
+
if (!p.id) return fail15("lookup \u9700\u8981 --id \u53C2\u6570");
|
|
6546
6713
|
const result = await ctx.page.evaluate(
|
|
6547
6714
|
`(function() { var m = window.__xbTagMap; if (!m) return JSON.stringify({err:'no-map'}); var e = m[${JSON.stringify(p.id)}]; return e ? JSON.stringify(e) : JSON.stringify({err:'not-found'}); })()`
|
|
6548
6715
|
);
|
|
6549
6716
|
const parsed = JSON.parse(result);
|
|
6550
|
-
if (parsed.err) return
|
|
6551
|
-
return
|
|
6717
|
+
if (parsed.err) return fail15(`ID ${p.id}: ${parsed.err}`);
|
|
6718
|
+
return ok30({ action: "lookup", id: p.id, element: parsed });
|
|
6552
6719
|
}
|
|
6553
6720
|
case "list": {
|
|
6554
6721
|
const result = await ctx.page.evaluate(
|
|
6555
6722
|
`(function() { var m = window.__xbTagMap; if (!m) return '{}'; var out = {}; for (var k in m) { out[k] = m[k].text || m[k].tagName; } return JSON.stringify(out); })()`
|
|
6556
6723
|
);
|
|
6557
|
-
return
|
|
6724
|
+
return ok30({ action: "list", element: JSON.parse(result) });
|
|
6558
6725
|
}
|
|
6559
6726
|
case "clear": {
|
|
6560
6727
|
await ctx.page.evaluate(`(function(){var o=document.getElementById('__xb-tag-overlay');if(o)o.remove();window.__xbTagMap=null;return 'cleared'})()`);
|
|
6561
|
-
return
|
|
6728
|
+
return ok30({ action: "clear" });
|
|
6562
6729
|
}
|
|
6563
6730
|
}
|
|
6564
6731
|
}
|
|
6565
6732
|
});
|
|
6566
6733
|
|
|
6567
6734
|
// src/commands/visual-tag-v2.ts
|
|
6568
|
-
import { z as
|
|
6569
|
-
import { ok as
|
|
6735
|
+
import { z as z32 } from "zod";
|
|
6736
|
+
import { ok as ok31, fail as fail16 } from "@dyyz1993/xcli-core";
|
|
6570
6737
|
var SAFE_SET2 = "ahjkmnprtw3479".split("");
|
|
6571
6738
|
var TAG_V2_SCRIPT = `
|
|
6572
6739
|
(function() {
|
|
@@ -6913,45 +7080,45 @@ var visualTagV2Command = registerCommand({
|
|
|
6913
7080
|
name: "visual-tag-v2",
|
|
6914
7081
|
description: "\u5206\u8272\u6807\u6CE8\u9875\u9762\u5143\u7D20\uFF08\u7EA2=\u53EF\u70B9\u51FB \u84DD=\u8F93\u5165 \u7EFF=\u56FE\u7247 \u9EC4=\u5217\u8868 \u7D2B=\u6570\u5B57 \u6A59=\u6587\u672C\uFF09",
|
|
6915
7082
|
scope: "page",
|
|
6916
|
-
parameters:
|
|
6917
|
-
action:
|
|
6918
|
-
id:
|
|
6919
|
-
query:
|
|
6920
|
-
type:
|
|
6921
|
-
"interact-action":
|
|
6922
|
-
value:
|
|
7083
|
+
parameters: z32.object({
|
|
7084
|
+
action: z32.enum(["tag", "lookup", "clear", "stats", "by-type", "find", "export", "interact"]),
|
|
7085
|
+
id: z32.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID"),
|
|
7086
|
+
query: z32.string().optional().describe('find \u65F6\u6307\u5B9A\u641C\u7D22\u8BCD\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09'),
|
|
7087
|
+
type: z32.string().optional().describe("by-type \u65F6\u8FC7\u6EE4\u7C7B\u578B\uFF1Aclick/input/img/list/count/text"),
|
|
7088
|
+
"interact-action": z32.enum(["click", "fill", "read"]).optional().describe("interact \u52A8\u4F5C\u7C7B\u578B"),
|
|
7089
|
+
value: z32.string().optional().describe("fill \u65F6\u7684\u586B\u5145\u503C")
|
|
6923
7090
|
}),
|
|
6924
|
-
result:
|
|
6925
|
-
action:
|
|
6926
|
-
total:
|
|
6927
|
-
byType:
|
|
6928
|
-
element:
|
|
7091
|
+
result: z32.object({
|
|
7092
|
+
action: z32.string(),
|
|
7093
|
+
total: z32.number().optional(),
|
|
7094
|
+
byType: z32.record(z32.number()).optional(),
|
|
7095
|
+
element: z32.record(z32.unknown()).optional()
|
|
6929
7096
|
}),
|
|
6930
7097
|
handler: async (p, ctx) => {
|
|
6931
7098
|
switch (p.action) {
|
|
6932
7099
|
case "tag": {
|
|
6933
7100
|
const result = await ctx.page.evaluate(TAG_V2_SCRIPT);
|
|
6934
7101
|
const parsed = JSON.parse(result);
|
|
6935
|
-
return
|
|
7102
|
+
return ok31({ action: "tag", total: parsed.total, byType: parsed.byType });
|
|
6936
7103
|
}
|
|
6937
7104
|
case "lookup": {
|
|
6938
|
-
if (!p.id) return
|
|
7105
|
+
if (!p.id) return fail16("lookup \u9700\u8981 --id");
|
|
6939
7106
|
const result = await ctx.page.evaluate(
|
|
6940
7107
|
`(function(){var m=window.__xbTagMap;if(!m)return JSON.stringify({err:'no-map'});var e=m[${JSON.stringify(p.id)}];return e?JSON.stringify(e):JSON.stringify({err:'not-found'})})()`
|
|
6941
7108
|
);
|
|
6942
7109
|
const parsed = JSON.parse(result);
|
|
6943
|
-
if (parsed.err) return
|
|
6944
|
-
return
|
|
7110
|
+
if (parsed.err) return fail16(`ID ${p.id}: ${parsed.err}`);
|
|
7111
|
+
return ok31({ action: "lookup", id: p.id, element: parsed });
|
|
6945
7112
|
}
|
|
6946
7113
|
case "by-type": {
|
|
6947
7114
|
const result = await ctx.page.evaluate(
|
|
6948
7115
|
`(function(){var m=window.__xbTagMap;if(!m)return'{}';var out={};for(var k in m){if(!${JSON.stringify(p.type || "")}||m[k].type===${JSON.stringify(p.type || "")}){out[k]={type:m[k].type,text:m[k].text,num:m[k].num,label:m[k].formLabel}}}return JSON.stringify(out)})()`
|
|
6949
7116
|
);
|
|
6950
|
-
return
|
|
7117
|
+
return ok31({ action: "by-type", element: JSON.parse(result) });
|
|
6951
7118
|
}
|
|
6952
7119
|
case "find": {
|
|
6953
7120
|
const query = p.query;
|
|
6954
|
-
if (!query) return
|
|
7121
|
+
if (!query) return fail16('find \u9700\u8981 --query \u53C2\u6570\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09');
|
|
6955
7122
|
const result = await ctx.page.evaluate(
|
|
6956
7123
|
`(function(){
|
|
6957
7124
|
var map = window.__xbTagSerializable;
|
|
@@ -6993,21 +7160,21 @@ var visualTagV2Command = registerCommand({
|
|
|
6993
7160
|
return JSON.stringify({total:results.length, results:results.slice(0,20)});
|
|
6994
7161
|
})()`
|
|
6995
7162
|
);
|
|
6996
|
-
return
|
|
7163
|
+
return ok31({ action: "find", query, element: JSON.parse(result) });
|
|
6997
7164
|
}
|
|
6998
7165
|
case "stats": {
|
|
6999
7166
|
const result = await ctx.page.evaluate(
|
|
7000
7167
|
`(function(){return JSON.stringify(window.__xbTagStats||{})})()`
|
|
7001
7168
|
);
|
|
7002
|
-
return
|
|
7169
|
+
return ok31({ action: "stats", element: JSON.parse(result) });
|
|
7003
7170
|
}
|
|
7004
7171
|
case "interact": {
|
|
7005
7172
|
const query = p.query;
|
|
7006
7173
|
const pAny = p;
|
|
7007
7174
|
const action = pAny["interact-action"] || pAny.interactAction || pAny.interact_action;
|
|
7008
7175
|
const value = pAny.value;
|
|
7009
|
-
if (!query) return
|
|
7010
|
-
if (!action) return
|
|
7176
|
+
if (!query) return fail16("interact \u9700\u8981 --query \u53C2\u6570");
|
|
7177
|
+
if (!action) return fail16("interact \u9700\u8981 --interact-action \u53C2\u6570\uFF08click/fill/read\uFF09");
|
|
7011
7178
|
const findResult = await ctx.page.evaluate(
|
|
7012
7179
|
`(function(){
|
|
7013
7180
|
var map = window.__xbTagSerializable;
|
|
@@ -7037,11 +7204,11 @@ var visualTagV2Command = registerCommand({
|
|
|
7037
7204
|
})()`
|
|
7038
7205
|
);
|
|
7039
7206
|
const parsed = JSON.parse(findResult);
|
|
7040
|
-
if (parsed.err) return
|
|
7041
|
-
if (!parsed.total || !parsed.results?.length) return
|
|
7207
|
+
if (parsed.err) return fail16(parsed.err);
|
|
7208
|
+
if (!parsed.total || !parsed.results?.length) return fail16(`\u672A\u627E\u5230\u5339\u914D "${query}" \u7684\u5143\u7D20`);
|
|
7042
7209
|
const target = parsed.results[0];
|
|
7043
7210
|
if (action === "read") {
|
|
7044
|
-
return
|
|
7211
|
+
return ok31({ action: "interact", query, target, result: { read: target.text || target.label } });
|
|
7045
7212
|
}
|
|
7046
7213
|
if (action === "click") {
|
|
7047
7214
|
const el = await ctx.page.evaluate(
|
|
@@ -7054,12 +7221,12 @@ var visualTagV2Command = registerCommand({
|
|
|
7054
7221
|
return {x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2)};
|
|
7055
7222
|
})()`
|
|
7056
7223
|
);
|
|
7057
|
-
if (!el) return
|
|
7224
|
+
if (!el) return fail16(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
|
|
7058
7225
|
await ctx.page.mouse.click(el.x, el.y, { stealth: true });
|
|
7059
|
-
return
|
|
7226
|
+
return ok31({ action: "interact", query, target, result: { clicked: true, x: el.x, y: el.y } });
|
|
7060
7227
|
}
|
|
7061
7228
|
if (action === "fill") {
|
|
7062
|
-
if (!value) return
|
|
7229
|
+
if (!value) return fail16("fill \u9700\u8981 --value \u53C2\u6570");
|
|
7063
7230
|
const el = await ctx.page.evaluate(
|
|
7064
7231
|
`(function(){
|
|
7065
7232
|
var map = window.__xbTagMap;
|
|
@@ -7070,12 +7237,12 @@ var visualTagV2Command = registerCommand({
|
|
|
7070
7237
|
return {x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2)};
|
|
7071
7238
|
})()`
|
|
7072
7239
|
);
|
|
7073
|
-
if (!el) return
|
|
7240
|
+
if (!el) return fail16(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
|
|
7074
7241
|
await ctx.page.mouse.click(el.x, el.y, { stealth: true });
|
|
7075
7242
|
await ctx.page.keyboard.type(value, { stealth: true });
|
|
7076
|
-
return
|
|
7243
|
+
return ok31({ action: "interact", query, target, result: { filled: true, value } });
|
|
7077
7244
|
}
|
|
7078
|
-
return
|
|
7245
|
+
return fail16(`\u672A\u77E5 action: ${action}`);
|
|
7079
7246
|
}
|
|
7080
7247
|
case "export": {
|
|
7081
7248
|
const result = await ctx.page.evaluate(
|
|
@@ -7123,12 +7290,12 @@ var visualTagV2Command = registerCommand({
|
|
|
7123
7290
|
})()`
|
|
7124
7291
|
);
|
|
7125
7292
|
const parsed = JSON.parse(result);
|
|
7126
|
-
if (parsed.err) return
|
|
7127
|
-
return
|
|
7293
|
+
if (parsed.err) return fail16(String(parsed.err));
|
|
7294
|
+
return ok31({ action: "export", element: parsed });
|
|
7128
7295
|
}
|
|
7129
7296
|
case "clear": {
|
|
7130
7297
|
await ctx.page.evaluate(`(function(){var o=document.getElementById('__xb-tag-overlay');if(o)o.remove();window.__xbTagMap=null;window.__xbTagStats=null;return 'ok'})()`);
|
|
7131
|
-
return
|
|
7298
|
+
return ok31({ action: "clear" });
|
|
7132
7299
|
}
|
|
7133
7300
|
}
|
|
7134
7301
|
}
|
|
@@ -7803,7 +7970,7 @@ async function guardCheck(commandName) {
|
|
|
7803
7970
|
}
|
|
7804
7971
|
}
|
|
7805
7972
|
function errorResult(message) {
|
|
7806
|
-
return { ...
|
|
7973
|
+
return { ...fail17(message), duration: 0 };
|
|
7807
7974
|
}
|
|
7808
7975
|
function tipsToMessages(tips) {
|
|
7809
7976
|
if (!tips || tips.length === 0) return [];
|
|
@@ -7992,7 +8159,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7992
8159
|
const cache = /* @__PURE__ */ new Map();
|
|
7993
8160
|
const resolved = await resolveRefParams(session.page, params, command.selectorParams, cache, session.id);
|
|
7994
8161
|
if (resolved.tips.length > 0) {
|
|
7995
|
-
refTips =
|
|
8162
|
+
refTips = normalizeTips7(resolved.tips);
|
|
7996
8163
|
params = resolved.params;
|
|
7997
8164
|
}
|
|
7998
8165
|
}
|
|
@@ -8060,8 +8227,8 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
8060
8227
|
}
|
|
8061
8228
|
const merged = [
|
|
8062
8229
|
...raw.tips || [],
|
|
8063
|
-
...
|
|
8064
|
-
...snapshotHint ?
|
|
8230
|
+
...normalizeTips7(smartTips),
|
|
8231
|
+
...snapshotHint ? normalizeTips7([snapshotHint]) : [],
|
|
8065
8232
|
...refTips
|
|
8066
8233
|
];
|
|
8067
8234
|
const isSuccess = raw.success !== false;
|
|
@@ -8076,7 +8243,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
8076
8243
|
timestamp: start
|
|
8077
8244
|
});
|
|
8078
8245
|
if (isSuccess) {
|
|
8079
|
-
return { ...
|
|
8246
|
+
return { ...ok32(raw.data, merged.length > 0 ? merged : raw.tips), duration, ...hookOutputs ? { hookOutputs } : {} };
|
|
8080
8247
|
}
|
|
8081
8248
|
const fc = classifyFailure(raw.message);
|
|
8082
8249
|
return {
|
|
@@ -8089,7 +8256,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
8089
8256
|
...hookOutputs ? { hookOutputs } : {}
|
|
8090
8257
|
};
|
|
8091
8258
|
}
|
|
8092
|
-
const smartTipNormalized =
|
|
8259
|
+
const smartTipNormalized = normalizeTips7(smartTips);
|
|
8093
8260
|
recordArchive(session?.id, sessionName, {
|
|
8094
8261
|
step: 0,
|
|
8095
8262
|
command: commandName,
|
|
@@ -8099,7 +8266,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
8099
8266
|
duration,
|
|
8100
8267
|
timestamp: start
|
|
8101
8268
|
});
|
|
8102
|
-
return { ...
|
|
8269
|
+
return { ...ok32(raw, smartTipNormalized), duration, ...hookOutputs ? { hookOutputs } : {} };
|
|
8103
8270
|
} catch (err) {
|
|
8104
8271
|
const end = Date.now();
|
|
8105
8272
|
const duration = end - start;
|
|
@@ -8144,7 +8311,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
8144
8311
|
duration,
|
|
8145
8312
|
timestamp: start
|
|
8146
8313
|
});
|
|
8147
|
-
return { ...
|
|
8314
|
+
return { ...fail17(errorMessage), duration };
|
|
8148
8315
|
} finally {
|
|
8149
8316
|
}
|
|
8150
8317
|
}
|
|
@@ -8189,7 +8356,7 @@ async function executeChain(input, options) {
|
|
|
8189
8356
|
results.push({
|
|
8190
8357
|
command: cmdName,
|
|
8191
8358
|
raw: cmdStr,
|
|
8192
|
-
...
|
|
8359
|
+
...fail17(`Plugin "${cmdName}" requires a sub-command`),
|
|
8193
8360
|
duration: 0
|
|
8194
8361
|
});
|
|
8195
8362
|
if (type === "and") {
|
|
@@ -8208,7 +8375,7 @@ async function executeChain(input, options) {
|
|
|
8208
8375
|
results.push({
|
|
8209
8376
|
command: cmdName,
|
|
8210
8377
|
raw: cmdStr,
|
|
8211
|
-
...
|
|
8378
|
+
...fail17(`Unknown command "${subCommand}" for plugin "${cmdName}"`),
|
|
8212
8379
|
duration: 0
|
|
8213
8380
|
});
|
|
8214
8381
|
if (type === "and") {
|
|
@@ -8278,7 +8445,7 @@ async function executeChain(input, options) {
|
|
|
8278
8445
|
success: false,
|
|
8279
8446
|
data: data2,
|
|
8280
8447
|
message: loginGuard.message,
|
|
8281
|
-
tips:
|
|
8448
|
+
tips: normalizeTips7(loginGuard.tips),
|
|
8282
8449
|
duration: duration3
|
|
8283
8450
|
});
|
|
8284
8451
|
if (type === "and") {
|
|
@@ -8320,7 +8487,7 @@ async function executeChain(input, options) {
|
|
|
8320
8487
|
results.push({
|
|
8321
8488
|
command: `${cmdName} ${subCommand}`,
|
|
8322
8489
|
raw: cmdStr,
|
|
8323
|
-
...
|
|
8490
|
+
...ok32(data),
|
|
8324
8491
|
duration: duration2,
|
|
8325
8492
|
...hookOutputs ? { hookOutputs } : {}
|
|
8326
8493
|
});
|
|
@@ -8348,7 +8515,7 @@ async function executeChain(input, options) {
|
|
|
8348
8515
|
results.push({
|
|
8349
8516
|
command: `${cmdName} ${subCommand}`,
|
|
8350
8517
|
raw: cmdStr,
|
|
8351
|
-
...
|
|
8518
|
+
...fail17(errorMessage),
|
|
8352
8519
|
duration: duration2
|
|
8353
8520
|
});
|
|
8354
8521
|
if (type === "and") {
|
|
@@ -9772,10 +9939,10 @@ function createRPCHandler() {
|
|
|
9772
9939
|
const errors = Array.isArray(input.errors) ? input.errors : [];
|
|
9773
9940
|
const eventsPlayed = typeof input.eventsPlayed === "number" ? input.eventsPlayed : 0;
|
|
9774
9941
|
const totalEvents = typeof input.totalEvents === "number" ? input.totalEvents : eventsPlayed + errors.length;
|
|
9775
|
-
const
|
|
9942
|
+
const ok33 = input.ok ?? errors.length === 0;
|
|
9776
9943
|
return {
|
|
9777
|
-
ok:
|
|
9778
|
-
success:
|
|
9944
|
+
ok: ok33,
|
|
9945
|
+
success: ok33,
|
|
9779
9946
|
duration: typeof input.duration === "number" ? input.duration : 0,
|
|
9780
9947
|
eventsPlayed,
|
|
9781
9948
|
totalEvents,
|