@xbrowser/cli 1.26.0 → 1.28.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.
@@ -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,
@@ -1285,9 +1285,12 @@ var visionTaskCommand = registerCommand({
1285
1285
  } catch {
1286
1286
  }
1287
1287
  }
1288
- const buffer = await page.screenshot({ type: "png" });
1288
+ const shotQuality = Math.max(30, Math.min(95, parseInt(process.env.XBROWSER_VLM_SHOT_QUALITY ?? "75", 10) || 75));
1289
+ const buffer = await page.screenshot({ type: "jpeg", quality: shotQuality });
1289
1290
  const b64 = buffer.toString("base64");
1290
- const { w, h } = pngDims(b64);
1291
+ const vp = typeof page.viewportSize === "function" ? page.viewportSize() : null;
1292
+ const w = vp?.width ?? pngDims(b64).w;
1293
+ const h = vp?.height ?? pngDims(b64).h;
1291
1294
  const obsText = [
1292
1295
  `\u4EFB\u52A1\uFF1A${p.task}`,
1293
1296
  `\u622A\u56FE\u5C3A\u5BF8\uFF1A${w}x${h}\uFF08\u5750\u6807\u539F\u70B9\uFF1A\u5DE6\u4E0A\u89D2\uFF09`,
@@ -1296,7 +1299,7 @@ var visionTaskCommand = registerCommand({
1296
1299
  ${history.slice(-6).join("\n")}` : "\u5C1A\u65E0\u52A8\u4F5C\u3002"
1297
1300
  ].join("\n");
1298
1301
  const reply = await vlmAskRetry(creds, [
1299
- { type: "image", source: { type: "base64", media_type: "image/png", data: b64 } },
1302
+ { type: "image", source: { type: "base64", media_type: shotQuality >= 100 ? "image/png" : "image/jpeg", data: b64 } },
1300
1303
  { type: "text", text: `${SYSTEM_PROMPT}
1301
1304
 
1302
1305
  ${obsText}` }
@@ -4740,6 +4743,25 @@ function getRefTarget(sessionKey2, ref) {
4740
4743
  if (!session || !target) return null;
4741
4744
  return { screenHash: session.screenHash, target };
4742
4745
  }
4746
+ function inheritStableRefs(key, rawTargets) {
4747
+ const prev = sessions.get(key);
4748
+ if (!prev || prev.targets.size === 0) {
4749
+ return rawTargets.map((target, index) => ({ ...target, ref: `e${index + 1}` }));
4750
+ }
4751
+ const bySelector = /* @__PURE__ */ new Map();
4752
+ let maxId = 0;
4753
+ for (const [ref, target] of prev.targets) {
4754
+ bySelector.set(target.selector, ref);
4755
+ const id = Number(ref.slice(1));
4756
+ if (Number.isFinite(id) && id > maxId) maxId = id;
4757
+ }
4758
+ let next = maxId + 1;
4759
+ return rawTargets.map((target) => {
4760
+ const inherited = bySelector.get(target.selector);
4761
+ if (inherited) return { ...target, ref: inherited };
4762
+ return { ...target, ref: `e${next++}` };
4763
+ });
4764
+ }
4743
4765
 
4744
4766
  // src/utils/resolve-selector.ts
4745
4767
  function buildElementSelector(el) {
@@ -5364,10 +5386,7 @@ async function observePage(page, sessionId, options = {}) {
5364
5386
  { includeHidden: !!options.includeHidden, limit: options.limit ?? 80 }
5365
5387
  )
5366
5388
  ]);
5367
- const targets = raw.targets.map((target, index) => ({
5368
- ref: `e${index + 1}`,
5369
- ...target
5370
- }));
5389
+ const targets = inheritStableRefs(sessionKey(sessionId), raw.targets);
5371
5390
  replaceRefs(sessionKey(sessionId), raw.screenHash, targets);
5372
5391
  return {
5373
5392
  url: page.url(),
@@ -5859,26 +5878,193 @@ var waitForCommand = registerCommand({
5859
5878
  }
5860
5879
  });
5861
5880
 
5862
- // src/commands/tab.ts
5881
+ // src/commands/task.ts
5863
5882
  import { z as z27 } from "zod";
5864
- import { ok as ok26, fail as fail12 } from "@dyyz1993/xcli-core";
5865
- var TabParams = z27.object({
5866
- subcommand: z27.enum(["list", "new", "close", "switch"]),
5867
- url: z27.string().optional(),
5868
- index: z27.number().int().min(0).optional()
5883
+ import { ok as ok26, fail as fail12, normalizeTips as normalizeTips5 } from "@dyyz1993/xcli-core";
5884
+ 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
5885
+
5886
+ \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
5887
+ {"action":"click","ref":"@eN","thought":"\u4E3A\u4EC0\u4E48"}
5888
+ {"action":"fill","ref":"@eN","value":"\u6587\u672C","thought":"\u4E3A\u4EC0\u4E48"}
5889
+ {"action":"select","ref":"@eN","value":"\u9009\u9879\u503C","thought":"\u4E3A\u4EC0\u4E48"}
5890
+ {"action":"press","value":"Enter","thought":"\u4E3A\u4EC0\u4E48"}
5891
+ {"action":"scroll","value":"down \u6216 up","thought":"\u4E3A\u4EC0\u4E48"}
5892
+ {"action":"done","value":"\u5B8C\u6210\u6458\u8981","thought":"\u4E3A\u4EC0\u4E48"}
5893
+ {"action":"blocked","value":"\u5361\u4F4F\u539F\u56E0","thought":"\u4E3A\u4EC0\u4E48"}
5894
+
5895
+ \u89C4\u5219\uFF1A
5896
+ 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
5897
+ 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
5898
+ 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`;
5899
+ function extractDecision(raw) {
5900
+ let s = raw.trim().replace(/^```(?:json)?\s*/i, "").replace(/\s*```$/, "");
5901
+ const start = s.indexOf("{");
5902
+ if (start < 0) return null;
5903
+ let depth = 0;
5904
+ for (let i = start; i < s.length; i++) {
5905
+ if (s[i] === "{") depth++;
5906
+ else if (s[i] === "}") {
5907
+ depth--;
5908
+ if (depth === 0) {
5909
+ try {
5910
+ return JSON.parse(s.slice(start, i + 1));
5911
+ } catch {
5912
+ return null;
5913
+ }
5914
+ }
5915
+ }
5916
+ }
5917
+ return null;
5918
+ }
5919
+ var taskCommand = registerCommand({
5920
+ name: "task",
5921
+ description: "Autonomous goal loop: observe refs \u2192 LLM decides \u2192 act, until done/blocked (budget-capped)",
5922
+ scope: "page",
5923
+ parameters: z27.object({
5924
+ goal: z27.string().describe("Natural-language goal"),
5925
+ maxSteps: z27.number().int().positive().max(50).optional().default(15).describe("Hard action budget"),
5926
+ timeout: z27.number().optional().default(18e4).describe("Wall clock budget in ms"),
5927
+ limit: z27.number().int().positive().max(300).optional().default(80).describe("Max targets per observe")
5928
+ }),
5929
+ result: z27.object({
5930
+ status: z27.enum(["done", "blocked", "max_steps", "error"]),
5931
+ summary: z27.string().optional(),
5932
+ steps: z27.array(z27.record(z27.unknown())),
5933
+ finalUrl: z27.string().optional(),
5934
+ usage: z27.object({ llmCalls: z27.number(), steps: z27.number() }).passthrough().optional()
5935
+ }).passthrough(),
5936
+ handler: async (p, ctx) => {
5937
+ const creds = loadVLMCredentials2();
5938
+ if (!creds) {
5939
+ return fail12("task \u9700\u8981\u51B3\u7B56\u6A21\u578B\u51ED\u8BC1\uFF1A\u8BBE\u7F6E XBROWSER_VLM_CONFIG \u6216 ~/.zcode/v2/config.json");
5940
+ }
5941
+ const model = process.env.XBROWSER_TASK_MODEL || creds.model;
5942
+ const started = Date.now();
5943
+ const steps = [];
5944
+ const history = [];
5945
+ let llmCalls = 0;
5946
+ let status = "max_steps";
5947
+ let summary = "";
5948
+ let lastError = "";
5949
+ for (let step = 1; step <= p.maxSteps; step++) {
5950
+ if (Date.now() - started > p.timeout) {
5951
+ status = "blocked";
5952
+ summary = `timeout after ${step - 1} steps`;
5953
+ break;
5954
+ }
5955
+ const obs = await observePage(ctx.page, ctx.sessionId, { limit: p.limit, includeHidden: false });
5956
+ const compact = obs.compact ?? obs.targets.map((t, i) => `@e${i + 1} [${t.tag ?? ""}] ${t.name ?? ""}`).join("\n");
5957
+ const screenHash = obs.screenHash;
5958
+ const userPayload = [
5959
+ `\u76EE\u6807\uFF1A${p.goal}`,
5960
+ `\u5F53\u524D\u9875\u9762\uFF08URL: ${obs.url ?? ""}\uFF09\uFF1A`,
5961
+ compact,
5962
+ history.length ? `
5963
+ \u5DF2\u6267\u884C\uFF08\u52FF\u91CD\u590D\u5931\u8D25\u52A8\u4F5C\uFF09\uFF1A
5964
+ ${history.slice(-6).join("\n")}` : ""
5965
+ ].filter(Boolean).join("\n");
5966
+ let raw = "";
5967
+ try {
5968
+ raw = await vlmAsk({ ...creds, model }, [{ type: "text", text: `${DECISION_SYSTEM}
5969
+
5970
+ ---
5971
+
5972
+ ${userPayload}` }], 900);
5973
+ llmCalls++;
5974
+ } catch (e) {
5975
+ lastError = e instanceof Error ? e.message : String(e);
5976
+ status = "error";
5977
+ summary = `LLM call failed: ${lastError}`;
5978
+ break;
5979
+ }
5980
+ const decision = extractDecision(raw);
5981
+ if (!decision || typeof decision.action !== "string") {
5982
+ status = "blocked";
5983
+ summary = `LLM returned unparsable decision: ${raw.slice(0, 120)}`;
5984
+ break;
5985
+ }
5986
+ const action = decision.action;
5987
+ const ref = typeof decision.ref === "string" ? decision.ref : void 0;
5988
+ const value = typeof decision.value === "string" ? decision.value : void 0;
5989
+ const thought = typeof decision.thought === "string" ? decision.thought : void 0;
5990
+ if (action === "done") {
5991
+ status = "done";
5992
+ summary = value || thought || "task done";
5993
+ steps.push({ step, thought, action: "done", ok: true, screenHash });
5994
+ break;
5995
+ }
5996
+ if (action === "blocked") {
5997
+ status = "blocked";
5998
+ summary = value || thought || "LLM judged blocked";
5999
+ steps.push({ step, thought, action: "blocked", ok: true, screenHash });
6000
+ break;
6001
+ }
6002
+ const legalRefs = new Set(obs.targets.map((t, i) => t.ref ?? `e${i + 1}`));
6003
+ const normalizedRef = ref ? legalRefs.has(ref.replace("@", "")) || legalRefs.has(ref) ? ref : void 0 : void 0;
6004
+ if (ref && !normalizedRef && action !== "scroll" && action !== "press") {
6005
+ history.push(`step${step}: ${action} ${ref} REJECTED (ref not in current list)`);
6006
+ steps.push({ step, thought, action, ref, ok: false, error: "ref not in current list", screenHash });
6007
+ continue;
6008
+ }
6009
+ const res = await actOnPage(ctx.page, ctx.sessionId, {
6010
+ action,
6011
+ ref: normalizedRef,
6012
+ value,
6013
+ selector: void 0,
6014
+ force: false,
6015
+ timeout: 1e4
6016
+ });
6017
+ const record = {
6018
+ step,
6019
+ thought,
6020
+ action,
6021
+ ref: normalizedRef,
6022
+ value,
6023
+ ok: res.success === true,
6024
+ stale: res.stale,
6025
+ error: res.success ? void 0 : res.message || res.reason,
6026
+ screenHash
6027
+ };
6028
+ steps.push(record);
6029
+ history.push(`step${step}: ${action} ${normalizedRef ?? ""} ${value ?? ""} -> ${res.success ? "ok" : `failed(${res.reason || res.message})`}`);
6030
+ const sig = (s) => `${s.action}|${s.ref ?? ""}|${s.value ?? ""}`;
6031
+ const last3 = steps.slice(-3);
6032
+ if (last3.length === 3 && new Set(last3.map(sig)).size === 1) {
6033
+ status = "blocked";
6034
+ summary = "dead loop: identical action repeated 3 times";
6035
+ break;
6036
+ }
6037
+ }
6038
+ if (status === "max_steps") summary = summary || `hit maxSteps=${p.maxSteps}`;
6039
+ const finalUrl = ctx.page ? ctx.page.url() : void 0;
6040
+ const data = { status, summary, steps, finalUrl, usage: { llmCalls, steps: steps.length } };
6041
+ if (status === "error") return fail12(summary || lastError, normalizeTips5([`completed steps: ${steps.length}`]));
6042
+ return ok26(data, normalizeTips5([
6043
+ status === "done" ? `\u2705 task done (${steps.length} steps, ${llmCalls} LLM calls)` : `\u26A0\uFE0F task ${status}: ${summary.slice(0, 80)}`
6044
+ ]));
6045
+ }
6046
+ });
6047
+
6048
+ // src/commands/tab.ts
6049
+ import { z as z28 } from "zod";
6050
+ import { ok as ok27, fail as fail13 } from "@dyyz1993/xcli-core";
6051
+ var TabParams = z28.object({
6052
+ subcommand: z28.enum(["list", "new", "close", "switch"]),
6053
+ url: z28.string().optional(),
6054
+ index: z28.number().int().min(0).optional()
5869
6055
  });
5870
6056
  var tabCommand = registerCommand({
5871
6057
  name: "tab",
5872
6058
  description: "Manage browser tabs: list, new, close, switch",
5873
6059
  scope: "page",
5874
6060
  parameters: TabParams,
5875
- result: z27.object({
5876
- success: z27.boolean(),
5877
- data: z27.unknown()
6061
+ result: z28.object({
6062
+ success: z28.boolean(),
6063
+ data: z28.unknown()
5878
6064
  }),
5879
6065
  handler: async (p, ctx) => {
5880
6066
  if (!ctx.browserContext) {
5881
- return fail12("No browser context available. Use --cdp to connect to a browser first.");
6067
+ return fail13("No browser context available. Use --cdp to connect to a browser first.");
5882
6068
  }
5883
6069
  const pages = ctx.browserContext.pages();
5884
6070
  switch (p.subcommand) {
@@ -5891,7 +6077,7 @@ var tabCommand = registerCommand({
5891
6077
  case "switch":
5892
6078
  return handleSwitch(p, pages, ctx);
5893
6079
  default:
5894
- return fail12(`Unknown subcommand: ${p.subcommand}`);
6080
+ return fail13(`Unknown subcommand: ${p.subcommand}`);
5895
6081
  }
5896
6082
  }
5897
6083
  });
@@ -5906,7 +6092,7 @@ async function handleList(pages, ctx) {
5906
6092
  if (isActive) activeIndex = i;
5907
6093
  tabs.push({ index: i, url, title, active: isActive });
5908
6094
  }
5909
- return ok26({ tabs, total: tabs.length, activeIndex });
6095
+ return ok27({ tabs, total: tabs.length, activeIndex });
5910
6096
  }
5911
6097
  async function handleNew(p, _pages, ctx) {
5912
6098
  const newPage = await ctx.browserContext.newPage();
@@ -5934,7 +6120,7 @@ async function handleNew(p, _pages, ctx) {
5934
6120
  const title = await newPage.title().catch(() => "");
5935
6121
  const allPages = ctx.browserContext.pages();
5936
6122
  const newIndex = allPages.indexOf(newPage);
5937
- return ok26({
6123
+ return ok27({
5938
6124
  index: newIndex >= 0 ? newIndex : allPages.length - 1,
5939
6125
  url: newPage.url(),
5940
6126
  title,
@@ -5945,11 +6131,11 @@ async function handleNew(p, _pages, ctx) {
5945
6131
  async function handleClose(p, ctx) {
5946
6132
  const currentPages = ctx.browserContext.pages();
5947
6133
  if (currentPages.length <= 1) {
5948
- return fail12("Cannot close the last remaining tab");
6134
+ return fail13("Cannot close the last remaining tab");
5949
6135
  }
5950
6136
  const closeIndex = p.index ?? currentPages.findIndex((pg) => pg === ctx.page);
5951
6137
  if (closeIndex < 0 || closeIndex >= currentPages.length) {
5952
- return fail12(`Invalid tab index: ${closeIndex}. Valid range: 0-${currentPages.length - 1}`);
6138
+ return fail13(`Invalid tab index: ${closeIndex}. Valid range: 0-${currentPages.length - 1}`);
5953
6139
  }
5954
6140
  const pageToClose = currentPages[closeIndex];
5955
6141
  const isActivePage = pageToClose === ctx.page;
@@ -5964,7 +6150,7 @@ async function handleClose(p, ctx) {
5964
6150
  }
5965
6151
  ctx.page = newActivePage;
5966
6152
  }
5967
- return ok26({
6153
+ return ok27({
5968
6154
  closedIndex: closeIndex,
5969
6155
  total: remainingPages.length,
5970
6156
  activeIndex: isActivePage ? closeIndex < remainingPages.length ? closeIndex : remainingPages.length - 1 : remainingPages.findIndex((pg) => pg === ctx.page)
@@ -5972,10 +6158,10 @@ async function handleClose(p, ctx) {
5972
6158
  }
5973
6159
  async function handleSwitch(p, pages, ctx) {
5974
6160
  if (p.index === void 0) {
5975
- return fail12("Parameter --index is required for switch subcommand");
6161
+ return fail13("Parameter --index is required for switch subcommand");
5976
6162
  }
5977
6163
  if (p.index < 0 || p.index >= pages.length) {
5978
- return fail12(`Invalid tab index: ${p.index}. Valid range: 0-${pages.length - 1}`);
6164
+ return fail13(`Invalid tab index: ${p.index}. Valid range: 0-${pages.length - 1}`);
5979
6165
  }
5980
6166
  const targetPage = pages[p.index];
5981
6167
  await targetPage.bringToFront().catch(() => {
@@ -5997,7 +6183,7 @@ async function handleSwitch(p, pages, ctx) {
5997
6183
  }
5998
6184
  ctx.page = targetPage;
5999
6185
  const title = await targetPage.title().catch(() => "");
6000
- return ok26({
6186
+ return ok27({
6001
6187
  index: p.index,
6002
6188
  url: targetPage.url(),
6003
6189
  title,
@@ -6006,8 +6192,8 @@ async function handleSwitch(p, pages, ctx) {
6006
6192
  }
6007
6193
 
6008
6194
  // src/commands/addinitscript.ts
6009
- import { z as z28 } from "zod";
6010
- import { ok as ok27 } from "@dyyz1993/xcli-core";
6195
+ import { z as z29 } from "zod";
6196
+ import { ok as ok28 } from "@dyyz1993/xcli-core";
6011
6197
  import { readFileSync as readFileSync4 } from "fs";
6012
6198
 
6013
6199
  // src/chain-parser.ts
@@ -6148,14 +6334,14 @@ registerCommandDefinition("tab", ["subcommand"]);
6148
6334
  registerCommandDefinition("mouse", ["action", "x", "y"]);
6149
6335
 
6150
6336
  // src/commands/addinitscript.ts
6151
- var InitScriptParams = z28.object({
6152
- script: z28.string().optional(),
6153
- file: z28.string().optional(),
6154
- stdin: z28.boolean().optional(),
6155
- name: z28.string().optional(),
6156
- list: z28.boolean().optional(),
6157
- remove: z28.union([z28.string(), z28.boolean()]).optional(),
6158
- base64: z28.string().optional()
6337
+ var InitScriptParams = z29.object({
6338
+ script: z29.string().optional(),
6339
+ file: z29.string().optional(),
6340
+ stdin: z29.boolean().optional(),
6341
+ name: z29.string().optional(),
6342
+ list: z29.boolean().optional(),
6343
+ remove: z29.union([z29.string(), z29.boolean()]).optional(),
6344
+ base64: z29.string().optional()
6159
6345
  });
6160
6346
  var registeredScripts = /* @__PURE__ */ new Map();
6161
6347
  function resolveScriptContent(params) {
@@ -6189,14 +6375,14 @@ var addInitScriptCommand = registerCommand({
6189
6375
  description: "Add an initialization script that runs on every page load",
6190
6376
  scope: "page",
6191
6377
  parameters: InitScriptParams,
6192
- result: z28.object({
6193
- scripts: z28.array(z28.object({ name: z28.string(), size: z28.number(), preview: z28.string() })).optional(),
6194
- removed: z28.string().optional(),
6195
- existed: z28.boolean().optional(),
6196
- error: z28.string().optional(),
6197
- registered: z28.string().optional(),
6198
- hint: z28.string().optional(),
6199
- executedImmediately: z28.boolean().optional()
6378
+ result: z29.object({
6379
+ scripts: z29.array(z29.object({ name: z29.string(), size: z29.number(), preview: z29.string() })).optional(),
6380
+ removed: z29.string().optional(),
6381
+ existed: z29.boolean().optional(),
6382
+ error: z29.string().optional(),
6383
+ registered: z29.string().optional(),
6384
+ hint: z29.string().optional(),
6385
+ executedImmediately: z29.boolean().optional()
6200
6386
  }).passthrough(),
6201
6387
  handler: async (params, ctx) => {
6202
6388
  if (params.list) {
@@ -6205,20 +6391,20 @@ var addInitScriptCommand = registerCommand({
6205
6391
  size: content2.length,
6206
6392
  preview: content2.slice(0, 80)
6207
6393
  }));
6208
- return ok27({ scripts });
6394
+ return ok28({ scripts });
6209
6395
  }
6210
6396
  if (params.remove && typeof params.remove === "string") {
6211
6397
  const existed = registeredScripts.delete(params.remove);
6212
- return ok27({ removed: params.remove, existed });
6398
+ return ok28({ removed: params.remove, existed });
6213
6399
  }
6214
6400
  const removeTarget = (typeof params.remove === "string" ? params.remove : null) || (params.name && !resolveScriptContent(params) ? params.name : null);
6215
6401
  if (removeTarget && !resolveScriptContent(params)) {
6216
6402
  const existed = registeredScripts.delete(removeTarget);
6217
- return ok27({ removed: removeTarget, existed });
6403
+ return ok28({ removed: removeTarget, existed });
6218
6404
  }
6219
6405
  let content = params.stdin ? await readStdin() : resolveScriptContent(params);
6220
6406
  if (!content) {
6221
- return ok27({ error: "No script content provided. Use --script, --file, --stdin, or --base64" });
6407
+ return ok28({ error: "No script content provided. Use --script, --file, --stdin, or --base64" });
6222
6408
  }
6223
6409
  const scriptName = params.name ?? `script-${Date.now()}`;
6224
6410
  registeredScripts.set(scriptName, content);
@@ -6226,45 +6412,45 @@ var addInitScriptCommand = registerCommand({
6226
6412
  try {
6227
6413
  await ctx.page.evaluate(content);
6228
6414
  } catch {
6229
- return ok27({
6415
+ return ok28({
6230
6416
  registered: scriptName,
6231
6417
  hint: "Script registered for future page loads; immediate execution skipped (page may not be ready)"
6232
6418
  });
6233
6419
  }
6234
- return ok27({ registered: scriptName, executedImmediately: true });
6420
+ return ok28({ registered: scriptName, executedImmediately: true });
6235
6421
  }
6236
6422
  });
6237
6423
  registerCommandDefinition("addinitscript", ["script"]);
6238
6424
 
6239
6425
  // src/commands/find.ts
6240
- import { z as z29 } from "zod";
6241
- import { ok as ok28, fail as fail13, normalizeTips as normalizeTips5 } from "@dyyz1993/xcli-core";
6242
- var actionSchema2 = z29.enum(["click", "fill", "type", "select", "hover", "check"]);
6426
+ import { z as z30 } from "zod";
6427
+ import { ok as ok29, fail as fail14, normalizeTips as normalizeTips6 } from "@dyyz1993/xcli-core";
6428
+ var actionSchema2 = z30.enum(["click", "fill", "type", "select", "hover", "check"]);
6243
6429
  var findCommand = registerCommand({
6244
6430
  name: "find",
6245
6431
  description: "Find elements by semantic strategy (text/role/label/placeholder/testid) and optionally perform an action",
6246
6432
  scope: "page",
6247
- parameters: z29.object({
6248
- strategy: z29.enum(["text", "role", "label", "placeholder", "testid", "alt", "title", "first", "last", "nth"]),
6249
- value: z29.string(),
6250
- name: z29.string().optional(),
6251
- exact: z29.boolean().optional().default(false),
6252
- operation: z29.string().optional().describe('Trailing operation syntax, e.g. click, fill "text", type "text"'),
6433
+ parameters: z30.object({
6434
+ strategy: z30.enum(["text", "role", "label", "placeholder", "testid", "alt", "title", "first", "last", "nth"]),
6435
+ value: z30.string(),
6436
+ name: z30.string().optional(),
6437
+ exact: z30.boolean().optional().default(false),
6438
+ operation: z30.string().optional().describe('Trailing operation syntax, e.g. click, fill "text", type "text"'),
6253
6439
  action: actionSchema2.optional().describe("Action to perform when not using trailing operation syntax"),
6254
- actionValue: z29.string().optional().describe("Value for fill/type/select when using action"),
6255
- index: z29.number().int().optional().describe("Index for nth strategy"),
6256
- click: z29.boolean().optional().default(false),
6257
- fill: z29.string().optional(),
6258
- type: z29.string().optional(),
6259
- select: z29.string().optional(),
6260
- hover: z29.boolean().optional().default(false),
6261
- check: z29.boolean().optional().default(false),
6262
- timeout: z29.number().optional().default(1e4)
6440
+ actionValue: z30.string().optional().describe("Value for fill/type/select when using action"),
6441
+ index: z30.number().int().optional().describe("Index for nth strategy"),
6442
+ click: z30.boolean().optional().default(false),
6443
+ fill: z30.string().optional(),
6444
+ type: z30.string().optional(),
6445
+ select: z30.string().optional(),
6446
+ hover: z30.boolean().optional().default(false),
6447
+ check: z30.boolean().optional().default(false),
6448
+ timeout: z30.number().optional().default(1e4)
6263
6449
  }),
6264
- result: z29.object({
6265
- matched: z29.number(),
6266
- selector: z29.string(),
6267
- action: z29.string().optional()
6450
+ result: z30.object({
6451
+ matched: z30.number(),
6452
+ selector: z30.string(),
6453
+ action: z30.string().optional()
6268
6454
  }),
6269
6455
  handler: async (p, ctx) => {
6270
6456
  const page = ctx.page;
@@ -6279,7 +6465,7 @@ var findCommand = registerCommand({
6279
6465
  });
6280
6466
  const count = await locator.count();
6281
6467
  if (count === 0) {
6282
- return fail13(`No element found with ${p.strategy}="${p.value}"`);
6468
+ return fail14(`No element found with ${p.strategy}="${p.value}"`);
6283
6469
  }
6284
6470
  const tips = [];
6285
6471
  const target = selectTarget(locator, p.strategy);
@@ -6291,15 +6477,15 @@ var findCommand = registerCommand({
6291
6477
  await target.click({ timeout: p.timeout, force: true });
6292
6478
  return okWithTips({ matched: count, selector, action: "click" }, tips);
6293
6479
  } else if (actionName === "fill") {
6294
- if (actionValue === void 0) return fail13("find fill requires a value");
6480
+ if (actionValue === void 0) return fail14("find fill requires a value");
6295
6481
  await target.fill(actionValue, { timeout: p.timeout, force: true });
6296
6482
  return okWithTips({ matched: count, selector, action: `fill("${actionValue}")` }, tips);
6297
6483
  } else if (actionName === "type") {
6298
- if (actionValue === void 0) return fail13("find type requires a value");
6484
+ if (actionValue === void 0) return fail14("find type requires a value");
6299
6485
  await target.type(actionValue, { delay: 10, timeout: p.timeout });
6300
6486
  return okWithTips({ matched: count, selector, action: `type("${actionValue}")` }, tips);
6301
6487
  } else if (actionName === "select") {
6302
- if (actionValue === void 0) return fail13("find select requires a value");
6488
+ if (actionValue === void 0) return fail14("find select requires a value");
6303
6489
  await target.selectOption(actionValue);
6304
6490
  return okWithTips({ matched: count, selector, action: `select("${actionValue}")` }, tips);
6305
6491
  } else if (actionName === "hover") {
@@ -6313,8 +6499,8 @@ var findCommand = registerCommand({
6313
6499
  }
6314
6500
  });
6315
6501
  function okWithTips(data, tips) {
6316
- const result = ok28(data);
6317
- if (tips.length > 0) result.tips = normalizeTips5(tips);
6502
+ const result = ok29(data);
6503
+ if (tips.length > 0) result.tips = normalizeTips6(tips);
6318
6504
  return result;
6319
6505
  }
6320
6506
  function parseOperation(operation) {
@@ -6412,8 +6598,8 @@ function describeSelector(strategy, value, name) {
6412
6598
  }
6413
6599
 
6414
6600
  // src/commands/visual-tag.ts
6415
- import { z as z30 } from "zod";
6416
- import { ok as ok29, fail as fail14 } from "@dyyz1993/xcli-core";
6601
+ import { z as z31 } from "zod";
6602
+ import { ok as ok30, fail as fail15 } from "@dyyz1993/xcli-core";
6417
6603
  var SAFE_SET = "ahjkmnprtw3479".split("");
6418
6604
  var TAG_SCRIPT = `
6419
6605
  (function() {
@@ -6504,49 +6690,49 @@ var visualTagCommand = registerCommand({
6504
6690
  name: "visual-tag",
6505
6691
  description: "\u5728\u9875\u9762\u4E0A\u7ED9\u53EF\u4EA4\u4E92\u5143\u7D20\u53E0\u52A0\u9632\u6DF7\u6DC6\u77ED ID \u6807\u7B7E\uFF08\u89C6\u89C9\u5B9A\u4F4D\u7528\uFF09",
6506
6692
  scope: "page",
6507
- parameters: z30.object({
6508
- action: z30.enum(["tag", "lookup", "clear", "list"]),
6509
- id: z30.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID")
6693
+ parameters: z31.object({
6694
+ action: z31.enum(["tag", "lookup", "clear", "list"]),
6695
+ id: z31.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID")
6510
6696
  }),
6511
- result: z30.object({
6512
- action: z30.string(),
6513
- tagged: z30.number().optional(),
6514
- id: z30.string().optional(),
6515
- element: z30.record(z30.unknown()).optional()
6697
+ result: z31.object({
6698
+ action: z31.string(),
6699
+ tagged: z31.number().optional(),
6700
+ id: z31.string().optional(),
6701
+ element: z31.record(z31.unknown()).optional()
6516
6702
  }),
6517
6703
  handler: async (p, ctx) => {
6518
6704
  switch (p.action) {
6519
6705
  case "tag": {
6520
6706
  const result = await ctx.page.evaluate(TAG_SCRIPT);
6521
6707
  const parsed = JSON.parse(result);
6522
- return ok29({ action: "tag", tagged: parsed.tagged });
6708
+ return ok30({ action: "tag", tagged: parsed.tagged });
6523
6709
  }
6524
6710
  case "lookup": {
6525
- if (!p.id) return fail14("lookup \u9700\u8981 --id \u53C2\u6570");
6711
+ if (!p.id) return fail15("lookup \u9700\u8981 --id \u53C2\u6570");
6526
6712
  const result = await ctx.page.evaluate(
6527
6713
  `(function() { var m = window.__xbTagMap; if (!m) return JSON.stringify({err:'no-map'}); var e = m[${JSON.stringify(p.id)}]; return e ? JSON.stringify(e) : JSON.stringify({err:'not-found'}); })()`
6528
6714
  );
6529
6715
  const parsed = JSON.parse(result);
6530
- if (parsed.err) return fail14(`ID ${p.id}: ${parsed.err}`);
6531
- return ok29({ action: "lookup", id: p.id, element: parsed });
6716
+ if (parsed.err) return fail15(`ID ${p.id}: ${parsed.err}`);
6717
+ return ok30({ action: "lookup", id: p.id, element: parsed });
6532
6718
  }
6533
6719
  case "list": {
6534
6720
  const result = await ctx.page.evaluate(
6535
6721
  `(function() { var m = window.__xbTagMap; if (!m) return '{}'; var out = {}; for (var k in m) { out[k] = m[k].text || m[k].tagName; } return JSON.stringify(out); })()`
6536
6722
  );
6537
- return ok29({ action: "list", element: JSON.parse(result) });
6723
+ return ok30({ action: "list", element: JSON.parse(result) });
6538
6724
  }
6539
6725
  case "clear": {
6540
6726
  await ctx.page.evaluate(`(function(){var o=document.getElementById('__xb-tag-overlay');if(o)o.remove();window.__xbTagMap=null;return 'cleared'})()`);
6541
- return ok29({ action: "clear" });
6727
+ return ok30({ action: "clear" });
6542
6728
  }
6543
6729
  }
6544
6730
  }
6545
6731
  });
6546
6732
 
6547
6733
  // src/commands/visual-tag-v2.ts
6548
- import { z as z31 } from "zod";
6549
- import { ok as ok30, fail as fail15 } from "@dyyz1993/xcli-core";
6734
+ import { z as z32 } from "zod";
6735
+ import { ok as ok31, fail as fail16 } from "@dyyz1993/xcli-core";
6550
6736
  var SAFE_SET2 = "ahjkmnprtw3479".split("");
6551
6737
  var TAG_V2_SCRIPT = `
6552
6738
  (function() {
@@ -6893,45 +7079,45 @@ var visualTagV2Command = registerCommand({
6893
7079
  name: "visual-tag-v2",
6894
7080
  description: "\u5206\u8272\u6807\u6CE8\u9875\u9762\u5143\u7D20\uFF08\u7EA2=\u53EF\u70B9\u51FB \u84DD=\u8F93\u5165 \u7EFF=\u56FE\u7247 \u9EC4=\u5217\u8868 \u7D2B=\u6570\u5B57 \u6A59=\u6587\u672C\uFF09",
6895
7081
  scope: "page",
6896
- parameters: z31.object({
6897
- action: z31.enum(["tag", "lookup", "clear", "stats", "by-type", "find", "export", "interact"]),
6898
- id: z31.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID"),
6899
- query: z31.string().optional().describe('find \u65F6\u6307\u5B9A\u641C\u7D22\u8BCD\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09'),
6900
- type: z31.string().optional().describe("by-type \u65F6\u8FC7\u6EE4\u7C7B\u578B\uFF1Aclick/input/img/list/count/text"),
6901
- "interact-action": z31.enum(["click", "fill", "read"]).optional().describe("interact \u52A8\u4F5C\u7C7B\u578B"),
6902
- value: z31.string().optional().describe("fill \u65F6\u7684\u586B\u5145\u503C")
7082
+ parameters: z32.object({
7083
+ action: z32.enum(["tag", "lookup", "clear", "stats", "by-type", "find", "export", "interact"]),
7084
+ id: z32.string().optional().describe("lookup \u65F6\u6307\u5B9A\u8981\u67E5\u7684 ID"),
7085
+ query: z32.string().optional().describe('find \u65F6\u6307\u5B9A\u641C\u7D22\u8BCD\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09'),
7086
+ type: z32.string().optional().describe("by-type \u65F6\u8FC7\u6EE4\u7C7B\u578B\uFF1Aclick/input/img/list/count/text"),
7087
+ "interact-action": z32.enum(["click", "fill", "read"]).optional().describe("interact \u52A8\u4F5C\u7C7B\u578B"),
7088
+ value: z32.string().optional().describe("fill \u65F6\u7684\u586B\u5145\u503C")
6903
7089
  }),
6904
- result: z31.object({
6905
- action: z31.string(),
6906
- total: z31.number().optional(),
6907
- byType: z31.record(z31.number()).optional(),
6908
- element: z31.record(z31.unknown()).optional()
7090
+ result: z32.object({
7091
+ action: z32.string(),
7092
+ total: z32.number().optional(),
7093
+ byType: z32.record(z32.number()).optional(),
7094
+ element: z32.record(z32.unknown()).optional()
6909
7095
  }),
6910
7096
  handler: async (p, ctx) => {
6911
7097
  switch (p.action) {
6912
7098
  case "tag": {
6913
7099
  const result = await ctx.page.evaluate(TAG_V2_SCRIPT);
6914
7100
  const parsed = JSON.parse(result);
6915
- return ok30({ action: "tag", total: parsed.total, byType: parsed.byType });
7101
+ return ok31({ action: "tag", total: parsed.total, byType: parsed.byType });
6916
7102
  }
6917
7103
  case "lookup": {
6918
- if (!p.id) return fail15("lookup \u9700\u8981 --id");
7104
+ if (!p.id) return fail16("lookup \u9700\u8981 --id");
6919
7105
  const result = await ctx.page.evaluate(
6920
7106
  `(function(){var m=window.__xbTagMap;if(!m)return JSON.stringify({err:'no-map'});var e=m[${JSON.stringify(p.id)}];return e?JSON.stringify(e):JSON.stringify({err:'not-found'})})()`
6921
7107
  );
6922
7108
  const parsed = JSON.parse(result);
6923
- if (parsed.err) return fail15(`ID ${p.id}: ${parsed.err}`);
6924
- return ok30({ action: "lookup", id: p.id, element: parsed });
7109
+ if (parsed.err) return fail16(`ID ${p.id}: ${parsed.err}`);
7110
+ return ok31({ action: "lookup", id: p.id, element: parsed });
6925
7111
  }
6926
7112
  case "by-type": {
6927
7113
  const result = await ctx.page.evaluate(
6928
7114
  `(function(){var m=window.__xbTagMap;if(!m)return'{}';var out={};for(var k in m){if(!${JSON.stringify(p.type || "")}||m[k].type===${JSON.stringify(p.type || "")}){out[k]={type:m[k].type,text:m[k].text,num:m[k].num,label:m[k].formLabel}}}return JSON.stringify(out)})()`
6929
7115
  );
6930
- return ok30({ action: "by-type", element: JSON.parse(result) });
7116
+ return ok31({ action: "by-type", element: JSON.parse(result) });
6931
7117
  }
6932
7118
  case "find": {
6933
7119
  const query = p.query;
6934
- if (!query) return fail15('find \u9700\u8981 --query \u53C2\u6570\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09');
7120
+ if (!query) return fail16('find \u9700\u8981 --query \u53C2\u6570\uFF08\u5982 "\u627E\u6709AI\u7F16\u7A0B\u6807\u7B7E\u7684\u5361\u7247"\uFF09');
6935
7121
  const result = await ctx.page.evaluate(
6936
7122
  `(function(){
6937
7123
  var map = window.__xbTagSerializable;
@@ -6973,21 +7159,21 @@ var visualTagV2Command = registerCommand({
6973
7159
  return JSON.stringify({total:results.length, results:results.slice(0,20)});
6974
7160
  })()`
6975
7161
  );
6976
- return ok30({ action: "find", query, element: JSON.parse(result) });
7162
+ return ok31({ action: "find", query, element: JSON.parse(result) });
6977
7163
  }
6978
7164
  case "stats": {
6979
7165
  const result = await ctx.page.evaluate(
6980
7166
  `(function(){return JSON.stringify(window.__xbTagStats||{})})()`
6981
7167
  );
6982
- return ok30({ action: "stats", element: JSON.parse(result) });
7168
+ return ok31({ action: "stats", element: JSON.parse(result) });
6983
7169
  }
6984
7170
  case "interact": {
6985
7171
  const query = p.query;
6986
7172
  const pAny = p;
6987
7173
  const action = pAny["interact-action"] || pAny.interactAction || pAny.interact_action;
6988
7174
  const value = pAny.value;
6989
- if (!query) return fail15("interact \u9700\u8981 --query \u53C2\u6570");
6990
- if (!action) return fail15("interact \u9700\u8981 --interact-action \u53C2\u6570\uFF08click/fill/read\uFF09");
7175
+ if (!query) return fail16("interact \u9700\u8981 --query \u53C2\u6570");
7176
+ if (!action) return fail16("interact \u9700\u8981 --interact-action \u53C2\u6570\uFF08click/fill/read\uFF09");
6991
7177
  const findResult = await ctx.page.evaluate(
6992
7178
  `(function(){
6993
7179
  var map = window.__xbTagSerializable;
@@ -7017,11 +7203,11 @@ var visualTagV2Command = registerCommand({
7017
7203
  })()`
7018
7204
  );
7019
7205
  const parsed = JSON.parse(findResult);
7020
- if (parsed.err) return fail15(parsed.err);
7021
- if (!parsed.total || !parsed.results?.length) return fail15(`\u672A\u627E\u5230\u5339\u914D "${query}" \u7684\u5143\u7D20`);
7206
+ if (parsed.err) return fail16(parsed.err);
7207
+ if (!parsed.total || !parsed.results?.length) return fail16(`\u672A\u627E\u5230\u5339\u914D "${query}" \u7684\u5143\u7D20`);
7022
7208
  const target = parsed.results[0];
7023
7209
  if (action === "read") {
7024
- return ok30({ action: "interact", query, target, result: { read: target.text || target.label } });
7210
+ return ok31({ action: "interact", query, target, result: { read: target.text || target.label } });
7025
7211
  }
7026
7212
  if (action === "click") {
7027
7213
  const el = await ctx.page.evaluate(
@@ -7034,12 +7220,12 @@ var visualTagV2Command = registerCommand({
7034
7220
  return {x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2)};
7035
7221
  })()`
7036
7222
  );
7037
- if (!el) return fail15(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
7223
+ if (!el) return fail16(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
7038
7224
  await ctx.page.mouse.click(el.x, el.y, { stealth: true });
7039
- return ok30({ action: "interact", query, target, result: { clicked: true, x: el.x, y: el.y } });
7225
+ return ok31({ action: "interact", query, target, result: { clicked: true, x: el.x, y: el.y } });
7040
7226
  }
7041
7227
  if (action === "fill") {
7042
- if (!value) return fail15("fill \u9700\u8981 --value \u53C2\u6570");
7228
+ if (!value) return fail16("fill \u9700\u8981 --value \u53C2\u6570");
7043
7229
  const el = await ctx.page.evaluate(
7044
7230
  `(function(){
7045
7231
  var map = window.__xbTagMap;
@@ -7050,12 +7236,12 @@ var visualTagV2Command = registerCommand({
7050
7236
  return {x: Math.round(r.x + r.width/2), y: Math.round(r.y + r.height/2)};
7051
7237
  })()`
7052
7238
  );
7053
- if (!el) return fail15(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
7239
+ if (!el) return fail16(`\u5143\u7D20 ${target.id} \u4E0D\u53EF\u4EA4\u4E92`);
7054
7240
  await ctx.page.mouse.click(el.x, el.y, { stealth: true });
7055
7241
  await ctx.page.keyboard.type(value, { stealth: true });
7056
- return ok30({ action: "interact", query, target, result: { filled: true, value } });
7242
+ return ok31({ action: "interact", query, target, result: { filled: true, value } });
7057
7243
  }
7058
- return fail15(`\u672A\u77E5 action: ${action}`);
7244
+ return fail16(`\u672A\u77E5 action: ${action}`);
7059
7245
  }
7060
7246
  case "export": {
7061
7247
  const result = await ctx.page.evaluate(
@@ -7103,12 +7289,12 @@ var visualTagV2Command = registerCommand({
7103
7289
  })()`
7104
7290
  );
7105
7291
  const parsed = JSON.parse(result);
7106
- if (parsed.err) return fail15(String(parsed.err));
7107
- return ok30({ action: "export", element: parsed });
7292
+ if (parsed.err) return fail16(String(parsed.err));
7293
+ return ok31({ action: "export", element: parsed });
7108
7294
  }
7109
7295
  case "clear": {
7110
7296
  await ctx.page.evaluate(`(function(){var o=document.getElementById('__xb-tag-overlay');if(o)o.remove();window.__xbTagMap=null;window.__xbTagStats=null;return 'ok'})()`);
7111
- return ok30({ action: "clear" });
7297
+ return ok31({ action: "clear" });
7112
7298
  }
7113
7299
  }
7114
7300
  }
@@ -8251,7 +8437,7 @@ async function guardCheck(commandName) {
8251
8437
  }
8252
8438
  }
8253
8439
  function errorResult(message) {
8254
- return { ...fail16(message), duration: 0 };
8440
+ return { ...fail17(message), duration: 0 };
8255
8441
  }
8256
8442
  function tipsToMessages(tips) {
8257
8443
  if (!tips || tips.length === 0) return [];
@@ -8440,7 +8626,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8440
8626
  const cache = /* @__PURE__ */ new Map();
8441
8627
  const resolved = await resolveRefParams(session.page, params, command.selectorParams, cache, session.id);
8442
8628
  if (resolved.tips.length > 0) {
8443
- refTips = normalizeTips6(resolved.tips);
8629
+ refTips = normalizeTips7(resolved.tips);
8444
8630
  params = resolved.params;
8445
8631
  }
8446
8632
  }
@@ -8508,8 +8694,8 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8508
8694
  }
8509
8695
  const merged = [
8510
8696
  ...raw.tips || [],
8511
- ...normalizeTips6(smartTips),
8512
- ...snapshotHint ? normalizeTips6([snapshotHint]) : [],
8697
+ ...normalizeTips7(smartTips),
8698
+ ...snapshotHint ? normalizeTips7([snapshotHint]) : [],
8513
8699
  ...refTips
8514
8700
  ];
8515
8701
  const isSuccess = raw.success !== false;
@@ -8524,7 +8710,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8524
8710
  timestamp: start
8525
8711
  });
8526
8712
  if (isSuccess) {
8527
- return { ...ok31(raw.data, merged.length > 0 ? merged : raw.tips), duration, ...hookOutputs ? { hookOutputs } : {} };
8713
+ return { ...ok32(raw.data, merged.length > 0 ? merged : raw.tips), duration, ...hookOutputs ? { hookOutputs } : {} };
8528
8714
  }
8529
8715
  const fc = classifyFailure(raw.message);
8530
8716
  return {
@@ -8537,7 +8723,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8537
8723
  ...hookOutputs ? { hookOutputs } : {}
8538
8724
  };
8539
8725
  }
8540
- const smartTipNormalized = normalizeTips6(smartTips);
8726
+ const smartTipNormalized = normalizeTips7(smartTips);
8541
8727
  recordArchive(session?.id, sessionName, {
8542
8728
  step: 0,
8543
8729
  command: commandName,
@@ -8547,7 +8733,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8547
8733
  duration,
8548
8734
  timestamp: start
8549
8735
  });
8550
- return { ...ok31(raw, smartTipNormalized), duration, ...hookOutputs ? { hookOutputs } : {} };
8736
+ return { ...ok32(raw, smartTipNormalized), duration, ...hookOutputs ? { hookOutputs } : {} };
8551
8737
  } catch (err) {
8552
8738
  const end = Date.now();
8553
8739
  const duration = end - start;
@@ -8592,7 +8778,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
8592
8778
  duration,
8593
8779
  timestamp: start
8594
8780
  });
8595
- return { ...fail16(errorMessage), duration };
8781
+ return { ...fail17(errorMessage), duration };
8596
8782
  } finally {
8597
8783
  }
8598
8784
  }
@@ -8637,7 +8823,7 @@ async function executeChain(input, options) {
8637
8823
  results.push({
8638
8824
  command: cmdName,
8639
8825
  raw: cmdStr,
8640
- ...fail16(`Plugin "${cmdName}" requires a sub-command`),
8826
+ ...fail17(`Plugin "${cmdName}" requires a sub-command`),
8641
8827
  duration: 0
8642
8828
  });
8643
8829
  if (type === "and") {
@@ -8656,7 +8842,7 @@ async function executeChain(input, options) {
8656
8842
  results.push({
8657
8843
  command: cmdName,
8658
8844
  raw: cmdStr,
8659
- ...fail16(`Unknown command "${subCommand}" for plugin "${cmdName}"`),
8845
+ ...fail17(`Unknown command "${subCommand}" for plugin "${cmdName}"`),
8660
8846
  duration: 0
8661
8847
  });
8662
8848
  if (type === "and") {
@@ -8726,7 +8912,7 @@ async function executeChain(input, options) {
8726
8912
  success: false,
8727
8913
  data: data2,
8728
8914
  message: loginGuard.message,
8729
- tips: normalizeTips6(loginGuard.tips),
8915
+ tips: normalizeTips7(loginGuard.tips),
8730
8916
  duration: duration3
8731
8917
  });
8732
8918
  if (type === "and") {
@@ -8768,7 +8954,7 @@ async function executeChain(input, options) {
8768
8954
  results.push({
8769
8955
  command: `${cmdName} ${subCommand}`,
8770
8956
  raw: cmdStr,
8771
- ...ok31(data),
8957
+ ...ok32(data),
8772
8958
  duration: duration2,
8773
8959
  ...hookOutputs ? { hookOutputs } : {}
8774
8960
  });
@@ -8796,7 +8982,7 @@ async function executeChain(input, options) {
8796
8982
  results.push({
8797
8983
  command: `${cmdName} ${subCommand}`,
8798
8984
  raw: cmdStr,
8799
- ...fail16(errorMessage),
8985
+ ...fail17(errorMessage),
8800
8986
  duration: duration2
8801
8987
  });
8802
8988
  if (type === "and") {