cortico-world-hands 0.1.1 → 0.1.2

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 +134 -0
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -249,6 +249,10 @@ function inputCommand(command) {
249
249
  return command.ms >= 400 ? `input swipe ${command.x} ${command.y} ${command.x} ${command.y} ${command.ms}` : `input tap ${command.x} ${command.y}`;
250
250
  case "swipe":
251
251
  return `input swipe ${command.x1} ${command.y1} ${command.x2} ${command.y2} ${command.ms}`;
252
+ case "pinch":
253
+ return `input swipe ${command.cx - 220} ${command.cy} ${command.cx + 220} ${command.cy} ${command.ms}`;
254
+ case "drag":
255
+ return `input draganddrop ${command.x1} ${command.y1} ${command.x2} ${command.y2} ${command.ms}`;
252
256
  case "key":
253
257
  return `input keyevent ${command.code}`;
254
258
  // 文本在拼命令这一刻才转义:只有 input 这条路吃不下非 ASCII,无障碍那条能原样收
@@ -384,6 +388,10 @@ var EyesActuator = class {
384
388
  return this.send(`/hand/tap?x=${command.x}&y=${command.y}&ms=${command.ms}`);
385
389
  case "swipe":
386
390
  return this.send(`/hand/swipe?x1=${command.x1}&y1=${command.y1}&x2=${command.x2}&y2=${command.y2}&ms=${command.ms}`);
391
+ case "pinch":
392
+ return this.send(`/hand/pinch?cx=${command.cx}&cy=${command.cy}&scale=${command.scale}&ms=${command.ms}`);
393
+ case "drag":
394
+ return this.send(`/hand/drag?x1=${command.x1}&y1=${command.y1}&x2=${command.x2}&y2=${command.y2}&ms=${command.ms}`);
387
395
  case "key":
388
396
  return this.send(`/hand/key?name=${encodeURIComponent(command.name)}&code=${command.code}`);
389
397
  case "text":
@@ -453,6 +461,10 @@ var describeCommand = (command) => {
453
461
  return `\u70B9 (${command.x},${command.y})`;
454
462
  case "swipe":
455
463
  return `\u4ECE (${command.x1},${command.y1}) \u6ED1\u5230 (${command.x2},${command.y2})`;
464
+ case "pinch":
465
+ return `\u5728 (${command.cx},${command.cy}) ${command.scale >= 1 ? "\u653E\u5927" : "\u7F29\u5C0F"} ${command.scale} \u500D`;
466
+ case "drag":
467
+ return `\u628A (${command.x1},${command.y1}) \u62D6\u5230 (${command.x2},${command.y2})`;
456
468
  case "key":
457
469
  return `\u6309 ${command.name}`;
458
470
  case "text":
@@ -641,6 +653,39 @@ var Hands = class {
641
653
  const ms = milliseconds(opts.ms, 300);
642
654
  return this.perform({ kind: "swipe", x1: a, y1: b, x2: c, y2: d, ms });
643
655
  }
656
+ async pinch(cx, cy, scale, opts = {}) {
657
+ const x = coord(cx);
658
+ const y = coord(cy);
659
+ const ms = milliseconds(opts.ms, 400);
660
+ const factor = Math.max(0.25, Math.min(4, Number(scale) || 1));
661
+ return this.perform({ kind: "pinch", cx: x, cy: y, scale: factor, ms });
662
+ }
663
+ async drag(x1, y1, x2, y2, opts = {}) {
664
+ const a = coord(x1);
665
+ const b = coord(y1);
666
+ const c = coord(x2);
667
+ const d = coord(y2);
668
+ await this.bounds(a, b);
669
+ await this.bounds(c, d);
670
+ const ms = milliseconds(opts.ms, 900);
671
+ return this.perform({ kind: "drag", x1: a, y1: b, x2: c, y2: d, ms });
672
+ }
673
+ /** 一屏屏翻着找文字(只查不点)。 */
674
+ async findItem(text, opts = {}) {
675
+ const cfg = this.cfg();
676
+ const tries = Math.max(0, Math.min(12, Math.round(Number(opts.tries ?? 5))));
677
+ const scroll = opts.scroll === false ? "0" : "1";
678
+ const token = cfg.handToken ? `&t=${encodeURIComponent(cfg.handToken)}` : "";
679
+ const path = `/hand/find?text=${encodeURIComponent(text)}&tries=${tries}&scroll=${scroll}${token}`;
680
+ const res = await get(this.port(cfg.handPort), path, ACTION_TIMEOUT_MS);
681
+ let body = {};
682
+ try {
683
+ body = JSON.parse(res.body.toString("utf8"));
684
+ } catch {
685
+ }
686
+ if (res.status === 200 && body.ok) return { ok: true, x: body.x, y: body.y, detail: flat(body.detail, 80) };
687
+ return { ok: false, detail: flat(body.error || `\u627E\u4E0D\u5230\u300C${text}\u300D`, 120) };
688
+ }
644
689
  async press(key) {
645
690
  const name = String(key ?? "").trim().toLowerCase().replace(/[\s_-]/g, "");
646
691
  const code = keyCode(name);
@@ -791,6 +836,51 @@ var HANDS_TOOL_DECLS = [
791
836
  required: ["x1", "y1", "x2", "y2"]
792
837
  }
793
838
  },
839
+ {
840
+ name: "hand_pinch",
841
+ tags: ["act"],
842
+ description: "\u53CC\u6307\u7F29\u653E\uFF1A\u653E\u5927\u6216\u7F29\u5C0F\u56FE\u7247\u3001\u5730\u56FE\u3001\u7F51\u9875\u3002scale>1 \u653E\u5927\uFF0C<1 \u7F29\u5C0F\uFF1B\u4E0D\u7ED9 cx/cy \u5C31\u4EE5\u5C4F\u5E55\u4E2D\u5FC3\u4E3A\u57FA\u51C6\u3002",
843
+ parameters: {
844
+ type: "object",
845
+ properties: {
846
+ scale: { type: "number", minimum: 0.25, maximum: 4, description: "\u500D\u6570\uFF1A1.5 \u653E\u5927\u4E00\u534A\uFF0C0.6 \u7F29\u5C0F\u3002" },
847
+ cx: { type: "integer", description: "\u4E2D\u5FC3\u6A2A\u5750\u6807\uFF08\u53EF\u7701\u7565\uFF09\u3002" },
848
+ cy: { type: "integer", description: "\u4E2D\u5FC3\u7EB5\u5750\u6807\uFF08\u53EF\u7701\u7565\uFF09\u3002" },
849
+ ms: { type: "integer", minimum: 120, maximum: 2e3, description: "\u624B\u52BF\u65F6\u957F\uFF0C\u9ED8\u8BA4 400 \u6BEB\u79D2\u3002" }
850
+ },
851
+ required: ["scale"]
852
+ }
853
+ },
854
+ {
855
+ name: "hand_drag",
856
+ tags: ["act"],
857
+ description: "\u957F\u6309\u540E\u62D6\u62FD\uFF1A\u62D6\u5217\u8868\u9879\u3001\u62D6\u6ED1\u5757\u3001\u62D6\u56FE\u6807\u3001\u62D6\u8FDB\u5EA6\u3002\u548C swipe \u7684\u533A\u522B\u662F\u5B83\u6309\u4F4F\u4E0D\u653E\u518D\u62D6\uFF0C\u9002\u5408\u6709\u62D6\u62FD\u8BED\u4E49\u7684\u63A7\u4EF6\u3002",
858
+ parameters: {
859
+ type: "object",
860
+ properties: {
861
+ x1: { type: "integer", description: "\u8D77\u70B9\u6A2A\u5750\u6807\u3002" },
862
+ y1: { type: "integer", description: "\u8D77\u70B9\u7EB5\u5750\u6807\u3002" },
863
+ x2: { type: "integer", description: "\u7EC8\u70B9\u6A2A\u5750\u6807\u3002" },
864
+ y2: { type: "integer", description: "\u7EC8\u70B9\u7EB5\u5750\u6807\u3002" },
865
+ ms: { type: "integer", minimum: 300, maximum: 4e3, description: "\u62D6\u591A\u4E45\uFF0C\u9ED8\u8BA4 900 \u6BEB\u79D2\u3002" }
866
+ },
867
+ required: ["x1", "y1", "x2", "y2"]
868
+ }
869
+ },
870
+ {
871
+ name: "hand_find",
872
+ tags: ["read"],
873
+ description: "\u4E00\u5C4F\u5C4F\u5F80\u4E0B\u7FFB\uFF0C\u627E\u5C4F\u5E55\u4E0A\u542B\u6709\u67D0\u6BB5\u6587\u5B57\u7684\u4E1C\u897F\uFF0C\u8FD4\u56DE\u5B83\u7684\u5750\u6807\uFF08\u53EA\u627E\u4E0D\u70B9\uFF09\u3002\u8868\u683C\u3001\u957F\u5217\u8868\u3001\u8BBE\u7F6E\u9879\u91CC\u627E\u4E1C\u897F\u7528\u5B83\uFF0C\u6BD4\u8089\u773C\u4E00\u9875\u9875\u770B\u5FEB\u3002",
874
+ parameters: {
875
+ type: "object",
876
+ properties: {
877
+ text: { type: "string", description: "\u8981\u627E\u7684\u6587\u5B57\uFF08\u5305\u542B\u5339\u914D\uFF0C\u4E0D\u533A\u5206\u5927\u5C0F\u5199\uFF09\u3002" },
878
+ tries: { type: "integer", minimum: 0, maximum: 12, description: "\u6700\u591A\u7FFB\u51E0\u5C4F\uFF0C\u9ED8\u8BA4 5\u3002" },
879
+ scroll: { type: "boolean", description: "\u627E\u4E0D\u5230\u65F6\u662F\u5426\u81EA\u52A8\u6EDA\u52A8\uFF0C\u9ED8\u8BA4 true\u3002" }
880
+ },
881
+ required: ["text"]
882
+ }
883
+ },
794
884
  {
795
885
  name: "hand_type",
796
886
  tags: ["act"],
@@ -899,6 +989,12 @@ var HandsWorld = class {
899
989
  return await this.long(args);
900
990
  case "hand_swipe":
901
991
  return await this.swipe(args);
992
+ case "hand_pinch":
993
+ return await this.pinch(args);
994
+ case "hand_drag":
995
+ return await this.drag(args);
996
+ case "hand_find":
997
+ return await this.findItem(args);
902
998
  case "hand_type":
903
999
  return await this.type(args);
904
1000
  case "hand_key":
@@ -935,6 +1031,44 @@ var HandsWorld = class {
935
1031
  return { text: report.text, ...blobs.length ? { blobs } : {} };
936
1032
  }
937
1033
  /** 给文字就先在屏幕上找,找到唯一一处才点;给坐标就直接点。 */
1034
+ async pinch(args) {
1035
+ const scale = Number(args.scale);
1036
+ if (!Number.isFinite(scale) || scale <= 0) return failed("scale \u8981\u662F\u6B63\u6570\uFF0C\u6BD4\u5982 1.5 \u653E\u5927\u30010.6 \u7F29\u5C0F\u3002");
1037
+ const cx = args.cx === void 0 ? void 0 : Number(args.cx);
1038
+ const cy = args.cy === void 0 ? void 0 : Number(args.cy);
1039
+ const ms = args.ms === void 0 ? void 0 : Number(args.ms);
1040
+ const size = await this.hands.screenSize();
1041
+ const x = cx ?? Math.round((size?.w ?? 1080) / 2);
1042
+ const y = cy ?? Math.round((size?.h ?? 1920) / 2);
1043
+ const receipt = await this.hands.pinch(x, y, scale, ms === void 0 ? {} : { ms });
1044
+ this.note(receipt);
1045
+ return receipt.text;
1046
+ }
1047
+ async drag(args) {
1048
+ const need = ["x1", "y1", "x2", "y2"];
1049
+ if (need.some((k) => args[k] === void 0)) return failed("\u62D6\u62FD\u8981\u7ED9\u9F50 x1\u3001y1\u3001x2\u3001y2\u3002");
1050
+ const receipt = await this.hands.drag(
1051
+ Number(args.x1),
1052
+ Number(args.y1),
1053
+ Number(args.x2),
1054
+ Number(args.y2),
1055
+ args.ms === void 0 ? {} : { ms: Number(args.ms) }
1056
+ );
1057
+ this.note(receipt);
1058
+ return receipt.text;
1059
+ }
1060
+ async findItem(args) {
1061
+ const text = typeof args.text === "string" ? args.text.trim() : "";
1062
+ if (!text) return failed("\u8981\u627E\u4EC0\u4E48\u6587\u5B57\uFF1F\u7ED9 text\u3002");
1063
+ const tries = args.tries === void 0 ? void 0 : Number(args.tries);
1064
+ const scroll = args.scroll === void 0 ? void 0 : Boolean(args.scroll);
1065
+ const found = await this.hands.findItem(text, {
1066
+ ...tries === void 0 ? {} : { tries },
1067
+ ...scroll === void 0 ? {} : { scroll }
1068
+ });
1069
+ if (!found.ok) return failed(found.detail);
1070
+ return `\u627E\u5230\u4E86\u300C${text}\u300D@(${found.x},${found.y})${found.detail ? `\uFF08${found.detail}\uFF09` : ""}\uFF1B\u8981\u52A8\u624B\u5C31 hand_tap \u4F20\u8FD9\u7EC4\u5750\u6807\u3002`;
1071
+ }
938
1072
  async tap(args) {
939
1073
  const text = typeof args.text === "string" ? args.text.trim() : "";
940
1074
  if (text) {
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "cortico-world-hands",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
- "description": "Cortico World: hands for the desktop pet — looks at the phone screen, then taps, swipes, types and presses keys through whatever actuator the device actually has",
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",
7
7
  "keywords": [
8
8
  "cortico-world",
@@ -28,4 +28,4 @@
28
28
  "README.md"
29
29
  ],
30
30
  "scripts": {}
31
- }
31
+ }