@xbrowser/cli 1.25.2 → 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.
@@ -9,7 +9,7 @@ import {
9
9
  resolveLaunchOpts,
10
10
  saveSessionDiskMeta,
11
11
  setActivePage
12
- } from "./chunk-NNI5RT4A.js";
12
+ } from "./chunk-KECYFWJO.js";
13
13
  import {
14
14
  detectAntiBot,
15
15
  formatDetectionMessage
@@ -867,10 +867,14 @@ var clickCommand = registerCommand({
867
867
  targetIdsBefore = /* @__PURE__ */ new Set();
868
868
  }
869
869
  const pagePromise = new Promise((resolve3) => {
870
+ const waitMs = (() => {
871
+ const v = parseInt(process.env.XBROWSER_NEW_TAB_WAIT ?? "250", 10);
872
+ return Number.isFinite(v) && v > 0 ? v : 250;
873
+ })();
870
874
  const timer = setTimeout(() => {
871
875
  ctx.browserContext.off("page", handler);
872
876
  resolve3(void 0);
873
- }, 3e3);
877
+ }, waitMs);
874
878
  const handler = (page2) => {
875
879
  if (targetIdsBefore.has(targetIdOf(page2))) return;
876
880
  try {
@@ -6053,26 +6057,193 @@ var waitForCommand = registerCommand({
6053
6057
  }
6054
6058
  });
6055
6059
 
6056
- // src/commands/tab.ts
6060
+ // src/commands/task.ts
6057
6061
  import { z as z27 } from "zod";
6058
- import { ok as ok26, fail as fail12 } from "@dyyz1993/xcli-core";
6059
- var TabParams = z27.object({
6060
- subcommand: z27.enum(["list", "new", "close", "switch"]),
6061
- url: z27.string().optional(),
6062
- index: z27.number().int().min(0).optional()
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()
6063
6234
  });
6064
6235
  var tabCommand = registerCommand({
6065
6236
  name: "tab",
6066
6237
  description: "Manage browser tabs: list, new, close, switch",
6067
6238
  scope: "page",
6068
6239
  parameters: TabParams,
6069
- result: z27.object({
6070
- success: z27.boolean(),
6071
- data: z27.unknown()
6240
+ result: z28.object({
6241
+ success: z28.boolean(),
6242
+ data: z28.unknown()
6072
6243
  }),
6073
6244
  handler: async (p, ctx) => {
6074
6245
  if (!ctx.browserContext) {
6075
- return fail12("No browser context available. Use --cdp to connect to a browser first.");
6246
+ return fail13("No browser context available. Use --cdp to connect to a browser first.");
6076
6247
  }
6077
6248
  const pages = ctx.browserContext.pages();
6078
6249
  switch (p.subcommand) {
@@ -6085,7 +6256,7 @@ var tabCommand = registerCommand({
6085
6256
  case "switch":
6086
6257
  return handleSwitch(p, pages, ctx);
6087
6258
  default:
6088
- return fail12(`Unknown subcommand: ${p.subcommand}`);
6259
+ return fail13(`Unknown subcommand: ${p.subcommand}`);
6089
6260
  }
6090
6261
  }
6091
6262
  });
@@ -6100,7 +6271,7 @@ async function handleList(pages, ctx) {
6100
6271
  if (isActive) activeIndex = i;
6101
6272
  tabs.push({ index: i, url, title, active: isActive });
6102
6273
  }
6103
- return ok26({ tabs, total: tabs.length, activeIndex });
6274
+ return ok27({ tabs, total: tabs.length, activeIndex });
6104
6275
  }
6105
6276
  async function handleNew(p, _pages, ctx) {
6106
6277
  const newPage = await ctx.browserContext.newPage();
@@ -6128,7 +6299,7 @@ async function handleNew(p, _pages, ctx) {
6128
6299
  const title = await newPage.title().catch(() => "");
6129
6300
  const allPages = ctx.browserContext.pages();
6130
6301
  const newIndex = allPages.indexOf(newPage);
6131
- return ok26({
6302
+ return ok27({
6132
6303
  index: newIndex >= 0 ? newIndex : allPages.length - 1,
6133
6304
  url: newPage.url(),
6134
6305
  title,
@@ -6139,11 +6310,11 @@ async function handleNew(p, _pages, ctx) {
6139
6310
  async function handleClose(p, ctx) {
6140
6311
  const currentPages = ctx.browserContext.pages();
6141
6312
  if (currentPages.length <= 1) {
6142
- return fail12("Cannot close the last remaining tab");
6313
+ return fail13("Cannot close the last remaining tab");
6143
6314
  }
6144
6315
  const closeIndex = p.index ?? currentPages.findIndex((pg) => pg === ctx.page);
6145
6316
  if (closeIndex < 0 || closeIndex >= currentPages.length) {
6146
- return fail12(`Invalid tab index: ${closeIndex}. Valid range: 0-${currentPages.length - 1}`);
6317
+ return fail13(`Invalid tab index: ${closeIndex}. Valid range: 0-${currentPages.length - 1}`);
6147
6318
  }
6148
6319
  const pageToClose = currentPages[closeIndex];
6149
6320
  const isActivePage = pageToClose === ctx.page;
@@ -6158,7 +6329,7 @@ async function handleClose(p, ctx) {
6158
6329
  }
6159
6330
  ctx.page = newActivePage;
6160
6331
  }
6161
- return ok26({
6332
+ return ok27({
6162
6333
  closedIndex: closeIndex,
6163
6334
  total: remainingPages.length,
6164
6335
  activeIndex: isActivePage ? closeIndex < remainingPages.length ? closeIndex : remainingPages.length - 1 : remainingPages.findIndex((pg) => pg === ctx.page)
@@ -6166,10 +6337,10 @@ async function handleClose(p, ctx) {
6166
6337
  }
6167
6338
  async function handleSwitch(p, pages, ctx) {
6168
6339
  if (p.index === void 0) {
6169
- return fail12("Parameter --index is required for switch subcommand");
6340
+ return fail13("Parameter --index is required for switch subcommand");
6170
6341
  }
6171
6342
  if (p.index < 0 || p.index >= pages.length) {
6172
- return fail12(`Invalid tab index: ${p.index}. Valid range: 0-${pages.length - 1}`);
6343
+ return fail13(`Invalid tab index: ${p.index}. Valid range: 0-${pages.length - 1}`);
6173
6344
  }
6174
6345
  const targetPage = pages[p.index];
6175
6346
  await targetPage.bringToFront().catch(() => {
@@ -6191,7 +6362,7 @@ async function handleSwitch(p, pages, ctx) {
6191
6362
  }
6192
6363
  ctx.page = targetPage;
6193
6364
  const title = await targetPage.title().catch(() => "");
6194
- return ok26({
6365
+ return ok27({
6195
6366
  index: p.index,
6196
6367
  url: targetPage.url(),
6197
6368
  title,
@@ -6200,17 +6371,17 @@ async function handleSwitch(p, pages, ctx) {
6200
6371
  }
6201
6372
 
6202
6373
  // src/commands/addinitscript.ts
6203
- import { z as z28 } from "zod";
6204
- import { ok as ok27 } from "@dyyz1993/xcli-core";
6374
+ import { z as z29 } from "zod";
6375
+ import { ok as ok28 } from "@dyyz1993/xcli-core";
6205
6376
  import { readFileSync as readFileSync4 } from "fs";
6206
- var InitScriptParams = z28.object({
6207
- script: z28.string().optional(),
6208
- file: z28.string().optional(),
6209
- stdin: z28.boolean().optional(),
6210
- name: z28.string().optional(),
6211
- list: z28.boolean().optional(),
6212
- remove: z28.union([z28.string(), z28.boolean()]).optional(),
6213
- base64: z28.string().optional()
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()
6214
6385
  });
6215
6386
  var registeredScripts = /* @__PURE__ */ new Map();
6216
6387
  function resolveScriptContent(params) {
@@ -6244,14 +6415,14 @@ var addInitScriptCommand = registerCommand({
6244
6415
  description: "Add an initialization script that runs on every page load",
6245
6416
  scope: "page",
6246
6417
  parameters: InitScriptParams,
6247
- result: z28.object({
6248
- scripts: z28.array(z28.object({ name: z28.string(), size: z28.number(), preview: z28.string() })).optional(),
6249
- removed: z28.string().optional(),
6250
- existed: z28.boolean().optional(),
6251
- error: z28.string().optional(),
6252
- registered: z28.string().optional(),
6253
- hint: z28.string().optional(),
6254
- executedImmediately: z28.boolean().optional()
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()
6255
6426
  }).passthrough(),
6256
6427
  handler: async (params, ctx) => {
6257
6428
  if (params.list) {
@@ -6260,20 +6431,20 @@ var addInitScriptCommand = registerCommand({
6260
6431
  size: content2.length,
6261
6432
  preview: content2.slice(0, 80)
6262
6433
  }));
6263
- return ok27({ scripts });
6434
+ return ok28({ scripts });
6264
6435
  }
6265
6436
  if (params.remove && typeof params.remove === "string") {
6266
6437
  const existed = registeredScripts.delete(params.remove);
6267
- return ok27({ removed: params.remove, existed });
6438
+ return ok28({ removed: params.remove, existed });
6268
6439
  }
6269
6440
  const removeTarget = (typeof params.remove === "string" ? params.remove : null) || (params.name && !resolveScriptContent(params) ? params.name : null);
6270
6441
  if (removeTarget && !resolveScriptContent(params)) {
6271
6442
  const existed = registeredScripts.delete(removeTarget);
6272
- return ok27({ removed: removeTarget, existed });
6443
+ return ok28({ removed: removeTarget, existed });
6273
6444
  }
6274
6445
  let content = params.stdin ? await readStdin() : resolveScriptContent(params);
6275
6446
  if (!content) {
6276
- return ok27({ error: "No script content provided. Use --script, --file, --stdin, or --base64" });
6447
+ return ok28({ error: "No script content provided. Use --script, --file, --stdin, or --base64" });
6277
6448
  }
6278
6449
  const scriptName = params.name ?? `script-${Date.now()}`;
6279
6450
  registeredScripts.set(scriptName, content);
@@ -6281,45 +6452,45 @@ var addInitScriptCommand = registerCommand({
6281
6452
  try {
6282
6453
  await ctx.page.evaluate(content);
6283
6454
  } catch {
6284
- return ok27({
6455
+ return ok28({
6285
6456
  registered: scriptName,
6286
6457
  hint: "Script registered for future page loads; immediate execution skipped (page may not be ready)"
6287
6458
  });
6288
6459
  }
6289
- return ok27({ registered: scriptName, executedImmediately: true });
6460
+ return ok28({ registered: scriptName, executedImmediately: true });
6290
6461
  }
6291
6462
  });
6292
6463
  registerCommandDefinition("addinitscript", ["script"]);
6293
6464
 
6294
6465
  // src/commands/find.ts
6295
- import { z as z29 } from "zod";
6296
- import { ok as ok28, fail as fail13, normalizeTips as normalizeTips5 } from "@dyyz1993/xcli-core";
6297
- var actionSchema2 = z29.enum(["click", "fill", "type", "select", "hover", "check"]);
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"]);
6298
6469
  var findCommand = registerCommand({
6299
6470
  name: "find",
6300
6471
  description: "Find elements by semantic strategy (text/role/label/placeholder/testid) and optionally perform an action",
6301
6472
  scope: "page",
6302
- parameters: z29.object({
6303
- strategy: z29.enum(["text", "role", "label", "placeholder", "testid", "alt", "title", "first", "last", "nth"]),
6304
- value: z29.string(),
6305
- name: z29.string().optional(),
6306
- exact: z29.boolean().optional().default(false),
6307
- operation: z29.string().optional().describe('Trailing operation syntax, e.g. click, fill "text", type "text"'),
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"'),
6308
6479
  action: actionSchema2.optional().describe("Action to perform when not using trailing operation syntax"),
6309
- actionValue: z29.string().optional().describe("Value for fill/type/select when using action"),
6310
- index: z29.number().int().optional().describe("Index for nth strategy"),
6311
- click: z29.boolean().optional().default(false),
6312
- fill: z29.string().optional(),
6313
- type: z29.string().optional(),
6314
- select: z29.string().optional(),
6315
- hover: z29.boolean().optional().default(false),
6316
- check: z29.boolean().optional().default(false),
6317
- timeout: z29.number().optional().default(1e4)
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)
6318
6489
  }),
6319
- result: z29.object({
6320
- matched: z29.number(),
6321
- selector: z29.string(),
6322
- action: z29.string().optional()
6490
+ result: z30.object({
6491
+ matched: z30.number(),
6492
+ selector: z30.string(),
6493
+ action: z30.string().optional()
6323
6494
  }),
6324
6495
  handler: async (p, ctx) => {
6325
6496
  const page = ctx.page;
@@ -6334,7 +6505,7 @@ var findCommand = registerCommand({
6334
6505
  });
6335
6506
  const count = await locator.count();
6336
6507
  if (count === 0) {
6337
- return fail13(`No element found with ${p.strategy}="${p.value}"`);
6508
+ return fail14(`No element found with ${p.strategy}="${p.value}"`);
6338
6509
  }
6339
6510
  const tips = [];
6340
6511
  const target = selectTarget(locator, p.strategy);
@@ -6346,15 +6517,15 @@ var findCommand = registerCommand({
6346
6517
  await target.click({ timeout: p.timeout, force: true });
6347
6518
  return okWithTips({ matched: count, selector, action: "click" }, tips);
6348
6519
  } else if (actionName === "fill") {
6349
- if (actionValue === void 0) return fail13("find fill requires a value");
6520
+ if (actionValue === void 0) return fail14("find fill requires a value");
6350
6521
  await target.fill(actionValue, { timeout: p.timeout, force: true });
6351
6522
  return okWithTips({ matched: count, selector, action: `fill("${actionValue}")` }, tips);
6352
6523
  } else if (actionName === "type") {
6353
- if (actionValue === void 0) return fail13("find type requires a value");
6524
+ if (actionValue === void 0) return fail14("find type requires a value");
6354
6525
  await target.type(actionValue, { delay: 10, timeout: p.timeout });
6355
6526
  return okWithTips({ matched: count, selector, action: `type("${actionValue}")` }, tips);
6356
6527
  } else if (actionName === "select") {
6357
- if (actionValue === void 0) return fail13("find select requires a value");
6528
+ if (actionValue === void 0) return fail14("find select requires a value");
6358
6529
  await target.selectOption(actionValue);
6359
6530
  return okWithTips({ matched: count, selector, action: `select("${actionValue}")` }, tips);
6360
6531
  } else if (actionName === "hover") {
@@ -6368,8 +6539,8 @@ var findCommand = registerCommand({
6368
6539
  }
6369
6540
  });
6370
6541
  function okWithTips(data, tips) {
6371
- const result = ok28(data);
6372
- if (tips.length > 0) result.tips = normalizeTips5(tips);
6542
+ const result = ok29(data);
6543
+ if (tips.length > 0) result.tips = normalizeTips6(tips);
6373
6544
  return result;
6374
6545
  }
6375
6546
  function parseOperation(operation) {
@@ -6467,8 +6638,8 @@ function describeSelector(strategy, value, name) {
6467
6638
  }
6468
6639
 
6469
6640
  // src/commands/visual-tag.ts
6470
- import { z as z30 } from "zod";
6471
- import { ok as ok29, fail as fail14 } from "@dyyz1993/xcli-core";
6641
+ import { z as z31 } from "zod";
6642
+ import { ok as ok30, fail as fail15 } from "@dyyz1993/xcli-core";
6472
6643
  var SAFE_SET = "ahjkmnprtw3479".split("");
6473
6644
  var TAG_SCRIPT = `
6474
6645
  (function() {
@@ -6559,49 +6730,49 @@ var visualTagCommand = registerCommand({
6559
6730
  name: "visual-tag",
6560
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",
6561
6732
  scope: "page",
6562
- parameters: z30.object({
6563
- action: z30.enum(["tag", "lookup", "clear", "list"]),
6564
- id: z30.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 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")
6565
6736
  }),
6566
- result: z30.object({
6567
- action: z30.string(),
6568
- tagged: z30.number().optional(),
6569
- id: z30.string().optional(),
6570
- element: z30.record(z30.unknown()).optional()
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()
6571
6742
  }),
6572
6743
  handler: async (p, ctx) => {
6573
6744
  switch (p.action) {
6574
6745
  case "tag": {
6575
6746
  const result = await ctx.page.evaluate(TAG_SCRIPT);
6576
6747
  const parsed = JSON.parse(result);
6577
- return ok29({ action: "tag", tagged: parsed.tagged });
6748
+ return ok30({ action: "tag", tagged: parsed.tagged });
6578
6749
  }
6579
6750
  case "lookup": {
6580
- if (!p.id) return fail14("lookup \u9700\u8981 --id \u53C2\u6570");
6751
+ if (!p.id) return fail15("lookup \u9700\u8981 --id \u53C2\u6570");
6581
6752
  const result = await ctx.page.evaluate(
6582
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'}); })()`
6583
6754
  );
6584
6755
  const parsed = JSON.parse(result);
6585
- if (parsed.err) return fail14(`ID ${p.id}: ${parsed.err}`);
6586
- return ok29({ action: "lookup", id: p.id, element: parsed });
6756
+ if (parsed.err) return fail15(`ID ${p.id}: ${parsed.err}`);
6757
+ return ok30({ action: "lookup", id: p.id, element: parsed });
6587
6758
  }
6588
6759
  case "list": {
6589
6760
  const result = await ctx.page.evaluate(
6590
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); })()`
6591
6762
  );
6592
- return ok29({ action: "list", element: JSON.parse(result) });
6763
+ return ok30({ action: "list", element: JSON.parse(result) });
6593
6764
  }
6594
6765
  case "clear": {
6595
6766
  await ctx.page.evaluate(`(function(){var o=document.getElementById('__xb-tag-overlay');if(o)o.remove();window.__xbTagMap=null;return 'cleared'})()`);
6596
- return ok29({ action: "clear" });
6767
+ return ok30({ action: "clear" });
6597
6768
  }
6598
6769
  }
6599
6770
  }
6600
6771
  });
6601
6772
 
6602
6773
  // src/commands/visual-tag-v2.ts
6603
- import { z as z31 } from "zod";
6604
- import { ok as ok30, fail as fail15 } from "@dyyz1993/xcli-core";
6774
+ import { z as z32 } from "zod";
6775
+ import { ok as ok31, fail as fail16 } from "@dyyz1993/xcli-core";
6605
6776
  var SAFE_SET2 = "ahjkmnprtw3479".split("");
6606
6777
  var TAG_V2_SCRIPT = `
6607
6778
  (function() {
@@ -6948,45 +7119,45 @@ var visualTagV2Command = registerCommand({
6948
7119
  name: "visual-tag-v2",
6949
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",
6950
7121
  scope: "page",
6951
- parameters: z31.object({
6952
- action: z31.enum(["tag", "lookup", "clear", "stats", "by-type", "find", "export", "interact"]),
6953
- id: z31.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID"),
6954
- query: z31.string().optional().describe('find \u65F6\u6307\u5B9A\u641C\u7D22\u8BCD\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09'),
6955
- type: z31.string().optional().describe("by-type \u65F6\u8FC7\u6EE4\u7C7B\u578B\uFF1Aclick/input/img/list/count/text"),
6956
- "interact-action": z31.enum(["click", "fill", "read"]).optional().describe("interact \u52A8\u4F5C\u7C7B\u578B"),
6957
- value: z31.string().optional().describe("fill \u65F6\u7684\u586B\u5145\u503C")
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")
6958
7129
  }),
6959
- result: z31.object({
6960
- action: z31.string(),
6961
- total: z31.number().optional(),
6962
- byType: z31.record(z31.number()).optional(),
6963
- element: z31.record(z31.unknown()).optional()
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()
6964
7135
  }),
6965
7136
  handler: async (p, ctx) => {
6966
7137
  switch (p.action) {
6967
7138
  case "tag": {
6968
7139
  const result = await ctx.page.evaluate(TAG_V2_SCRIPT);
6969
7140
  const parsed = JSON.parse(result);
6970
- return ok30({ action: "tag", total: parsed.total, byType: parsed.byType });
7141
+ return ok31({ action: "tag", total: parsed.total, byType: parsed.byType });
6971
7142
  }
6972
7143
  case "lookup": {
6973
- if (!p.id) return fail15("lookup \u9700\u8981 --id");
7144
+ if (!p.id) return fail16("lookup \u9700\u8981 --id");
6974
7145
  const result = await ctx.page.evaluate(
6975
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'})})()`
6976
7147
  );
6977
7148
  const parsed = JSON.parse(result);
6978
- if (parsed.err) return fail15(`ID ${p.id}: ${parsed.err}`);
6979
- return ok30({ action: "lookup", id: p.id, element: parsed });
7149
+ if (parsed.err) return fail16(`ID ${p.id}: ${parsed.err}`);
7150
+ return ok31({ action: "lookup", id: p.id, element: parsed });
6980
7151
  }
6981
7152
  case "by-type": {
6982
7153
  const result = await ctx.page.evaluate(
6983
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)})()`
6984
7155
  );
6985
- return ok30({ action: "by-type", element: JSON.parse(result) });
7156
+ return ok31({ action: "by-type", element: JSON.parse(result) });
6986
7157
  }
6987
7158
  case "find": {
6988
7159
  const query = p.query;
6989
- if (!query) return fail15('find \u9700\u8981 --query \u53C2\u6570\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09');
7160
+ if (!query) return fail16('find \u9700\u8981 --query \u53C2\u6570\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09');
6990
7161
  const result = await ctx.page.evaluate(
6991
7162
  `(function(){
6992
7163
  var map = window.__xbTagSerializable;
@@ -7028,21 +7199,21 @@ var visualTagV2Command = registerCommand({
7028
7199
  return JSON.stringify({total:results.length, results:results.slice(0,20)});
7029
7200
  })()`
7030
7201
  );
7031
- return ok30({ action: "find", query, element: JSON.parse(result) });
7202
+ return ok31({ action: "find", query, element: JSON.parse(result) });
7032
7203
  }
7033
7204
  case "stats": {
7034
7205
  const result = await ctx.page.evaluate(
7035
7206
  `(function(){return JSON.stringify(window.__xbTagStats||{})})()`
7036
7207
  );
7037
- return ok30({ action: "stats", element: JSON.parse(result) });
7208
+ return ok31({ action: "stats", element: JSON.parse(result) });
7038
7209
  }
7039
7210
  case "interact": {
7040
7211
  const query = p.query;
7041
7212
  const pAny = p;
7042
7213
  const action = pAny["interact-action"] || pAny.interactAction || pAny.interact_action;
7043
7214
  const value = pAny.value;
7044
- if (!query) return fail15("interact \u9700\u8981 --query \u53C2\u6570");
7045
- if (!action) return fail15("interact \u9700\u8981 --interact-action \u53C2\u6570\uFF08click/fill/read\uFF09");
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");
7046
7217
  const findResult = await ctx.page.evaluate(
7047
7218
  `(function(){
7048
7219
  var map = window.__xbTagSerializable;
@@ -7072,11 +7243,11 @@ var visualTagV2Command = registerCommand({
7072
7243
  })()`
7073
7244
  );
7074
7245
  const parsed = JSON.parse(findResult);
7075
- if (parsed.err) return fail15(parsed.err);
7076
- if (!parsed.total || !parsed.results?.length) return fail15(`\u672A\u627E\u5230\u5339\u914D "${query}" \u7684\u5143\u7D20`);
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`);
7077
7248
  const target = parsed.results[0];
7078
7249
  if (action === "read") {
7079
- return ok30({ action: "interact", query, target, result: { read: target.text || target.label } });
7250
+ return ok31({ action: "interact", query, target, result: { read: target.text || target.label } });
7080
7251
  }
7081
7252
  if (action === "click") {
7082
7253
  const el = await ctx.page.evaluate(
@@ -7089,12 +7260,12 @@ var visualTagV2Command = registerCommand({
7089
7260
  return {x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2)};
7090
7261
  })()`
7091
7262
  );
7092
- if (!el) return fail15(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
7263
+ if (!el) return fail16(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
7093
7264
  await ctx.page.mouse.click(el.x, el.y, { stealth: true });
7094
- return ok30({ action: "interact", query, target, result: { clicked: true, x: el.x, y: el.y } });
7265
+ return ok31({ action: "interact", query, target, result: { clicked: true, x: el.x, y: el.y } });
7095
7266
  }
7096
7267
  if (action === "fill") {
7097
- if (!value) return fail15("fill \u9700\u8981 --value \u53C2\u6570");
7268
+ if (!value) return fail16("fill \u9700\u8981 --value \u53C2\u6570");
7098
7269
  const el = await ctx.page.evaluate(
7099
7270
  `(function(){
7100
7271
  var map = window.__xbTagMap;
@@ -7105,12 +7276,12 @@ var visualTagV2Command = registerCommand({
7105
7276
  return {x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2)};
7106
7277
  })()`
7107
7278
  );
7108
- if (!el) return fail15(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
7279
+ if (!el) return fail16(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
7109
7280
  await ctx.page.mouse.click(el.x, el.y, { stealth: true });
7110
7281
  await ctx.page.keyboard.type(value, { stealth: true });
7111
- return ok30({ action: "interact", query, target, result: { filled: true, value } });
7282
+ return ok31({ action: "interact", query, target, result: { filled: true, value } });
7112
7283
  }
7113
- return fail15(`\u672A\u77E5 action: ${action}`);
7284
+ return fail16(`\u672A\u77E5 action: ${action}`);
7114
7285
  }
7115
7286
  case "export": {
7116
7287
  const result = await ctx.page.evaluate(
@@ -7158,12 +7329,12 @@ var visualTagV2Command = registerCommand({
7158
7329
  })()`
7159
7330
  );
7160
7331
  const parsed = JSON.parse(result);
7161
- if (parsed.err) return fail15(String(parsed.err));
7162
- return ok30({ action: "export", element: parsed });
7332
+ if (parsed.err) return fail16(String(parsed.err));
7333
+ return ok31({ action: "export", element: parsed });
7163
7334
  }
7164
7335
  case "clear": {
7165
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'})()`);
7166
- return ok30({ action: "clear" });
7337
+ return ok31({ action: "clear" });
7167
7338
  }
7168
7339
  }
7169
7340
  }
@@ -7689,12 +7860,12 @@ function classifyFailure(message) {
7689
7860
 
7690
7861
  // src/executor.ts
7691
7862
  import {
7692
- ok as ok31,
7693
- fail as fail16,
7863
+ ok as ok32,
7864
+ fail as fail17,
7694
7865
  isCommandResult,
7695
7866
  CompositeStorage as CompositeStorage2,
7696
7867
  TipCollector as TipCollector2,
7697
- normalizeTips as normalizeTips6,
7868
+ normalizeTips as normalizeTips7,
7698
7869
  configureArchiveStore,
7699
7870
  appendCommandToArchive,
7700
7871
  checkGuard,
@@ -8295,7 +8466,10 @@ function buildSnapshot(elements) {
8295
8466
  }
8296
8467
 
8297
8468
  // src/tips/index.ts
8298
- var DEBOUNCE_MS = 500;
8469
+ function tipsDebounceMs() {
8470
+ const v = parseInt(process.env.XBROWSER_TIPS_DEBOUNCE ?? "120", 10);
8471
+ return Number.isFinite(v) && v > 0 ? v : 0;
8472
+ }
8299
8473
  var SKIP_DETECT_COMMANDS = /* @__PURE__ */ new Set([
8300
8474
  "goto",
8301
8475
  // 导航命令不需要检测
@@ -8387,7 +8561,9 @@ var TipsManager = class {
8387
8561
  }
8388
8562
  }
8389
8563
  debounce() {
8390
- return new Promise((resolve3) => setTimeout(resolve3, DEBOUNCE_MS));
8564
+ const ms = tipsDebounceMs();
8565
+ if (ms <= 0) return Promise.resolve();
8566
+ return new Promise((resolve3) => setTimeout(resolve3, ms));
8391
8567
  }
8392
8568
  formatTips(tips) {
8393
8569
  return tips.map((tip) => {
@@ -8556,7 +8732,7 @@ async function guardCheck(commandName) {
8556
8732
  }
8557
8733
  }
8558
8734
  function errorResult(message) {
8559
- return { ...fail16(message), duration: 0 };
8735
+ return { ...fail17(message), duration: 0 };
8560
8736
  }
8561
8737
  function tipsToMessages(tips) {
8562
8738
  if (!tips || tips.length === 0) return [];
@@ -8636,7 +8812,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8636
8812
  }
8637
8813
  let targetPageOverride = null;
8638
8814
  if (_target && extraOpts?.cdpEndpoint) {
8639
- const { findTargetPage } = await import("./browser-L3TUDYY3.js");
8815
+ const { findTargetPage } = await import("./browser-4IYIHZ6R.js");
8640
8816
  targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
8641
8817
  if (!targetPageOverride) {
8642
8818
  return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
@@ -8748,7 +8924,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8748
8924
  const cache = /* @__PURE__ */ new Map();
8749
8925
  const resolved = await resolveRefParams(session.page, params, command.selectorParams, cache, session.id);
8750
8926
  if (resolved.tips.length > 0) {
8751
- refTips = normalizeTips6(resolved.tips);
8927
+ refTips = normalizeTips7(resolved.tips);
8752
8928
  params = resolved.params;
8753
8929
  }
8754
8930
  }
@@ -8816,8 +8992,8 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8816
8992
  }
8817
8993
  const merged = [
8818
8994
  ...raw.tips || [],
8819
- ...normalizeTips6(smartTips),
8820
- ...snapshotHint ? normalizeTips6([snapshotHint]) : [],
8995
+ ...normalizeTips7(smartTips),
8996
+ ...snapshotHint ? normalizeTips7([snapshotHint]) : [],
8821
8997
  ...refTips
8822
8998
  ];
8823
8999
  const isSuccess = raw.success !== false;
@@ -8832,7 +9008,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8832
9008
  timestamp: start
8833
9009
  });
8834
9010
  if (isSuccess) {
8835
- return { ...ok31(raw.data, merged.length > 0 ? merged : raw.tips), duration, ...hookOutputs ? { hookOutputs } : {} };
9011
+ return { ...ok32(raw.data, merged.length > 0 ? merged : raw.tips), duration, ...hookOutputs ? { hookOutputs } : {} };
8836
9012
  }
8837
9013
  const fc = classifyFailure(raw.message);
8838
9014
  return {
@@ -8845,7 +9021,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8845
9021
  ...hookOutputs ? { hookOutputs } : {}
8846
9022
  };
8847
9023
  }
8848
- const smartTipNormalized = normalizeTips6(smartTips);
9024
+ const smartTipNormalized = normalizeTips7(smartTips);
8849
9025
  recordArchive(session?.id, sessionName, {
8850
9026
  step: 0,
8851
9027
  command: commandName,
@@ -8855,7 +9031,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8855
9031
  duration,
8856
9032
  timestamp: start
8857
9033
  });
8858
- return { ...ok31(raw, smartTipNormalized), duration, ...hookOutputs ? { hookOutputs } : {} };
9034
+ return { ...ok32(raw, smartTipNormalized), duration, ...hookOutputs ? { hookOutputs } : {} };
8859
9035
  } catch (err) {
8860
9036
  const end = Date.now();
8861
9037
  const duration = end - start;
@@ -8900,7 +9076,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8900
9076
  duration,
8901
9077
  timestamp: start
8902
9078
  });
8903
- return { ...fail16(errorMessage), duration };
9079
+ return { ...fail17(errorMessage), duration };
8904
9080
  } finally {
8905
9081
  }
8906
9082
  }
@@ -8945,7 +9121,7 @@ async function executeChain(input, options) {
8945
9121
  results.push({
8946
9122
  command: cmdName,
8947
9123
  raw: cmdStr,
8948
- ...fail16(`Plugin "${cmdName}" requires a sub-command`),
9124
+ ...fail17(`Plugin "${cmdName}" requires a sub-command`),
8949
9125
  duration: 0
8950
9126
  });
8951
9127
  if (type === "and") {
@@ -8964,7 +9140,7 @@ async function executeChain(input, options) {
8964
9140
  results.push({
8965
9141
  command: cmdName,
8966
9142
  raw: cmdStr,
8967
- ...fail16(`Unknown command "${subCommand}" for plugin "${cmdName}"`),
9143
+ ...fail17(`Unknown command "${subCommand}" for plugin "${cmdName}"`),
8968
9144
  duration: 0
8969
9145
  });
8970
9146
  if (type === "and") {
@@ -9034,7 +9210,7 @@ async function executeChain(input, options) {
9034
9210
  success: false,
9035
9211
  data: data2,
9036
9212
  message: loginGuard.message,
9037
- tips: normalizeTips6(loginGuard.tips),
9213
+ tips: normalizeTips7(loginGuard.tips),
9038
9214
  duration: duration3
9039
9215
  });
9040
9216
  if (type === "and") {
@@ -9076,7 +9252,7 @@ async function executeChain(input, options) {
9076
9252
  results.push({
9077
9253
  command: `${cmdName} ${subCommand}`,
9078
9254
  raw: cmdStr,
9079
- ...ok31(data),
9255
+ ...ok32(data),
9080
9256
  duration: duration2,
9081
9257
  ...hookOutputs ? { hookOutputs } : {}
9082
9258
  });
@@ -9104,7 +9280,7 @@ async function executeChain(input, options) {
9104
9280
  results.push({
9105
9281
  command: `${cmdName} ${subCommand}`,
9106
9282
  raw: cmdStr,
9107
- ...fail16(errorMessage),
9283
+ ...fail17(errorMessage),
9108
9284
  duration: duration2
9109
9285
  });
9110
9286
  if (type === "and") {