@xbrowser/cli 1.27.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.
@@ -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(),
@@ -74,6 +74,25 @@ function getRefTarget(sessionKey2, ref) {
74
74
  if (!session || !target) return null;
75
75
  return { screenHash: session.screenHash, target };
76
76
  }
77
+ function inheritStableRefs(key, rawTargets) {
78
+ const prev = sessions.get(key);
79
+ if (!prev || prev.targets.size === 0) {
80
+ return rawTargets.map((target, index) => ({ ...target, ref: `e${index + 1}` }));
81
+ }
82
+ const bySelector = /* @__PURE__ */ new Map();
83
+ let maxId = 0;
84
+ for (const [ref, target] of prev.targets) {
85
+ bySelector.set(target.selector, ref);
86
+ const id = Number(ref.slice(1));
87
+ if (Number.isFinite(id) && id > maxId) maxId = id;
88
+ }
89
+ let next = maxId + 1;
90
+ return rawTargets.map((target) => {
91
+ const inherited = bySelector.get(target.selector);
92
+ if (inherited) return { ...target, ref: inherited };
93
+ return { ...target, ref: `e${next++}` };
94
+ });
95
+ }
77
96
 
78
97
  // src/runtime/agent-runtime.ts
79
98
  function sessionKey(sessionId) {
@@ -225,10 +244,7 @@ async function observePage(page, sessionId, options = {}) {
225
244
  { includeHidden: !!options.includeHidden, limit: options.limit ?? 80 }
226
245
  )
227
246
  ]);
228
- const targets = raw.targets.map((target, index) => ({
229
- ref: `e${index + 1}`,
230
- ...target
231
- }));
247
+ const targets = inheritStableRefs(sessionKey(sessionId), raw.targets);
232
248
  replaceRefs(sessionKey(sessionId), raw.screenHash, targets);
233
249
  return {
234
250
  url: page.url(),
@@ -1637,9 +1653,12 @@ var visionTaskCommand = registerCommand({
1637
1653
  } catch {
1638
1654
  }
1639
1655
  }
1640
- const buffer = await page.screenshot({ type: "png" });
1656
+ const shotQuality = Math.max(30, Math.min(95, parseInt(process.env.XBROWSER_VLM_SHOT_QUALITY ?? "75", 10) || 75));
1657
+ const buffer = await page.screenshot({ type: "jpeg", quality: shotQuality });
1641
1658
  const b64 = buffer.toString("base64");
1642
- const { w, h } = pngDims(b64);
1659
+ const vp = typeof page.viewportSize === "function" ? page.viewportSize() : null;
1660
+ const w = vp?.width ?? pngDims(b64).w;
1661
+ const h = vp?.height ?? pngDims(b64).h;
1643
1662
  const obsText = [
1644
1663
  `\u4EFB\u52A1\uFF1A${p.task}`,
1645
1664
  `\u622A\u56FE\u5C3A\u5BF8\uFF1A${w}x${h}\uFF08\u5750\u6807\u539F\u70B9\uFF1A\u5DE6\u4E0A\u89D2\uFF09`,
@@ -1648,7 +1667,7 @@ var visionTaskCommand = registerCommand({
1648
1667
  ${history.slice(-6).join("\n")}` : "\u5C1A\u65E0\u52A8\u4F5C\u3002"
1649
1668
  ].join("\n");
1650
1669
  const reply = await vlmAskRetry(creds, [
1651
- { type: "image", source: { type: "base64", media_type: "image/png", data: b64 } },
1670
+ { type: "image", source: { type: "base64", media_type: shotQuality >= 100 ? "image/png" : "image/jpeg", data: b64 } },
1652
1671
  { type: "text", text: `${SYSTEM_PROMPT}
1653
1672
 
1654
1673
  ${obsText}` }
package/dist/cli.js CHANGED
@@ -17,7 +17,7 @@ import {
17
17
  loadHooks,
18
18
  parsePluginParams,
19
19
  readJsonFile
20
- } from "./chunk-YITK42HZ.js";
20
+ } from "./chunk-OEC7ZSFW.js";
21
21
  import "./chunk-JKVUFP3G.js";
22
22
  import {
23
23
  forwardCommandLog,
@@ -6297,7 +6297,7 @@ async function handleRemote(args, options, mode) {
6297
6297
  }
6298
6298
  }
6299
6299
  async function startMcpServer() {
6300
- const { startMcpStdio } = await import("./server-YKMRFDEM.js");
6300
+ const { startMcpStdio } = await import("./server-JXF3JOAM.js");
6301
6301
  startMcpStdio();
6302
6302
  }
6303
6303
 
@@ -1305,9 +1305,12 @@ var visionTaskCommand = registerCommand({
1305
1305
  } catch {
1306
1306
  }
1307
1307
  }
1308
- const buffer = await page.screenshot({ type: "png" });
1308
+ const shotQuality = Math.max(30, Math.min(95, parseInt(process.env.XBROWSER_VLM_SHOT_QUALITY ?? "75", 10) || 75));
1309
+ const buffer = await page.screenshot({ type: "jpeg", quality: shotQuality });
1309
1310
  const b64 = buffer.toString("base64");
1310
- const { w, h } = pngDims(b64);
1311
+ const vp = typeof page.viewportSize === "function" ? page.viewportSize() : null;
1312
+ const w = vp?.width ?? pngDims(b64).w;
1313
+ const h = vp?.height ?? pngDims(b64).h;
1311
1314
  const obsText = [
1312
1315
  `\u4EFB\u52A1\uFF1A${p.task}`,
1313
1316
  `\u622A\u56FE\u5C3A\u5BF8\uFF1A${w}x${h}\uFF08\u5750\u6807\u539F\u70B9\uFF1A\u5DE6\u4E0A\u89D2\uFF09`,
@@ -1316,7 +1319,7 @@ var visionTaskCommand = registerCommand({
1316
1319
  ${history.slice(-6).join("\n")}` : "\u5C1A\u65E0\u52A8\u4F5C\u3002"
1317
1320
  ].join("\n");
1318
1321
  const reply = await vlmAskRetry(creds, [
1319
- { type: "image", source: { type: "base64", media_type: "image/png", data: b64 } },
1322
+ { type: "image", source: { type: "base64", media_type: shotQuality >= 100 ? "image/png" : "image/jpeg", data: b64 } },
1320
1323
  { type: "text", text: `${SYSTEM_PROMPT}
1321
1324
 
1322
1325
  ${obsText}` }
@@ -4760,6 +4763,25 @@ function getRefTarget(sessionKey2, ref) {
4760
4763
  if (!session || !target) return null;
4761
4764
  return { screenHash: session.screenHash, target };
4762
4765
  }
4766
+ function inheritStableRefs(key, rawTargets) {
4767
+ const prev = sessions.get(key);
4768
+ if (!prev || prev.targets.size === 0) {
4769
+ return rawTargets.map((target, index) => ({ ...target, ref: `e${index + 1}` }));
4770
+ }
4771
+ const bySelector = /* @__PURE__ */ new Map();
4772
+ let maxId = 0;
4773
+ for (const [ref, target] of prev.targets) {
4774
+ bySelector.set(target.selector, ref);
4775
+ const id = Number(ref.slice(1));
4776
+ if (Number.isFinite(id) && id > maxId) maxId = id;
4777
+ }
4778
+ let next = maxId + 1;
4779
+ return rawTargets.map((target) => {
4780
+ const inherited = bySelector.get(target.selector);
4781
+ if (inherited) return { ...target, ref: inherited };
4782
+ return { ...target, ref: `e${next++}` };
4783
+ });
4784
+ }
4763
4785
 
4764
4786
  // src/utils/resolve-selector.ts
4765
4787
  function buildElementSelector(el) {
@@ -5384,10 +5406,7 @@ async function observePage(page, sessionId, options = {}) {
5384
5406
  { includeHidden: !!options.includeHidden, limit: options.limit ?? 80 }
5385
5407
  )
5386
5408
  ]);
5387
- const targets = raw.targets.map((target, index) => ({
5388
- ref: `e${index + 1}`,
5389
- ...target
5390
- }));
5409
+ const targets = inheritStableRefs(sessionKey(sessionId), raw.targets);
5391
5410
  replaceRefs(sessionKey(sessionId), raw.screenHash, targets);
5392
5411
  return {
5393
5412
  url: page.url(),
package/dist/index.js CHANGED
@@ -48,7 +48,7 @@ import {
48
48
  splitCommand,
49
49
  waitForAIResponse,
50
50
  waitForPage
51
- } from "./chunk-IDXOIXQR.js";
51
+ } from "./chunk-WK3INZLA.js";
52
52
  import {
53
53
  SessionRecorder
54
54
  } from "./chunk-IR6C24P7.js";
@@ -6392,7 +6392,7 @@ async function handleRemote(args, options, mode) {
6392
6392
  }
6393
6393
  }
6394
6394
  async function startMcpServer() {
6395
- const { startMcpStdio } = await import("./server-WDDGIV3C.js");
6395
+ const { startMcpStdio } = await import("./server-26SE6YZR.js");
6396
6396
  startMcpStdio();
6397
6397
  }
6398
6398
 
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  executeChain,
3
3
  executeCommand
4
- } from "./chunk-IDXOIXQR.js";
4
+ } from "./chunk-WK3INZLA.js";
5
5
  import "./chunk-KECYFWJO.js";
6
6
  import "./chunk-JKVUFP3G.js";
7
7
  import "./chunk-3OD76SUE.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  executeChain,
3
3
  executeCommand
4
- } from "./chunk-YITK42HZ.js";
4
+ } from "./chunk-OEC7ZSFW.js";
5
5
  import "./chunk-JKVUFP3G.js";
6
6
  import "./chunk-3OD76SUE.js";
7
7
  import "./chunk-ZTHE5RBZ.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xbrowser/cli",
3
- "version": "1.27.0",
3
+ "version": "1.28.0",
4
4
  "description": "Browser automation CLI for web scraping, headless browsing, SEO analysis, and AI agent workflows. A command-line alternative to Playwright, Puppeteer, and Selenium.",
5
5
  "type": "module",
6
6
  "bin": {