cortico-world-hands 0.7.0 → 0.8.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.
- package/dist/index.js +146 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -496,7 +496,7 @@ var Honcho = class {
|
|
|
496
496
|
// src/hands.ts
|
|
497
497
|
import { execFile } from "node:child_process";
|
|
498
498
|
import { readFileSync } from "node:fs";
|
|
499
|
-
import { get as httpGet } from "node:http";
|
|
499
|
+
import { get as httpGet, request as httpRequest } from "node:http";
|
|
500
500
|
var ACTION_TIMEOUT_MS = 6e3;
|
|
501
501
|
var PROBE_TTL_MS = 2e4;
|
|
502
502
|
var COORD_LIMIT = 2e4;
|
|
@@ -524,6 +524,38 @@ function get(port, path, timeoutMs) {
|
|
|
524
524
|
req.on("error", (err) => reject(err));
|
|
525
525
|
});
|
|
526
526
|
}
|
|
527
|
+
async function post(port, path, body, timeoutMs) {
|
|
528
|
+
return new Promise((resolve, reject) => {
|
|
529
|
+
const data = Buffer.from(body, "utf8");
|
|
530
|
+
const req = httpRequest(
|
|
531
|
+
{
|
|
532
|
+
host: "127.0.0.1",
|
|
533
|
+
port,
|
|
534
|
+
path,
|
|
535
|
+
method: "POST",
|
|
536
|
+
timeout: timeoutMs,
|
|
537
|
+
headers: { "content-type": "application/json", "content-length": data.length }
|
|
538
|
+
},
|
|
539
|
+
(res) => {
|
|
540
|
+
const chunks = [];
|
|
541
|
+
res.on("data", (chunk) => chunks.push(chunk));
|
|
542
|
+
res.on("end", () => {
|
|
543
|
+
resolve({
|
|
544
|
+
status: res.statusCode ?? 0,
|
|
545
|
+
body: Buffer.concat(chunks),
|
|
546
|
+
header: (name) => {
|
|
547
|
+
const value = res.headers[name.toLowerCase()];
|
|
548
|
+
return Array.isArray(value) ? value[0] ?? "" : value ?? "";
|
|
549
|
+
}
|
|
550
|
+
});
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
);
|
|
554
|
+
req.on("timeout", () => req.destroy(new Error(`\u7B49\u592A\u4E45\uFF08${timeoutMs}ms\uFF09`)));
|
|
555
|
+
req.on("error", (err) => reject(err));
|
|
556
|
+
req.end(data);
|
|
557
|
+
});
|
|
558
|
+
}
|
|
527
559
|
async function getJson(port, path, timeoutMs = 6e3) {
|
|
528
560
|
try {
|
|
529
561
|
const res = await get(port, path, timeoutMs);
|
|
@@ -1031,6 +1063,31 @@ var Hands = class {
|
|
|
1031
1063
|
}
|
|
1032
1064
|
return { ok: res.status === 200 && body.ok !== false, detail: flat(body.detail || body.error || "", 80) };
|
|
1033
1065
|
}
|
|
1066
|
+
/** 画板:新开一张。 */
|
|
1067
|
+
async canvasNew(w = 512, h = 512, bg = "transparent") {
|
|
1068
|
+
const cfg = this.cfg();
|
|
1069
|
+
const credential = this.readToken();
|
|
1070
|
+
const t = credential ? `&t=${encodeURIComponent(credential)}` : "";
|
|
1071
|
+
const res = await get(this.port(cfg.handPort), `/canvas/new?w=${w}&h=${h}&bg=${encodeURIComponent(bg)}${t}`, ACTION_TIMEOUT_MS);
|
|
1072
|
+
return res.body.toString("utf8");
|
|
1073
|
+
}
|
|
1074
|
+
/** 画板:画一笔。 */
|
|
1075
|
+
async canvasStroke(points, color = "#111111", width = 4) {
|
|
1076
|
+
const cfg = this.cfg();
|
|
1077
|
+
const credential = this.readToken();
|
|
1078
|
+
const t = credential ? `t=${encodeURIComponent(credential)}` : "";
|
|
1079
|
+
const body = JSON.stringify({ points, color, width });
|
|
1080
|
+
const res = await post(this.port(cfg.handPort), `/canvas/stroke?${t}`, body, ACTION_TIMEOUT_MS);
|
|
1081
|
+
return res.body.toString("utf8");
|
|
1082
|
+
}
|
|
1083
|
+
/** 画板:撤销 / 清空 / 保存 / 列表。 */
|
|
1084
|
+
async canvasOp(op) {
|
|
1085
|
+
const cfg = this.cfg();
|
|
1086
|
+
const credential = this.readToken();
|
|
1087
|
+
const t = credential ? `t=${encodeURIComponent(credential)}` : "";
|
|
1088
|
+
const res = op === "list" || op === "state" ? await get(this.port(cfg.handPort), `/canvas/${op}?${t}`, ACTION_TIMEOUT_MS) : await post(this.port(cfg.handPort), `/canvas/${op}?${t}`, "", ACTION_TIMEOUT_MS);
|
|
1089
|
+
return res.body.toString("utf8");
|
|
1090
|
+
}
|
|
1034
1091
|
/** 日记:写一篇。 */
|
|
1035
1092
|
async diaryWrite(title, text, date) {
|
|
1036
1093
|
const cfg = this.cfg();
|
|
@@ -1385,6 +1442,57 @@ var HANDS_TOOL_DECLS = [
|
|
|
1385
1442
|
description: "\u770B\u624B\u81EA\u5DF1\u7684\u72B6\u6001\uFF1A\u8D70\u54EA\u6761\u901A\u9053\u3001\u901A\u4E0D\u901A\u3001\u8FD9\u4E00\u5206\u949F\u52A8\u4E86\u51E0\u4E2A\u52A8\u4F5C\u3001\u521A\u624D\u90A3\u4E00\u4E0B\u6210\u4E86\u6CA1\u6709\u3002\u5BF9\u65B9\u95EE\u300C\u624B\u80FD\u7528\u5417\u300D\u300C\u4F60\u521A\u624D\u70B9\u4E86\u4EC0\u4E48\u300D\u65F6\u7528\u5B83\u3002",
|
|
1386
1443
|
parameters: { type: "object", properties: {}, required: [] }
|
|
1387
1444
|
},
|
|
1445
|
+
{
|
|
1446
|
+
name: "canvas_new",
|
|
1447
|
+
tags: ["act"],
|
|
1448
|
+
description: "\u65B0\u5F00\u4E00\u5F20\u753B\u5E03\uFF08\u9ED8\u8BA4 512\xD7512\uFF0C\u80CC\u666F\u900F\u660E\u6216\u767D\u8272\uFF09\uFF0C\u4F1A\u628A\u5F53\u524D\u8FD9\u5F20\u6E05\u6389\u3002",
|
|
1449
|
+
parameters: {
|
|
1450
|
+
type: "object",
|
|
1451
|
+
properties: {
|
|
1452
|
+
w: { type: "integer", description: "\u5BBD\uFF0C\u9ED8\u8BA4 512" },
|
|
1453
|
+
h: { type: "integer", description: "\u9AD8\uFF0C\u9ED8\u8BA4 512" },
|
|
1454
|
+
bg: { type: "string", description: "transparent \u6216 white" }
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
},
|
|
1458
|
+
{
|
|
1459
|
+
name: "canvas_stroke",
|
|
1460
|
+
tags: ["act"],
|
|
1461
|
+
description: "\u5728\u753B\u5E03\u4E0A\u753B\u4E00\u7B14\uFF1A\u7ED9\u4E00\u4E32\u5750\u6807\u70B9\u3001\u989C\u8272\u3001\u7C97\u7EC6\u3002\u60F3\u753B\u66F2\u7EBF\u5C31\u591A\u7ED9\u70B9\uFF0C\u6BCF\u7B14\u6700\u591A\u51E0\u5341\u4E2A\u70B9\uFF1B\u753B\u6B6A\u4E86\u5C31 canvas_undo\u3002",
|
|
1462
|
+
parameters: {
|
|
1463
|
+
type: "object",
|
|
1464
|
+
properties: {
|
|
1465
|
+
points: { type: "array", description: "\u5750\u6807 [[x,y],[x,y],\u2026]\uFF0C\u539F\u70B9\u662F\u753B\u5E03\u5DE6\u4E0A\u89D2" },
|
|
1466
|
+
color: { type: "string", description: "\u989C\u8272\uFF0C#RRGGBB" },
|
|
1467
|
+
width: { type: "integer", description: "\u7B14\u753B\u7C97\u7EC6\uFF0C\u9ED8\u8BA4 4" }
|
|
1468
|
+
},
|
|
1469
|
+
required: ["points"]
|
|
1470
|
+
}
|
|
1471
|
+
},
|
|
1472
|
+
{
|
|
1473
|
+
name: "canvas_undo",
|
|
1474
|
+
tags: ["act"],
|
|
1475
|
+
description: "\u64A4\u9500\u521A\u624D\u90A3\u4E00\u7B14\uFF08\u53EF\u4EE5\u8FDE\u7740\u64A4\u9500\uFF09\u3002",
|
|
1476
|
+
parameters: { type: "object", properties: {} }
|
|
1477
|
+
},
|
|
1478
|
+
{
|
|
1479
|
+
name: "canvas_clear",
|
|
1480
|
+
tags: ["act"],
|
|
1481
|
+
description: "\u6E05\u7A7A\u6574\u5F20\u753B\u5E03\uFF08\u53EA\u6E05\u7B14\u753B\uFF0C\u4E0D\u5220\u6587\u4EF6\uFF09\u3002",
|
|
1482
|
+
parameters: { type: "object", properties: {} }
|
|
1483
|
+
},
|
|
1484
|
+
{
|
|
1485
|
+
name: "canvas_save",
|
|
1486
|
+
tags: ["act"],
|
|
1487
|
+
description: "\u628A\u753B\u5E03\u5B58\u6210 PNG\uFF0C\u843D\u5230 blobs/drawings/\u65E5\u671F-\u65F6\u95F4.png\uFF0C\u8FD4\u56DE\u8DEF\u5F84\u3002\u53EA\u65B0\u589E\u6587\u4EF6\uFF0C\u4E0D\u8986\u76D6\u65E7\u56FE\u3002",
|
|
1488
|
+
parameters: { type: "object", properties: {} }
|
|
1489
|
+
},
|
|
1490
|
+
{
|
|
1491
|
+
name: "canvas_list",
|
|
1492
|
+
tags: ["read"],
|
|
1493
|
+
description: "\u770B\u770B\u81EA\u5DF1\u753B\u8FC7\u54EA\u4E9B\u56FE\uFF08\u6587\u4EF6\u540D\u548C\u5730\u5740\uFF09\u3002",
|
|
1494
|
+
parameters: { type: "object", properties: {} }
|
|
1495
|
+
},
|
|
1388
1496
|
{
|
|
1389
1497
|
name: "skin_install",
|
|
1390
1498
|
tags: ["act"],
|
|
@@ -1793,6 +1901,18 @@ ${lines.join("\n")}
|
|
|
1793
1901
|
return await this.diaryRead(args);
|
|
1794
1902
|
case "skin_install":
|
|
1795
1903
|
return await this.skinInstall(args);
|
|
1904
|
+
case "canvas_new":
|
|
1905
|
+
return await this.canvasNew(args);
|
|
1906
|
+
case "canvas_stroke":
|
|
1907
|
+
return await this.canvasStroke(args);
|
|
1908
|
+
case "canvas_undo":
|
|
1909
|
+
return await this.canvasSimple("undo");
|
|
1910
|
+
case "canvas_clear":
|
|
1911
|
+
return await this.canvasSimple("clear");
|
|
1912
|
+
case "canvas_save":
|
|
1913
|
+
return await this.canvasSimple("save");
|
|
1914
|
+
case "canvas_list":
|
|
1915
|
+
return await this.canvasSimple("list");
|
|
1796
1916
|
case "memory_audit":
|
|
1797
1917
|
return await this.memoryAudit(args);
|
|
1798
1918
|
case "memory_search":
|
|
@@ -1905,6 +2025,31 @@ ${lines.join("\n")}
|
|
|
1905
2025
|
}
|
|
1906
2026
|
return `\u8BB0\u7262\u4E86\uFF1A\u300C${key}\u300D\u2192 ${value}${cloud}`;
|
|
1907
2027
|
}
|
|
2028
|
+
async canvasNew(args) {
|
|
2029
|
+
const w = args.w === void 0 ? 512 : Math.max(64, Math.min(2048, Math.round(Number(args.w))));
|
|
2030
|
+
const h = args.h === void 0 ? 512 : Math.max(64, Math.min(2048, Math.round(Number(args.h))));
|
|
2031
|
+
const bg = typeof args.bg === "string" && args.bg ? args.bg : "transparent";
|
|
2032
|
+
return await this.hands.canvasNew(w, h, bg);
|
|
2033
|
+
}
|
|
2034
|
+
async canvasStroke(args) {
|
|
2035
|
+
const raw = args.points;
|
|
2036
|
+
if (!Array.isArray(raw) || raw.length === 0) return failed("\u8981 points\uFF0C\u50CF [[10,10],[20,30]]\u3002");
|
|
2037
|
+
const points = [];
|
|
2038
|
+
for (const p of raw.slice(0, 200)) {
|
|
2039
|
+
if (Array.isArray(p) && p.length >= 2) {
|
|
2040
|
+
const x = Number(p[0]);
|
|
2041
|
+
const y = Number(p[1]);
|
|
2042
|
+
if (Number.isFinite(x) && Number.isFinite(y)) points.push([x, y]);
|
|
2043
|
+
}
|
|
2044
|
+
}
|
|
2045
|
+
if (points.length === 0) return failed("points \u91CC\u6CA1\u6709\u5408\u6CD5\u5750\u6807\u3002");
|
|
2046
|
+
const color = typeof args.color === "string" && /^#[0-9a-fA-F]{6}$/.test(args.color) ? args.color : "#111111";
|
|
2047
|
+
const width = args.width === void 0 ? 4 : Math.max(1, Math.min(40, Math.round(Number(args.width))));
|
|
2048
|
+
return await this.hands.canvasStroke(points, color, width);
|
|
2049
|
+
}
|
|
2050
|
+
async canvasSimple(op) {
|
|
2051
|
+
return await this.hands.canvasOp(op);
|
|
2052
|
+
}
|
|
1908
2053
|
/** 装一件外部服装包:从本地 HTTP 拿包,写进桌宠 web 目录。 */
|
|
1909
2054
|
async skinInstall(args) {
|
|
1910
2055
|
const url = typeof args.url === "string" && args.url.trim() ? args.url.trim() : this.opts.cfg.skinPackUrl || "";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cortico-world-hands",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
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",
|