@honor-claw/yoyo 2026.6.9-beta.9 → 2026.7.1-alpha.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 (30) hide show
  1. package/dist/capabilities/node/invoke.mjs +27 -22
  2. package/dist/cli/index.mjs +2 -2
  3. package/dist/cli/login/impl.mjs +1 -1
  4. package/dist/cli/logout/impl.mjs +17 -7
  5. package/dist/cloud-channel/dispatcher/impl.mjs +13 -19
  6. package/dist/core/hooks/tool-trace.mjs +24 -18
  7. package/dist/core/prompt/cloud-tool.mjs +1 -1
  8. package/dist/honor-auth/browser/result-page.mjs +125 -75
  9. package/dist/honor-auth/logout.mjs +6 -6
  10. package/dist/index.mjs +1 -1
  11. package/dist/messaging/dispatchers/stream/error.mjs +13 -0
  12. package/dist/messaging/inbound/context.mjs +4 -1
  13. package/dist/messaging/trace/index.mjs +1 -0
  14. package/dist/messaging/trace/lifecycle.mjs +17 -12
  15. package/dist/messaging/trace/storage.mjs +26 -24
  16. package/dist/messaging/trace/tool-context.mjs +30 -0
  17. package/dist/modules/configs/channel.mjs +12 -3
  18. package/dist/modules/configs/plugin-init.mjs +35 -43
  19. package/dist/utils/object.mjs +8 -0
  20. package/dist/utils/version.mjs +21 -16
  21. package/package.json +1 -1
  22. package/skills/yoyo-phone-control/SKILL.md +3 -76
  23. package/skills/yoyo-phone-control/references/gui-task-create.md +22 -15
  24. package/skills/yoyo-phone-control/references/{local_user_data_qa.md → local-user-data-qa.md} +18 -34
  25. package/skills/yoyo-phone-control/references/{local_user_file_search.md → local-user-file-search.md} +10 -10
  26. package/skills/yoyo-phone-control/references/{task_result_query.md → task-result-query.md} +2 -2
  27. package/skills/yoyo-smart-home/mcptools/device_control.json +1 -1
  28. package/skills/yoyo-smart-home/mcptools/device_query.json +1 -1
  29. package/skills/yoyo-update/SKILL.md +13 -4
  30. package/dist/utils/array.mjs +0 -6
@@ -2,10 +2,12 @@ import { clawLogger as e } from "../../utils/claw-logger.mjs";
2
2
  import { buildEndpoint as t } from "../../cloud-channel/protocol/target.mjs";
3
3
  import { resolveEnabledYoyoAccountId as n } from "../../modules/configs/channel.mjs";
4
4
  import { ClawClient as r } from "../../connection/registry.mjs";
5
+ import { getToolCallContext as i } from "../../messaging/trace/tool-context.mjs";
6
+ import "../../messaging/trace/index.mjs";
5
7
  //#region src/capabilities/node/invoke.ts
6
- var i = e("capabilities");
7
- async function a(e) {
8
- let i = {
8
+ var a = e("capabilities");
9
+ async function o(e) {
10
+ let a = i(e.toolCallId) ?? void 0, o = {
9
11
  to: t("node", e.nodeId),
10
12
  msgType: "nodeInvokeRequest",
11
13
  data: { node: {
@@ -13,28 +15,31 @@ async function a(e) {
13
15
  nodeId: e.nodeId,
14
16
  name: e.name,
15
17
  ...e.params ? { params: { arguments: JSON.stringify(e.params) } } : {}
16
- } }
17
- }, a = n();
18
- return r.forAccount(a).request(i, {
18
+ } },
19
+ ...a ? { traceInfo: a } : {}
20
+ }, c = n();
21
+ return r.forAccount(c).request(o, {
19
22
  timeoutMs: e.timeoutMs,
20
- matchResult: o
23
+ matchResult: s(e.toolCallId)
21
24
  });
22
25
  }
23
- function o(e) {
24
- if (e.payload.msgType !== "nodeInvokeResult") return { matched: !1 };
25
- let t = e.data?.node;
26
- return !t || typeof t.runStatus != "number" || !t.nodeId || !t.toolCallId ? (i.warn("nodeInvokeResult missing required fields", { node: t }), {
27
- matched: !0,
28
- error: "missing required fields in invoke result"
29
- }) : {
30
- matched: !0,
31
- result: {
32
- nodeId: t.nodeId,
33
- toolCallId: t.toolCallId,
34
- runStatus: t.runStatus,
35
- result: t.result
36
- }
26
+ function s(e) {
27
+ return (t) => {
28
+ if (t.payload.msgType !== "nodeInvokeResult") return { matched: !1 };
29
+ let n = t.data?.node;
30
+ return !n || n.toolCallId !== e ? { matched: !1 } : typeof n.runStatus != "number" || !n.nodeId ? (a.warn("nodeInvokeResult missing required fields", { node: n }), {
31
+ matched: !0,
32
+ error: "missing required fields in invoke result"
33
+ }) : {
34
+ matched: !0,
35
+ result: {
36
+ nodeId: n.nodeId,
37
+ toolCallId: e,
38
+ runStatus: n.runStatus,
39
+ result: n.result
40
+ }
41
+ };
37
42
  };
38
43
  }
39
44
  //#endregion
40
- export { a as invokeNodeTool };
45
+ export { o as invokeNodeTool };
@@ -10,8 +10,8 @@ import "./logout/index.mjs";
10
10
  //#region src/cli/index.ts
11
11
  function a(a) {
12
12
  a.registerCli((o) => {
13
- let s = o.program.command("honor").description("Commands for honor yoyoclaw");
14
- r(a, s), i(a, s), t(a, s), e() && n(a, s);
13
+ let s = o.program.command("honor").description("Commands for Honor yoyoclaw");
14
+ r(a, s), i(a, s), e() && (n(a, s), t(a, s));
15
15
  }, { commands: ["honor"] });
16
16
  }
17
17
  //#endregion
@@ -8,7 +8,7 @@ import "../../honor-auth/index.mjs";
8
8
  //#region src/cli/login/impl.ts
9
9
  var l = t("login-cli");
10
10
  function u(t, u) {
11
- u.command("login").description("login to yoyoclaw and register devices").option("-u, --uid <userId>", "login with a specific user ID").option("--token <token>", "login with a specific token").action(async (u) => e(t.runtime, async () => {
11
+ u.command("login").description("login to Honor and register devices").option("-u, --uid <userId>", "login with a specific user ID").option("--token <token>", "login with a specific token").action(async (u) => e(t.runtime, async () => {
12
12
  let { token: e } = u;
13
13
  l.debug("login CLI command called");
14
14
  let t = a(), d = await c({ token: e });
@@ -1,14 +1,24 @@
1
1
  import { withCommandRuntime as e } from "../../core/runtime.mjs";
2
2
  import { toErrorMessage as t } from "../../utils/error.mjs";
3
3
  import { clawLogger as n } from "../../utils/claw-logger.mjs";
4
- import { performLogout as r } from "../../honor-auth/logout.mjs";
4
+ import { loadConfig as r, saveConfig as i } from "../../modules/configs/config-store.mjs";
5
+ import { removeYoyoChannelAccount as a, resolveEnabledYoyoAccountId as o } from "../../modules/configs/channel.mjs";
6
+ import "../../modules/configs/index.mjs";
7
+ import { performLogout as s } from "../../honor-auth/logout.mjs";
5
8
  //#region src/cli/logout/impl.ts
6
- var i = n("logout-cli");
7
- function a(n, a) {
8
- a.command("logout").description("Logout and clear user configuration").action(async () => e(n.runtime, async () => {
9
- i.info("logout CLI command called");
9
+ var c = n("logout-cli");
10
+ function l(n, l) {
11
+ l.command("logout").description("Logout and clear user configuration").action(async () => e(n.runtime, async () => {
12
+ c.info("logout CLI command called");
13
+ let e = o();
10
14
  try {
11
- await r(), console.log("✅ Logout successful, gateway will automatically restart to handle new configuration");
15
+ await s(e);
16
+ try {
17
+ await i(a(r(), e));
18
+ } catch (t) {
19
+ c.error("failed to remove channel account after logout", t, { userId: e });
20
+ }
21
+ console.log("✅ Logout successful, gateway will automatically stop the account connection");
12
22
  } catch (e) {
13
23
  let n = t(e);
14
24
  console.error("🚫 Logout failed:", n);
@@ -16,4 +26,4 @@ function a(n, a) {
16
26
  }));
17
27
  }
18
28
  //#endregion
19
- export { a as registerLogoutCommand };
29
+ export { l as registerLogoutCommand };
@@ -21,13 +21,10 @@ function s(e) {
21
21
  send: u,
22
22
  async request(e, t) {
23
23
  let { matchResult: r, timeoutMs: i } = t, s = n();
24
- if (!await u({
25
- ...e,
26
- traceInfo: { traceId: s }
27
- })) throw Error("send failed");
24
+ if (!await u(e)) throw Error("send failed");
28
25
  return new Promise((e, t) => {
29
26
  let n = setTimeout(() => {
30
- l.has(s) && (l.delete(s), o.warn("request timeout", { traceId: s }), t(/* @__PURE__ */ Error("request timeout")));
27
+ l.has(s) && (l.delete(s), o.warn("request timeout", { requestId: s }), t(/* @__PURE__ */ Error("request timeout")));
31
28
  }, a(i));
32
29
  l.set(s, {
33
30
  timeout: n,
@@ -38,25 +35,22 @@ function s(e) {
38
35
  });
39
36
  },
40
37
  consume(e) {
41
- let t = e.payload.traceInfo?.traceId;
42
- if (!t) return;
43
- let n = l.get(t);
44
- if (n) {
38
+ for (let [t, n] of l) {
39
+ let r;
45
40
  try {
46
- let r = n.matchResult(e);
47
- if (r.matched) {
48
- if (l.delete(t), clearTimeout(n.timeout), "error" in r) {
49
- n.reject(r.error);
50
- return;
51
- }
52
- n.resolve(r.result);
53
- return;
54
- }
41
+ r = n.matchResult(e);
55
42
  } catch (e) {
56
43
  o.error("match request result failed", e);
44
+ continue;
45
+ }
46
+ if (r?.matched) {
47
+ if (l.delete(t), clearTimeout(n.timeout), "error" in r) {
48
+ n.reject(r.error);
49
+ return;
50
+ }
51
+ n.resolve(r.result);
57
52
  return;
58
53
  }
59
- o.warn("response shape not matched, keep pending", { traceId: t });
60
54
  }
61
55
  },
62
56
  destroy() {
@@ -1,26 +1,32 @@
1
- import { recordToolCallEnd as e, recordToolCallStart as t } from "../../messaging/dispatchers/stream/hooks.mjs";
1
+ import { bindToolCallContext as e, releaseToolCallContext as t } from "../../messaging/trace/tool-context.mjs";
2
+ import { resolveTurnSessionBySessionKey as n } from "../../messaging/trace/lifecycle.mjs";
3
+ import "../../messaging/trace/index.mjs";
4
+ import { recordToolCallEnd as r, recordToolCallStart as i } from "../../messaging/dispatchers/stream/hooks.mjs";
2
5
  //#region src/core/hooks/tool-trace.ts
3
- function n(n) {
4
- n.on("before_tool_call", (e, n) => {
5
- t({
6
+ function a(a) {
7
+ a.on("before_tool_call", (t, r) => {
8
+ let a = t.toolCallId ?? r.toolCallId;
9
+ i({
10
+ sessionKey: r.sessionKey,
11
+ toolName: t.toolName,
12
+ params: t.params,
13
+ toolCallId: a,
14
+ runId: t.runId ?? r.runId
15
+ });
16
+ let o = n(r.sessionKey);
17
+ a && o && e(a, o);
18
+ }), a.on("after_tool_call", (e, n) => {
19
+ r({
6
20
  sessionKey: n.sessionKey,
7
21
  toolName: e.toolName,
8
22
  params: e.params,
9
23
  toolCallId: e.toolCallId ?? n.toolCallId,
10
- runId: e.runId ?? n.runId
11
- });
12
- }), n.on("after_tool_call", (t, n) => {
13
- e({
14
- sessionKey: n.sessionKey,
15
- toolName: t.toolName,
16
- params: t.params,
17
- toolCallId: t.toolCallId ?? n.toolCallId,
18
- runId: t.runId ?? n.runId,
19
- result: t.result,
20
- error: typeof t.error == "string" ? t.error : void 0,
21
- durationMs: typeof t.durationMs == "number" ? t.durationMs : void 0
22
- });
24
+ runId: e.runId ?? n.runId,
25
+ result: e.result,
26
+ error: typeof e.error == "string" ? e.error : void 0,
27
+ durationMs: typeof e.durationMs == "number" ? e.durationMs : void 0
28
+ }), t(e.toolCallId ?? n.toolCallId);
23
29
  });
24
30
  }
25
31
  //#endregion
26
- export { n as registerToolTraceHooks };
32
+ export { a as registerToolTraceHooks };
@@ -1,5 +1,5 @@
1
1
  //#region src/core/prompt/cloud-tool.ts
2
- var e = "## Skill 使用云工具调用规则\n\n当已读取的 SKILL.md frontmatter 包含 allowed-tools 声明时:\n\n1. 根据用户意图从 allowed-tools 选择工具。\n2. 调用前必须读取当前 skill 目录下对应的 mcptools/<name>.json。\n3. JSON id 获取 toolId,按 inputSchema 提取 params。\n4. 调用 cloud_invoke,传入 { toolId, params }。\n\n不得猜测 toolId,不得使用未在 allowed-tools 中声明的工具。\n明确属于 yoyo-phone-control 等设备控制 Skill(走 node_invoke 通道)的工具,不得通过 cloud_invoke 调用。";
2
+ var e = "## Skill 使用云工具调用规则\n\n当已读取的 SKILL.md frontmatter 包含 allowed-tools 声明时:\n\n1. 根据用户意图和 SKILL.md 正文,从 allowed-tools 中选定工具名。\n2. 工具名对应当前 Skill 目录下的 mcptools/<工具名>.json;选定后直接使用 read 读取该文件,无需先查看 mcptools 目录。\n3. 使用 JSON 顶层 id 作为 cloud_invoke.toolId,并按 inputSchema 提取 params。allowed-tools 中的名称、<tool> 信息中的 toolName 和 JSON 的 name 仅用于定位工具,不作为 toolId。\n4. 若工具定义说明不可实际调用,则按其说明处理;否则调用 cloud_invoke,传入 { toolId: JSON.id, params }。\n\n例如,选中 demo_tool 后直接读取 mcptools/demo_tool.json;若其中 id 为 service-123,则 cloud_invoke.toolId 使用 service-123。\n\n明确属于 yoyo-phone-control 等设备控制 Skill(走 node_invoke 通道)的工具,不得通过 cloud_invoke 调用。";
3
3
  function t() {
4
4
  return { prependSystemContext: e };
5
5
  }
@@ -1,6 +1,6 @@
1
1
  import "./assets/favicon.mjs";
2
2
  //#region src/honor-auth/browser/result-page.ts
3
- var e = "<svg aria-hidden=\"true\" viewBox=\"0 0 64 64\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"32\" cy=\"32\" r=\"30\" fill=\"currentColor\" opacity=\"0.12\"/><circle cx=\"32\" cy=\"32\" r=\"21\" fill=\"currentColor\"/><path d=\"M22.5 32.5L29 39L42.5 25.5\" stroke=\"white\" stroke-width=\"4.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>", t = "<svg aria-hidden=\"true\" viewBox=\"0 0 64 64\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"32\" cy=\"32\" r=\"30\" fill=\"currentColor\" opacity=\"0.12\"/><circle cx=\"32\" cy=\"32\" r=\"21\" fill=\"currentColor\"/><path d=\"M24.5 24.5L39.5 39.5M39.5 24.5L24.5 39.5\" stroke=\"white\" stroke-width=\"4.5\" stroke-linecap=\"round\"/></svg>", n = { favicon: "/favicon.png" };
3
+ var e = "<svg aria-hidden=\"true\" viewBox=\"0 0 48 48\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"24\" cy=\"24\" r=\"22\" fill=\"currentColor\"/><path d=\"M15.5 24.5L21.5 30.5L33 18.5\" stroke=\"white\" stroke-width=\"4\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/></svg>", t = "<svg aria-hidden=\"true\" viewBox=\"0 0 48 48\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><circle cx=\"24\" cy=\"24\" r=\"22\" fill=\"currentColor\"/><path d=\"M18 18L30 30M30 18L18 30\" stroke=\"white\" stroke-width=\"4\" stroke-linecap=\"round\"/></svg>", n = { favicon: "/favicon.png" };
4
4
  function r(e) {
5
5
  return e.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("\"", "&quot;").replaceAll("'", "&#39;");
6
6
  }
@@ -8,145 +8,158 @@ function i(e) {
8
8
  return !e || e.length === 0 ? "" : `<div class="details">${e.map((e) => `<div class="detail-item"><span class="detail-key">${r(e.key)}</span><span class="detail-value">${r(e.value)}</span></div>`).join("")}</div>`;
9
9
  }
10
10
  function a(n) {
11
- let a = n.statusClass === "success" ? e : t;
11
+ let a = n.statusClass === "success" ? e : t, o = "data:image/png;base64,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";
12
12
  return `<!doctype html>
13
13
  <html lang="zh-CN">
14
14
  <head>
15
15
  <meta charset="UTF-8" />
16
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
17
- <link rel="icon" type="image/png" href="data:image/png;base64,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" />
16
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
17
+ <link rel="icon" type="image/png" href="${o}" />
18
18
  <title>${r(n.pageTitle)}</title>
19
19
  <style>
20
20
  :root {
21
21
  color-scheme: light;
22
- --surface: rgba(255, 255, 255, 0.94);
23
- --text: #172033;
24
- --muted: #667085;
25
- --faint: #98a2b3;
26
- --border: rgba(23, 32, 51, 0.1);
27
- --shadow: 0 22px 70px rgba(31, 41, 55, 0.14);
28
- --success: #168255;
29
- --error: #d14343;
30
- --accent: #2563eb;
22
+ --text: #0f1729;
23
+ --muted: #5b6478;
24
+ --faint: #8a93a6;
25
+ --hair: rgba(15, 23, 41, 0.07);
26
+ --hair-strong: rgba(15, 23, 41, 0.11);
27
+ --surface: #ffffff;
28
+ --surface-soft: #f7f8fb;
29
+ --success: #16a34a;
30
+ --success-soft: rgba(22, 163, 74, 0.10);
31
+ --error: #dc2626;
32
+ --error-soft: rgba(220, 38, 38, 0.10);
33
+ --shadow:
34
+ 0 1px 2px rgba(15, 23, 41, 0.04),
35
+ 0 4px 12px rgba(15, 23, 41, 0.06);
36
+ --ease: cubic-bezier(0.16, 1, 0.3, 1);
31
37
  }
32
38
 
33
39
  * {
34
40
  box-sizing: border-box;
35
41
  }
36
42
 
43
+ html,
44
+ body {
45
+ height: 100%;
46
+ }
47
+
37
48
  body {
38
49
  margin: 0;
39
- min-height: 100vh;
40
- display: grid;
41
- place-items: center;
50
+ min-height: 100dvh;
51
+ display: flex;
52
+ align-items: center;
53
+ justify-content: center;
42
54
  padding: 24px;
43
55
  font-family:
44
- "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
56
+ "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
57
+ -apple-system, BlinkMacSystemFont, sans-serif;
45
58
  color: var(--text);
46
- background:
47
- linear-gradient(135deg, rgba(37, 99, 235, 0.09), transparent 34%),
48
- linear-gradient(315deg, rgba(22, 130, 85, 0.12), transparent 38%),
49
- #f6f8fb;
59
+ background-color: #eef1f6;
60
+ background-image:
61
+ radial-gradient(900px 540px at 18% -8%, rgba(37, 99, 235, 0.07), transparent 60%),
62
+ radial-gradient(820px 520px at 92% 108%, rgba(15, 23, 41, 0.05), transparent 58%);
63
+ background-attachment: fixed;
64
+ -webkit-font-smoothing: antialiased;
65
+ text-rendering: optimizeLegibility;
50
66
  }
51
67
 
52
68
  .card {
53
- width: min(100%, 480px);
54
- padding: 24px;
55
- border-radius: 18px;
69
+ width: min(100%, 460px);
70
+ padding: 36px 32px 28px;
71
+ border-radius: 22px;
56
72
  background: var(--surface);
57
- border: 1px solid var(--border);
73
+ border: 1px solid var(--hair);
58
74
  box-shadow: var(--shadow);
59
- backdrop-filter: blur(10px);
60
75
  text-align: center;
76
+ animation: card-in 0.5s var(--ease) both;
61
77
  }
62
78
 
63
79
  .brand {
64
- display: flex;
80
+ display: inline-flex;
65
81
  align-items: center;
66
- justify-content: center;
67
- gap: 9px;
68
- margin-bottom: 24px;
82
+ gap: 8px;
83
+ margin-bottom: 30px;
69
84
  color: var(--text);
70
- font-size: 15px;
71
- font-weight: 700;
85
+ font-size: 14px;
86
+ font-weight: 650;
87
+ letter-spacing: 0.01em;
72
88
  }
73
89
 
74
90
  .brand-logo {
75
- width: 26px;
76
- height: 26px;
91
+ width: 22px;
92
+ height: 22px;
93
+ border-radius: 6px;
77
94
  display: block;
78
- border-radius: 8px;
79
95
  }
80
96
 
81
97
  .icon-wrap {
82
- width: 96px;
83
- height: 96px;
84
- margin: 0 auto 20px;
85
- border-radius: 50%;
98
+ width: 64px;
99
+ height: 64px;
100
+ margin: 0 auto 22px;
86
101
  display: grid;
87
102
  place-items: center;
88
- background: transparent;
89
- }
90
-
91
- .icon-wrap.success {
92
103
  color: var(--success);
93
- filter: drop-shadow(0 16px 28px rgba(22, 130, 85, 0.18));
94
104
  }
95
105
 
96
106
  .icon-wrap.error {
97
107
  color: var(--error);
98
- filter: drop-shadow(0 16px 28px rgba(209, 67, 67, 0.18));
99
108
  }
100
109
 
101
110
  .icon-wrap svg {
102
111
  display: block;
103
- width: 78px;
104
- height: 78px;
112
+ width: 64px;
113
+ height: 64px;
114
+ animation: icon-pop 0.55s var(--ease) both;
105
115
  }
106
116
 
107
117
  h1 {
108
118
  margin: 0;
109
- font-size: 26px;
110
- line-height: 1.2;
119
+ font-size: 24px;
120
+ line-height: 1.25;
121
+ letter-spacing: -0.01em;
111
122
  font-weight: 700;
112
123
  }
113
124
 
114
125
  .details {
115
- margin: 18px 0 0;
116
- padding: 0;
117
- border-radius: 16px;
118
- background: rgba(255, 255, 255, 0.72);
119
- border: 1px solid rgba(29, 36, 51, 0.07);
126
+ margin: 22px 0 0;
127
+ padding: 4px 0;
128
+ border-radius: 14px;
129
+ background: var(--surface-soft);
130
+ border: 1px solid var(--hair);
120
131
  overflow: hidden;
121
132
  text-align: left;
122
133
  }
123
134
 
124
135
  .detail-item {
125
136
  display: grid;
126
- grid-template-columns: 64px minmax(0, 1fr);
127
- gap: 10px;
128
- padding: 12px 14px;
137
+ grid-template-columns: 72px minmax(0, 1fr);
138
+ gap: 12px;
139
+ padding: 12px 16px;
129
140
  font-size: 13px;
130
- line-height: 1.5;
141
+ line-height: 1.55;
131
142
  }
132
143
 
133
144
  .detail-item + .detail-item {
134
- border-top: 1px solid rgba(29, 36, 51, 0.07);
145
+ border-top: 1px solid var(--hair);
135
146
  }
136
147
 
137
148
  .detail-key {
138
- color: #7a808d;
149
+ color: var(--faint);
150
+ font-weight: 500;
139
151
  }
140
152
 
141
153
  .detail-value {
142
154
  color: var(--text);
155
+ font-weight: 600;
143
156
  word-break: break-word;
144
157
  }
145
158
 
146
159
  .footer {
147
- margin-top: 22px;
148
- padding-top: 16px;
149
- border-top: 1px solid rgba(29, 36, 51, 0.08);
160
+ margin-top: 24px;
161
+ padding-top: 18px;
162
+ border-top: 1px solid var(--hair);
150
163
  }
151
164
 
152
165
  .hint {
@@ -157,38 +170,74 @@ function a(n) {
157
170
  }
158
171
 
159
172
  .caption {
160
- margin: 8px 0 0;
173
+ margin: 10px 0 0;
161
174
  color: var(--faint);
162
175
  font-size: 12px;
163
176
  line-height: 1.5;
164
177
  }
165
178
 
179
+ @keyframes card-in {
180
+ from {
181
+ opacity: 0;
182
+ transform: translateY(10px) scale(0.985);
183
+ }
184
+ to {
185
+ opacity: 1;
186
+ transform: none;
187
+ }
188
+ }
189
+
190
+ @keyframes icon-pop {
191
+ 0% {
192
+ opacity: 0;
193
+ transform: scale(0.6);
194
+ }
195
+ 60% {
196
+ opacity: 1;
197
+ transform: scale(1.06);
198
+ }
199
+ 100% {
200
+ transform: scale(1);
201
+ }
202
+ }
203
+
166
204
  @media (max-width: 480px) {
167
205
  body {
168
- padding: 16px;
206
+ padding: 0;
207
+ align-items: stretch;
169
208
  }
170
209
 
171
210
  .card {
172
- padding: 22px 18px 18px;
173
- border-radius: 16px;
211
+ width: 100%;
212
+ min-height: 100dvh;
213
+ padding: calc(env(safe-area-inset-top, 0px) + 32px) 22px
214
+ calc(env(safe-area-inset-bottom, 0px) + 24px);
215
+ border-radius: 0;
216
+ border: none;
217
+ display: flex;
218
+ flex-direction: column;
219
+ justify-content: center;
220
+ box-shadow: none;
174
221
  }
175
222
 
176
223
  .brand {
177
- margin-bottom: 22px;
224
+ margin-bottom: 26px;
178
225
  }
179
226
 
180
227
  h1 {
181
- font-size: 23px;
228
+ font-size: 22px;
182
229
  }
183
230
 
184
- .icon-wrap {
185
- width: 84px;
186
- height: 84px;
231
+ .detail-item {
232
+ grid-template-columns: 64px minmax(0, 1fr);
233
+ padding: 12px 14px;
187
234
  }
235
+ }
188
236
 
237
+ @media (prefers-reduced-motion: reduce) {
238
+ .card,
189
239
  .icon-wrap svg {
190
- width: 70px;
191
- height: 70px;
240
+ animation: none;
192
241
  }
193
242
  }
194
243
  </style>
@@ -196,7 +245,8 @@ function a(n) {
196
245
  <body>
197
246
  <main class="card">
198
247
  <div class="brand">
199
- <span>YOYOClaw</span>
248
+ <img class="brand-logo" src="${o}" alt="" width="22" height="22" />
249
+ <span>YOYO 控虾</span>
200
250
  </div>
201
251
  <div class="icon-wrap ${n.statusClass}">${a}</div>
202
252
  <h1>${r(n.title)}</h1>
@@ -5,12 +5,12 @@ import { loadDeviceInfo as r } from "../modules/device/device-info.mjs";
5
5
  import "./vault/index.mjs";
6
6
  import "../apis/index.mjs";
7
7
  //#region src/honor-auth/logout.ts
8
- async function i() {
9
- let i = e.fromUser(), a = await i.current();
10
- if (!a) throw Error("⚠️ Not logged in");
11
- let o = await r(), s = await n().logoutDevice(o, a);
12
- if (!t(s)) throw Error(s.data?.cnMessage || "Unknown error");
13
- await i.clear();
8
+ async function i(i) {
9
+ let a = e.fromUser(i), o = await a.current();
10
+ if (!o) throw Error("Not logged in, please login first!");
11
+ let s = await r(), c = await n().logoutDevice(s, o);
12
+ if (!t(c)) throw Error(c.data?.cnMessage || "Unknown error");
13
+ await a.clear();
14
14
  }
15
15
  //#endregion
16
16
  export { i as performLogout };
package/dist/index.mjs CHANGED
@@ -10,7 +10,7 @@ import { registerTools as l } from "./tools/index.mjs";
10
10
  //#region src/index.ts
11
11
  var u = {
12
12
  id: e,
13
- name: "YOYOClaw",
13
+ name: "YOYO 控虾",
14
14
  description: "OpenClaw Honor Yoyo connection plugin.",
15
15
  configSchema: c,
16
16
  register(e) {