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.
- package/dist/index.js +134 -0
- 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.
|
|
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
|
+
}
|