@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.
@@ -20,7 +20,7 @@ import {
20
20
  resolveLaunchOpts,
21
21
  saveSessionDiskMeta,
22
22
  setActivePage
23
- } from "./chunk-2EEAXSBA.js";
23
+ } from "./chunk-HSYRAV3H.js";
24
24
  import {
25
25
  rand,
26
26
  sleep,
@@ -63,12 +63,12 @@ function classifyFailure(message) {
63
63
 
64
64
  // src/executor.ts
65
65
  import {
66
- ok as ok31,
67
- fail as fail16,
66
+ ok as ok32,
67
+ fail as fail17,
68
68
  isCommandResult,
69
69
  CompositeStorage as CompositeStorage2,
70
70
  TipCollector as TipCollector2,
71
- normalizeTips as normalizeTips6,
71
+ normalizeTips as normalizeTips7,
72
72
  configureArchiveStore,
73
73
  appendCommandToArchive,
74
74
  checkGuard,
@@ -515,10 +515,14 @@ var clickCommand = registerCommand({
515
515
  targetIdsBefore = /* @__PURE__ */ new Set();
516
516
  }
517
517
  const pagePromise = new Promise((resolve3) => {
518
+ const waitMs = (() => {
519
+ const v = parseInt(process.env.XBROWSER_NEW_TAB_WAIT ?? "250", 10);
520
+ return Number.isFinite(v) && v > 0 ? v : 250;
521
+ })();
518
522
  const timer = setTimeout(() => {
519
523
  ctx.browserContext.off("page", handler);
520
524
  resolve3(void 0);
521
- }, 3e3);
525
+ }, waitMs);
522
526
  const handler = (page2) => {
523
527
  if (targetIdsBefore.has(targetIdOf(page2))) return;
524
528
  try {
@@ -5855,26 +5859,193 @@ var waitForCommand = registerCommand({
5855
5859
  }
5856
5860
  });
5857
5861
 
5858
- // src/commands/tab.ts
5862
+ // src/commands/task.ts
5859
5863
  import { z as z27 } from "zod";
5860
- import { ok as ok26, fail as fail12 } from "@dyyz1993/xcli-core";
5861
- var TabParams = z27.object({
5862
- subcommand: z27.enum(["list", "new", "close", "switch"]),
5863
- url: z27.string().optional(),
5864
- index: z27.number().int().min(0).optional()
5864
+ import { ok as ok26, fail as fail12, normalizeTips as normalizeTips5 } from "@dyyz1993/xcli-core";
5865
+ var DECISION_SYSTEM = `\u4F60\u662F\u6D4F\u89C8\u5668\u4EFB\u52A1\u51B3\u7B56\u5668\u3002\u6839\u636E\u76EE\u6807\u3001\u5F53\u524D\u9875\u9762\u5143\u7D20\u6E05\u5355\uFF08\u6BCF\u9879\u5E26 @eN \u7F16\u53F7\uFF09\u548C\u5DF2\u6267\u884C\u5386\u53F2\uFF0C\u8F93\u51FA\u4E0B\u4E00\u6B65\u52A8\u4F5C\u3002
5866
+
5867
+ \u53EF\u7528\u52A8\u4F5C\uFF08\u53EA\u80FD\u8F93\u51FA\u4E00\u4E2A JSON \u5BF9\u8C61\uFF0C\u4E0D\u8981\u8F93\u51FA\u4EFB\u4F55\u5176\u4ED6\u6587\u5B57\uFF09\uFF1A
5868
+ {"action":"click","ref":"@eN","thought":"\u4E3A\u4EC0\u4E48"}
5869
+ {"action":"fill","ref":"@eN","value":"\u6587\u672C","thought":"\u4E3A\u4EC0\u4E48"}
5870
+ {"action":"select","ref":"@eN","value":"\u9009\u9879\u503C","thought":"\u4E3A\u4EC0\u4E48"}
5871
+ {"action":"press","value":"Enter","thought":"\u4E3A\u4EC0\u4E48"}
5872
+ {"action":"scroll","value":"down \u6216 up","thought":"\u4E3A\u4EC0\u4E48"}
5873
+ {"action":"done","value":"\u5B8C\u6210\u6458\u8981","thought":"\u4E3A\u4EC0\u4E48"}
5874
+ {"action":"blocked","value":"\u5361\u4F4F\u539F\u56E0","thought":"\u4E3A\u4EC0\u4E48"}
5875
+
5876
+ \u89C4\u5219\uFF1A
5877
+ 1. ref \u5FC5\u987B\u539F\u6837\u6765\u81EA\u672C\u6B21\u5143\u7D20\u6E05\u5355\uFF1B\u6E05\u5355\u91CC\u6CA1\u6709\u80FD\u63A8\u8FDB\u76EE\u6807\u7684\u5143\u7D20\u5C31\u8F93\u51FA blocked\u3002
5878
+ 2. \u76EE\u6807\u5DF2\u5B8C\u6210\uFF08\u9875\u9762\u4E0A\u80FD\u786E\u8BA4\u7ED3\u679C\uFF09\u5C31\u8F93\u51FA done\uFF0Cvalue \u5199\u5B8C\u6210\u6458\u8981\u3002
5879
+ 3. \u4E0D\u8981\u91CD\u590D\u521A\u5931\u8D25\u8FC7\u7684\u540C\u4E00\u52A8\u4F5C\uFF1B\u8FDE\u7EED\u5931\u8D25\u6362\u601D\u8DEF\u6216 blocked\u3002`;
5880
+ function extractDecision(raw) {
5881
+ let s = raw.trim().replace(/^```(?:json)?\s*/i, "").replace(/\s*```$/, "");
5882
+ const start = s.indexOf("{");
5883
+ if (start < 0) return null;
5884
+ let depth = 0;
5885
+ for (let i = start; i < s.length; i++) {
5886
+ if (s[i] === "{") depth++;
5887
+ else if (s[i] === "}") {
5888
+ depth--;
5889
+ if (depth === 0) {
5890
+ try {
5891
+ return JSON.parse(s.slice(start, i + 1));
5892
+ } catch {
5893
+ return null;
5894
+ }
5895
+ }
5896
+ }
5897
+ }
5898
+ return null;
5899
+ }
5900
+ var taskCommand = registerCommand({
5901
+ name: "task",
5902
+ description: "Autonomous goal loop: observe refs \u2192 LLM decides \u2192 act, until done/blocked (budget-capped)",
5903
+ scope: "page",
5904
+ parameters: z27.object({
5905
+ goal: z27.string().describe("Natural-language goal"),
5906
+ maxSteps: z27.number().int().positive().max(50).optional().default(15).describe("Hard action budget"),
5907
+ timeout: z27.number().optional().default(18e4).describe("Wall clock budget in ms"),
5908
+ limit: z27.number().int().positive().max(300).optional().default(80).describe("Max targets per observe")
5909
+ }),
5910
+ result: z27.object({
5911
+ status: z27.enum(["done", "blocked", "max_steps", "error"]),
5912
+ summary: z27.string().optional(),
5913
+ steps: z27.array(z27.record(z27.unknown())),
5914
+ finalUrl: z27.string().optional(),
5915
+ usage: z27.object({ llmCalls: z27.number(), steps: z27.number() }).passthrough().optional()
5916
+ }).passthrough(),
5917
+ handler: async (p, ctx) => {
5918
+ const creds = loadVLMCredentials2();
5919
+ if (!creds) {
5920
+ return fail12("task \u9700\u8981\u51B3\u7B56\u6A21\u578B\u51ED\u8BC1\uFF1A\u8BBE\u7F6E XBROWSER_VLM_CONFIG \u6216 ~/.zcode/v2/config.json");
5921
+ }
5922
+ const model = process.env.XBROWSER_TASK_MODEL || creds.model;
5923
+ const started = Date.now();
5924
+ const steps = [];
5925
+ const history = [];
5926
+ let llmCalls = 0;
5927
+ let status = "max_steps";
5928
+ let summary = "";
5929
+ let lastError = "";
5930
+ for (let step = 1; step <= p.maxSteps; step++) {
5931
+ if (Date.now() - started > p.timeout) {
5932
+ status = "blocked";
5933
+ summary = `timeout after ${step - 1} steps`;
5934
+ break;
5935
+ }
5936
+ const obs = await observePage(ctx.page, ctx.sessionId, { limit: p.limit, includeHidden: false });
5937
+ const compact = obs.compact ?? obs.targets.map((t, i) => `@e${i + 1} [${t.tag ?? ""}] ${t.name ?? ""}`).join("\n");
5938
+ const screenHash = obs.screenHash;
5939
+ const userPayload = [
5940
+ `\u76EE\u6807\uFF1A${p.goal}`,
5941
+ `\u5F53\u524D\u9875\u9762\uFF08URL: ${obs.url ?? ""}\uFF09\uFF1A`,
5942
+ compact,
5943
+ history.length ? `
5944
+ \u5DF2\u6267\u884C\uFF08\u52FF\u91CD\u590D\u5931\u8D25\u52A8\u4F5C\uFF09\uFF1A
5945
+ ${history.slice(-6).join("\n")}` : ""
5946
+ ].filter(Boolean).join("\n");
5947
+ let raw = "";
5948
+ try {
5949
+ raw = await vlmAsk({ ...creds, model }, [{ type: "text", text: `${DECISION_SYSTEM}
5950
+
5951
+ ---
5952
+
5953
+ ${userPayload}` }], 900);
5954
+ llmCalls++;
5955
+ } catch (e) {
5956
+ lastError = e instanceof Error ? e.message : String(e);
5957
+ status = "error";
5958
+ summary = `LLM call failed: ${lastError}`;
5959
+ break;
5960
+ }
5961
+ const decision = extractDecision(raw);
5962
+ if (!decision || typeof decision.action !== "string") {
5963
+ status = "blocked";
5964
+ summary = `LLM returned unparsable decision: ${raw.slice(0, 120)}`;
5965
+ break;
5966
+ }
5967
+ const action = decision.action;
5968
+ const ref = typeof decision.ref === "string" ? decision.ref : void 0;
5969
+ const value = typeof decision.value === "string" ? decision.value : void 0;
5970
+ const thought = typeof decision.thought === "string" ? decision.thought : void 0;
5971
+ if (action === "done") {
5972
+ status = "done";
5973
+ summary = value || thought || "task done";
5974
+ steps.push({ step, thought, action: "done", ok: true, screenHash });
5975
+ break;
5976
+ }
5977
+ if (action === "blocked") {
5978
+ status = "blocked";
5979
+ summary = value || thought || "LLM judged blocked";
5980
+ steps.push({ step, thought, action: "blocked", ok: true, screenHash });
5981
+ break;
5982
+ }
5983
+ const legalRefs = new Set(obs.targets.map((t, i) => t.ref ?? `e${i + 1}`));
5984
+ const normalizedRef = ref ? legalRefs.has(ref.replace("@", "")) || legalRefs.has(ref) ? ref : void 0 : void 0;
5985
+ if (ref && !normalizedRef && action !== "scroll" && action !== "press") {
5986
+ history.push(`step${step}: ${action} ${ref} REJECTED (ref not in current list)`);
5987
+ steps.push({ step, thought, action, ref, ok: false, error: "ref not in current list", screenHash });
5988
+ continue;
5989
+ }
5990
+ const res = await actOnPage(ctx.page, ctx.sessionId, {
5991
+ action,
5992
+ ref: normalizedRef,
5993
+ value,
5994
+ selector: void 0,
5995
+ force: false,
5996
+ timeout: 1e4
5997
+ });
5998
+ const record = {
5999
+ step,
6000
+ thought,
6001
+ action,
6002
+ ref: normalizedRef,
6003
+ value,
6004
+ ok: res.success === true,
6005
+ stale: res.stale,
6006
+ error: res.success ? void 0 : res.message || res.reason,
6007
+ screenHash
6008
+ };
6009
+ steps.push(record);
6010
+ history.push(`step${step}: ${action} ${normalizedRef ?? ""} ${value ?? ""} -> ${res.success ? "ok" : `failed(${res.reason || res.message})`}`);
6011
+ const sig = (s) => `${s.action}|${s.ref ?? ""}|${s.value ?? ""}`;
6012
+ const last3 = steps.slice(-3);
6013
+ if (last3.length === 3 && new Set(last3.map(sig)).size === 1) {
6014
+ status = "blocked";
6015
+ summary = "dead loop: identical action repeated 3 times";
6016
+ break;
6017
+ }
6018
+ }
6019
+ if (status === "max_steps") summary = summary || `hit maxSteps=${p.maxSteps}`;
6020
+ const finalUrl = ctx.page ? ctx.page.url() : void 0;
6021
+ const data = { status, summary, steps, finalUrl, usage: { llmCalls, steps: steps.length } };
6022
+ if (status === "error") return fail12(summary || lastError, normalizeTips5([`completed steps: ${steps.length}`]));
6023
+ return ok26(data, normalizeTips5([
6024
+ status === "done" ? `\u2705 task done (${steps.length} steps, ${llmCalls} LLM calls)` : `\u26A0\uFE0F task ${status}: ${summary.slice(0, 80)}`
6025
+ ]));
6026
+ }
6027
+ });
6028
+
6029
+ // src/commands/tab.ts
6030
+ import { z as z28 } from "zod";
6031
+ import { ok as ok27, fail as fail13 } from "@dyyz1993/xcli-core";
6032
+ var TabParams = z28.object({
6033
+ subcommand: z28.enum(["list", "new", "close", "switch"]),
6034
+ url: z28.string().optional(),
6035
+ index: z28.number().int().min(0).optional()
5865
6036
  });
5866
6037
  var tabCommand = registerCommand({
5867
6038
  name: "tab",
5868
6039
  description: "Manage browser tabs: list, new, close, switch",
5869
6040
  scope: "page",
5870
6041
  parameters: TabParams,
5871
- result: z27.object({
5872
- success: z27.boolean(),
5873
- data: z27.unknown()
6042
+ result: z28.object({
6043
+ success: z28.boolean(),
6044
+ data: z28.unknown()
5874
6045
  }),
5875
6046
  handler: async (p, ctx) => {
5876
6047
  if (!ctx.browserContext) {
5877
- return fail12("No browser context available. Use --cdp to connect to a browser first.");
6048
+ return fail13("No browser context available. Use --cdp to connect to a browser first.");
5878
6049
  }
5879
6050
  const pages = ctx.browserContext.pages();
5880
6051
  switch (p.subcommand) {
@@ -5887,7 +6058,7 @@ var tabCommand = registerCommand({
5887
6058
  case "switch":
5888
6059
  return handleSwitch(p, pages, ctx);
5889
6060
  default:
5890
- return fail12(`Unknown subcommand: ${p.subcommand}`);
6061
+ return fail13(`Unknown subcommand: ${p.subcommand}`);
5891
6062
  }
5892
6063
  }
5893
6064
  });
@@ -5902,7 +6073,7 @@ async function handleList(pages, ctx) {
5902
6073
  if (isActive) activeIndex = i;
5903
6074
  tabs.push({ index: i, url, title, active: isActive });
5904
6075
  }
5905
- return ok26({ tabs, total: tabs.length, activeIndex });
6076
+ return ok27({ tabs, total: tabs.length, activeIndex });
5906
6077
  }
5907
6078
  async function handleNew(p, _pages, ctx) {
5908
6079
  const newPage = await ctx.browserContext.newPage();
@@ -5930,7 +6101,7 @@ async function handleNew(p, _pages, ctx) {
5930
6101
  const title = await newPage.title().catch(() => "");
5931
6102
  const allPages = ctx.browserContext.pages();
5932
6103
  const newIndex = allPages.indexOf(newPage);
5933
- return ok26({
6104
+ return ok27({
5934
6105
  index: newIndex >= 0 ? newIndex : allPages.length - 1,
5935
6106
  url: newPage.url(),
5936
6107
  title,
@@ -5941,11 +6112,11 @@ async function handleNew(p, _pages, ctx) {
5941
6112
  async function handleClose(p, ctx) {
5942
6113
  const currentPages = ctx.browserContext.pages();
5943
6114
  if (currentPages.length <= 1) {
5944
- return fail12("Cannot close the last remaining tab");
6115
+ return fail13("Cannot close the last remaining tab");
5945
6116
  }
5946
6117
  const closeIndex = p.index ?? currentPages.findIndex((pg) => pg === ctx.page);
5947
6118
  if (closeIndex < 0 || closeIndex >= currentPages.length) {
5948
- return fail12(`Invalid tab index: ${closeIndex}. Valid range: 0-${currentPages.length - 1}`);
6119
+ return fail13(`Invalid tab index: ${closeIndex}. Valid range: 0-${currentPages.length - 1}`);
5949
6120
  }
5950
6121
  const pageToClose = currentPages[closeIndex];
5951
6122
  const isActivePage = pageToClose === ctx.page;
@@ -5960,7 +6131,7 @@ async function handleClose(p, ctx) {
5960
6131
  }
5961
6132
  ctx.page = newActivePage;
5962
6133
  }
5963
- return ok26({
6134
+ return ok27({
5964
6135
  closedIndex: closeIndex,
5965
6136
  total: remainingPages.length,
5966
6137
  activeIndex: isActivePage ? closeIndex < remainingPages.length ? closeIndex : remainingPages.length - 1 : remainingPages.findIndex((pg) => pg === ctx.page)
@@ -5968,10 +6139,10 @@ async function handleClose(p, ctx) {
5968
6139
  }
5969
6140
  async function handleSwitch(p, pages, ctx) {
5970
6141
  if (p.index === void 0) {
5971
- return fail12("Parameter --index is required for switch subcommand");
6142
+ return fail13("Parameter --index is required for switch subcommand");
5972
6143
  }
5973
6144
  if (p.index < 0 || p.index >= pages.length) {
5974
- return fail12(`Invalid tab index: ${p.index}. Valid range: 0-${pages.length - 1}`);
6145
+ return fail13(`Invalid tab index: ${p.index}. Valid range: 0-${pages.length - 1}`);
5975
6146
  }
5976
6147
  const targetPage = pages[p.index];
5977
6148
  await targetPage.bringToFront().catch(() => {
@@ -5993,7 +6164,7 @@ async function handleSwitch(p, pages, ctx) {
5993
6164
  }
5994
6165
  ctx.page = targetPage;
5995
6166
  const title = await targetPage.title().catch(() => "");
5996
- return ok26({
6167
+ return ok27({
5997
6168
  index: p.index,
5998
6169
  url: targetPage.url(),
5999
6170
  title,
@@ -6002,8 +6173,8 @@ async function handleSwitch(p, pages, ctx) {
6002
6173
  }
6003
6174
 
6004
6175
  // src/commands/addinitscript.ts
6005
- import { z as z28 } from "zod";
6006
- import { ok as ok27 } from "@dyyz1993/xcli-core";
6176
+ import { z as z29 } from "zod";
6177
+ import { ok as ok28 } from "@dyyz1993/xcli-core";
6007
6178
  import { readFileSync as readFileSync4 } from "fs";
6008
6179
 
6009
6180
  // src/chain-parser.ts
@@ -6144,14 +6315,14 @@ registerCommandDefinition("tab", ["subcommand"]);
6144
6315
  registerCommandDefinition("mouse", ["action", "x", "y"]);
6145
6316
 
6146
6317
  // src/commands/addinitscript.ts
6147
- var InitScriptParams = z28.object({
6148
- script: z28.string().optional(),
6149
- file: z28.string().optional(),
6150
- stdin: z28.boolean().optional(),
6151
- name: z28.string().optional(),
6152
- list: z28.boolean().optional(),
6153
- remove: z28.union([z28.string(), z28.boolean()]).optional(),
6154
- base64: z28.string().optional()
6318
+ var InitScriptParams = z29.object({
6319
+ script: z29.string().optional(),
6320
+ file: z29.string().optional(),
6321
+ stdin: z29.boolean().optional(),
6322
+ name: z29.string().optional(),
6323
+ list: z29.boolean().optional(),
6324
+ remove: z29.union([z29.string(), z29.boolean()]).optional(),
6325
+ base64: z29.string().optional()
6155
6326
  });
6156
6327
  var registeredScripts = /* @__PURE__ */ new Map();
6157
6328
  function resolveScriptContent(params) {
@@ -6185,14 +6356,14 @@ var addInitScriptCommand = registerCommand({
6185
6356
  description: "Add an initialization script that runs on every page load",
6186
6357
  scope: "page",
6187
6358
  parameters: InitScriptParams,
6188
- result: z28.object({
6189
- scripts: z28.array(z28.object({ name: z28.string(), size: z28.number(), preview: z28.string() })).optional(),
6190
- removed: z28.string().optional(),
6191
- existed: z28.boolean().optional(),
6192
- error: z28.string().optional(),
6193
- registered: z28.string().optional(),
6194
- hint: z28.string().optional(),
6195
- executedImmediately: z28.boolean().optional()
6359
+ result: z29.object({
6360
+ scripts: z29.array(z29.object({ name: z29.string(), size: z29.number(), preview: z29.string() })).optional(),
6361
+ removed: z29.string().optional(),
6362
+ existed: z29.boolean().optional(),
6363
+ error: z29.string().optional(),
6364
+ registered: z29.string().optional(),
6365
+ hint: z29.string().optional(),
6366
+ executedImmediately: z29.boolean().optional()
6196
6367
  }).passthrough(),
6197
6368
  handler: async (params, ctx) => {
6198
6369
  if (params.list) {
@@ -6201,20 +6372,20 @@ var addInitScriptCommand = registerCommand({
6201
6372
  size: content2.length,
6202
6373
  preview: content2.slice(0, 80)
6203
6374
  }));
6204
- return ok27({ scripts });
6375
+ return ok28({ scripts });
6205
6376
  }
6206
6377
  if (params.remove && typeof params.remove === "string") {
6207
6378
  const existed = registeredScripts.delete(params.remove);
6208
- return ok27({ removed: params.remove, existed });
6379
+ return ok28({ removed: params.remove, existed });
6209
6380
  }
6210
6381
  const removeTarget = (typeof params.remove === "string" ? params.remove : null) || (params.name && !resolveScriptContent(params) ? params.name : null);
6211
6382
  if (removeTarget && !resolveScriptContent(params)) {
6212
6383
  const existed = registeredScripts.delete(removeTarget);
6213
- return ok27({ removed: removeTarget, existed });
6384
+ return ok28({ removed: removeTarget, existed });
6214
6385
  }
6215
6386
  let content = params.stdin ? await readStdin() : resolveScriptContent(params);
6216
6387
  if (!content) {
6217
- return ok27({ error: "No script content provided. Use --script, --file, --stdin, or --base64" });
6388
+ return ok28({ error: "No script content provided. Use --script, --file, --stdin, or --base64" });
6218
6389
  }
6219
6390
  const scriptName = params.name ?? `script-${Date.now()}`;
6220
6391
  registeredScripts.set(scriptName, content);
@@ -6222,45 +6393,45 @@ var addInitScriptCommand = registerCommand({
6222
6393
  try {
6223
6394
  await ctx.page.evaluate(content);
6224
6395
  } catch {
6225
- return ok27({
6396
+ return ok28({
6226
6397
  registered: scriptName,
6227
6398
  hint: "Script registered for future page loads; immediate execution skipped (page may not be ready)"
6228
6399
  });
6229
6400
  }
6230
- return ok27({ registered: scriptName, executedImmediately: true });
6401
+ return ok28({ registered: scriptName, executedImmediately: true });
6231
6402
  }
6232
6403
  });
6233
6404
  registerCommandDefinition("addinitscript", ["script"]);
6234
6405
 
6235
6406
  // src/commands/find.ts
6236
- import { z as z29 } from "zod";
6237
- import { ok as ok28, fail as fail13, normalizeTips as normalizeTips5 } from "@dyyz1993/xcli-core";
6238
- var actionSchema2 = z29.enum(["click", "fill", "type", "select", "hover", "check"]);
6407
+ import { z as z30 } from "zod";
6408
+ import { ok as ok29, fail as fail14, normalizeTips as normalizeTips6 } from "@dyyz1993/xcli-core";
6409
+ var actionSchema2 = z30.enum(["click", "fill", "type", "select", "hover", "check"]);
6239
6410
  var findCommand = registerCommand({
6240
6411
  name: "find",
6241
6412
  description: "Find elements by semantic strategy (text/role/label/placeholder/testid) and optionally perform an action",
6242
6413
  scope: "page",
6243
- parameters: z29.object({
6244
- strategy: z29.enum(["text", "role", "label", "placeholder", "testid", "alt", "title", "first", "last", "nth"]),
6245
- value: z29.string(),
6246
- name: z29.string().optional(),
6247
- exact: z29.boolean().optional().default(false),
6248
- operation: z29.string().optional().describe('Trailing operation syntax, e.g. click, fill "text", type "text"'),
6414
+ parameters: z30.object({
6415
+ strategy: z30.enum(["text", "role", "label", "placeholder", "testid", "alt", "title", "first", "last", "nth"]),
6416
+ value: z30.string(),
6417
+ name: z30.string().optional(),
6418
+ exact: z30.boolean().optional().default(false),
6419
+ operation: z30.string().optional().describe('Trailing operation syntax, e.g. click, fill "text", type "text"'),
6249
6420
  action: actionSchema2.optional().describe("Action to perform when not using trailing operation syntax"),
6250
- actionValue: z29.string().optional().describe("Value for fill/type/select when using action"),
6251
- index: z29.number().int().optional().describe("Index for nth strategy"),
6252
- click: z29.boolean().optional().default(false),
6253
- fill: z29.string().optional(),
6254
- type: z29.string().optional(),
6255
- select: z29.string().optional(),
6256
- hover: z29.boolean().optional().default(false),
6257
- check: z29.boolean().optional().default(false),
6258
- timeout: z29.number().optional().default(1e4)
6421
+ actionValue: z30.string().optional().describe("Value for fill/type/select when using action"),
6422
+ index: z30.number().int().optional().describe("Index for nth strategy"),
6423
+ click: z30.boolean().optional().default(false),
6424
+ fill: z30.string().optional(),
6425
+ type: z30.string().optional(),
6426
+ select: z30.string().optional(),
6427
+ hover: z30.boolean().optional().default(false),
6428
+ check: z30.boolean().optional().default(false),
6429
+ timeout: z30.number().optional().default(1e4)
6259
6430
  }),
6260
- result: z29.object({
6261
- matched: z29.number(),
6262
- selector: z29.string(),
6263
- action: z29.string().optional()
6431
+ result: z30.object({
6432
+ matched: z30.number(),
6433
+ selector: z30.string(),
6434
+ action: z30.string().optional()
6264
6435
  }),
6265
6436
  handler: async (p, ctx) => {
6266
6437
  const page = ctx.page;
@@ -6275,7 +6446,7 @@ var findCommand = registerCommand({
6275
6446
  });
6276
6447
  const count = await locator.count();
6277
6448
  if (count === 0) {
6278
- return fail13(`No element found with ${p.strategy}="${p.value}"`);
6449
+ return fail14(`No element found with ${p.strategy}="${p.value}"`);
6279
6450
  }
6280
6451
  const tips = [];
6281
6452
  const target = selectTarget(locator, p.strategy);
@@ -6287,15 +6458,15 @@ var findCommand = registerCommand({
6287
6458
  await target.click({ timeout: p.timeout, force: true });
6288
6459
  return okWithTips({ matched: count, selector, action: "click" }, tips);
6289
6460
  } else if (actionName === "fill") {
6290
- if (actionValue === void 0) return fail13("find fill requires a value");
6461
+ if (actionValue === void 0) return fail14("find fill requires a value");
6291
6462
  await target.fill(actionValue, { timeout: p.timeout, force: true });
6292
6463
  return okWithTips({ matched: count, selector, action: `fill("${actionValue}")` }, tips);
6293
6464
  } else if (actionName === "type") {
6294
- if (actionValue === void 0) return fail13("find type requires a value");
6465
+ if (actionValue === void 0) return fail14("find type requires a value");
6295
6466
  await target.type(actionValue, { delay: 10, timeout: p.timeout });
6296
6467
  return okWithTips({ matched: count, selector, action: `type("${actionValue}")` }, tips);
6297
6468
  } else if (actionName === "select") {
6298
- if (actionValue === void 0) return fail13("find select requires a value");
6469
+ if (actionValue === void 0) return fail14("find select requires a value");
6299
6470
  await target.selectOption(actionValue);
6300
6471
  return okWithTips({ matched: count, selector, action: `select("${actionValue}")` }, tips);
6301
6472
  } else if (actionName === "hover") {
@@ -6309,8 +6480,8 @@ var findCommand = registerCommand({
6309
6480
  }
6310
6481
  });
6311
6482
  function okWithTips(data, tips) {
6312
- const result = ok28(data);
6313
- if (tips.length > 0) result.tips = normalizeTips5(tips);
6483
+ const result = ok29(data);
6484
+ if (tips.length > 0) result.tips = normalizeTips6(tips);
6314
6485
  return result;
6315
6486
  }
6316
6487
  function parseOperation(operation) {
@@ -6408,8 +6579,8 @@ function describeSelector(strategy, value, name) {
6408
6579
  }
6409
6580
 
6410
6581
  // src/commands/visual-tag.ts
6411
- import { z as z30 } from "zod";
6412
- import { ok as ok29, fail as fail14 } from "@dyyz1993/xcli-core";
6582
+ import { z as z31 } from "zod";
6583
+ import { ok as ok30, fail as fail15 } from "@dyyz1993/xcli-core";
6413
6584
  var SAFE_SET = "ahjkmnprtw3479".split("");
6414
6585
  var TAG_SCRIPT = `
6415
6586
  (function() {
@@ -6500,49 +6671,49 @@ var visualTagCommand = registerCommand({
6500
6671
  name: "visual-tag",
6501
6672
  description: "\u5728\u9875\u9762\u4E0A\u7ED9\u53EF\u4EA4\u4E92\u5143\u7D20\u53E0\u52A0\u9632\u6DF7\u6DC6\u77ED ID \u6807\u7B7E\uFF08\u89C6\u89C9\u5B9A\u4F4D\u7528\uFF09",
6502
6673
  scope: "page",
6503
- parameters: z30.object({
6504
- action: z30.enum(["tag", "lookup", "clear", "list"]),
6505
- id: z30.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID")
6674
+ parameters: z31.object({
6675
+ action: z31.enum(["tag", "lookup", "clear", "list"]),
6676
+ id: z31.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID")
6506
6677
  }),
6507
- result: z30.object({
6508
- action: z30.string(),
6509
- tagged: z30.number().optional(),
6510
- id: z30.string().optional(),
6511
- element: z30.record(z30.unknown()).optional()
6678
+ result: z31.object({
6679
+ action: z31.string(),
6680
+ tagged: z31.number().optional(),
6681
+ id: z31.string().optional(),
6682
+ element: z31.record(z31.unknown()).optional()
6512
6683
  }),
6513
6684
  handler: async (p, ctx) => {
6514
6685
  switch (p.action) {
6515
6686
  case "tag": {
6516
6687
  const result = await ctx.page.evaluate(TAG_SCRIPT);
6517
6688
  const parsed = JSON.parse(result);
6518
- return ok29({ action: "tag", tagged: parsed.tagged });
6689
+ return ok30({ action: "tag", tagged: parsed.tagged });
6519
6690
  }
6520
6691
  case "lookup": {
6521
- if (!p.id) return fail14("lookup \u9700\u8981 --id \u53C2\u6570");
6692
+ if (!p.id) return fail15("lookup \u9700\u8981 --id \u53C2\u6570");
6522
6693
  const result = await ctx.page.evaluate(
6523
6694
  `(function() { var m = window.__xbTagMap; if (!m) return JSON.stringify({err:'no-map'}); var e = m[${JSON.stringify(p.id)}]; return e ? JSON.stringify(e) : JSON.stringify({err:'not-found'}); })()`
6524
6695
  );
6525
6696
  const parsed = JSON.parse(result);
6526
- if (parsed.err) return fail14(`ID ${p.id}: ${parsed.err}`);
6527
- return ok29({ action: "lookup", id: p.id, element: parsed });
6697
+ if (parsed.err) return fail15(`ID ${p.id}: ${parsed.err}`);
6698
+ return ok30({ action: "lookup", id: p.id, element: parsed });
6528
6699
  }
6529
6700
  case "list": {
6530
6701
  const result = await ctx.page.evaluate(
6531
6702
  `(function() { var m = window.__xbTagMap; if (!m) return '{}'; var out = {}; for (var k in m) { out[k] = m[k].text || m[k].tagName; } return JSON.stringify(out); })()`
6532
6703
  );
6533
- return ok29({ action: "list", element: JSON.parse(result) });
6704
+ return ok30({ action: "list", element: JSON.parse(result) });
6534
6705
  }
6535
6706
  case "clear": {
6536
6707
  await ctx.page.evaluate(`(function(){var o=document.getElementById('__xb-tag-overlay');if(o)o.remove();window.__xbTagMap=null;return 'cleared'})()`);
6537
- return ok29({ action: "clear" });
6708
+ return ok30({ action: "clear" });
6538
6709
  }
6539
6710
  }
6540
6711
  }
6541
6712
  });
6542
6713
 
6543
6714
  // src/commands/visual-tag-v2.ts
6544
- import { z as z31 } from "zod";
6545
- import { ok as ok30, fail as fail15 } from "@dyyz1993/xcli-core";
6715
+ import { z as z32 } from "zod";
6716
+ import { ok as ok31, fail as fail16 } from "@dyyz1993/xcli-core";
6546
6717
  var SAFE_SET2 = "ahjkmnprtw3479".split("");
6547
6718
  var TAG_V2_SCRIPT = `
6548
6719
  (function() {
@@ -6889,45 +7060,45 @@ var visualTagV2Command = registerCommand({
6889
7060
  name: "visual-tag-v2",
6890
7061
  description: "\u5206\u8272\u6807\u6CE8\u9875\u9762\u5143\u7D20\uFF08\u7EA2=\u53EF\u70B9\u51FB \u84DD=\u8F93\u5165 \u7EFF=\u56FE\u7247 \u9EC4=\u5217\u8868 \u7D2B=\u6570\u5B57 \u6A59=\u6587\u672C\uFF09",
6891
7062
  scope: "page",
6892
- parameters: z31.object({
6893
- action: z31.enum(["tag", "lookup", "clear", "stats", "by-type", "find", "export", "interact"]),
6894
- id: z31.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID"),
6895
- query: z31.string().optional().describe('find \u65F6\u6307\u5B9A\u641C\u7D22\u8BCD\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09'),
6896
- type: z31.string().optional().describe("by-type \u65F6\u8FC7\u6EE4\u7C7B\u578B\uFF1Aclick/input/img/list/count/text"),
6897
- "interact-action": z31.enum(["click", "fill", "read"]).optional().describe("interact \u52A8\u4F5C\u7C7B\u578B"),
6898
- value: z31.string().optional().describe("fill \u65F6\u7684\u586B\u5145\u503C")
7063
+ parameters: z32.object({
7064
+ action: z32.enum(["tag", "lookup", "clear", "stats", "by-type", "find", "export", "interact"]),
7065
+ id: z32.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID"),
7066
+ query: z32.string().optional().describe('find \u65F6\u6307\u5B9A\u641C\u7D22\u8BCD\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09'),
7067
+ type: z32.string().optional().describe("by-type \u65F6\u8FC7\u6EE4\u7C7B\u578B\uFF1Aclick/input/img/list/count/text"),
7068
+ "interact-action": z32.enum(["click", "fill", "read"]).optional().describe("interact \u52A8\u4F5C\u7C7B\u578B"),
7069
+ value: z32.string().optional().describe("fill \u65F6\u7684\u586B\u5145\u503C")
6899
7070
  }),
6900
- result: z31.object({
6901
- action: z31.string(),
6902
- total: z31.number().optional(),
6903
- byType: z31.record(z31.number()).optional(),
6904
- element: z31.record(z31.unknown()).optional()
7071
+ result: z32.object({
7072
+ action: z32.string(),
7073
+ total: z32.number().optional(),
7074
+ byType: z32.record(z32.number()).optional(),
7075
+ element: z32.record(z32.unknown()).optional()
6905
7076
  }),
6906
7077
  handler: async (p, ctx) => {
6907
7078
  switch (p.action) {
6908
7079
  case "tag": {
6909
7080
  const result = await ctx.page.evaluate(TAG_V2_SCRIPT);
6910
7081
  const parsed = JSON.parse(result);
6911
- return ok30({ action: "tag", total: parsed.total, byType: parsed.byType });
7082
+ return ok31({ action: "tag", total: parsed.total, byType: parsed.byType });
6912
7083
  }
6913
7084
  case "lookup": {
6914
- if (!p.id) return fail15("lookup \u9700\u8981 --id");
7085
+ if (!p.id) return fail16("lookup \u9700\u8981 --id");
6915
7086
  const result = await ctx.page.evaluate(
6916
7087
  `(function(){var m=window.__xbTagMap;if(!m)return JSON.stringify({err:'no-map'});var e=m[${JSON.stringify(p.id)}];return e?JSON.stringify(e):JSON.stringify({err:'not-found'})})()`
6917
7088
  );
6918
7089
  const parsed = JSON.parse(result);
6919
- if (parsed.err) return fail15(`ID ${p.id}: ${parsed.err}`);
6920
- return ok30({ action: "lookup", id: p.id, element: parsed });
7090
+ if (parsed.err) return fail16(`ID ${p.id}: ${parsed.err}`);
7091
+ return ok31({ action: "lookup", id: p.id, element: parsed });
6921
7092
  }
6922
7093
  case "by-type": {
6923
7094
  const result = await ctx.page.evaluate(
6924
7095
  `(function(){var m=window.__xbTagMap;if(!m)return'{}';var out={};for(var k in m){if(!${JSON.stringify(p.type || "")}||m[k].type===${JSON.stringify(p.type || "")}){out[k]={type:m[k].type,text:m[k].text,num:m[k].num,label:m[k].formLabel}}}return JSON.stringify(out)})()`
6925
7096
  );
6926
- return ok30({ action: "by-type", element: JSON.parse(result) });
7097
+ return ok31({ action: "by-type", element: JSON.parse(result) });
6927
7098
  }
6928
7099
  case "find": {
6929
7100
  const query = p.query;
6930
- if (!query) return fail15('find \u9700\u8981 --query \u53C2\u6570\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09');
7101
+ if (!query) return fail16('find \u9700\u8981 --query \u53C2\u6570\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09');
6931
7102
  const result = await ctx.page.evaluate(
6932
7103
  `(function(){
6933
7104
  var map = window.__xbTagSerializable;
@@ -6969,21 +7140,21 @@ var visualTagV2Command = registerCommand({
6969
7140
  return JSON.stringify({total:results.length, results:results.slice(0,20)});
6970
7141
  })()`
6971
7142
  );
6972
- return ok30({ action: "find", query, element: JSON.parse(result) });
7143
+ return ok31({ action: "find", query, element: JSON.parse(result) });
6973
7144
  }
6974
7145
  case "stats": {
6975
7146
  const result = await ctx.page.evaluate(
6976
7147
  `(function(){return JSON.stringify(window.__xbTagStats||{})})()`
6977
7148
  );
6978
- return ok30({ action: "stats", element: JSON.parse(result) });
7149
+ return ok31({ action: "stats", element: JSON.parse(result) });
6979
7150
  }
6980
7151
  case "interact": {
6981
7152
  const query = p.query;
6982
7153
  const pAny = p;
6983
7154
  const action = pAny["interact-action"] || pAny.interactAction || pAny.interact_action;
6984
7155
  const value = pAny.value;
6985
- if (!query) return fail15("interact \u9700\u8981 --query \u53C2\u6570");
6986
- if (!action) return fail15("interact \u9700\u8981 --interact-action \u53C2\u6570\uFF08click/fill/read\uFF09");
7156
+ if (!query) return fail16("interact \u9700\u8981 --query \u53C2\u6570");
7157
+ if (!action) return fail16("interact \u9700\u8981 --interact-action \u53C2\u6570\uFF08click/fill/read\uFF09");
6987
7158
  const findResult = await ctx.page.evaluate(
6988
7159
  `(function(){
6989
7160
  var map = window.__xbTagSerializable;
@@ -7013,11 +7184,11 @@ var visualTagV2Command = registerCommand({
7013
7184
  })()`
7014
7185
  );
7015
7186
  const parsed = JSON.parse(findResult);
7016
- if (parsed.err) return fail15(parsed.err);
7017
- if (!parsed.total || !parsed.results?.length) return fail15(`\u672A\u627E\u5230\u5339\u914D "${query}" \u7684\u5143\u7D20`);
7187
+ if (parsed.err) return fail16(parsed.err);
7188
+ if (!parsed.total || !parsed.results?.length) return fail16(`\u672A\u627E\u5230\u5339\u914D "${query}" \u7684\u5143\u7D20`);
7018
7189
  const target = parsed.results[0];
7019
7190
  if (action === "read") {
7020
- return ok30({ action: "interact", query, target, result: { read: target.text || target.label } });
7191
+ return ok31({ action: "interact", query, target, result: { read: target.text || target.label } });
7021
7192
  }
7022
7193
  if (action === "click") {
7023
7194
  const el = await ctx.page.evaluate(
@@ -7030,12 +7201,12 @@ var visualTagV2Command = registerCommand({
7030
7201
  return {x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2)};
7031
7202
  })()`
7032
7203
  );
7033
- if (!el) return fail15(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
7204
+ if (!el) return fail16(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
7034
7205
  await ctx.page.mouse.click(el.x, el.y, { stealth: true });
7035
- return ok30({ action: "interact", query, target, result: { clicked: true, x: el.x, y: el.y } });
7206
+ return ok31({ action: "interact", query, target, result: { clicked: true, x: el.x, y: el.y } });
7036
7207
  }
7037
7208
  if (action === "fill") {
7038
- if (!value) return fail15("fill \u9700\u8981 --value \u53C2\u6570");
7209
+ if (!value) return fail16("fill \u9700\u8981 --value \u53C2\u6570");
7039
7210
  const el = await ctx.page.evaluate(
7040
7211
  `(function(){
7041
7212
  var map = window.__xbTagMap;
@@ -7046,12 +7217,12 @@ var visualTagV2Command = registerCommand({
7046
7217
  return {x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2)};
7047
7218
  })()`
7048
7219
  );
7049
- if (!el) return fail15(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
7220
+ if (!el) return fail16(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
7050
7221
  await ctx.page.mouse.click(el.x, el.y, { stealth: true });
7051
7222
  await ctx.page.keyboard.type(value, { stealth: true });
7052
- return ok30({ action: "interact", query, target, result: { filled: true, value } });
7223
+ return ok31({ action: "interact", query, target, result: { filled: true, value } });
7053
7224
  }
7054
- return fail15(`\u672A\u77E5 action: ${action}`);
7225
+ return fail16(`\u672A\u77E5 action: ${action}`);
7055
7226
  }
7056
7227
  case "export": {
7057
7228
  const result = await ctx.page.evaluate(
@@ -7099,12 +7270,12 @@ var visualTagV2Command = registerCommand({
7099
7270
  })()`
7100
7271
  );
7101
7272
  const parsed = JSON.parse(result);
7102
- if (parsed.err) return fail15(String(parsed.err));
7103
- return ok30({ action: "export", element: parsed });
7273
+ if (parsed.err) return fail16(String(parsed.err));
7274
+ return ok31({ action: "export", element: parsed });
7104
7275
  }
7105
7276
  case "clear": {
7106
7277
  await ctx.page.evaluate(`(function(){var o=document.getElementById('__xb-tag-overlay');if(o)o.remove();window.__xbTagMap=null;window.__xbTagStats=null;return 'ok'})()`);
7107
- return ok30({ action: "clear" });
7278
+ return ok31({ action: "clear" });
7108
7279
  }
7109
7280
  }
7110
7281
  }
@@ -7981,7 +8152,10 @@ function buildSnapshot(elements) {
7981
8152
  }
7982
8153
 
7983
8154
  // src/tips/index.ts
7984
- var DEBOUNCE_MS = 500;
8155
+ function tipsDebounceMs() {
8156
+ const v = parseInt(process.env.XBROWSER_TIPS_DEBOUNCE ?? "120", 10);
8157
+ return Number.isFinite(v) && v > 0 ? v : 0;
8158
+ }
7985
8159
  var SKIP_DETECT_COMMANDS = /* @__PURE__ */ new Set([
7986
8160
  "goto",
7987
8161
  // 导航命令不需要检测
@@ -8073,7 +8247,9 @@ var TipsManager = class {
8073
8247
  }
8074
8248
  }
8075
8249
  debounce() {
8076
- return new Promise((resolve3) => setTimeout(resolve3, DEBOUNCE_MS));
8250
+ const ms = tipsDebounceMs();
8251
+ if (ms <= 0) return Promise.resolve();
8252
+ return new Promise((resolve3) => setTimeout(resolve3, ms));
8077
8253
  }
8078
8254
  formatTips(tips) {
8079
8255
  return tips.map((tip) => {
@@ -8242,7 +8418,7 @@ async function guardCheck(commandName) {
8242
8418
  }
8243
8419
  }
8244
8420
  function errorResult(message) {
8245
- return { ...fail16(message), duration: 0 };
8421
+ return { ...fail17(message), duration: 0 };
8246
8422
  }
8247
8423
  function tipsToMessages(tips) {
8248
8424
  if (!tips || tips.length === 0) return [];
@@ -8319,7 +8495,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8319
8495
  }
8320
8496
  let targetPageOverride = null;
8321
8497
  if (_target && extraOpts?.cdpEndpoint) {
8322
- const { findTargetPage } = await import("./browser-33QQWEDI.js");
8498
+ const { findTargetPage } = await import("./browser-NYYCR4O7.js");
8323
8499
  targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
8324
8500
  if (!targetPageOverride) {
8325
8501
  return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
@@ -8431,7 +8607,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8431
8607
  const cache = /* @__PURE__ */ new Map();
8432
8608
  const resolved = await resolveRefParams(session.page, params, command.selectorParams, cache, session.id);
8433
8609
  if (resolved.tips.length > 0) {
8434
- refTips = normalizeTips6(resolved.tips);
8610
+ refTips = normalizeTips7(resolved.tips);
8435
8611
  params = resolved.params;
8436
8612
  }
8437
8613
  }
@@ -8499,8 +8675,8 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8499
8675
  }
8500
8676
  const merged = [
8501
8677
  ...raw.tips || [],
8502
- ...normalizeTips6(smartTips),
8503
- ...snapshotHint ? normalizeTips6([snapshotHint]) : [],
8678
+ ...normalizeTips7(smartTips),
8679
+ ...snapshotHint ? normalizeTips7([snapshotHint]) : [],
8504
8680
  ...refTips
8505
8681
  ];
8506
8682
  const isSuccess = raw.success !== false;
@@ -8515,7 +8691,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8515
8691
  timestamp: start
8516
8692
  });
8517
8693
  if (isSuccess) {
8518
- return { ...ok31(raw.data, merged.length > 0 ? merged : raw.tips), duration, ...hookOutputs ? { hookOutputs } : {} };
8694
+ return { ...ok32(raw.data, merged.length > 0 ? merged : raw.tips), duration, ...hookOutputs ? { hookOutputs } : {} };
8519
8695
  }
8520
8696
  const fc = classifyFailure(raw.message);
8521
8697
  return {
@@ -8528,7 +8704,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8528
8704
  ...hookOutputs ? { hookOutputs } : {}
8529
8705
  };
8530
8706
  }
8531
- const smartTipNormalized = normalizeTips6(smartTips);
8707
+ const smartTipNormalized = normalizeTips7(smartTips);
8532
8708
  recordArchive(session?.id, sessionName, {
8533
8709
  step: 0,
8534
8710
  command: commandName,
@@ -8538,7 +8714,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8538
8714
  duration,
8539
8715
  timestamp: start
8540
8716
  });
8541
- return { ...ok31(raw, smartTipNormalized), duration, ...hookOutputs ? { hookOutputs } : {} };
8717
+ return { ...ok32(raw, smartTipNormalized), duration, ...hookOutputs ? { hookOutputs } : {} };
8542
8718
  } catch (err) {
8543
8719
  const end = Date.now();
8544
8720
  const duration = end - start;
@@ -8583,7 +8759,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8583
8759
  duration,
8584
8760
  timestamp: start
8585
8761
  });
8586
- return { ...fail16(errorMessage), duration };
8762
+ return { ...fail17(errorMessage), duration };
8587
8763
  } finally {
8588
8764
  }
8589
8765
  }
@@ -8628,7 +8804,7 @@ async function executeChain(input, options) {
8628
8804
  results.push({
8629
8805
  command: cmdName,
8630
8806
  raw: cmdStr,
8631
- ...fail16(`Plugin "${cmdName}" requires a sub-command`),
8807
+ ...fail17(`Plugin "${cmdName}" requires a sub-command`),
8632
8808
  duration: 0
8633
8809
  });
8634
8810
  if (type === "and") {
@@ -8647,7 +8823,7 @@ async function executeChain(input, options) {
8647
8823
  results.push({
8648
8824
  command: cmdName,
8649
8825
  raw: cmdStr,
8650
- ...fail16(`Unknown command "${subCommand}" for plugin "${cmdName}"`),
8826
+ ...fail17(`Unknown command "${subCommand}" for plugin "${cmdName}"`),
8651
8827
  duration: 0
8652
8828
  });
8653
8829
  if (type === "and") {
@@ -8717,7 +8893,7 @@ async function executeChain(input, options) {
8717
8893
  success: false,
8718
8894
  data: data2,
8719
8895
  message: loginGuard.message,
8720
- tips: normalizeTips6(loginGuard.tips),
8896
+ tips: normalizeTips7(loginGuard.tips),
8721
8897
  duration: duration3
8722
8898
  });
8723
8899
  if (type === "and") {
@@ -8759,7 +8935,7 @@ async function executeChain(input, options) {
8759
8935
  results.push({
8760
8936
  command: `${cmdName} ${subCommand}`,
8761
8937
  raw: cmdStr,
8762
- ...ok31(data),
8938
+ ...ok32(data),
8763
8939
  duration: duration2,
8764
8940
  ...hookOutputs ? { hookOutputs } : {}
8765
8941
  });
@@ -8787,7 +8963,7 @@ async function executeChain(input, options) {
8787
8963
  results.push({
8788
8964
  command: `${cmdName} ${subCommand}`,
8789
8965
  raw: cmdStr,
8790
- ...fail16(errorMessage),
8966
+ ...fail17(errorMessage),
8791
8967
  duration: duration2
8792
8968
  });
8793
8969
  if (type === "and") {