@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
|
@@ -63,12 +63,12 @@ function classifyFailure(message) {
|
|
|
63
63
|
|
|
64
64
|
// src/executor.ts
|
|
65
65
|
import {
|
|
66
|
-
ok as
|
|
67
|
-
fail as
|
|
66
|
+
ok as ok32,
|
|
67
|
+
fail as fail17,
|
|
68
68
|
isCommandResult,
|
|
69
69
|
CompositeStorage as CompositeStorage2,
|
|
70
70
|
TipCollector as TipCollector2,
|
|
71
|
-
normalizeTips as
|
|
71
|
+
normalizeTips as normalizeTips7,
|
|
72
72
|
configureArchiveStore,
|
|
73
73
|
appendCommandToArchive,
|
|
74
74
|
checkGuard,
|
|
@@ -5859,26 +5859,193 @@ var waitForCommand = registerCommand({
|
|
|
5859
5859
|
}
|
|
5860
5860
|
});
|
|
5861
5861
|
|
|
5862
|
-
// src/commands/
|
|
5862
|
+
// src/commands/task.ts
|
|
5863
5863
|
import { z as z27 } from "zod";
|
|
5864
|
-
import { ok as ok26, fail as fail12 } from "@dyyz1993/xcli-core";
|
|
5865
|
-
var
|
|
5866
|
-
|
|
5867
|
-
|
|
5868
|
-
|
|
5864
|
+
import { ok as ok26, fail as fail12, normalizeTips as normalizeTips5 } from "@dyyz1993/xcli-core";
|
|
5865
|
+
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
|
|
5866
|
+
|
|
5867
|
+
\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
|
|
5868
|
+
{"action":"click","ref":"@eN","thought":"\u4E3A\u4EC0\u4E48"}
|
|
5869
|
+
{"action":"fill","ref":"@eN","value":"\u6587\u672C","thought":"\u4E3A\u4EC0\u4E48"}
|
|
5870
|
+
{"action":"select","ref":"@eN","value":"\u9009\u9879\u503C","thought":"\u4E3A\u4EC0\u4E48"}
|
|
5871
|
+
{"action":"press","value":"Enter","thought":"\u4E3A\u4EC0\u4E48"}
|
|
5872
|
+
{"action":"scroll","value":"down \u6216 up","thought":"\u4E3A\u4EC0\u4E48"}
|
|
5873
|
+
{"action":"done","value":"\u5B8C\u6210\u6458\u8981","thought":"\u4E3A\u4EC0\u4E48"}
|
|
5874
|
+
{"action":"blocked","value":"\u5361\u4F4F\u539F\u56E0","thought":"\u4E3A\u4EC0\u4E48"}
|
|
5875
|
+
|
|
5876
|
+
\u89C4\u5219\uFF1A
|
|
5877
|
+
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
|
|
5878
|
+
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
|
|
5879
|
+
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`;
|
|
5880
|
+
function extractDecision(raw) {
|
|
5881
|
+
let s = raw.trim().replace(/^```(?:json)?\s*/i, "").replace(/\s*```$/, "");
|
|
5882
|
+
const start = s.indexOf("{");
|
|
5883
|
+
if (start < 0) return null;
|
|
5884
|
+
let depth = 0;
|
|
5885
|
+
for (let i = start; i < s.length; i++) {
|
|
5886
|
+
if (s[i] === "{") depth++;
|
|
5887
|
+
else if (s[i] === "}") {
|
|
5888
|
+
depth--;
|
|
5889
|
+
if (depth === 0) {
|
|
5890
|
+
try {
|
|
5891
|
+
return JSON.parse(s.slice(start, i + 1));
|
|
5892
|
+
} catch {
|
|
5893
|
+
return null;
|
|
5894
|
+
}
|
|
5895
|
+
}
|
|
5896
|
+
}
|
|
5897
|
+
}
|
|
5898
|
+
return null;
|
|
5899
|
+
}
|
|
5900
|
+
var taskCommand = registerCommand({
|
|
5901
|
+
name: "task",
|
|
5902
|
+
description: "Autonomous goal loop: observe refs \u2192 LLM decides \u2192 act, until done/blocked (budget-capped)",
|
|
5903
|
+
scope: "page",
|
|
5904
|
+
parameters: z27.object({
|
|
5905
|
+
goal: z27.string().describe("Natural-language goal"),
|
|
5906
|
+
maxSteps: z27.number().int().positive().max(50).optional().default(15).describe("Hard action budget"),
|
|
5907
|
+
timeout: z27.number().optional().default(18e4).describe("Wall clock budget in ms"),
|
|
5908
|
+
limit: z27.number().int().positive().max(300).optional().default(80).describe("Max targets per observe")
|
|
5909
|
+
}),
|
|
5910
|
+
result: z27.object({
|
|
5911
|
+
status: z27.enum(["done", "blocked", "max_steps", "error"]),
|
|
5912
|
+
summary: z27.string().optional(),
|
|
5913
|
+
steps: z27.array(z27.record(z27.unknown())),
|
|
5914
|
+
finalUrl: z27.string().optional(),
|
|
5915
|
+
usage: z27.object({ llmCalls: z27.number(), steps: z27.number() }).passthrough().optional()
|
|
5916
|
+
}).passthrough(),
|
|
5917
|
+
handler: async (p, ctx) => {
|
|
5918
|
+
const creds = loadVLMCredentials2();
|
|
5919
|
+
if (!creds) {
|
|
5920
|
+
return fail12("task \u9700\u8981\u51B3\u7B56\u6A21\u578B\u51ED\u8BC1\uFF1A\u8BBE\u7F6E XBROWSER_VLM_CONFIG \u6216 ~/.zcode/v2/config.json");
|
|
5921
|
+
}
|
|
5922
|
+
const model = process.env.XBROWSER_TASK_MODEL || creds.model;
|
|
5923
|
+
const started = Date.now();
|
|
5924
|
+
const steps = [];
|
|
5925
|
+
const history = [];
|
|
5926
|
+
let llmCalls = 0;
|
|
5927
|
+
let status = "max_steps";
|
|
5928
|
+
let summary = "";
|
|
5929
|
+
let lastError = "";
|
|
5930
|
+
for (let step = 1; step <= p.maxSteps; step++) {
|
|
5931
|
+
if (Date.now() - started > p.timeout) {
|
|
5932
|
+
status = "blocked";
|
|
5933
|
+
summary = `timeout after ${step - 1} steps`;
|
|
5934
|
+
break;
|
|
5935
|
+
}
|
|
5936
|
+
const obs = await observePage(ctx.page, ctx.sessionId, { limit: p.limit, includeHidden: false });
|
|
5937
|
+
const compact = obs.compact ?? obs.targets.map((t, i) => `@e${i + 1} [${t.tag ?? ""}] ${t.name ?? ""}`).join("\n");
|
|
5938
|
+
const screenHash = obs.screenHash;
|
|
5939
|
+
const userPayload = [
|
|
5940
|
+
`\u76EE\u6807\uFF1A${p.goal}`,
|
|
5941
|
+
`\u5F53\u524D\u9875\u9762\uFF08URL: ${obs.url ?? ""}\uFF09\uFF1A`,
|
|
5942
|
+
compact,
|
|
5943
|
+
history.length ? `
|
|
5944
|
+
\u5DF2\u6267\u884C\uFF08\u52FF\u91CD\u590D\u5931\u8D25\u52A8\u4F5C\uFF09\uFF1A
|
|
5945
|
+
${history.slice(-6).join("\n")}` : ""
|
|
5946
|
+
].filter(Boolean).join("\n");
|
|
5947
|
+
let raw = "";
|
|
5948
|
+
try {
|
|
5949
|
+
raw = await vlmAsk({ ...creds, model }, [{ type: "text", text: `${DECISION_SYSTEM}
|
|
5950
|
+
|
|
5951
|
+
---
|
|
5952
|
+
|
|
5953
|
+
${userPayload}` }], 900);
|
|
5954
|
+
llmCalls++;
|
|
5955
|
+
} catch (e) {
|
|
5956
|
+
lastError = e instanceof Error ? e.message : String(e);
|
|
5957
|
+
status = "error";
|
|
5958
|
+
summary = `LLM call failed: ${lastError}`;
|
|
5959
|
+
break;
|
|
5960
|
+
}
|
|
5961
|
+
const decision = extractDecision(raw);
|
|
5962
|
+
if (!decision || typeof decision.action !== "string") {
|
|
5963
|
+
status = "blocked";
|
|
5964
|
+
summary = `LLM returned unparsable decision: ${raw.slice(0, 120)}`;
|
|
5965
|
+
break;
|
|
5966
|
+
}
|
|
5967
|
+
const action = decision.action;
|
|
5968
|
+
const ref = typeof decision.ref === "string" ? decision.ref : void 0;
|
|
5969
|
+
const value = typeof decision.value === "string" ? decision.value : void 0;
|
|
5970
|
+
const thought = typeof decision.thought === "string" ? decision.thought : void 0;
|
|
5971
|
+
if (action === "done") {
|
|
5972
|
+
status = "done";
|
|
5973
|
+
summary = value || thought || "task done";
|
|
5974
|
+
steps.push({ step, thought, action: "done", ok: true, screenHash });
|
|
5975
|
+
break;
|
|
5976
|
+
}
|
|
5977
|
+
if (action === "blocked") {
|
|
5978
|
+
status = "blocked";
|
|
5979
|
+
summary = value || thought || "LLM judged blocked";
|
|
5980
|
+
steps.push({ step, thought, action: "blocked", ok: true, screenHash });
|
|
5981
|
+
break;
|
|
5982
|
+
}
|
|
5983
|
+
const legalRefs = new Set(obs.targets.map((t, i) => t.ref ?? `e${i + 1}`));
|
|
5984
|
+
const normalizedRef = ref ? legalRefs.has(ref.replace("@", "")) || legalRefs.has(ref) ? ref : void 0 : void 0;
|
|
5985
|
+
if (ref && !normalizedRef && action !== "scroll" && action !== "press") {
|
|
5986
|
+
history.push(`step${step}: ${action} ${ref} REJECTED (ref not in current list)`);
|
|
5987
|
+
steps.push({ step, thought, action, ref, ok: false, error: "ref not in current list", screenHash });
|
|
5988
|
+
continue;
|
|
5989
|
+
}
|
|
5990
|
+
const res = await actOnPage(ctx.page, ctx.sessionId, {
|
|
5991
|
+
action,
|
|
5992
|
+
ref: normalizedRef,
|
|
5993
|
+
value,
|
|
5994
|
+
selector: void 0,
|
|
5995
|
+
force: false,
|
|
5996
|
+
timeout: 1e4
|
|
5997
|
+
});
|
|
5998
|
+
const record = {
|
|
5999
|
+
step,
|
|
6000
|
+
thought,
|
|
6001
|
+
action,
|
|
6002
|
+
ref: normalizedRef,
|
|
6003
|
+
value,
|
|
6004
|
+
ok: res.success === true,
|
|
6005
|
+
stale: res.stale,
|
|
6006
|
+
error: res.success ? void 0 : res.message || res.reason,
|
|
6007
|
+
screenHash
|
|
6008
|
+
};
|
|
6009
|
+
steps.push(record);
|
|
6010
|
+
history.push(`step${step}: ${action} ${normalizedRef ?? ""} ${value ?? ""} -> ${res.success ? "ok" : `failed(${res.reason || res.message})`}`);
|
|
6011
|
+
const sig = (s) => `${s.action}|${s.ref ?? ""}|${s.value ?? ""}`;
|
|
6012
|
+
const last3 = steps.slice(-3);
|
|
6013
|
+
if (last3.length === 3 && new Set(last3.map(sig)).size === 1) {
|
|
6014
|
+
status = "blocked";
|
|
6015
|
+
summary = "dead loop: identical action repeated 3 times";
|
|
6016
|
+
break;
|
|
6017
|
+
}
|
|
6018
|
+
}
|
|
6019
|
+
if (status === "max_steps") summary = summary || `hit maxSteps=${p.maxSteps}`;
|
|
6020
|
+
const finalUrl = ctx.page ? ctx.page.url() : void 0;
|
|
6021
|
+
const data = { status, summary, steps, finalUrl, usage: { llmCalls, steps: steps.length } };
|
|
6022
|
+
if (status === "error") return fail12(summary || lastError, normalizeTips5([`completed steps: ${steps.length}`]));
|
|
6023
|
+
return ok26(data, normalizeTips5([
|
|
6024
|
+
status === "done" ? `\u2705 task done (${steps.length} steps, ${llmCalls} LLM calls)` : `\u26A0\uFE0F task ${status}: ${summary.slice(0, 80)}`
|
|
6025
|
+
]));
|
|
6026
|
+
}
|
|
6027
|
+
});
|
|
6028
|
+
|
|
6029
|
+
// src/commands/tab.ts
|
|
6030
|
+
import { z as z28 } from "zod";
|
|
6031
|
+
import { ok as ok27, fail as fail13 } from "@dyyz1993/xcli-core";
|
|
6032
|
+
var TabParams = z28.object({
|
|
6033
|
+
subcommand: z28.enum(["list", "new", "close", "switch"]),
|
|
6034
|
+
url: z28.string().optional(),
|
|
6035
|
+
index: z28.number().int().min(0).optional()
|
|
5869
6036
|
});
|
|
5870
6037
|
var tabCommand = registerCommand({
|
|
5871
6038
|
name: "tab",
|
|
5872
6039
|
description: "Manage browser tabs: list, new, close, switch",
|
|
5873
6040
|
scope: "page",
|
|
5874
6041
|
parameters: TabParams,
|
|
5875
|
-
result:
|
|
5876
|
-
success:
|
|
5877
|
-
data:
|
|
6042
|
+
result: z28.object({
|
|
6043
|
+
success: z28.boolean(),
|
|
6044
|
+
data: z28.unknown()
|
|
5878
6045
|
}),
|
|
5879
6046
|
handler: async (p, ctx) => {
|
|
5880
6047
|
if (!ctx.browserContext) {
|
|
5881
|
-
return
|
|
6048
|
+
return fail13("No browser context available. Use --cdp to connect to a browser first.");
|
|
5882
6049
|
}
|
|
5883
6050
|
const pages = ctx.browserContext.pages();
|
|
5884
6051
|
switch (p.subcommand) {
|
|
@@ -5891,7 +6058,7 @@ var tabCommand = registerCommand({
|
|
|
5891
6058
|
case "switch":
|
|
5892
6059
|
return handleSwitch(p, pages, ctx);
|
|
5893
6060
|
default:
|
|
5894
|
-
return
|
|
6061
|
+
return fail13(`Unknown subcommand: ${p.subcommand}`);
|
|
5895
6062
|
}
|
|
5896
6063
|
}
|
|
5897
6064
|
});
|
|
@@ -5906,7 +6073,7 @@ async function handleList(pages, ctx) {
|
|
|
5906
6073
|
if (isActive) activeIndex = i;
|
|
5907
6074
|
tabs.push({ index: i, url, title, active: isActive });
|
|
5908
6075
|
}
|
|
5909
|
-
return
|
|
6076
|
+
return ok27({ tabs, total: tabs.length, activeIndex });
|
|
5910
6077
|
}
|
|
5911
6078
|
async function handleNew(p, _pages, ctx) {
|
|
5912
6079
|
const newPage = await ctx.browserContext.newPage();
|
|
@@ -5934,7 +6101,7 @@ async function handleNew(p, _pages, ctx) {
|
|
|
5934
6101
|
const title = await newPage.title().catch(() => "");
|
|
5935
6102
|
const allPages = ctx.browserContext.pages();
|
|
5936
6103
|
const newIndex = allPages.indexOf(newPage);
|
|
5937
|
-
return
|
|
6104
|
+
return ok27({
|
|
5938
6105
|
index: newIndex >= 0 ? newIndex : allPages.length - 1,
|
|
5939
6106
|
url: newPage.url(),
|
|
5940
6107
|
title,
|
|
@@ -5945,11 +6112,11 @@ async function handleNew(p, _pages, ctx) {
|
|
|
5945
6112
|
async function handleClose(p, ctx) {
|
|
5946
6113
|
const currentPages = ctx.browserContext.pages();
|
|
5947
6114
|
if (currentPages.length <= 1) {
|
|
5948
|
-
return
|
|
6115
|
+
return fail13("Cannot close the last remaining tab");
|
|
5949
6116
|
}
|
|
5950
6117
|
const closeIndex = p.index ?? currentPages.findIndex((pg) => pg === ctx.page);
|
|
5951
6118
|
if (closeIndex < 0 || closeIndex >= currentPages.length) {
|
|
5952
|
-
return
|
|
6119
|
+
return fail13(`Invalid tab index: ${closeIndex}. Valid range: 0-${currentPages.length - 1}`);
|
|
5953
6120
|
}
|
|
5954
6121
|
const pageToClose = currentPages[closeIndex];
|
|
5955
6122
|
const isActivePage = pageToClose === ctx.page;
|
|
@@ -5964,7 +6131,7 @@ async function handleClose(p, ctx) {
|
|
|
5964
6131
|
}
|
|
5965
6132
|
ctx.page = newActivePage;
|
|
5966
6133
|
}
|
|
5967
|
-
return
|
|
6134
|
+
return ok27({
|
|
5968
6135
|
closedIndex: closeIndex,
|
|
5969
6136
|
total: remainingPages.length,
|
|
5970
6137
|
activeIndex: isActivePage ? closeIndex < remainingPages.length ? closeIndex : remainingPages.length - 1 : remainingPages.findIndex((pg) => pg === ctx.page)
|
|
@@ -5972,10 +6139,10 @@ async function handleClose(p, ctx) {
|
|
|
5972
6139
|
}
|
|
5973
6140
|
async function handleSwitch(p, pages, ctx) {
|
|
5974
6141
|
if (p.index === void 0) {
|
|
5975
|
-
return
|
|
6142
|
+
return fail13("Parameter --index is required for switch subcommand");
|
|
5976
6143
|
}
|
|
5977
6144
|
if (p.index < 0 || p.index >= pages.length) {
|
|
5978
|
-
return
|
|
6145
|
+
return fail13(`Invalid tab index: ${p.index}. Valid range: 0-${pages.length - 1}`);
|
|
5979
6146
|
}
|
|
5980
6147
|
const targetPage = pages[p.index];
|
|
5981
6148
|
await targetPage.bringToFront().catch(() => {
|
|
@@ -5997,7 +6164,7 @@ async function handleSwitch(p, pages, ctx) {
|
|
|
5997
6164
|
}
|
|
5998
6165
|
ctx.page = targetPage;
|
|
5999
6166
|
const title = await targetPage.title().catch(() => "");
|
|
6000
|
-
return
|
|
6167
|
+
return ok27({
|
|
6001
6168
|
index: p.index,
|
|
6002
6169
|
url: targetPage.url(),
|
|
6003
6170
|
title,
|
|
@@ -6006,8 +6173,8 @@ async function handleSwitch(p, pages, ctx) {
|
|
|
6006
6173
|
}
|
|
6007
6174
|
|
|
6008
6175
|
// src/commands/addinitscript.ts
|
|
6009
|
-
import { z as
|
|
6010
|
-
import { ok as
|
|
6176
|
+
import { z as z29 } from "zod";
|
|
6177
|
+
import { ok as ok28 } from "@dyyz1993/xcli-core";
|
|
6011
6178
|
import { readFileSync as readFileSync4 } from "fs";
|
|
6012
6179
|
|
|
6013
6180
|
// src/chain-parser.ts
|
|
@@ -6148,14 +6315,14 @@ registerCommandDefinition("tab", ["subcommand"]);
|
|
|
6148
6315
|
registerCommandDefinition("mouse", ["action", "x", "y"]);
|
|
6149
6316
|
|
|
6150
6317
|
// src/commands/addinitscript.ts
|
|
6151
|
-
var InitScriptParams =
|
|
6152
|
-
script:
|
|
6153
|
-
file:
|
|
6154
|
-
stdin:
|
|
6155
|
-
name:
|
|
6156
|
-
list:
|
|
6157
|
-
remove:
|
|
6158
|
-
base64:
|
|
6318
|
+
var InitScriptParams = z29.object({
|
|
6319
|
+
script: z29.string().optional(),
|
|
6320
|
+
file: z29.string().optional(),
|
|
6321
|
+
stdin: z29.boolean().optional(),
|
|
6322
|
+
name: z29.string().optional(),
|
|
6323
|
+
list: z29.boolean().optional(),
|
|
6324
|
+
remove: z29.union([z29.string(), z29.boolean()]).optional(),
|
|
6325
|
+
base64: z29.string().optional()
|
|
6159
6326
|
});
|
|
6160
6327
|
var registeredScripts = /* @__PURE__ */ new Map();
|
|
6161
6328
|
function resolveScriptContent(params) {
|
|
@@ -6189,14 +6356,14 @@ var addInitScriptCommand = registerCommand({
|
|
|
6189
6356
|
description: "Add an initialization script that runs on every page load",
|
|
6190
6357
|
scope: "page",
|
|
6191
6358
|
parameters: InitScriptParams,
|
|
6192
|
-
result:
|
|
6193
|
-
scripts:
|
|
6194
|
-
removed:
|
|
6195
|
-
existed:
|
|
6196
|
-
error:
|
|
6197
|
-
registered:
|
|
6198
|
-
hint:
|
|
6199
|
-
executedImmediately:
|
|
6359
|
+
result: z29.object({
|
|
6360
|
+
scripts: z29.array(z29.object({ name: z29.string(), size: z29.number(), preview: z29.string() })).optional(),
|
|
6361
|
+
removed: z29.string().optional(),
|
|
6362
|
+
existed: z29.boolean().optional(),
|
|
6363
|
+
error: z29.string().optional(),
|
|
6364
|
+
registered: z29.string().optional(),
|
|
6365
|
+
hint: z29.string().optional(),
|
|
6366
|
+
executedImmediately: z29.boolean().optional()
|
|
6200
6367
|
}).passthrough(),
|
|
6201
6368
|
handler: async (params, ctx) => {
|
|
6202
6369
|
if (params.list) {
|
|
@@ -6205,20 +6372,20 @@ var addInitScriptCommand = registerCommand({
|
|
|
6205
6372
|
size: content2.length,
|
|
6206
6373
|
preview: content2.slice(0, 80)
|
|
6207
6374
|
}));
|
|
6208
|
-
return
|
|
6375
|
+
return ok28({ scripts });
|
|
6209
6376
|
}
|
|
6210
6377
|
if (params.remove && typeof params.remove === "string") {
|
|
6211
6378
|
const existed = registeredScripts.delete(params.remove);
|
|
6212
|
-
return
|
|
6379
|
+
return ok28({ removed: params.remove, existed });
|
|
6213
6380
|
}
|
|
6214
6381
|
const removeTarget = (typeof params.remove === "string" ? params.remove : null) || (params.name && !resolveScriptContent(params) ? params.name : null);
|
|
6215
6382
|
if (removeTarget && !resolveScriptContent(params)) {
|
|
6216
6383
|
const existed = registeredScripts.delete(removeTarget);
|
|
6217
|
-
return
|
|
6384
|
+
return ok28({ removed: removeTarget, existed });
|
|
6218
6385
|
}
|
|
6219
6386
|
let content = params.stdin ? await readStdin() : resolveScriptContent(params);
|
|
6220
6387
|
if (!content) {
|
|
6221
|
-
return
|
|
6388
|
+
return ok28({ error: "No script content provided. Use --script, --file, --stdin, or --base64" });
|
|
6222
6389
|
}
|
|
6223
6390
|
const scriptName = params.name ?? `script-${Date.now()}`;
|
|
6224
6391
|
registeredScripts.set(scriptName, content);
|
|
@@ -6226,45 +6393,45 @@ var addInitScriptCommand = registerCommand({
|
|
|
6226
6393
|
try {
|
|
6227
6394
|
await ctx.page.evaluate(content);
|
|
6228
6395
|
} catch {
|
|
6229
|
-
return
|
|
6396
|
+
return ok28({
|
|
6230
6397
|
registered: scriptName,
|
|
6231
6398
|
hint: "Script registered for future page loads; immediate execution skipped (page may not be ready)"
|
|
6232
6399
|
});
|
|
6233
6400
|
}
|
|
6234
|
-
return
|
|
6401
|
+
return ok28({ registered: scriptName, executedImmediately: true });
|
|
6235
6402
|
}
|
|
6236
6403
|
});
|
|
6237
6404
|
registerCommandDefinition("addinitscript", ["script"]);
|
|
6238
6405
|
|
|
6239
6406
|
// src/commands/find.ts
|
|
6240
|
-
import { z as
|
|
6241
|
-
import { ok as
|
|
6242
|
-
var actionSchema2 =
|
|
6407
|
+
import { z as z30 } from "zod";
|
|
6408
|
+
import { ok as ok29, fail as fail14, normalizeTips as normalizeTips6 } from "@dyyz1993/xcli-core";
|
|
6409
|
+
var actionSchema2 = z30.enum(["click", "fill", "type", "select", "hover", "check"]);
|
|
6243
6410
|
var findCommand = registerCommand({
|
|
6244
6411
|
name: "find",
|
|
6245
6412
|
description: "Find elements by semantic strategy (text/role/label/placeholder/testid) and optionally perform an action",
|
|
6246
6413
|
scope: "page",
|
|
6247
|
-
parameters:
|
|
6248
|
-
strategy:
|
|
6249
|
-
value:
|
|
6250
|
-
name:
|
|
6251
|
-
exact:
|
|
6252
|
-
operation:
|
|
6414
|
+
parameters: z30.object({
|
|
6415
|
+
strategy: z30.enum(["text", "role", "label", "placeholder", "testid", "alt", "title", "first", "last", "nth"]),
|
|
6416
|
+
value: z30.string(),
|
|
6417
|
+
name: z30.string().optional(),
|
|
6418
|
+
exact: z30.boolean().optional().default(false),
|
|
6419
|
+
operation: z30.string().optional().describe('Trailing operation syntax, e.g. click, fill "text", type "text"'),
|
|
6253
6420
|
action: actionSchema2.optional().describe("Action to perform when not using trailing operation syntax"),
|
|
6254
|
-
actionValue:
|
|
6255
|
-
index:
|
|
6256
|
-
click:
|
|
6257
|
-
fill:
|
|
6258
|
-
type:
|
|
6259
|
-
select:
|
|
6260
|
-
hover:
|
|
6261
|
-
check:
|
|
6262
|
-
timeout:
|
|
6421
|
+
actionValue: z30.string().optional().describe("Value for fill/type/select when using action"),
|
|
6422
|
+
index: z30.number().int().optional().describe("Index for nth strategy"),
|
|
6423
|
+
click: z30.boolean().optional().default(false),
|
|
6424
|
+
fill: z30.string().optional(),
|
|
6425
|
+
type: z30.string().optional(),
|
|
6426
|
+
select: z30.string().optional(),
|
|
6427
|
+
hover: z30.boolean().optional().default(false),
|
|
6428
|
+
check: z30.boolean().optional().default(false),
|
|
6429
|
+
timeout: z30.number().optional().default(1e4)
|
|
6263
6430
|
}),
|
|
6264
|
-
result:
|
|
6265
|
-
matched:
|
|
6266
|
-
selector:
|
|
6267
|
-
action:
|
|
6431
|
+
result: z30.object({
|
|
6432
|
+
matched: z30.number(),
|
|
6433
|
+
selector: z30.string(),
|
|
6434
|
+
action: z30.string().optional()
|
|
6268
6435
|
}),
|
|
6269
6436
|
handler: async (p, ctx) => {
|
|
6270
6437
|
const page = ctx.page;
|
|
@@ -6279,7 +6446,7 @@ var findCommand = registerCommand({
|
|
|
6279
6446
|
});
|
|
6280
6447
|
const count = await locator.count();
|
|
6281
6448
|
if (count === 0) {
|
|
6282
|
-
return
|
|
6449
|
+
return fail14(`No element found with ${p.strategy}="${p.value}"`);
|
|
6283
6450
|
}
|
|
6284
6451
|
const tips = [];
|
|
6285
6452
|
const target = selectTarget(locator, p.strategy);
|
|
@@ -6291,15 +6458,15 @@ var findCommand = registerCommand({
|
|
|
6291
6458
|
await target.click({ timeout: p.timeout, force: true });
|
|
6292
6459
|
return okWithTips({ matched: count, selector, action: "click" }, tips);
|
|
6293
6460
|
} else if (actionName === "fill") {
|
|
6294
|
-
if (actionValue === void 0) return
|
|
6461
|
+
if (actionValue === void 0) return fail14("find fill requires a value");
|
|
6295
6462
|
await target.fill(actionValue, { timeout: p.timeout, force: true });
|
|
6296
6463
|
return okWithTips({ matched: count, selector, action: `fill("${actionValue}")` }, tips);
|
|
6297
6464
|
} else if (actionName === "type") {
|
|
6298
|
-
if (actionValue === void 0) return
|
|
6465
|
+
if (actionValue === void 0) return fail14("find type requires a value");
|
|
6299
6466
|
await target.type(actionValue, { delay: 10, timeout: p.timeout });
|
|
6300
6467
|
return okWithTips({ matched: count, selector, action: `type("${actionValue}")` }, tips);
|
|
6301
6468
|
} else if (actionName === "select") {
|
|
6302
|
-
if (actionValue === void 0) return
|
|
6469
|
+
if (actionValue === void 0) return fail14("find select requires a value");
|
|
6303
6470
|
await target.selectOption(actionValue);
|
|
6304
6471
|
return okWithTips({ matched: count, selector, action: `select("${actionValue}")` }, tips);
|
|
6305
6472
|
} else if (actionName === "hover") {
|
|
@@ -6313,8 +6480,8 @@ var findCommand = registerCommand({
|
|
|
6313
6480
|
}
|
|
6314
6481
|
});
|
|
6315
6482
|
function okWithTips(data, tips) {
|
|
6316
|
-
const result =
|
|
6317
|
-
if (tips.length > 0) result.tips =
|
|
6483
|
+
const result = ok29(data);
|
|
6484
|
+
if (tips.length > 0) result.tips = normalizeTips6(tips);
|
|
6318
6485
|
return result;
|
|
6319
6486
|
}
|
|
6320
6487
|
function parseOperation(operation) {
|
|
@@ -6412,8 +6579,8 @@ function describeSelector(strategy, value, name) {
|
|
|
6412
6579
|
}
|
|
6413
6580
|
|
|
6414
6581
|
// src/commands/visual-tag.ts
|
|
6415
|
-
import { z as
|
|
6416
|
-
import { ok as
|
|
6582
|
+
import { z as z31 } from "zod";
|
|
6583
|
+
import { ok as ok30, fail as fail15 } from "@dyyz1993/xcli-core";
|
|
6417
6584
|
var SAFE_SET = "ahjkmnprtw3479".split("");
|
|
6418
6585
|
var TAG_SCRIPT = `
|
|
6419
6586
|
(function() {
|
|
@@ -6504,49 +6671,49 @@ var visualTagCommand = registerCommand({
|
|
|
6504
6671
|
name: "visual-tag",
|
|
6505
6672
|
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",
|
|
6506
6673
|
scope: "page",
|
|
6507
|
-
parameters:
|
|
6508
|
-
action:
|
|
6509
|
-
id:
|
|
6674
|
+
parameters: z31.object({
|
|
6675
|
+
action: z31.enum(["tag", "lookup", "clear", "list"]),
|
|
6676
|
+
id: z31.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID")
|
|
6510
6677
|
}),
|
|
6511
|
-
result:
|
|
6512
|
-
action:
|
|
6513
|
-
tagged:
|
|
6514
|
-
id:
|
|
6515
|
-
element:
|
|
6678
|
+
result: z31.object({
|
|
6679
|
+
action: z31.string(),
|
|
6680
|
+
tagged: z31.number().optional(),
|
|
6681
|
+
id: z31.string().optional(),
|
|
6682
|
+
element: z31.record(z31.unknown()).optional()
|
|
6516
6683
|
}),
|
|
6517
6684
|
handler: async (p, ctx) => {
|
|
6518
6685
|
switch (p.action) {
|
|
6519
6686
|
case "tag": {
|
|
6520
6687
|
const result = await ctx.page.evaluate(TAG_SCRIPT);
|
|
6521
6688
|
const parsed = JSON.parse(result);
|
|
6522
|
-
return
|
|
6689
|
+
return ok30({ action: "tag", tagged: parsed.tagged });
|
|
6523
6690
|
}
|
|
6524
6691
|
case "lookup": {
|
|
6525
|
-
if (!p.id) return
|
|
6692
|
+
if (!p.id) return fail15("lookup \u9700\u8981 --id \u53C2\u6570");
|
|
6526
6693
|
const result = await ctx.page.evaluate(
|
|
6527
6694
|
`(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'}); })()`
|
|
6528
6695
|
);
|
|
6529
6696
|
const parsed = JSON.parse(result);
|
|
6530
|
-
if (parsed.err) return
|
|
6531
|
-
return
|
|
6697
|
+
if (parsed.err) return fail15(`ID ${p.id}: ${parsed.err}`);
|
|
6698
|
+
return ok30({ action: "lookup", id: p.id, element: parsed });
|
|
6532
6699
|
}
|
|
6533
6700
|
case "list": {
|
|
6534
6701
|
const result = await ctx.page.evaluate(
|
|
6535
6702
|
`(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); })()`
|
|
6536
6703
|
);
|
|
6537
|
-
return
|
|
6704
|
+
return ok30({ action: "list", element: JSON.parse(result) });
|
|
6538
6705
|
}
|
|
6539
6706
|
case "clear": {
|
|
6540
6707
|
await ctx.page.evaluate(`(function(){var o=document.getElementById('__xb-tag-overlay');if(o)o.remove();window.__xbTagMap=null;return 'cleared'})()`);
|
|
6541
|
-
return
|
|
6708
|
+
return ok30({ action: "clear" });
|
|
6542
6709
|
}
|
|
6543
6710
|
}
|
|
6544
6711
|
}
|
|
6545
6712
|
});
|
|
6546
6713
|
|
|
6547
6714
|
// src/commands/visual-tag-v2.ts
|
|
6548
|
-
import { z as
|
|
6549
|
-
import { ok as
|
|
6715
|
+
import { z as z32 } from "zod";
|
|
6716
|
+
import { ok as ok31, fail as fail16 } from "@dyyz1993/xcli-core";
|
|
6550
6717
|
var SAFE_SET2 = "ahjkmnprtw3479".split("");
|
|
6551
6718
|
var TAG_V2_SCRIPT = `
|
|
6552
6719
|
(function() {
|
|
@@ -6893,45 +7060,45 @@ var visualTagV2Command = registerCommand({
|
|
|
6893
7060
|
name: "visual-tag-v2",
|
|
6894
7061
|
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",
|
|
6895
7062
|
scope: "page",
|
|
6896
|
-
parameters:
|
|
6897
|
-
action:
|
|
6898
|
-
id:
|
|
6899
|
-
query:
|
|
6900
|
-
type:
|
|
6901
|
-
"interact-action":
|
|
6902
|
-
value:
|
|
7063
|
+
parameters: z32.object({
|
|
7064
|
+
action: z32.enum(["tag", "lookup", "clear", "stats", "by-type", "find", "export", "interact"]),
|
|
7065
|
+
id: z32.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID"),
|
|
7066
|
+
query: z32.string().optional().describe('find \u65F6\u6307\u5B9A\u641C\u7D22\u8BCD\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09'),
|
|
7067
|
+
type: z32.string().optional().describe("by-type \u65F6\u8FC7\u6EE4\u7C7B\u578B\uFF1Aclick/input/img/list/count/text"),
|
|
7068
|
+
"interact-action": z32.enum(["click", "fill", "read"]).optional().describe("interact \u52A8\u4F5C\u7C7B\u578B"),
|
|
7069
|
+
value: z32.string().optional().describe("fill \u65F6\u7684\u586B\u5145\u503C")
|
|
6903
7070
|
}),
|
|
6904
|
-
result:
|
|
6905
|
-
action:
|
|
6906
|
-
total:
|
|
6907
|
-
byType:
|
|
6908
|
-
element:
|
|
7071
|
+
result: z32.object({
|
|
7072
|
+
action: z32.string(),
|
|
7073
|
+
total: z32.number().optional(),
|
|
7074
|
+
byType: z32.record(z32.number()).optional(),
|
|
7075
|
+
element: z32.record(z32.unknown()).optional()
|
|
6909
7076
|
}),
|
|
6910
7077
|
handler: async (p, ctx) => {
|
|
6911
7078
|
switch (p.action) {
|
|
6912
7079
|
case "tag": {
|
|
6913
7080
|
const result = await ctx.page.evaluate(TAG_V2_SCRIPT);
|
|
6914
7081
|
const parsed = JSON.parse(result);
|
|
6915
|
-
return
|
|
7082
|
+
return ok31({ action: "tag", total: parsed.total, byType: parsed.byType });
|
|
6916
7083
|
}
|
|
6917
7084
|
case "lookup": {
|
|
6918
|
-
if (!p.id) return
|
|
7085
|
+
if (!p.id) return fail16("lookup \u9700\u8981 --id");
|
|
6919
7086
|
const result = await ctx.page.evaluate(
|
|
6920
7087
|
`(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'})})()`
|
|
6921
7088
|
);
|
|
6922
7089
|
const parsed = JSON.parse(result);
|
|
6923
|
-
if (parsed.err) return
|
|
6924
|
-
return
|
|
7090
|
+
if (parsed.err) return fail16(`ID ${p.id}: ${parsed.err}`);
|
|
7091
|
+
return ok31({ action: "lookup", id: p.id, element: parsed });
|
|
6925
7092
|
}
|
|
6926
7093
|
case "by-type": {
|
|
6927
7094
|
const result = await ctx.page.evaluate(
|
|
6928
7095
|
`(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)})()`
|
|
6929
7096
|
);
|
|
6930
|
-
return
|
|
7097
|
+
return ok31({ action: "by-type", element: JSON.parse(result) });
|
|
6931
7098
|
}
|
|
6932
7099
|
case "find": {
|
|
6933
7100
|
const query = p.query;
|
|
6934
|
-
if (!query) return
|
|
7101
|
+
if (!query) return fail16('find \u9700\u8981 --query \u53C2\u6570\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09');
|
|
6935
7102
|
const result = await ctx.page.evaluate(
|
|
6936
7103
|
`(function(){
|
|
6937
7104
|
var map = window.__xbTagSerializable;
|
|
@@ -6973,21 +7140,21 @@ var visualTagV2Command = registerCommand({
|
|
|
6973
7140
|
return JSON.stringify({total:results.length, results:results.slice(0,20)});
|
|
6974
7141
|
})()`
|
|
6975
7142
|
);
|
|
6976
|
-
return
|
|
7143
|
+
return ok31({ action: "find", query, element: JSON.parse(result) });
|
|
6977
7144
|
}
|
|
6978
7145
|
case "stats": {
|
|
6979
7146
|
const result = await ctx.page.evaluate(
|
|
6980
7147
|
`(function(){return JSON.stringify(window.__xbTagStats||{})})()`
|
|
6981
7148
|
);
|
|
6982
|
-
return
|
|
7149
|
+
return ok31({ action: "stats", element: JSON.parse(result) });
|
|
6983
7150
|
}
|
|
6984
7151
|
case "interact": {
|
|
6985
7152
|
const query = p.query;
|
|
6986
7153
|
const pAny = p;
|
|
6987
7154
|
const action = pAny["interact-action"] || pAny.interactAction || pAny.interact_action;
|
|
6988
7155
|
const value = pAny.value;
|
|
6989
|
-
if (!query) return
|
|
6990
|
-
if (!action) return
|
|
7156
|
+
if (!query) return fail16("interact \u9700\u8981 --query \u53C2\u6570");
|
|
7157
|
+
if (!action) return fail16("interact \u9700\u8981 --interact-action \u53C2\u6570\uFF08click/fill/read\uFF09");
|
|
6991
7158
|
const findResult = await ctx.page.evaluate(
|
|
6992
7159
|
`(function(){
|
|
6993
7160
|
var map = window.__xbTagSerializable;
|
|
@@ -7017,11 +7184,11 @@ var visualTagV2Command = registerCommand({
|
|
|
7017
7184
|
})()`
|
|
7018
7185
|
);
|
|
7019
7186
|
const parsed = JSON.parse(findResult);
|
|
7020
|
-
if (parsed.err) return
|
|
7021
|
-
if (!parsed.total || !parsed.results?.length) return
|
|
7187
|
+
if (parsed.err) return fail16(parsed.err);
|
|
7188
|
+
if (!parsed.total || !parsed.results?.length) return fail16(`\u672A\u627E\u5230\u5339\u914D "${query}" \u7684\u5143\u7D20`);
|
|
7022
7189
|
const target = parsed.results[0];
|
|
7023
7190
|
if (action === "read") {
|
|
7024
|
-
return
|
|
7191
|
+
return ok31({ action: "interact", query, target, result: { read: target.text || target.label } });
|
|
7025
7192
|
}
|
|
7026
7193
|
if (action === "click") {
|
|
7027
7194
|
const el = await ctx.page.evaluate(
|
|
@@ -7034,12 +7201,12 @@ var visualTagV2Command = registerCommand({
|
|
|
7034
7201
|
return {x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2)};
|
|
7035
7202
|
})()`
|
|
7036
7203
|
);
|
|
7037
|
-
if (!el) return
|
|
7204
|
+
if (!el) return fail16(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
|
|
7038
7205
|
await ctx.page.mouse.click(el.x, el.y, { stealth: true });
|
|
7039
|
-
return
|
|
7206
|
+
return ok31({ action: "interact", query, target, result: { clicked: true, x: el.x, y: el.y } });
|
|
7040
7207
|
}
|
|
7041
7208
|
if (action === "fill") {
|
|
7042
|
-
if (!value) return
|
|
7209
|
+
if (!value) return fail16("fill \u9700\u8981 --value \u53C2\u6570");
|
|
7043
7210
|
const el = await ctx.page.evaluate(
|
|
7044
7211
|
`(function(){
|
|
7045
7212
|
var map = window.__xbTagMap;
|
|
@@ -7050,12 +7217,12 @@ var visualTagV2Command = registerCommand({
|
|
|
7050
7217
|
return {x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2)};
|
|
7051
7218
|
})()`
|
|
7052
7219
|
);
|
|
7053
|
-
if (!el) return
|
|
7220
|
+
if (!el) return fail16(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
|
|
7054
7221
|
await ctx.page.mouse.click(el.x, el.y, { stealth: true });
|
|
7055
7222
|
await ctx.page.keyboard.type(value, { stealth: true });
|
|
7056
|
-
return
|
|
7223
|
+
return ok31({ action: "interact", query, target, result: { filled: true, value } });
|
|
7057
7224
|
}
|
|
7058
|
-
return
|
|
7225
|
+
return fail16(`\u672A\u77E5 action: ${action}`);
|
|
7059
7226
|
}
|
|
7060
7227
|
case "export": {
|
|
7061
7228
|
const result = await ctx.page.evaluate(
|
|
@@ -7103,12 +7270,12 @@ var visualTagV2Command = registerCommand({
|
|
|
7103
7270
|
})()`
|
|
7104
7271
|
);
|
|
7105
7272
|
const parsed = JSON.parse(result);
|
|
7106
|
-
if (parsed.err) return
|
|
7107
|
-
return
|
|
7273
|
+
if (parsed.err) return fail16(String(parsed.err));
|
|
7274
|
+
return ok31({ action: "export", element: parsed });
|
|
7108
7275
|
}
|
|
7109
7276
|
case "clear": {
|
|
7110
7277
|
await ctx.page.evaluate(`(function(){var o=document.getElementById('__xb-tag-overlay');if(o)o.remove();window.__xbTagMap=null;window.__xbTagStats=null;return 'ok'})()`);
|
|
7111
|
-
return
|
|
7278
|
+
return ok31({ action: "clear" });
|
|
7112
7279
|
}
|
|
7113
7280
|
}
|
|
7114
7281
|
}
|
|
@@ -8251,7 +8418,7 @@ async function guardCheck(commandName) {
|
|
|
8251
8418
|
}
|
|
8252
8419
|
}
|
|
8253
8420
|
function errorResult(message) {
|
|
8254
|
-
return { ...
|
|
8421
|
+
return { ...fail17(message), duration: 0 };
|
|
8255
8422
|
}
|
|
8256
8423
|
function tipsToMessages(tips) {
|
|
8257
8424
|
if (!tips || tips.length === 0) return [];
|
|
@@ -8440,7 +8607,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
8440
8607
|
const cache = /* @__PURE__ */ new Map();
|
|
8441
8608
|
const resolved = await resolveRefParams(session.page, params, command.selectorParams, cache, session.id);
|
|
8442
8609
|
if (resolved.tips.length > 0) {
|
|
8443
|
-
refTips =
|
|
8610
|
+
refTips = normalizeTips7(resolved.tips);
|
|
8444
8611
|
params = resolved.params;
|
|
8445
8612
|
}
|
|
8446
8613
|
}
|
|
@@ -8508,8 +8675,8 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
8508
8675
|
}
|
|
8509
8676
|
const merged = [
|
|
8510
8677
|
...raw.tips || [],
|
|
8511
|
-
...
|
|
8512
|
-
...snapshotHint ?
|
|
8678
|
+
...normalizeTips7(smartTips),
|
|
8679
|
+
...snapshotHint ? normalizeTips7([snapshotHint]) : [],
|
|
8513
8680
|
...refTips
|
|
8514
8681
|
];
|
|
8515
8682
|
const isSuccess = raw.success !== false;
|
|
@@ -8524,7 +8691,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
8524
8691
|
timestamp: start
|
|
8525
8692
|
});
|
|
8526
8693
|
if (isSuccess) {
|
|
8527
|
-
return { ...
|
|
8694
|
+
return { ...ok32(raw.data, merged.length > 0 ? merged : raw.tips), duration, ...hookOutputs ? { hookOutputs } : {} };
|
|
8528
8695
|
}
|
|
8529
8696
|
const fc = classifyFailure(raw.message);
|
|
8530
8697
|
return {
|
|
@@ -8537,7 +8704,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
8537
8704
|
...hookOutputs ? { hookOutputs } : {}
|
|
8538
8705
|
};
|
|
8539
8706
|
}
|
|
8540
|
-
const smartTipNormalized =
|
|
8707
|
+
const smartTipNormalized = normalizeTips7(smartTips);
|
|
8541
8708
|
recordArchive(session?.id, sessionName, {
|
|
8542
8709
|
step: 0,
|
|
8543
8710
|
command: commandName,
|
|
@@ -8547,7 +8714,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
8547
8714
|
duration,
|
|
8548
8715
|
timestamp: start
|
|
8549
8716
|
});
|
|
8550
|
-
return { ...
|
|
8717
|
+
return { ...ok32(raw, smartTipNormalized), duration, ...hookOutputs ? { hookOutputs } : {} };
|
|
8551
8718
|
} catch (err) {
|
|
8552
8719
|
const end = Date.now();
|
|
8553
8720
|
const duration = end - start;
|
|
@@ -8592,7 +8759,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
8592
8759
|
duration,
|
|
8593
8760
|
timestamp: start
|
|
8594
8761
|
});
|
|
8595
|
-
return { ...
|
|
8762
|
+
return { ...fail17(errorMessage), duration };
|
|
8596
8763
|
} finally {
|
|
8597
8764
|
}
|
|
8598
8765
|
}
|
|
@@ -8637,7 +8804,7 @@ async function executeChain(input, options) {
|
|
|
8637
8804
|
results.push({
|
|
8638
8805
|
command: cmdName,
|
|
8639
8806
|
raw: cmdStr,
|
|
8640
|
-
...
|
|
8807
|
+
...fail17(`Plugin "${cmdName}" requires a sub-command`),
|
|
8641
8808
|
duration: 0
|
|
8642
8809
|
});
|
|
8643
8810
|
if (type === "and") {
|
|
@@ -8656,7 +8823,7 @@ async function executeChain(input, options) {
|
|
|
8656
8823
|
results.push({
|
|
8657
8824
|
command: cmdName,
|
|
8658
8825
|
raw: cmdStr,
|
|
8659
|
-
...
|
|
8826
|
+
...fail17(`Unknown command "${subCommand}" for plugin "${cmdName}"`),
|
|
8660
8827
|
duration: 0
|
|
8661
8828
|
});
|
|
8662
8829
|
if (type === "and") {
|
|
@@ -8726,7 +8893,7 @@ async function executeChain(input, options) {
|
|
|
8726
8893
|
success: false,
|
|
8727
8894
|
data: data2,
|
|
8728
8895
|
message: loginGuard.message,
|
|
8729
|
-
tips:
|
|
8896
|
+
tips: normalizeTips7(loginGuard.tips),
|
|
8730
8897
|
duration: duration3
|
|
8731
8898
|
});
|
|
8732
8899
|
if (type === "and") {
|
|
@@ -8768,7 +8935,7 @@ async function executeChain(input, options) {
|
|
|
8768
8935
|
results.push({
|
|
8769
8936
|
command: `${cmdName} ${subCommand}`,
|
|
8770
8937
|
raw: cmdStr,
|
|
8771
|
-
...
|
|
8938
|
+
...ok32(data),
|
|
8772
8939
|
duration: duration2,
|
|
8773
8940
|
...hookOutputs ? { hookOutputs } : {}
|
|
8774
8941
|
});
|
|
@@ -8796,7 +8963,7 @@ async function executeChain(input, options) {
|
|
|
8796
8963
|
results.push({
|
|
8797
8964
|
command: `${cmdName} ${subCommand}`,
|
|
8798
8965
|
raw: cmdStr,
|
|
8799
|
-
...
|
|
8966
|
+
...fail17(errorMessage),
|
|
8800
8967
|
duration: duration2
|
|
8801
8968
|
});
|
|
8802
8969
|
if (type === "and") {
|