cortico-world-hands 0.20.4 → 0.20.5

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.
Files changed (2) hide show
  1. package/dist/index.js +86 -2
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -719,6 +719,12 @@ var MIN_GESTURE_MS = 20;
719
719
  var MAX_GESTURE_MS = 2e4;
720
720
  var HandError = class extends Error {
721
721
  };
722
+ function parseRect(raw) {
723
+ if (!raw) return void 0;
724
+ const m = raw.match(/\[(\d+),(\d+)\]\[(\d+),(\d+)\]/);
725
+ if (!m) return void 0;
726
+ return [Number(m[1]), Number(m[2]), Number(m[3]), Number(m[4])];
727
+ }
722
728
  function get(port, path, timeoutMs) {
723
729
  return new Promise((resolve2, reject) => {
724
730
  const req = httpGet({ host: "127.0.0.1", port, path, timeout: timeoutMs }, (res) => {
@@ -1065,6 +1071,10 @@ var describeCommand = (command) => {
1065
1071
  }
1066
1072
  };
1067
1073
  var Hands = class {
1074
+ /** 读屏幕上的字(转发给眼睛客户端)。 */
1075
+ async uiSnapshot() {
1076
+ return this.eyes.ui();
1077
+ }
1068
1078
  eyes;
1069
1079
  rootActuator;
1070
1080
  shellActuator;
@@ -1110,7 +1120,7 @@ var Hands = class {
1110
1120
  for (const item of ui.items) {
1111
1121
  if (!item.center) continue;
1112
1122
  if (!item.text.toLowerCase().includes(query)) continue;
1113
- hits2.push({ text: item.text, center: item.center });
1123
+ hits2.push({ text: item.text, center: item.center, rect: parseRect(item.bounds) });
1114
1124
  if (hits2.length >= 20) break;
1115
1125
  }
1116
1126
  return hits2;
@@ -2151,6 +2161,30 @@ var HANDS_TOOL_DECLS = [
2151
2161
  },
2152
2162
  required: ["x", "y", "w", "h"]
2153
2163
  }
2164
+ },
2165
+ {
2166
+ name: "hand_read_page",
2167
+ tags: ["read"],
2168
+ description: "\u628A\u4E00\u6574\u9875\u8BFB\u5B8C\uFF1A\u5F53\u524D\u5C4F\u7684\u6587\u5B57 + \u5F80\u4E0A\u6EDA\u51E0\u6B21\u628A\u540E\u9762\u7684\u4E5F\u8BFB\u8FDB\u6765\uFF0C\u53BB\u91CD\u540E\u62FC\u6210\u4E00\u6BB5\u3002\u957F\u5217\u8868\u3001\u957F\u6587\u7AE0\u7528\u5B83\uFF0C\u522B\u4E00\u5C4F\u4E00\u5C4F\u95EE\u3002",
2169
+ parameters: {
2170
+ type: "object",
2171
+ properties: {
2172
+ pages: { type: "integer", description: "\u6700\u591A\u7FFB\u51E0\u5C4F\uFF0C\u9ED8\u8BA4 3\uFF0C\u6700\u591A 8" }
2173
+ }
2174
+ }
2175
+ },
2176
+ {
2177
+ name: "hand_read_text",
2178
+ tags: ["read"],
2179
+ description: "\u8BFB\u67D0\u4E00\u5904\u6587\u5B57\uFF1B\u5B57\u592A\u5C0F\uFF08\u9AD8\u5EA6\u4E0D\u8DB3 40 \u50CF\u7D20\uFF09\u4F1A\u81EA\u52A8\u628A\u90A3\u4E00\u5757\u653E\u5927\u518D\u7ED9\u4F60\u770B\uFF0C\u7701\u5F97\u4F60\u81EA\u5DF1\u8C03 hand_zoom\u3002",
2180
+ parameters: {
2181
+ type: "object",
2182
+ properties: {
2183
+ text: { type: "string", description: "\u8981\u8BFB\u7684\u90A3\u5904\u6587\u5B57\uFF08\u53EF\u4EE5\u53EA\u7ED9\u4E00\u90E8\u5206\uFF09" },
2184
+ nth: { type: "integer", description: "\u540C\u540D\u591A\u5904\u65F6\u53D6\u7B2C\u51E0\u4E2A\uFF0C\u4ECE 0 \u5F00\u59CB" }
2185
+ },
2186
+ required: ["text"]
2187
+ }
2154
2188
  }
2155
2189
  ];
2156
2190
 
@@ -2559,6 +2593,56 @@ ${lines.join("\n")}
2559
2593
  return await this.runSync(true);
2560
2594
  case "sync_status":
2561
2595
  return this.lastSync ? `\u4E0A\u6B21\u540C\u6B65 ${this.lastSync.at.slice(0, 19)}\uFF0C\u8BB0\u5FC6 ${this.lastSync.lines} \u6761\uFF0C\u4EBA\u683C ${this.lastSync.persona} \u5B57` : "\u8FD8\u6CA1\u540C\u6B65\u8FC7";
2596
+ case "hand_read_page": {
2597
+ const pages = Math.max(1, Math.min(8, Math.round(Number(args.pages) || 3)));
2598
+ const seen = /* @__PURE__ */ new Set();
2599
+ const out = [];
2600
+ for (let i = 0; i < pages; i++) {
2601
+ const ui = await this.hands.uiSnapshot();
2602
+ if (!ui.ok) break;
2603
+ for (const item of ui.items) {
2604
+ const t = (item.text || "").trim();
2605
+ if (!t || t.length < 2 || seen.has(t)) continue;
2606
+ seen.add(t);
2607
+ out.push(t);
2608
+ }
2609
+ if (i < pages - 1) {
2610
+ await this.hands.swipe(1550, 1500, 1550, 700, 420);
2611
+ await new Promise((r) => setTimeout(r, 550));
2612
+ }
2613
+ }
2614
+ if (out.length === 0) return failed("\u8FD9\u4E00\u9875\u6CA1\u8BFB\u5230\u80FD\u5FF5\u7684\u5B57");
2615
+ const text = out.join("\uFF5C");
2616
+ return `\u8FD9\u4E00\u9875\u8BFB\u4E86 ${out.length} \u6BB5
2617
+ ${text.slice(0, 2200)}`;
2618
+ }
2619
+ case "hand_read_text": {
2620
+ const needle = typeof args.text === "string" ? args.text.trim() : "";
2621
+ if (!needle) return failed("\u8981\u8BFB\u54EA\u4E00\u6BB5\uFF1F\u7ED9 text");
2622
+ const hits2 = await this.hands.findText(needle);
2623
+ if (hits2.length === 0) return failed(`\u5C4F\u5E55\u4E0A\u6CA1\u627E\u5230\u300C${needle}\u300D`);
2624
+ const nth = args.nth === void 0 ? 0 : Math.max(0, Math.round(Number(args.nth)));
2625
+ const hit = hits2[nth];
2626
+ if (!hit) return failed(`\u300C${needle}\u300D\u53EA\u6709 ${hits2.length} \u5904`);
2627
+ const b = hit.rect;
2628
+ const h = b ? b[3] - b[1] : 0;
2629
+ if (h > 0 && h < 40) {
2630
+ const pad = 12;
2631
+ const f = await this.hands.zoom(
2632
+ Math.max(0, b[0] - pad),
2633
+ Math.max(0, b[1] - pad),
2634
+ Math.max(16, b[2] - b[0] + pad * 2),
2635
+ Math.max(16, b[3] - b[1] + pad * 2)
2636
+ );
2637
+ if (f) {
2638
+ return {
2639
+ text: `\u300C${hit.text}\u300D\u5B57\u592A\u5C0F\uFF08\u9AD8 ${h}px\uFF09\uFF0C\u6211\u628A\u8FD9\u5757\u653E\u5927\u4E86`,
2640
+ blobs: [{ bytes: f.bytes, mime: "image/jpeg", name: "zoom.jpg", fallbackText: "\uFF08\u8FD9\u4E00\u5757\u7684\u653E\u5927\u56FE\uFF09" }]
2641
+ };
2642
+ }
2643
+ }
2644
+ return `\u300C${hit.text}\u300D@(${hit.center.x},${hit.center.y})`;
2645
+ }
2562
2646
  case "hand_zoom": {
2563
2647
  const n = (v) => Math.round(Number(v));
2564
2648
  const x = n(args.x), y = n(args.y), w = n(args.w), h = n(args.h);
@@ -2729,7 +2813,7 @@ ${lines.join("\n")}
2729
2813
  async verifyChange(beforePkg) {
2730
2814
  try {
2731
2815
  await new Promise((r) => setTimeout(r, 450));
2732
- const ui = await this.hands.ui();
2816
+ const ui = await this.hands.uiSnapshot();
2733
2817
  const now = ui.ok ? ui.pkg : "";
2734
2818
  if (beforePkg && now && beforePkg !== now) return `\uFF0C\u754C\u9762\u5DF2\u7ECF\u5207\u5230 ${now}`;
2735
2819
  return "\uFF08\u5C4F\u5E55\u770B\u8D77\u6765\u6CA1\u53D8\uFF1B\u5982\u679C\u8BE5\u6709\u53CD\u5E94\uFF0C\u5148 hand_see \u770B\u4E00\u773C\u518D\u70B9\uFF09";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cortico-world-hands",
3
- "version": "0.20.4",
3
+ "version": "0.20.5",
4
4
  "type": "module",
5
5
  "description": "Cortico World: hands for the desktop pet — looks at the phone screen, then taps, swipes, pinches, drags, types and presses keys through whatever actuator the device actually has",
6
6
  "license": "MIT",