@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
|
@@ -6057,26 +6057,193 @@ var waitForCommand = registerCommand({
|
|
|
6057
6057
|
}
|
|
6058
6058
|
});
|
|
6059
6059
|
|
|
6060
|
-
// src/commands/
|
|
6060
|
+
// src/commands/task.ts
|
|
6061
6061
|
import { z as z27 } from "zod";
|
|
6062
|
-
import { ok as ok26, fail as fail12 } from "@dyyz1993/xcli-core";
|
|
6063
|
-
var
|
|
6064
|
-
|
|
6065
|
-
|
|
6066
|
-
|
|
6062
|
+
import { ok as ok26, fail as fail12, normalizeTips as normalizeTips5 } from "@dyyz1993/xcli-core";
|
|
6063
|
+
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
|
|
6064
|
+
|
|
6065
|
+
\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
|
|
6066
|
+
{"action":"click","ref":"@eN","thought":"\u4E3A\u4EC0\u4E48"}
|
|
6067
|
+
{"action":"fill","ref":"@eN","value":"\u6587\u672C","thought":"\u4E3A\u4EC0\u4E48"}
|
|
6068
|
+
{"action":"select","ref":"@eN","value":"\u9009\u9879\u503C","thought":"\u4E3A\u4EC0\u4E48"}
|
|
6069
|
+
{"action":"press","value":"Enter","thought":"\u4E3A\u4EC0\u4E48"}
|
|
6070
|
+
{"action":"scroll","value":"down \u6216 up","thought":"\u4E3A\u4EC0\u4E48"}
|
|
6071
|
+
{"action":"done","value":"\u5B8C\u6210\u6458\u8981","thought":"\u4E3A\u4EC0\u4E48"}
|
|
6072
|
+
{"action":"blocked","value":"\u5361\u4F4F\u539F\u56E0","thought":"\u4E3A\u4EC0\u4E48"}
|
|
6073
|
+
|
|
6074
|
+
\u89C4\u5219\uFF1A
|
|
6075
|
+
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
|
|
6076
|
+
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
|
|
6077
|
+
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`;
|
|
6078
|
+
function extractDecision(raw) {
|
|
6079
|
+
let s = raw.trim().replace(/^```(?:json)?\s*/i, "").replace(/\s*```$/, "");
|
|
6080
|
+
const start = s.indexOf("{");
|
|
6081
|
+
if (start < 0) return null;
|
|
6082
|
+
let depth = 0;
|
|
6083
|
+
for (let i = start; i < s.length; i++) {
|
|
6084
|
+
if (s[i] === "{") depth++;
|
|
6085
|
+
else if (s[i] === "}") {
|
|
6086
|
+
depth--;
|
|
6087
|
+
if (depth === 0) {
|
|
6088
|
+
try {
|
|
6089
|
+
return JSON.parse(s.slice(start, i + 1));
|
|
6090
|
+
} catch {
|
|
6091
|
+
return null;
|
|
6092
|
+
}
|
|
6093
|
+
}
|
|
6094
|
+
}
|
|
6095
|
+
}
|
|
6096
|
+
return null;
|
|
6097
|
+
}
|
|
6098
|
+
var taskCommand = registerCommand({
|
|
6099
|
+
name: "task",
|
|
6100
|
+
description: "Autonomous goal loop: observe refs \u2192 LLM decides \u2192 act, until done/blocked (budget-capped)",
|
|
6101
|
+
scope: "page",
|
|
6102
|
+
parameters: z27.object({
|
|
6103
|
+
goal: z27.string().describe("Natural-language goal"),
|
|
6104
|
+
maxSteps: z27.number().int().positive().max(50).optional().default(15).describe("Hard action budget"),
|
|
6105
|
+
timeout: z27.number().optional().default(18e4).describe("Wall clock budget in ms"),
|
|
6106
|
+
limit: z27.number().int().positive().max(300).optional().default(80).describe("Max targets per observe")
|
|
6107
|
+
}),
|
|
6108
|
+
result: z27.object({
|
|
6109
|
+
status: z27.enum(["done", "blocked", "max_steps", "error"]),
|
|
6110
|
+
summary: z27.string().optional(),
|
|
6111
|
+
steps: z27.array(z27.record(z27.unknown())),
|
|
6112
|
+
finalUrl: z27.string().optional(),
|
|
6113
|
+
usage: z27.object({ llmCalls: z27.number(), steps: z27.number() }).passthrough().optional()
|
|
6114
|
+
}).passthrough(),
|
|
6115
|
+
handler: async (p, ctx) => {
|
|
6116
|
+
const creds = loadVLMCredentials2();
|
|
6117
|
+
if (!creds) {
|
|
6118
|
+
return fail12("task \u9700\u8981\u51B3\u7B56\u6A21\u578B\u51ED\u8BC1\uFF1A\u8BBE\u7F6E XBROWSER_VLM_CONFIG \u6216 ~/.zcode/v2/config.json");
|
|
6119
|
+
}
|
|
6120
|
+
const model = process.env.XBROWSER_TASK_MODEL || creds.model;
|
|
6121
|
+
const started = Date.now();
|
|
6122
|
+
const steps = [];
|
|
6123
|
+
const history = [];
|
|
6124
|
+
let llmCalls = 0;
|
|
6125
|
+
let status = "max_steps";
|
|
6126
|
+
let summary = "";
|
|
6127
|
+
let lastError = "";
|
|
6128
|
+
for (let step = 1; step <= p.maxSteps; step++) {
|
|
6129
|
+
if (Date.now() - started > p.timeout) {
|
|
6130
|
+
status = "blocked";
|
|
6131
|
+
summary = `timeout after ${step - 1} steps`;
|
|
6132
|
+
break;
|
|
6133
|
+
}
|
|
6134
|
+
const obs = await observePage(ctx.page, ctx.sessionId, { limit: p.limit, includeHidden: false });
|
|
6135
|
+
const compact = obs.compact ?? obs.targets.map((t, i) => `@e${i + 1} [${t.tag ?? ""}] ${t.name ?? ""}`).join("\n");
|
|
6136
|
+
const screenHash = obs.screenHash;
|
|
6137
|
+
const userPayload = [
|
|
6138
|
+
`\u76EE\u6807\uFF1A${p.goal}`,
|
|
6139
|
+
`\u5F53\u524D\u9875\u9762\uFF08URL: ${obs.url ?? ""}\uFF09\uFF1A`,
|
|
6140
|
+
compact,
|
|
6141
|
+
history.length ? `
|
|
6142
|
+
\u5DF2\u6267\u884C\uFF08\u52FF\u91CD\u590D\u5931\u8D25\u52A8\u4F5C\uFF09\uFF1A
|
|
6143
|
+
${history.slice(-6).join("\n")}` : ""
|
|
6144
|
+
].filter(Boolean).join("\n");
|
|
6145
|
+
let raw = "";
|
|
6146
|
+
try {
|
|
6147
|
+
raw = await vlmAsk({ ...creds, model }, [{ type: "text", text: `${DECISION_SYSTEM}
|
|
6148
|
+
|
|
6149
|
+
---
|
|
6150
|
+
|
|
6151
|
+
${userPayload}` }], 900);
|
|
6152
|
+
llmCalls++;
|
|
6153
|
+
} catch (e) {
|
|
6154
|
+
lastError = e instanceof Error ? e.message : String(e);
|
|
6155
|
+
status = "error";
|
|
6156
|
+
summary = `LLM call failed: ${lastError}`;
|
|
6157
|
+
break;
|
|
6158
|
+
}
|
|
6159
|
+
const decision = extractDecision(raw);
|
|
6160
|
+
if (!decision || typeof decision.action !== "string") {
|
|
6161
|
+
status = "blocked";
|
|
6162
|
+
summary = `LLM returned unparsable decision: ${raw.slice(0, 120)}`;
|
|
6163
|
+
break;
|
|
6164
|
+
}
|
|
6165
|
+
const action = decision.action;
|
|
6166
|
+
const ref = typeof decision.ref === "string" ? decision.ref : void 0;
|
|
6167
|
+
const value = typeof decision.value === "string" ? decision.value : void 0;
|
|
6168
|
+
const thought = typeof decision.thought === "string" ? decision.thought : void 0;
|
|
6169
|
+
if (action === "done") {
|
|
6170
|
+
status = "done";
|
|
6171
|
+
summary = value || thought || "task done";
|
|
6172
|
+
steps.push({ step, thought, action: "done", ok: true, screenHash });
|
|
6173
|
+
break;
|
|
6174
|
+
}
|
|
6175
|
+
if (action === "blocked") {
|
|
6176
|
+
status = "blocked";
|
|
6177
|
+
summary = value || thought || "LLM judged blocked";
|
|
6178
|
+
steps.push({ step, thought, action: "blocked", ok: true, screenHash });
|
|
6179
|
+
break;
|
|
6180
|
+
}
|
|
6181
|
+
const legalRefs = new Set(obs.targets.map((t, i) => t.ref ?? `e${i + 1}`));
|
|
6182
|
+
const normalizedRef = ref ? legalRefs.has(ref.replace("@", "")) || legalRefs.has(ref) ? ref : void 0 : void 0;
|
|
6183
|
+
if (ref && !normalizedRef && action !== "scroll" && action !== "press") {
|
|
6184
|
+
history.push(`step${step}: ${action} ${ref} REJECTED (ref not in current list)`);
|
|
6185
|
+
steps.push({ step, thought, action, ref, ok: false, error: "ref not in current list", screenHash });
|
|
6186
|
+
continue;
|
|
6187
|
+
}
|
|
6188
|
+
const res = await actOnPage(ctx.page, ctx.sessionId, {
|
|
6189
|
+
action,
|
|
6190
|
+
ref: normalizedRef,
|
|
6191
|
+
value,
|
|
6192
|
+
selector: void 0,
|
|
6193
|
+
force: false,
|
|
6194
|
+
timeout: 1e4
|
|
6195
|
+
});
|
|
6196
|
+
const record = {
|
|
6197
|
+
step,
|
|
6198
|
+
thought,
|
|
6199
|
+
action,
|
|
6200
|
+
ref: normalizedRef,
|
|
6201
|
+
value,
|
|
6202
|
+
ok: res.success === true,
|
|
6203
|
+
stale: res.stale,
|
|
6204
|
+
error: res.success ? void 0 : res.message || res.reason,
|
|
6205
|
+
screenHash
|
|
6206
|
+
};
|
|
6207
|
+
steps.push(record);
|
|
6208
|
+
history.push(`step${step}: ${action} ${normalizedRef ?? ""} ${value ?? ""} -> ${res.success ? "ok" : `failed(${res.reason || res.message})`}`);
|
|
6209
|
+
const sig = (s) => `${s.action}|${s.ref ?? ""}|${s.value ?? ""}`;
|
|
6210
|
+
const last3 = steps.slice(-3);
|
|
6211
|
+
if (last3.length === 3 && new Set(last3.map(sig)).size === 1) {
|
|
6212
|
+
status = "blocked";
|
|
6213
|
+
summary = "dead loop: identical action repeated 3 times";
|
|
6214
|
+
break;
|
|
6215
|
+
}
|
|
6216
|
+
}
|
|
6217
|
+
if (status === "max_steps") summary = summary || `hit maxSteps=${p.maxSteps}`;
|
|
6218
|
+
const finalUrl = ctx.page ? ctx.page.url() : void 0;
|
|
6219
|
+
const data = { status, summary, steps, finalUrl, usage: { llmCalls, steps: steps.length } };
|
|
6220
|
+
if (status === "error") return fail12(summary || lastError, normalizeTips5([`completed steps: ${steps.length}`]));
|
|
6221
|
+
return ok26(data, normalizeTips5([
|
|
6222
|
+
status === "done" ? `\u2705 task done (${steps.length} steps, ${llmCalls} LLM calls)` : `\u26A0\uFE0F task ${status}: ${summary.slice(0, 80)}`
|
|
6223
|
+
]));
|
|
6224
|
+
}
|
|
6225
|
+
});
|
|
6226
|
+
|
|
6227
|
+
// src/commands/tab.ts
|
|
6228
|
+
import { z as z28 } from "zod";
|
|
6229
|
+
import { ok as ok27, fail as fail13 } from "@dyyz1993/xcli-core";
|
|
6230
|
+
var TabParams = z28.object({
|
|
6231
|
+
subcommand: z28.enum(["list", "new", "close", "switch"]),
|
|
6232
|
+
url: z28.string().optional(),
|
|
6233
|
+
index: z28.number().int().min(0).optional()
|
|
6067
6234
|
});
|
|
6068
6235
|
var tabCommand = registerCommand({
|
|
6069
6236
|
name: "tab",
|
|
6070
6237
|
description: "Manage browser tabs: list, new, close, switch",
|
|
6071
6238
|
scope: "page",
|
|
6072
6239
|
parameters: TabParams,
|
|
6073
|
-
result:
|
|
6074
|
-
success:
|
|
6075
|
-
data:
|
|
6240
|
+
result: z28.object({
|
|
6241
|
+
success: z28.boolean(),
|
|
6242
|
+
data: z28.unknown()
|
|
6076
6243
|
}),
|
|
6077
6244
|
handler: async (p, ctx) => {
|
|
6078
6245
|
if (!ctx.browserContext) {
|
|
6079
|
-
return
|
|
6246
|
+
return fail13("No browser context available. Use --cdp to connect to a browser first.");
|
|
6080
6247
|
}
|
|
6081
6248
|
const pages = ctx.browserContext.pages();
|
|
6082
6249
|
switch (p.subcommand) {
|
|
@@ -6089,7 +6256,7 @@ var tabCommand = registerCommand({
|
|
|
6089
6256
|
case "switch":
|
|
6090
6257
|
return handleSwitch(p, pages, ctx);
|
|
6091
6258
|
default:
|
|
6092
|
-
return
|
|
6259
|
+
return fail13(`Unknown subcommand: ${p.subcommand}`);
|
|
6093
6260
|
}
|
|
6094
6261
|
}
|
|
6095
6262
|
});
|
|
@@ -6104,7 +6271,7 @@ async function handleList(pages, ctx) {
|
|
|
6104
6271
|
if (isActive) activeIndex = i;
|
|
6105
6272
|
tabs.push({ index: i, url, title, active: isActive });
|
|
6106
6273
|
}
|
|
6107
|
-
return
|
|
6274
|
+
return ok27({ tabs, total: tabs.length, activeIndex });
|
|
6108
6275
|
}
|
|
6109
6276
|
async function handleNew(p, _pages, ctx) {
|
|
6110
6277
|
const newPage = await ctx.browserContext.newPage();
|
|
@@ -6132,7 +6299,7 @@ async function handleNew(p, _pages, ctx) {
|
|
|
6132
6299
|
const title = await newPage.title().catch(() => "");
|
|
6133
6300
|
const allPages = ctx.browserContext.pages();
|
|
6134
6301
|
const newIndex = allPages.indexOf(newPage);
|
|
6135
|
-
return
|
|
6302
|
+
return ok27({
|
|
6136
6303
|
index: newIndex >= 0 ? newIndex : allPages.length - 1,
|
|
6137
6304
|
url: newPage.url(),
|
|
6138
6305
|
title,
|
|
@@ -6143,11 +6310,11 @@ async function handleNew(p, _pages, ctx) {
|
|
|
6143
6310
|
async function handleClose(p, ctx) {
|
|
6144
6311
|
const currentPages = ctx.browserContext.pages();
|
|
6145
6312
|
if (currentPages.length <= 1) {
|
|
6146
|
-
return
|
|
6313
|
+
return fail13("Cannot close the last remaining tab");
|
|
6147
6314
|
}
|
|
6148
6315
|
const closeIndex = p.index ?? currentPages.findIndex((pg) => pg === ctx.page);
|
|
6149
6316
|
if (closeIndex < 0 || closeIndex >= currentPages.length) {
|
|
6150
|
-
return
|
|
6317
|
+
return fail13(`Invalid tab index: ${closeIndex}. Valid range: 0-${currentPages.length - 1}`);
|
|
6151
6318
|
}
|
|
6152
6319
|
const pageToClose = currentPages[closeIndex];
|
|
6153
6320
|
const isActivePage = pageToClose === ctx.page;
|
|
@@ -6162,7 +6329,7 @@ async function handleClose(p, ctx) {
|
|
|
6162
6329
|
}
|
|
6163
6330
|
ctx.page = newActivePage;
|
|
6164
6331
|
}
|
|
6165
|
-
return
|
|
6332
|
+
return ok27({
|
|
6166
6333
|
closedIndex: closeIndex,
|
|
6167
6334
|
total: remainingPages.length,
|
|
6168
6335
|
activeIndex: isActivePage ? closeIndex < remainingPages.length ? closeIndex : remainingPages.length - 1 : remainingPages.findIndex((pg) => pg === ctx.page)
|
|
@@ -6170,10 +6337,10 @@ async function handleClose(p, ctx) {
|
|
|
6170
6337
|
}
|
|
6171
6338
|
async function handleSwitch(p, pages, ctx) {
|
|
6172
6339
|
if (p.index === void 0) {
|
|
6173
|
-
return
|
|
6340
|
+
return fail13("Parameter --index is required for switch subcommand");
|
|
6174
6341
|
}
|
|
6175
6342
|
if (p.index < 0 || p.index >= pages.length) {
|
|
6176
|
-
return
|
|
6343
|
+
return fail13(`Invalid tab index: ${p.index}. Valid range: 0-${pages.length - 1}`);
|
|
6177
6344
|
}
|
|
6178
6345
|
const targetPage = pages[p.index];
|
|
6179
6346
|
await targetPage.bringToFront().catch(() => {
|
|
@@ -6195,7 +6362,7 @@ async function handleSwitch(p, pages, ctx) {
|
|
|
6195
6362
|
}
|
|
6196
6363
|
ctx.page = targetPage;
|
|
6197
6364
|
const title = await targetPage.title().catch(() => "");
|
|
6198
|
-
return
|
|
6365
|
+
return ok27({
|
|
6199
6366
|
index: p.index,
|
|
6200
6367
|
url: targetPage.url(),
|
|
6201
6368
|
title,
|
|
@@ -6204,17 +6371,17 @@ async function handleSwitch(p, pages, ctx) {
|
|
|
6204
6371
|
}
|
|
6205
6372
|
|
|
6206
6373
|
// src/commands/addinitscript.ts
|
|
6207
|
-
import { z as
|
|
6208
|
-
import { ok as
|
|
6374
|
+
import { z as z29 } from "zod";
|
|
6375
|
+
import { ok as ok28 } from "@dyyz1993/xcli-core";
|
|
6209
6376
|
import { readFileSync as readFileSync4 } from "fs";
|
|
6210
|
-
var InitScriptParams =
|
|
6211
|
-
script:
|
|
6212
|
-
file:
|
|
6213
|
-
stdin:
|
|
6214
|
-
name:
|
|
6215
|
-
list:
|
|
6216
|
-
remove:
|
|
6217
|
-
base64:
|
|
6377
|
+
var InitScriptParams = z29.object({
|
|
6378
|
+
script: z29.string().optional(),
|
|
6379
|
+
file: z29.string().optional(),
|
|
6380
|
+
stdin: z29.boolean().optional(),
|
|
6381
|
+
name: z29.string().optional(),
|
|
6382
|
+
list: z29.boolean().optional(),
|
|
6383
|
+
remove: z29.union([z29.string(), z29.boolean()]).optional(),
|
|
6384
|
+
base64: z29.string().optional()
|
|
6218
6385
|
});
|
|
6219
6386
|
var registeredScripts = /* @__PURE__ */ new Map();
|
|
6220
6387
|
function resolveScriptContent(params) {
|
|
@@ -6248,14 +6415,14 @@ var addInitScriptCommand = registerCommand({
|
|
|
6248
6415
|
description: "Add an initialization script that runs on every page load",
|
|
6249
6416
|
scope: "page",
|
|
6250
6417
|
parameters: InitScriptParams,
|
|
6251
|
-
result:
|
|
6252
|
-
scripts:
|
|
6253
|
-
removed:
|
|
6254
|
-
existed:
|
|
6255
|
-
error:
|
|
6256
|
-
registered:
|
|
6257
|
-
hint:
|
|
6258
|
-
executedImmediately:
|
|
6418
|
+
result: z29.object({
|
|
6419
|
+
scripts: z29.array(z29.object({ name: z29.string(), size: z29.number(), preview: z29.string() })).optional(),
|
|
6420
|
+
removed: z29.string().optional(),
|
|
6421
|
+
existed: z29.boolean().optional(),
|
|
6422
|
+
error: z29.string().optional(),
|
|
6423
|
+
registered: z29.string().optional(),
|
|
6424
|
+
hint: z29.string().optional(),
|
|
6425
|
+
executedImmediately: z29.boolean().optional()
|
|
6259
6426
|
}).passthrough(),
|
|
6260
6427
|
handler: async (params, ctx) => {
|
|
6261
6428
|
if (params.list) {
|
|
@@ -6264,20 +6431,20 @@ var addInitScriptCommand = registerCommand({
|
|
|
6264
6431
|
size: content2.length,
|
|
6265
6432
|
preview: content2.slice(0, 80)
|
|
6266
6433
|
}));
|
|
6267
|
-
return
|
|
6434
|
+
return ok28({ scripts });
|
|
6268
6435
|
}
|
|
6269
6436
|
if (params.remove && typeof params.remove === "string") {
|
|
6270
6437
|
const existed = registeredScripts.delete(params.remove);
|
|
6271
|
-
return
|
|
6438
|
+
return ok28({ removed: params.remove, existed });
|
|
6272
6439
|
}
|
|
6273
6440
|
const removeTarget = (typeof params.remove === "string" ? params.remove : null) || (params.name && !resolveScriptContent(params) ? params.name : null);
|
|
6274
6441
|
if (removeTarget && !resolveScriptContent(params)) {
|
|
6275
6442
|
const existed = registeredScripts.delete(removeTarget);
|
|
6276
|
-
return
|
|
6443
|
+
return ok28({ removed: removeTarget, existed });
|
|
6277
6444
|
}
|
|
6278
6445
|
let content = params.stdin ? await readStdin() : resolveScriptContent(params);
|
|
6279
6446
|
if (!content) {
|
|
6280
|
-
return
|
|
6447
|
+
return ok28({ error: "No script content provided. Use --script, --file, --stdin, or --base64" });
|
|
6281
6448
|
}
|
|
6282
6449
|
const scriptName = params.name ?? `script-${Date.now()}`;
|
|
6283
6450
|
registeredScripts.set(scriptName, content);
|
|
@@ -6285,45 +6452,45 @@ var addInitScriptCommand = registerCommand({
|
|
|
6285
6452
|
try {
|
|
6286
6453
|
await ctx.page.evaluate(content);
|
|
6287
6454
|
} catch {
|
|
6288
|
-
return
|
|
6455
|
+
return ok28({
|
|
6289
6456
|
registered: scriptName,
|
|
6290
6457
|
hint: "Script registered for future page loads; immediate execution skipped (page may not be ready)"
|
|
6291
6458
|
});
|
|
6292
6459
|
}
|
|
6293
|
-
return
|
|
6460
|
+
return ok28({ registered: scriptName, executedImmediately: true });
|
|
6294
6461
|
}
|
|
6295
6462
|
});
|
|
6296
6463
|
registerCommandDefinition("addinitscript", ["script"]);
|
|
6297
6464
|
|
|
6298
6465
|
// src/commands/find.ts
|
|
6299
|
-
import { z as
|
|
6300
|
-
import { ok as
|
|
6301
|
-
var actionSchema2 =
|
|
6466
|
+
import { z as z30 } from "zod";
|
|
6467
|
+
import { ok as ok29, fail as fail14, normalizeTips as normalizeTips6 } from "@dyyz1993/xcli-core";
|
|
6468
|
+
var actionSchema2 = z30.enum(["click", "fill", "type", "select", "hover", "check"]);
|
|
6302
6469
|
var findCommand = registerCommand({
|
|
6303
6470
|
name: "find",
|
|
6304
6471
|
description: "Find elements by semantic strategy (text/role/label/placeholder/testid) and optionally perform an action",
|
|
6305
6472
|
scope: "page",
|
|
6306
|
-
parameters:
|
|
6307
|
-
strategy:
|
|
6308
|
-
value:
|
|
6309
|
-
name:
|
|
6310
|
-
exact:
|
|
6311
|
-
operation:
|
|
6473
|
+
parameters: z30.object({
|
|
6474
|
+
strategy: z30.enum(["text", "role", "label", "placeholder", "testid", "alt", "title", "first", "last", "nth"]),
|
|
6475
|
+
value: z30.string(),
|
|
6476
|
+
name: z30.string().optional(),
|
|
6477
|
+
exact: z30.boolean().optional().default(false),
|
|
6478
|
+
operation: z30.string().optional().describe('Trailing operation syntax, e.g. click, fill "text", type "text"'),
|
|
6312
6479
|
action: actionSchema2.optional().describe("Action to perform when not using trailing operation syntax"),
|
|
6313
|
-
actionValue:
|
|
6314
|
-
index:
|
|
6315
|
-
click:
|
|
6316
|
-
fill:
|
|
6317
|
-
type:
|
|
6318
|
-
select:
|
|
6319
|
-
hover:
|
|
6320
|
-
check:
|
|
6321
|
-
timeout:
|
|
6480
|
+
actionValue: z30.string().optional().describe("Value for fill/type/select when using action"),
|
|
6481
|
+
index: z30.number().int().optional().describe("Index for nth strategy"),
|
|
6482
|
+
click: z30.boolean().optional().default(false),
|
|
6483
|
+
fill: z30.string().optional(),
|
|
6484
|
+
type: z30.string().optional(),
|
|
6485
|
+
select: z30.string().optional(),
|
|
6486
|
+
hover: z30.boolean().optional().default(false),
|
|
6487
|
+
check: z30.boolean().optional().default(false),
|
|
6488
|
+
timeout: z30.number().optional().default(1e4)
|
|
6322
6489
|
}),
|
|
6323
|
-
result:
|
|
6324
|
-
matched:
|
|
6325
|
-
selector:
|
|
6326
|
-
action:
|
|
6490
|
+
result: z30.object({
|
|
6491
|
+
matched: z30.number(),
|
|
6492
|
+
selector: z30.string(),
|
|
6493
|
+
action: z30.string().optional()
|
|
6327
6494
|
}),
|
|
6328
6495
|
handler: async (p, ctx) => {
|
|
6329
6496
|
const page = ctx.page;
|
|
@@ -6338,7 +6505,7 @@ var findCommand = registerCommand({
|
|
|
6338
6505
|
});
|
|
6339
6506
|
const count = await locator.count();
|
|
6340
6507
|
if (count === 0) {
|
|
6341
|
-
return
|
|
6508
|
+
return fail14(`No element found with ${p.strategy}="${p.value}"`);
|
|
6342
6509
|
}
|
|
6343
6510
|
const tips = [];
|
|
6344
6511
|
const target = selectTarget(locator, p.strategy);
|
|
@@ -6350,15 +6517,15 @@ var findCommand = registerCommand({
|
|
|
6350
6517
|
await target.click({ timeout: p.timeout, force: true });
|
|
6351
6518
|
return okWithTips({ matched: count, selector, action: "click" }, tips);
|
|
6352
6519
|
} else if (actionName === "fill") {
|
|
6353
|
-
if (actionValue === void 0) return
|
|
6520
|
+
if (actionValue === void 0) return fail14("find fill requires a value");
|
|
6354
6521
|
await target.fill(actionValue, { timeout: p.timeout, force: true });
|
|
6355
6522
|
return okWithTips({ matched: count, selector, action: `fill("${actionValue}")` }, tips);
|
|
6356
6523
|
} else if (actionName === "type") {
|
|
6357
|
-
if (actionValue === void 0) return
|
|
6524
|
+
if (actionValue === void 0) return fail14("find type requires a value");
|
|
6358
6525
|
await target.type(actionValue, { delay: 10, timeout: p.timeout });
|
|
6359
6526
|
return okWithTips({ matched: count, selector, action: `type("${actionValue}")` }, tips);
|
|
6360
6527
|
} else if (actionName === "select") {
|
|
6361
|
-
if (actionValue === void 0) return
|
|
6528
|
+
if (actionValue === void 0) return fail14("find select requires a value");
|
|
6362
6529
|
await target.selectOption(actionValue);
|
|
6363
6530
|
return okWithTips({ matched: count, selector, action: `select("${actionValue}")` }, tips);
|
|
6364
6531
|
} else if (actionName === "hover") {
|
|
@@ -6372,8 +6539,8 @@ var findCommand = registerCommand({
|
|
|
6372
6539
|
}
|
|
6373
6540
|
});
|
|
6374
6541
|
function okWithTips(data, tips) {
|
|
6375
|
-
const result =
|
|
6376
|
-
if (tips.length > 0) result.tips =
|
|
6542
|
+
const result = ok29(data);
|
|
6543
|
+
if (tips.length > 0) result.tips = normalizeTips6(tips);
|
|
6377
6544
|
return result;
|
|
6378
6545
|
}
|
|
6379
6546
|
function parseOperation(operation) {
|
|
@@ -6471,8 +6638,8 @@ function describeSelector(strategy, value, name) {
|
|
|
6471
6638
|
}
|
|
6472
6639
|
|
|
6473
6640
|
// src/commands/visual-tag.ts
|
|
6474
|
-
import { z as
|
|
6475
|
-
import { ok as
|
|
6641
|
+
import { z as z31 } from "zod";
|
|
6642
|
+
import { ok as ok30, fail as fail15 } from "@dyyz1993/xcli-core";
|
|
6476
6643
|
var SAFE_SET = "ahjkmnprtw3479".split("");
|
|
6477
6644
|
var TAG_SCRIPT = `
|
|
6478
6645
|
(function() {
|
|
@@ -6563,49 +6730,49 @@ var visualTagCommand = registerCommand({
|
|
|
6563
6730
|
name: "visual-tag",
|
|
6564
6731
|
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",
|
|
6565
6732
|
scope: "page",
|
|
6566
|
-
parameters:
|
|
6567
|
-
action:
|
|
6568
|
-
id:
|
|
6733
|
+
parameters: z31.object({
|
|
6734
|
+
action: z31.enum(["tag", "lookup", "clear", "list"]),
|
|
6735
|
+
id: z31.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID")
|
|
6569
6736
|
}),
|
|
6570
|
-
result:
|
|
6571
|
-
action:
|
|
6572
|
-
tagged:
|
|
6573
|
-
id:
|
|
6574
|
-
element:
|
|
6737
|
+
result: z31.object({
|
|
6738
|
+
action: z31.string(),
|
|
6739
|
+
tagged: z31.number().optional(),
|
|
6740
|
+
id: z31.string().optional(),
|
|
6741
|
+
element: z31.record(z31.unknown()).optional()
|
|
6575
6742
|
}),
|
|
6576
6743
|
handler: async (p, ctx) => {
|
|
6577
6744
|
switch (p.action) {
|
|
6578
6745
|
case "tag": {
|
|
6579
6746
|
const result = await ctx.page.evaluate(TAG_SCRIPT);
|
|
6580
6747
|
const parsed = JSON.parse(result);
|
|
6581
|
-
return
|
|
6748
|
+
return ok30({ action: "tag", tagged: parsed.tagged });
|
|
6582
6749
|
}
|
|
6583
6750
|
case "lookup": {
|
|
6584
|
-
if (!p.id) return
|
|
6751
|
+
if (!p.id) return fail15("lookup \u9700\u8981 --id \u53C2\u6570");
|
|
6585
6752
|
const result = await ctx.page.evaluate(
|
|
6586
6753
|
`(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'}); })()`
|
|
6587
6754
|
);
|
|
6588
6755
|
const parsed = JSON.parse(result);
|
|
6589
|
-
if (parsed.err) return
|
|
6590
|
-
return
|
|
6756
|
+
if (parsed.err) return fail15(`ID ${p.id}: ${parsed.err}`);
|
|
6757
|
+
return ok30({ action: "lookup", id: p.id, element: parsed });
|
|
6591
6758
|
}
|
|
6592
6759
|
case "list": {
|
|
6593
6760
|
const result = await ctx.page.evaluate(
|
|
6594
6761
|
`(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); })()`
|
|
6595
6762
|
);
|
|
6596
|
-
return
|
|
6763
|
+
return ok30({ action: "list", element: JSON.parse(result) });
|
|
6597
6764
|
}
|
|
6598
6765
|
case "clear": {
|
|
6599
6766
|
await ctx.page.evaluate(`(function(){var o=document.getElementById('__xb-tag-overlay');if(o)o.remove();window.__xbTagMap=null;return 'cleared'})()`);
|
|
6600
|
-
return
|
|
6767
|
+
return ok30({ action: "clear" });
|
|
6601
6768
|
}
|
|
6602
6769
|
}
|
|
6603
6770
|
}
|
|
6604
6771
|
});
|
|
6605
6772
|
|
|
6606
6773
|
// src/commands/visual-tag-v2.ts
|
|
6607
|
-
import { z as
|
|
6608
|
-
import { ok as
|
|
6774
|
+
import { z as z32 } from "zod";
|
|
6775
|
+
import { ok as ok31, fail as fail16 } from "@dyyz1993/xcli-core";
|
|
6609
6776
|
var SAFE_SET2 = "ahjkmnprtw3479".split("");
|
|
6610
6777
|
var TAG_V2_SCRIPT = `
|
|
6611
6778
|
(function() {
|
|
@@ -6952,45 +7119,45 @@ var visualTagV2Command = registerCommand({
|
|
|
6952
7119
|
name: "visual-tag-v2",
|
|
6953
7120
|
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",
|
|
6954
7121
|
scope: "page",
|
|
6955
|
-
parameters:
|
|
6956
|
-
action:
|
|
6957
|
-
id:
|
|
6958
|
-
query:
|
|
6959
|
-
type:
|
|
6960
|
-
"interact-action":
|
|
6961
|
-
value:
|
|
7122
|
+
parameters: z32.object({
|
|
7123
|
+
action: z32.enum(["tag", "lookup", "clear", "stats", "by-type", "find", "export", "interact"]),
|
|
7124
|
+
id: z32.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID"),
|
|
7125
|
+
query: z32.string().optional().describe('find \u65F6\u6307\u5B9A\u641C\u7D22\u8BCD\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09'),
|
|
7126
|
+
type: z32.string().optional().describe("by-type \u65F6\u8FC7\u6EE4\u7C7B\u578B\uFF1Aclick/input/img/list/count/text"),
|
|
7127
|
+
"interact-action": z32.enum(["click", "fill", "read"]).optional().describe("interact \u52A8\u4F5C\u7C7B\u578B"),
|
|
7128
|
+
value: z32.string().optional().describe("fill \u65F6\u7684\u586B\u5145\u503C")
|
|
6962
7129
|
}),
|
|
6963
|
-
result:
|
|
6964
|
-
action:
|
|
6965
|
-
total:
|
|
6966
|
-
byType:
|
|
6967
|
-
element:
|
|
7130
|
+
result: z32.object({
|
|
7131
|
+
action: z32.string(),
|
|
7132
|
+
total: z32.number().optional(),
|
|
7133
|
+
byType: z32.record(z32.number()).optional(),
|
|
7134
|
+
element: z32.record(z32.unknown()).optional()
|
|
6968
7135
|
}),
|
|
6969
7136
|
handler: async (p, ctx) => {
|
|
6970
7137
|
switch (p.action) {
|
|
6971
7138
|
case "tag": {
|
|
6972
7139
|
const result = await ctx.page.evaluate(TAG_V2_SCRIPT);
|
|
6973
7140
|
const parsed = JSON.parse(result);
|
|
6974
|
-
return
|
|
7141
|
+
return ok31({ action: "tag", total: parsed.total, byType: parsed.byType });
|
|
6975
7142
|
}
|
|
6976
7143
|
case "lookup": {
|
|
6977
|
-
if (!p.id) return
|
|
7144
|
+
if (!p.id) return fail16("lookup \u9700\u8981 --id");
|
|
6978
7145
|
const result = await ctx.page.evaluate(
|
|
6979
7146
|
`(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'})})()`
|
|
6980
7147
|
);
|
|
6981
7148
|
const parsed = JSON.parse(result);
|
|
6982
|
-
if (parsed.err) return
|
|
6983
|
-
return
|
|
7149
|
+
if (parsed.err) return fail16(`ID ${p.id}: ${parsed.err}`);
|
|
7150
|
+
return ok31({ action: "lookup", id: p.id, element: parsed });
|
|
6984
7151
|
}
|
|
6985
7152
|
case "by-type": {
|
|
6986
7153
|
const result = await ctx.page.evaluate(
|
|
6987
7154
|
`(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)})()`
|
|
6988
7155
|
);
|
|
6989
|
-
return
|
|
7156
|
+
return ok31({ action: "by-type", element: JSON.parse(result) });
|
|
6990
7157
|
}
|
|
6991
7158
|
case "find": {
|
|
6992
7159
|
const query = p.query;
|
|
6993
|
-
if (!query) return
|
|
7160
|
+
if (!query) return fail16('find \u9700\u8981 --query \u53C2\u6570\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09');
|
|
6994
7161
|
const result = await ctx.page.evaluate(
|
|
6995
7162
|
`(function(){
|
|
6996
7163
|
var map = window.__xbTagSerializable;
|
|
@@ -7032,21 +7199,21 @@ var visualTagV2Command = registerCommand({
|
|
|
7032
7199
|
return JSON.stringify({total:results.length, results:results.slice(0,20)});
|
|
7033
7200
|
})()`
|
|
7034
7201
|
);
|
|
7035
|
-
return
|
|
7202
|
+
return ok31({ action: "find", query, element: JSON.parse(result) });
|
|
7036
7203
|
}
|
|
7037
7204
|
case "stats": {
|
|
7038
7205
|
const result = await ctx.page.evaluate(
|
|
7039
7206
|
`(function(){return JSON.stringify(window.__xbTagStats||{})})()`
|
|
7040
7207
|
);
|
|
7041
|
-
return
|
|
7208
|
+
return ok31({ action: "stats", element: JSON.parse(result) });
|
|
7042
7209
|
}
|
|
7043
7210
|
case "interact": {
|
|
7044
7211
|
const query = p.query;
|
|
7045
7212
|
const pAny = p;
|
|
7046
7213
|
const action = pAny["interact-action"] || pAny.interactAction || pAny.interact_action;
|
|
7047
7214
|
const value = pAny.value;
|
|
7048
|
-
if (!query) return
|
|
7049
|
-
if (!action) return
|
|
7215
|
+
if (!query) return fail16("interact \u9700\u8981 --query \u53C2\u6570");
|
|
7216
|
+
if (!action) return fail16("interact \u9700\u8981 --interact-action \u53C2\u6570\uFF08click/fill/read\uFF09");
|
|
7050
7217
|
const findResult = await ctx.page.evaluate(
|
|
7051
7218
|
`(function(){
|
|
7052
7219
|
var map = window.__xbTagSerializable;
|
|
@@ -7076,11 +7243,11 @@ var visualTagV2Command = registerCommand({
|
|
|
7076
7243
|
})()`
|
|
7077
7244
|
);
|
|
7078
7245
|
const parsed = JSON.parse(findResult);
|
|
7079
|
-
if (parsed.err) return
|
|
7080
|
-
if (!parsed.total || !parsed.results?.length) return
|
|
7246
|
+
if (parsed.err) return fail16(parsed.err);
|
|
7247
|
+
if (!parsed.total || !parsed.results?.length) return fail16(`\u672A\u627E\u5230\u5339\u914D "${query}" \u7684\u5143\u7D20`);
|
|
7081
7248
|
const target = parsed.results[0];
|
|
7082
7249
|
if (action === "read") {
|
|
7083
|
-
return
|
|
7250
|
+
return ok31({ action: "interact", query, target, result: { read: target.text || target.label } });
|
|
7084
7251
|
}
|
|
7085
7252
|
if (action === "click") {
|
|
7086
7253
|
const el = await ctx.page.evaluate(
|
|
@@ -7093,12 +7260,12 @@ var visualTagV2Command = registerCommand({
|
|
|
7093
7260
|
return {x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2)};
|
|
7094
7261
|
})()`
|
|
7095
7262
|
);
|
|
7096
|
-
if (!el) return
|
|
7263
|
+
if (!el) return fail16(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
|
|
7097
7264
|
await ctx.page.mouse.click(el.x, el.y, { stealth: true });
|
|
7098
|
-
return
|
|
7265
|
+
return ok31({ action: "interact", query, target, result: { clicked: true, x: el.x, y: el.y } });
|
|
7099
7266
|
}
|
|
7100
7267
|
if (action === "fill") {
|
|
7101
|
-
if (!value) return
|
|
7268
|
+
if (!value) return fail16("fill \u9700\u8981 --value \u53C2\u6570");
|
|
7102
7269
|
const el = await ctx.page.evaluate(
|
|
7103
7270
|
`(function(){
|
|
7104
7271
|
var map = window.__xbTagMap;
|
|
@@ -7109,12 +7276,12 @@ var visualTagV2Command = registerCommand({
|
|
|
7109
7276
|
return {x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2)};
|
|
7110
7277
|
})()`
|
|
7111
7278
|
);
|
|
7112
|
-
if (!el) return
|
|
7279
|
+
if (!el) return fail16(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
|
|
7113
7280
|
await ctx.page.mouse.click(el.x, el.y, { stealth: true });
|
|
7114
7281
|
await ctx.page.keyboard.type(value, { stealth: true });
|
|
7115
|
-
return
|
|
7282
|
+
return ok31({ action: "interact", query, target, result: { filled: true, value } });
|
|
7116
7283
|
}
|
|
7117
|
-
return
|
|
7284
|
+
return fail16(`\u672A\u77E5 action: ${action}`);
|
|
7118
7285
|
}
|
|
7119
7286
|
case "export": {
|
|
7120
7287
|
const result = await ctx.page.evaluate(
|
|
@@ -7162,12 +7329,12 @@ var visualTagV2Command = registerCommand({
|
|
|
7162
7329
|
})()`
|
|
7163
7330
|
);
|
|
7164
7331
|
const parsed = JSON.parse(result);
|
|
7165
|
-
if (parsed.err) return
|
|
7166
|
-
return
|
|
7332
|
+
if (parsed.err) return fail16(String(parsed.err));
|
|
7333
|
+
return ok31({ action: "export", element: parsed });
|
|
7167
7334
|
}
|
|
7168
7335
|
case "clear": {
|
|
7169
7336
|
await ctx.page.evaluate(`(function(){var o=document.getElementById('__xb-tag-overlay');if(o)o.remove();window.__xbTagMap=null;window.__xbTagStats=null;return 'ok'})()`);
|
|
7170
|
-
return
|
|
7337
|
+
return ok31({ action: "clear" });
|
|
7171
7338
|
}
|
|
7172
7339
|
}
|
|
7173
7340
|
}
|
|
@@ -7693,12 +7860,12 @@ function classifyFailure(message) {
|
|
|
7693
7860
|
|
|
7694
7861
|
// src/executor.ts
|
|
7695
7862
|
import {
|
|
7696
|
-
ok as
|
|
7697
|
-
fail as
|
|
7863
|
+
ok as ok32,
|
|
7864
|
+
fail as fail17,
|
|
7698
7865
|
isCommandResult,
|
|
7699
7866
|
CompositeStorage as CompositeStorage2,
|
|
7700
7867
|
TipCollector as TipCollector2,
|
|
7701
|
-
normalizeTips as
|
|
7868
|
+
normalizeTips as normalizeTips7,
|
|
7702
7869
|
configureArchiveStore,
|
|
7703
7870
|
appendCommandToArchive,
|
|
7704
7871
|
checkGuard,
|
|
@@ -8565,7 +8732,7 @@ async function guardCheck(commandName) {
|
|
|
8565
8732
|
}
|
|
8566
8733
|
}
|
|
8567
8734
|
function errorResult(message) {
|
|
8568
|
-
return { ...
|
|
8735
|
+
return { ...fail17(message), duration: 0 };
|
|
8569
8736
|
}
|
|
8570
8737
|
function tipsToMessages(tips) {
|
|
8571
8738
|
if (!tips || tips.length === 0) return [];
|
|
@@ -8757,7 +8924,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
8757
8924
|
const cache = /* @__PURE__ */ new Map();
|
|
8758
8925
|
const resolved = await resolveRefParams(session.page, params, command.selectorParams, cache, session.id);
|
|
8759
8926
|
if (resolved.tips.length > 0) {
|
|
8760
|
-
refTips =
|
|
8927
|
+
refTips = normalizeTips7(resolved.tips);
|
|
8761
8928
|
params = resolved.params;
|
|
8762
8929
|
}
|
|
8763
8930
|
}
|
|
@@ -8825,8 +8992,8 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
8825
8992
|
}
|
|
8826
8993
|
const merged = [
|
|
8827
8994
|
...raw.tips || [],
|
|
8828
|
-
...
|
|
8829
|
-
...snapshotHint ?
|
|
8995
|
+
...normalizeTips7(smartTips),
|
|
8996
|
+
...snapshotHint ? normalizeTips7([snapshotHint]) : [],
|
|
8830
8997
|
...refTips
|
|
8831
8998
|
];
|
|
8832
8999
|
const isSuccess = raw.success !== false;
|
|
@@ -8841,7 +9008,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
8841
9008
|
timestamp: start
|
|
8842
9009
|
});
|
|
8843
9010
|
if (isSuccess) {
|
|
8844
|
-
return { ...
|
|
9011
|
+
return { ...ok32(raw.data, merged.length > 0 ? merged : raw.tips), duration, ...hookOutputs ? { hookOutputs } : {} };
|
|
8845
9012
|
}
|
|
8846
9013
|
const fc = classifyFailure(raw.message);
|
|
8847
9014
|
return {
|
|
@@ -8854,7 +9021,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
8854
9021
|
...hookOutputs ? { hookOutputs } : {}
|
|
8855
9022
|
};
|
|
8856
9023
|
}
|
|
8857
|
-
const smartTipNormalized =
|
|
9024
|
+
const smartTipNormalized = normalizeTips7(smartTips);
|
|
8858
9025
|
recordArchive(session?.id, sessionName, {
|
|
8859
9026
|
step: 0,
|
|
8860
9027
|
command: commandName,
|
|
@@ -8864,7 +9031,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
8864
9031
|
duration,
|
|
8865
9032
|
timestamp: start
|
|
8866
9033
|
});
|
|
8867
|
-
return { ...
|
|
9034
|
+
return { ...ok32(raw, smartTipNormalized), duration, ...hookOutputs ? { hookOutputs } : {} };
|
|
8868
9035
|
} catch (err) {
|
|
8869
9036
|
const end = Date.now();
|
|
8870
9037
|
const duration = end - start;
|
|
@@ -8909,7 +9076,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
8909
9076
|
duration,
|
|
8910
9077
|
timestamp: start
|
|
8911
9078
|
});
|
|
8912
|
-
return { ...
|
|
9079
|
+
return { ...fail17(errorMessage), duration };
|
|
8913
9080
|
} finally {
|
|
8914
9081
|
}
|
|
8915
9082
|
}
|
|
@@ -8954,7 +9121,7 @@ async function executeChain(input, options) {
|
|
|
8954
9121
|
results.push({
|
|
8955
9122
|
command: cmdName,
|
|
8956
9123
|
raw: cmdStr,
|
|
8957
|
-
...
|
|
9124
|
+
...fail17(`Plugin "${cmdName}" requires a sub-command`),
|
|
8958
9125
|
duration: 0
|
|
8959
9126
|
});
|
|
8960
9127
|
if (type === "and") {
|
|
@@ -8973,7 +9140,7 @@ async function executeChain(input, options) {
|
|
|
8973
9140
|
results.push({
|
|
8974
9141
|
command: cmdName,
|
|
8975
9142
|
raw: cmdStr,
|
|
8976
|
-
...
|
|
9143
|
+
...fail17(`Unknown command "${subCommand}" for plugin "${cmdName}"`),
|
|
8977
9144
|
duration: 0
|
|
8978
9145
|
});
|
|
8979
9146
|
if (type === "and") {
|
|
@@ -9043,7 +9210,7 @@ async function executeChain(input, options) {
|
|
|
9043
9210
|
success: false,
|
|
9044
9211
|
data: data2,
|
|
9045
9212
|
message: loginGuard.message,
|
|
9046
|
-
tips:
|
|
9213
|
+
tips: normalizeTips7(loginGuard.tips),
|
|
9047
9214
|
duration: duration3
|
|
9048
9215
|
});
|
|
9049
9216
|
if (type === "and") {
|
|
@@ -9085,7 +9252,7 @@ async function executeChain(input, options) {
|
|
|
9085
9252
|
results.push({
|
|
9086
9253
|
command: `${cmdName} ${subCommand}`,
|
|
9087
9254
|
raw: cmdStr,
|
|
9088
|
-
...
|
|
9255
|
+
...ok32(data),
|
|
9089
9256
|
duration: duration2,
|
|
9090
9257
|
...hookOutputs ? { hookOutputs } : {}
|
|
9091
9258
|
});
|
|
@@ -9113,7 +9280,7 @@ async function executeChain(input, options) {
|
|
|
9113
9280
|
results.push({
|
|
9114
9281
|
command: `${cmdName} ${subCommand}`,
|
|
9115
9282
|
raw: cmdStr,
|
|
9116
|
-
...
|
|
9283
|
+
...fail17(errorMessage),
|
|
9117
9284
|
duration: duration2
|
|
9118
9285
|
});
|
|
9119
9286
|
if (type === "and") {
|