@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.
@@ -102,12 +102,12 @@ function classifyFailure(message) {
102
102
 
103
103
  // src/executor.ts
104
104
  import {
105
- ok as ok31,
106
- fail as fail16,
105
+ ok as ok32,
106
+ fail as fail17,
107
107
  isCommandResult,
108
108
  CompositeStorage as CompositeStorage2,
109
109
  TipCollector as TipCollector2,
110
- normalizeTips as normalizeTips6,
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/tab.ts
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 TabParams = z27.object({
5886
- subcommand: z27.enum(["list", "new", "close", "switch"]),
5887
- url: z27.string().optional(),
5888
- index: z27.number().int().min(0).optional()
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: z27.object({
5896
- success: z27.boolean(),
5897
- data: z27.unknown()
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 fail12("No browser context available. Use --cdp to connect to a browser first.");
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 fail12(`Unknown subcommand: ${p.subcommand}`);
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 ok26({ tabs, total: tabs.length, activeIndex });
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 ok26({
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 fail12("Cannot close the last remaining tab");
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 fail12(`Invalid tab index: ${closeIndex}. Valid range: 0-${currentPages.length - 1}`);
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 ok26({
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 fail12("Parameter --index is required for switch subcommand");
6162
+ return fail13("Parameter --index is required for switch subcommand");
5996
6163
  }
5997
6164
  if (p.index < 0 || p.index >= pages.length) {
5998
- return fail12(`Invalid tab index: ${p.index}. Valid range: 0-${pages.length - 1}`);
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 ok26({
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 z28 } from "zod";
6030
- import { ok as ok27 } from "@dyyz1993/xcli-core";
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 = z28.object({
6172
- script: z28.string().optional(),
6173
- file: z28.string().optional(),
6174
- stdin: z28.boolean().optional(),
6175
- name: z28.string().optional(),
6176
- list: z28.boolean().optional(),
6177
- remove: z28.union([z28.string(), z28.boolean()]).optional(),
6178
- base64: z28.string().optional()
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: z28.object({
6213
- scripts: z28.array(z28.object({ name: z28.string(), size: z28.number(), preview: z28.string() })).optional(),
6214
- removed: z28.string().optional(),
6215
- existed: z28.boolean().optional(),
6216
- error: z28.string().optional(),
6217
- registered: z28.string().optional(),
6218
- hint: z28.string().optional(),
6219
- executedImmediately: z28.boolean().optional()
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 ok27({ scripts });
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 ok27({ removed: params.remove, existed });
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 ok27({ removed: removeTarget, existed });
6404
+ return ok28({ removed: removeTarget, existed });
6238
6405
  }
6239
6406
  let content = params.stdin ? await readStdin() : resolveScriptContent(params);
6240
6407
  if (!content) {
6241
- return ok27({ error: "No script content provided. Use --script, --file, --stdin, or --base64" });
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 ok27({
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 ok27({ registered: scriptName, executedImmediately: true });
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 z29 } from "zod";
6261
- import { ok as ok28, fail as fail13, normalizeTips as normalizeTips5 } from "@dyyz1993/xcli-core";
6262
- var actionSchema2 = z29.enum(["click", "fill", "type", "select", "hover", "check"]);
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: z29.object({
6268
- strategy: z29.enum(["text", "role", "label", "placeholder", "testid", "alt", "title", "first", "last", "nth"]),
6269
- value: z29.string(),
6270
- name: z29.string().optional(),
6271
- exact: z29.boolean().optional().default(false),
6272
- operation: z29.string().optional().describe('Trailing operation syntax, e.g. click, fill "text", type "text"'),
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: z29.string().optional().describe("Value for fill/type/select when using action"),
6275
- index: z29.number().int().optional().describe("Index for nth strategy"),
6276
- click: z29.boolean().optional().default(false),
6277
- fill: z29.string().optional(),
6278
- type: z29.string().optional(),
6279
- select: z29.string().optional(),
6280
- hover: z29.boolean().optional().default(false),
6281
- check: z29.boolean().optional().default(false),
6282
- timeout: z29.number().optional().default(1e4)
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: z29.object({
6285
- matched: z29.number(),
6286
- selector: z29.string(),
6287
- action: z29.string().optional()
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 fail13(`No element found with ${p.strategy}="${p.value}"`);
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 fail13("find fill requires a value");
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 fail13("find type requires a value");
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 fail13("find select requires a value");
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 = ok28(data);
6337
- if (tips.length > 0) result.tips = normalizeTips5(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 z30 } from "zod";
6436
- import { ok as ok29, fail as fail14 } from "@dyyz1993/xcli-core";
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: z30.object({
6528
- action: z30.enum(["tag", "lookup", "clear", "list"]),
6529
- id: z30.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 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: z30.object({
6532
- action: z30.string(),
6533
- tagged: z30.number().optional(),
6534
- id: z30.string().optional(),
6535
- element: z30.record(z30.unknown()).optional()
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 ok29({ action: "tag", tagged: parsed.tagged });
6709
+ return ok30({ action: "tag", tagged: parsed.tagged });
6543
6710
  }
6544
6711
  case "lookup": {
6545
- if (!p.id) return fail14("lookup \u9700\u8981 --id \u53C2\u6570");
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 fail14(`ID ${p.id}: ${parsed.err}`);
6551
- return ok29({ action: "lookup", id: p.id, element: parsed });
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 ok29({ action: "list", element: JSON.parse(result) });
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 ok29({ action: "clear" });
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 z31 } from "zod";
6569
- import { ok as ok30, fail as fail15 } from "@dyyz1993/xcli-core";
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: z31.object({
6917
- action: z31.enum(["tag", "lookup", "clear", "stats", "by-type", "find", "export", "interact"]),
6918
- id: z31.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID"),
6919
- query: z31.string().optional().describe('find \u65F6\u6307\u5B9A\u641C\u7D22\u8BCD\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09'),
6920
- type: z31.string().optional().describe("by-type \u65F6\u8FC7\u6EE4\u7C7B\u578B\uFF1Aclick/input/img/list/count/text"),
6921
- "interact-action": z31.enum(["click", "fill", "read"]).optional().describe("interact \u52A8\u4F5C\u7C7B\u578B"),
6922
- value: z31.string().optional().describe("fill \u65F6\u7684\u586B\u5145\u503C")
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: z31.object({
6925
- action: z31.string(),
6926
- total: z31.number().optional(),
6927
- byType: z31.record(z31.number()).optional(),
6928
- element: z31.record(z31.unknown()).optional()
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 ok30({ action: "tag", total: parsed.total, byType: parsed.byType });
7102
+ return ok31({ action: "tag", total: parsed.total, byType: parsed.byType });
6936
7103
  }
6937
7104
  case "lookup": {
6938
- if (!p.id) return fail15("lookup \u9700\u8981 --id");
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 fail15(`ID ${p.id}: ${parsed.err}`);
6944
- return ok30({ action: "lookup", id: p.id, element: parsed });
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 ok30({ action: "by-type", element: JSON.parse(result) });
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 fail15('find \u9700\u8981 --query \u53C2\u6570\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09');
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 ok30({ action: "find", query, element: JSON.parse(result) });
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 ok30({ action: "stats", element: JSON.parse(result) });
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 fail15("interact \u9700\u8981 --query \u53C2\u6570");
7010
- if (!action) return fail15("interact \u9700\u8981 --interact-action \u53C2\u6570\uFF08click/fill/read\uFF09");
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 fail15(parsed.err);
7041
- if (!parsed.total || !parsed.results?.length) return fail15(`\u672A\u627E\u5230\u5339\u914D "${query}" \u7684\u5143\u7D20`);
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 ok30({ action: "interact", query, target, result: { read: target.text || target.label } });
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 fail15(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
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 ok30({ action: "interact", query, target, result: { clicked: true, x: el.x, y: el.y } });
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 fail15("fill \u9700\u8981 --value \u53C2\u6570");
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 fail15(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
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 ok30({ action: "interact", query, target, result: { filled: true, value } });
7243
+ return ok31({ action: "interact", query, target, result: { filled: true, value } });
7077
7244
  }
7078
- return fail15(`\u672A\u77E5 action: ${action}`);
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 fail15(String(parsed.err));
7127
- return ok30({ action: "export", element: parsed });
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 ok30({ action: "clear" });
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 { ...fail16(message), duration: 0 };
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 = normalizeTips6(resolved.tips);
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
- ...normalizeTips6(smartTips),
8064
- ...snapshotHint ? normalizeTips6([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 { ...ok31(raw.data, merged.length > 0 ? merged : raw.tips), duration, ...hookOutputs ? { hookOutputs } : {} };
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 = normalizeTips6(smartTips);
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 { ...ok31(raw, smartTipNormalized), duration, ...hookOutputs ? { hookOutputs } : {} };
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 { ...fail16(errorMessage), duration };
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
- ...fail16(`Plugin "${cmdName}" requires a sub-command`),
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
- ...fail16(`Unknown command "${subCommand}" for plugin "${cmdName}"`),
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: normalizeTips6(loginGuard.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
- ...ok31(data),
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
- ...fail16(errorMessage),
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 ok32 = input.ok ?? errors.length === 0;
9942
+ const ok33 = input.ok ?? errors.length === 0;
9776
9943
  return {
9777
- ok: ok32,
9778
- success: ok32,
9944
+ ok: ok33,
9945
+ success: ok33,
9779
9946
  duration: typeof input.duration === "number" ? input.duration : 0,
9780
9947
  eventsPlayed,
9781
9948
  totalEvents,