@honor-claw/yoyo 2026.9.3-alpha.2 → 2026.9.4-alpha.1

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 (196) hide show
  1. package/dist/capabilities/cron/service.mjs +107 -36
  2. package/dist/capabilities/cron/timezone.mjs +16 -0
  3. package/dist/cloud-channel/handlers/context/cron.mjs +2 -1
  4. package/dist/command/mock/handler.mjs +1 -0
  5. package/dist/core/prompt/builder.mjs +11 -9
  6. package/dist/core/prompt/cron.mjs +26 -13
  7. package/dist/core/prompt/skill-fallback.mjs +34 -0
  8. package/dist/messaging/inbound/context.mjs +4 -1
  9. package/dist/modules/configs/plugin-init.mjs +15 -11
  10. package/dist/provisioning/toolset/index.mjs +1 -0
  11. package/dist/provisioning/toolset/skill-catalog.mjs +61 -0
  12. package/dist/utils/sleep.mjs +6 -0
  13. package/openclaw.plugin.json +2 -1
  14. package/package.json +3 -1
  15. package/skills/yoyo-phone-control/SKILL.md +0 -314
  16. package/skills/yoyo-phone-control/mcptools/about_device.json +0 -72
  17. package/skills/yoyo-phone-control/mcptools/adjust_brightness.json +0 -84
  18. package/skills/yoyo-phone-control/mcptools/ai_caption.json +0 -89
  19. package/skills/yoyo-phone-control/mcptools/airplane_mode.json +0 -67
  20. package/skills/yoyo-phone-control/mcptools/answer_phone.json +0 -35
  21. package/skills/yoyo-phone-control/mcptools/aod.json +0 -68
  22. package/skills/yoyo-phone-control/mcptools/app_clone.json +0 -77
  23. package/skills/yoyo-phone-control/mcptools/app_lock.json +0 -28
  24. package/skills/yoyo-phone-control/mcptools/app_manager.json +0 -88
  25. package/skills/yoyo-phone-control/mcptools/auto_intercept_one_ring_call.json +0 -64
  26. package/skills/yoyo-phone-control/mcptools/auto_rotate.json +0 -58
  27. package/skills/yoyo-phone-control/mcptools/autoscreen_onnotice.json +0 -63
  28. package/skills/yoyo-phone-control/mcptools/battery.json +0 -66
  29. package/skills/yoyo-phone-control/mcptools/bluetooth.json +0 -78
  30. package/skills/yoyo-phone-control/mcptools/book_train_ticket.json +0 -59
  31. package/skills/yoyo-phone-control/mcptools/brightness.json +0 -150
  32. package/skills/yoyo-phone-control/mcptools/call.json +0 -107
  33. package/skills/yoyo-phone-control/mcptools/camera.json +0 -146
  34. package/skills/yoyo-phone-control/mcptools/cancel_countdown_timer.json +0 -78
  35. package/skills/yoyo-phone-control/mcptools/cancel_countup_timer.json +0 -41
  36. package/skills/yoyo-phone-control/mcptools/capture_screenshot.json +0 -26
  37. package/skills/yoyo-phone-control/mcptools/check_alarm.json +0 -70
  38. package/skills/yoyo-phone-control/mcptools/check_countdown_timer.json +0 -55
  39. package/skills/yoyo-phone-control/mcptools/check_countup_timer.json +0 -41
  40. package/skills/yoyo-phone-control/mcptools/check_schedule.json +0 -79
  41. package/skills/yoyo-phone-control/mcptools/check_todo.json +0 -71
  42. package/skills/yoyo-phone-control/mcptools/clean_dirty.json +0 -61
  43. package/skills/yoyo-phone-control/mcptools/close_alarm.json +0 -98
  44. package/skills/yoyo-phone-control/mcptools/close_app.json +0 -90
  45. package/skills/yoyo-phone-control/mcptools/close_countdown_timer.json +0 -74
  46. package/skills/yoyo-phone-control/mcptools/close_countup_timer.json +0 -45
  47. package/skills/yoyo-phone-control/mcptools/close_ring.json +0 -53
  48. package/skills/yoyo-phone-control/mcptools/close_schedule.json +0 -37
  49. package/skills/yoyo-phone-control/mcptools/color_temp.json +0 -70
  50. package/skills/yoyo-phone-control/mcptools/configure_auto_record.json +0 -66
  51. package/skills/yoyo-phone-control/mcptools/control_center.json +0 -28
  52. package/skills/yoyo-phone-control/mcptools/copy_file.json +0 -70
  53. package/skills/yoyo-phone-control/mcptools/create_alarm.json +0 -105
  54. package/skills/yoyo-phone-control/mcptools/create_countdown_timer.json +0 -77
  55. package/skills/yoyo-phone-control/mcptools/create_countup_timer.json +0 -45
  56. package/skills/yoyo-phone-control/mcptools/create_file.json +0 -63
  57. package/skills/yoyo-phone-control/mcptools/create_schedule.json +0 -110
  58. package/skills/yoyo-phone-control/mcptools/create_todo.json +0 -89
  59. package/skills/yoyo-phone-control/mcptools/dark_mode.json +0 -63
  60. package/skills/yoyo-phone-control/mcptools/delay_ring.json +0 -59
  61. package/skills/yoyo-phone-control/mcptools/delete_alarm.json +0 -106
  62. package/skills/yoyo-phone-control/mcptools/delete_schedule.json +0 -126
  63. package/skills/yoyo-phone-control/mcptools/delete_todo.json +0 -118
  64. package/skills/yoyo-phone-control/mcptools/desktop.json +0 -110
  65. package/skills/yoyo-phone-control/mcptools/device_operation.json +0 -122
  66. package/skills/yoyo-phone-control/mcptools/digital_balance.json +0 -72
  67. package/skills/yoyo-phone-control/mcptools/display_and_brightness.json +0 -75
  68. package/skills/yoyo-phone-control/mcptools/download_app.json +0 -67
  69. package/skills/yoyo-phone-control/mcptools/express_logistics_query.json +0 -50
  70. package/skills/yoyo-phone-control/mcptools/eyecomfort.json +0 -79
  71. package/skills/yoyo-phone-control/mcptools/find_device.json +0 -38
  72. package/skills/yoyo-phone-control/mcptools/find_phone.json +0 -47
  73. package/skills/yoyo-phone-control/mcptools/flashlight.json +0 -65
  74. package/skills/yoyo-phone-control/mcptools/free_screen.json +0 -76
  75. package/skills/yoyo-phone-control/mcptools/get_address_lat_lng.json +0 -86
  76. package/skills/yoyo-phone-control/mcptools/get_user_location.json +0 -43
  77. package/skills/yoyo-phone-control/mcptools/gui_task_create.json +0 -116
  78. package/skills/yoyo-phone-control/mcptools/gui_task_pause.json +0 -66
  79. package/skills/yoyo-phone-control/mcptools/gui_task_terminate.json +0 -70
  80. package/skills/yoyo-phone-control/mcptools/hang_up_phone.json +0 -35
  81. package/skills/yoyo-phone-control/mcptools/harassment.json +0 -55
  82. package/skills/yoyo-phone-control/mcptools/honor_board.json +0 -92
  83. package/skills/yoyo-phone-control/mcptools/honor_share.json +0 -72
  84. package/skills/yoyo-phone-control/mcptools/hotspot.json +0 -66
  85. package/skills/yoyo-phone-control/mcptools/hover_button.json +0 -71
  86. package/skills/yoyo-phone-control/mcptools/identify_food_calories.json +0 -60
  87. package/skills/yoyo-phone-control/mcptools/image_search_commodity.json +0 -74
  88. package/skills/yoyo-phone-control/mcptools/image_to_document_router.json +0 -73
  89. package/skills/yoyo-phone-control/mcptools/input_method.json +0 -42
  90. package/skills/yoyo-phone-control/mcptools/jump_video_progress.json +0 -55
  91. package/skills/yoyo-phone-control/mcptools/language.json +0 -59
  92. package/skills/yoyo-phone-control/mcptools/local_user_data_qa.json +0 -124
  93. package/skills/yoyo-phone-control/mcptools/local_user_file_search.json +0 -128
  94. package/skills/yoyo-phone-control/mcptools/location_service.json +0 -79
  95. package/skills/yoyo-phone-control/mcptools/magazine_unlock.json +0 -80
  96. package/skills/yoyo-phone-control/mcptools/magic_portal.json +0 -58
  97. package/skills/yoyo-phone-control/mcptools/memorySearch.json +0 -100
  98. package/skills/yoyo-phone-control/mcptools/migrate.json +0 -84
  99. package/skills/yoyo-phone-control/mcptools/mobile_data.json +0 -74
  100. package/skills/yoyo-phone-control/mcptools/modify_alarm.json +0 -146
  101. package/skills/yoyo-phone-control/mcptools/modify_schedule.json +0 -131
  102. package/skills/yoyo-phone-control/mcptools/modify_todo.json +0 -122
  103. package/skills/yoyo-phone-control/mcptools/motion_sickness_relief.json +0 -76
  104. package/skills/yoyo-phone-control/mcptools/move_file.json +0 -73
  105. package/skills/yoyo-phone-control/mcptools/multi_screen.json +0 -169
  106. package/skills/yoyo-phone-control/mcptools/multi_window.json +0 -99
  107. package/skills/yoyo-phone-control/mcptools/multimodal_dialogue.json +0 -73
  108. package/skills/yoyo-phone-control/mcptools/musicFeedbackAction.json +0 -46
  109. package/skills/yoyo-phone-control/mcptools/navigation_bar.json +0 -60
  110. package/skills/yoyo-phone-control/mcptools/navigation_service.json +0 -129
  111. package/skills/yoyo-phone-control/mcptools/net_accelerate.json +0 -72
  112. package/skills/yoyo-phone-control/mcptools/nfc.json +0 -68
  113. package/skills/yoyo-phone-control/mcptools/no_disturb.json +0 -59
  114. package/skills/yoyo-phone-control/mcptools/no_disturb_schedule.json +0 -84
  115. package/skills/yoyo-phone-control/mcptools/notification_sound.json +0 -83
  116. package/skills/yoyo-phone-control/mcptools/onehanded_mode.json +0 -63
  117. package/skills/yoyo-phone-control/mcptools/open_alarm.json +0 -98
  118. package/skills/yoyo-phone-control/mcptools/open_app.json +0 -92
  119. package/skills/yoyo-phone-control/mcptools/open_countdown_timer.json +0 -42
  120. package/skills/yoyo-phone-control/mcptools/open_countup_timer.json +0 -47
  121. package/skills/yoyo-phone-control/mcptools/open_payment_code.json +0 -83
  122. package/skills/yoyo-phone-control/mcptools/open_schedule.json +0 -35
  123. package/skills/yoyo-phone-control/mcptools/open_transport_code.json +0 -53
  124. package/skills/yoyo-phone-control/mcptools/operateMusic.json +0 -76
  125. package/skills/yoyo-phone-control/mcptools/operateRhythm.json +0 -58
  126. package/skills/yoyo-phone-control/mcptools/operateVideo.json +0 -64
  127. package/skills/yoyo-phone-control/mcptools/operate_audio.json +0 -64
  128. package/skills/yoyo-phone-control/mcptools/outdoor_mode.json +0 -68
  129. package/skills/yoyo-phone-control/mcptools/parallel_space.json +0 -59
  130. package/skills/yoyo-phone-control/mcptools/pause_countdown_timer.json +0 -78
  131. package/skills/yoyo-phone-control/mcptools/pause_countup_timer.json +0 -45
  132. package/skills/yoyo-phone-control/mcptools/phone_service.json +0 -83
  133. package/skills/yoyo-phone-control/mcptools/playMusic.json +0 -125
  134. package/skills/yoyo-phone-control/mcptools/playNews.json +0 -35
  135. package/skills/yoyo-phone-control/mcptools/playVideo.json +0 -117
  136. package/skills/yoyo-phone-control/mcptools/play_audio.json +0 -66
  137. package/skills/yoyo-phone-control/mcptools/play_record.json +0 -56
  138. package/skills/yoyo-phone-control/mcptools/print_file.json +0 -60
  139. package/skills/yoyo-phone-control/mcptools/ptz_control.json +0 -62
  140. package/skills/yoyo-phone-control/mcptools/query_group_buy.json +0 -86
  141. package/skills/yoyo-phone-control/mcptools/quiet_mode.json +0 -67
  142. package/skills/yoyo-phone-control/mcptools/read_schedule.json +0 -77
  143. package/skills/yoyo-phone-control/mcptools/recognitionMusic.json +0 -54
  144. package/skills/yoyo-phone-control/mcptools/record.json +0 -88
  145. package/skills/yoyo-phone-control/mcptools/redial_recall.json +0 -81
  146. package/skills/yoyo-phone-control/mcptools/remote_control.json +0 -98
  147. package/skills/yoyo-phone-control/mcptools/renewal_query.json +0 -63
  148. package/skills/yoyo-phone-control/mcptools/restart_countdown_timer.json +0 -78
  149. package/skills/yoyo-phone-control/mcptools/restart_countup_timer.json +0 -49
  150. package/skills/yoyo-phone-control/mcptools/restore_screen_display.json +0 -55
  151. package/skills/yoyo-phone-control/mcptools/resume_countdown_timer.json +0 -78
  152. package/skills/yoyo-phone-control/mcptools/resume_countup_timer.json +0 -41
  153. package/skills/yoyo-phone-control/mcptools/ring_tone.json +0 -102
  154. package/skills/yoyo-phone-control/mcptools/ringing_mode.json +0 -63
  155. package/skills/yoyo-phone-control/mcptools/save_file.json +0 -70
  156. package/skills/yoyo-phone-control/mcptools/scan_code.json +0 -51
  157. package/skills/yoyo-phone-control/mcptools/scheduled_power_operation.json +0 -76
  158. package/skills/yoyo-phone-control/mcptools/screen_recorder.json +0 -76
  159. package/skills/yoyo-phone-control/mcptools/screen_saver.json +0 -72
  160. package/skills/yoyo-phone-control/mcptools/scroll_page.json +0 -30
  161. package/skills/yoyo-phone-control/mcptools/search_call_record.json +0 -80
  162. package/skills/yoyo-phone-control/mcptools/search_contact.json +0 -59
  163. package/skills/yoyo-phone-control/mcptools/search_message.json +0 -75
  164. package/skills/yoyo-phone-control/mcptools/search_nearby_share_device.json +0 -63
  165. package/skills/yoyo-phone-control/mcptools/search_notification.json +0 -64
  166. package/skills/yoyo-phone-control/mcptools/search_record.json +0 -72
  167. package/skills/yoyo-phone-control/mcptools/send_express.json +0 -51
  168. package/skills/yoyo-phone-control/mcptools/send_message.json +0 -102
  169. package/skills/yoyo-phone-control/mcptools/setMusicPlayMode.json +0 -56
  170. package/skills/yoyo-phone-control/mcptools/set_auto_record.json +0 -53
  171. package/skills/yoyo-phone-control/mcptools/set_specified_number_auto_record.json +0 -77
  172. package/skills/yoyo-phone-control/mcptools/set_video_clarity.json +0 -63
  173. package/skills/yoyo-phone-control/mcptools/set_video_play_mode.json +0 -46
  174. package/skills/yoyo-phone-control/mcptools/set_video_playback_speed.json +0 -42
  175. package/skills/yoyo-phone-control/mcptools/simple_mode.json +0 -75
  176. package/skills/yoyo-phone-control/mcptools/smart_call.json +0 -99
  177. package/skills/yoyo-phone-control/mcptools/smart_cover.json +0 -68
  178. package/skills/yoyo-phone-control/mcptools/sound_and_vibration.json +0 -71
  179. package/skills/yoyo-phone-control/mcptools/status_bar_show.json +0 -91
  180. package/skills/yoyo-phone-control/mcptools/storage.json +0 -117
  181. package/skills/yoyo-phone-control/mcptools/switchMusic.json +0 -66
  182. package/skills/yoyo-phone-control/mcptools/switch_audio.json +0 -50
  183. package/skills/yoyo-phone-control/mcptools/switch_video.json +0 -60
  184. package/skills/yoyo-phone-control/mcptools/system_update.json +0 -48
  185. package/skills/yoyo-phone-control/mcptools/theme.json +0 -65
  186. package/skills/yoyo-phone-control/mcptools/toAntiVirusActivity.json +0 -82
  187. package/skills/yoyo-phone-control/mcptools/toggle_auto_brightness.json +0 -58
  188. package/skills/yoyo-phone-control/mcptools/uninstall_app.json +0 -88
  189. package/skills/yoyo-phone-control/mcptools/update_app.json +0 -65
  190. package/skills/yoyo-phone-control/mcptools/usb_debug.json +0 -68
  191. package/skills/yoyo-phone-control/mcptools/usb_shared_network.json +0 -63
  192. package/skills/yoyo-phone-control/mcptools/vibration_mode.json +0 -86
  193. package/skills/yoyo-phone-control/mcptools/volume.json +0 -103
  194. package/skills/yoyo-phone-control/mcptools/wlan.json +0 -105
  195. package/skills/yoyo-phone-control/mcptools/yoyo_calendar.json +0 -56
  196. package/skills/yoyo-phone-control/mcptools/yoyo_suggestions.json +0 -115
@@ -5,94 +5,165 @@ import { resolveChatIdFromTo as r } from "../../messaging/target/outbound.mjs";
5
5
  import "../../messaging/target/index.mjs";
6
6
  import { CronRunStatus as i } from "../../messaging/notification/types.mjs";
7
7
  import "../../messaging/notification/index.mjs";
8
+ import { sleep as a } from "../../utils/sleep.mjs";
9
+ import { resolveListTimezone as o } from "./timezone.mjs";
8
10
  //#region src/capabilities/cron/service.ts
9
- var a = t("cron"), o = 50, s;
10
- function c(e) {
11
- s = e, a.info("cron service handle updated", { available: e !== void 0 });
11
+ var s = t("cron"), c = 50, l = 300, u = 3, d;
12
+ function f(e) {
13
+ d = e, s.info("cron service handle updated", { available: e !== void 0 });
12
14
  }
13
- function l() {
14
- s = void 0;
15
+ function p() {
16
+ d = void 0;
15
17
  }
16
- async function u(t, r) {
18
+ async function m(t, r) {
17
19
  let i = await n(t, r);
18
- if (!i) return a.info("cron list: request device has no chat mapping, empty result", {
20
+ if (!i) return s.info("cron list: request device has no chat mapping, empty result", {
19
21
  accountId: t,
20
22
  requestDeviceId: r
21
23
  }), {
22
24
  ok: !0,
23
25
  jobs: [],
24
- total: 0
26
+ total: 0,
27
+ timezone: o()
25
28
  };
26
- let c = s;
27
- if (!c) return {
29
+ let a = d;
30
+ if (!a) return {
28
31
  ok: !1,
29
32
  error: "cron_unavailable"
30
33
  };
31
34
  let l;
32
35
  try {
33
- l = await c.list({ includeDisabled: !0 });
36
+ l = await a.list({ includeDisabled: !0 });
34
37
  } catch (t) {
35
- return a.error("cron list failed", t), {
38
+ return s.error("cron list failed", t), {
36
39
  ok: !1,
37
40
  error: e(t)
38
41
  };
39
42
  }
40
43
  let u = [];
41
44
  for (let e of l) {
42
- if (!await p(e, t, i)) continue;
43
- let n = m(e);
45
+ if (!await b(e, t, i)) continue;
46
+ let n = x(e);
44
47
  n && u.push(n);
45
48
  }
46
- return a.info("cron list for chat", {
49
+ return s.info("cron list for chat", {
47
50
  accountId: t,
48
51
  requestDeviceId: r,
49
52
  requestChatId: i,
50
53
  total: l.length,
51
54
  owned: u.length,
52
- returned: Math.min(u.length, o)
55
+ returned: Math.min(u.length, c)
53
56
  }), {
54
57
  ok: !0,
55
- jobs: u.slice(0, o),
56
- total: l.length
58
+ jobs: u.slice(0, c),
59
+ total: l.length,
60
+ timezone: o()
57
61
  };
58
62
  }
59
- async function d(t) {
60
- let n = s;
63
+ async function h(t) {
64
+ let n = d;
61
65
  if (n) try {
62
66
  return (await n.list({ includeDisabled: !1 })).find((e) => e?.id === t);
63
67
  } catch (n) {
64
- a.warn("cron job lookup failed", {
68
+ s.warn("cron job lookup failed", {
65
69
  jobId: t,
66
70
  error: e(n)
67
71
  });
68
72
  return;
69
73
  }
70
74
  }
71
- async function f(t) {
72
- let n = s;
73
- if (!n) return {
75
+ async function g(e) {
76
+ let t = d;
77
+ if (!t) return {
74
78
  ok: !1,
75
79
  error: "cron_unavailable"
76
80
  };
81
+ let n = Date.now(), r = _(t, e).catch(() => void 0), i = v(t, e), a = await Promise.race([i.then((e) => e ? "polling" : "polling-exhausted"), r.then(() => "remove")]);
82
+ if (a === "remove") {
83
+ let t = await r, i = Date.now() - n;
84
+ return t === void 0 ? (s.warn("cron remove unresolved: upstream result absent", {
85
+ jobId: e,
86
+ elapsedMs: i
87
+ }), {
88
+ ok: !1,
89
+ error: "cron remove failed"
90
+ }) : (s.debug("cron remove settled by upstream result", {
91
+ jobId: e,
92
+ elapsedMs: i,
93
+ ok: t.ok,
94
+ removed: t.ok ? t.removed : void 0
95
+ }), t);
96
+ }
97
+ return r.then((t) => {
98
+ s.info("cron remove late upstream outcome after returning", {
99
+ jobId: e,
100
+ winner: a,
101
+ ok: t?.ok,
102
+ removed: t?.ok ? t.removed : void 0
103
+ });
104
+ }), a === "polling" ? (s.info("cron remove confirmed by store polling, skipping cleanup wait", {
105
+ jobId: e,
106
+ elapsedMs: Date.now() - n
107
+ }), {
108
+ ok: !0,
109
+ removed: !0
110
+ }) : (s.warn("cron remove polling exhausted, returning without cleanup wait", {
111
+ jobId: e,
112
+ elapsedMs: Date.now() - n
113
+ }), {
114
+ ok: !0,
115
+ removed: !1
116
+ });
117
+ }
118
+ async function _(t, n) {
77
119
  try {
78
120
  return {
79
121
  ok: !0,
80
- removed: (await n.remove(t))?.removed === !0
122
+ removed: (await t.remove(n))?.removed === !0
81
123
  };
82
- } catch (n) {
83
- return a.error("cron remove failed", n, { jobId: t }), {
124
+ } catch (r) {
125
+ return await y(t, n) === !1 ? (s.warn("cron remove errored but job no longer exists, treated as success", {
126
+ jobId: n,
127
+ error: e(r)
128
+ }), {
129
+ ok: !0,
130
+ removed: !1
131
+ }) : (s.error("cron remove failed", r, { jobId: n }), {
84
132
  ok: !1,
85
- error: e(n)
86
- };
133
+ error: e(r)
134
+ });
135
+ }
136
+ }
137
+ async function v(e, t) {
138
+ for (let n = 1; n <= u; n++) {
139
+ await a(l);
140
+ let r = await y(e, t);
141
+ if (s.debug("cron remove polling probe", {
142
+ jobId: t,
143
+ attempt: n,
144
+ present: r
145
+ }), r === !1) return !0;
146
+ }
147
+ return !1;
148
+ }
149
+ async function y(t, n) {
150
+ try {
151
+ return (await t.list({ includeDisabled: !0 })).some((e) => e?.id === n);
152
+ } catch (t) {
153
+ s.warn("cron job presence lookup failed", {
154
+ jobId: n,
155
+ error: e(t)
156
+ });
157
+ return;
87
158
  }
88
159
  }
89
- async function p(e, t, n) {
160
+ async function b(e, t, n) {
90
161
  let i = e.delivery?.to;
91
162
  return typeof i != "string" || i.length === 0 ? !1 : await r(i, t) === n;
92
163
  }
93
- function m(e) {
164
+ function x(e) {
94
165
  if (e.enabled !== !0) return;
95
- let t = h(e.schedule);
166
+ let t = S(e.schedule);
96
167
  if (!t) return;
97
168
  let n = e.state, r = n?.lastRunAtMs;
98
169
  if (r != null) {
@@ -105,11 +176,11 @@ function m(e) {
105
176
  ...e.description ? { description: e.description } : {},
106
177
  schedule: t,
107
178
  nextRunAtMs: n?.nextRunAtMs ?? null,
108
- ...n?.lastRunStatus === void 0 ? {} : { lastRunStatus: g(n.lastRunStatus) },
179
+ ...n?.lastRunStatus === void 0 ? {} : { lastRunStatus: C(n.lastRunStatus) },
109
180
  ...r === void 0 ? {} : { lastRunAtMs: r }
110
181
  };
111
182
  }
112
- function h(e) {
183
+ function S(e) {
113
184
  switch (e?.kind) {
114
185
  case "cron": return {
115
186
  kind: "cron",
@@ -129,7 +200,7 @@ function h(e) {
129
200
  default: return;
130
201
  }
131
202
  }
132
- function g(e) {
203
+ function C(e) {
133
204
  switch (e) {
134
205
  case "ok": return i.Success;
135
206
  case "error": return i.Failed;
@@ -137,4 +208,4 @@ function g(e) {
137
208
  }
138
209
  }
139
210
  //#endregion
140
- export { c as captureCronService, d as findCronJobById, u as listCronJobsForChat, l as releaseCronService, f as removeCronJob };
211
+ export { f as captureCronService, h as findCronJobById, m as listCronJobsForChat, p as releaseCronService, g as removeCronJob };
@@ -0,0 +1,16 @@
1
+ import { getRuntimeConfig as e } from "openclaw/plugin-sdk/config-runtime";
2
+ //#region src/capabilities/cron/timezone.ts
3
+ function t() {
4
+ let t = e().agents?.defaults?.userTimezone, r = typeof t == "string" ? t.trim() : "";
5
+ return n(r) ? r : Intl.DateTimeFormat().resolvedOptions().timeZone?.trim() || "UTC";
6
+ }
7
+ function n(e) {
8
+ if (!e) return !1;
9
+ try {
10
+ return new Intl.DateTimeFormat("en-US", { timeZone: e }).format(/* @__PURE__ */ new Date()), !0;
11
+ } catch {
12
+ return !1;
13
+ }
14
+ }
15
+ //#endregion
16
+ export { t as resolveListTimezone };
@@ -16,7 +16,8 @@ var n = "cron.list", r = "cron.remove", i = async ({ event: t, accountId: n }) =
16
16
  ok: !0,
17
17
  responsePayload: {
18
18
  ok: !0,
19
- jobs: i.jobs
19
+ jobs: i.jobs,
20
+ timezone: i.timezone
20
21
  }
21
22
  } : {
22
23
  ok: !1,
@@ -51,6 +51,7 @@ function m(e, t) {
51
51
  ` 请求方:account=\`${t.accountId}\` deviceId=\`${t.deviceId}\``,
52
52
  ` 归属过滤键:\`chat:${t.chatId}\`(delivery.to 归一后等于该 chatId 的任务才返回)`,
53
53
  ` 任务统计:网关共 ${e.total} 条,归属当前会话 ${e.jobs.length} 条`,
54
+ ` 展示时区:\`${e.timezone}\`(at/every 墙钟换算)`,
54
55
  ""
55
56
  ];
56
57
  return e.jobs.length === 0 ? (n.push(e.total > 0 ? `(当前会话无归属任务;网关另有 ${e.total} 条任务,其 delivery.to 未指向 \`chat:${t.chatId}\`)` : "(网关无任何任务)", "", "验证提示:端侧任务列表应同样为空"), n.join("\n")) : (n.push("| # | 名称 | jobId | 调度 | 下次执行 | 上次执行 |", "| --- | --- | --- | --- | --- | --- |", ...e.jobs.map((e, t) => p(t + 1, e)), "", "&nbsp;", "", "验证提示:", "- 端侧任务列表应与上表一致(列即端侧 DTO 投影,无 delivery 等内部字段)", "- 删除验证:`/yoyo mock cron remove <jobId>` 后重新执行本命令,对应任务应消失"), n.join("\n"));
@@ -2,27 +2,29 @@ import { resolveAgentPromptContribution as e } from "./agent.mjs";
2
2
  import { resolveCloudToolPromptContribution as t } from "./cloud-tool.mjs";
3
3
  import { resolveCronDeliveryPromptContribution as n } from "./cron.mjs";
4
4
  import { resolveLocationPromptContribution as r } from "./location.mjs";
5
- import { resolveSkillPromptContribution as i } from "./skill.mjs";
5
+ import { resolveCronSkillFallbackContribution as i } from "./skill-fallback.mjs";
6
+ import { resolveSkillPromptContribution as a } from "./skill.mjs";
6
7
  //#region src/core/prompt/builder.ts
7
- function a(e) {
8
+ function o(e) {
8
9
  let t = e.filter((e) => !!e);
9
10
  return t.length > 0 ? t.join("\n\n") : void 0;
10
11
  }
11
- function o(e) {
12
- let t = a(e.map((e) => e.prependSystemContext)), n = a(e.map((e) => e.prependContext));
12
+ function s(e) {
13
+ let t = o(e.map((e) => e.prependSystemContext)), n = o(e.map((e) => e.prependContext));
13
14
  return {
14
15
  ...t ? { prependSystemContext: t } : {},
15
16
  ...n ? { prependContext: n } : {}
16
17
  };
17
18
  }
18
- async function s(a) {
19
- return o([
19
+ async function c(o) {
20
+ return s([
20
21
  t(),
21
22
  e(),
22
- n(a),
23
- await i(),
23
+ n(o),
24
+ await a(),
25
+ await i(o),
24
26
  r()
25
27
  ]);
26
28
  }
27
29
  //#endregion
28
- export { s as resolvePromptBuildContribution };
30
+ export { c as resolvePromptBuildContribution };
@@ -1,19 +1,32 @@
1
- import "../../consts.mjs";
2
- import { looksLikeChatId as e } from "../../messaging/target/chat-id.mjs";
3
- import { readChatIdFromSessionKey as t } from "../../messaging/target/address.mjs";
1
+ import { clawLogger as e } from "../../utils/claw-logger.mjs";
2
+ import { looksLikeChatId as t } from "../../messaging/target/chat-id.mjs";
3
+ import { readChatIdFromSessionKey as n } from "../../messaging/target/address.mjs";
4
4
  import "../../messaging/target/index.mjs";
5
5
  //#region src/core/prompt/cron.ts
6
- function n(t) {
7
- return t.chatId && e(t.chatId) ? t.chatId : void 0;
6
+ var r = e("cron");
7
+ function i(e) {
8
+ return e.chatId && t(e.chatId) ? e.chatId : void 0;
8
9
  }
9
- function r(e) {
10
- if (!e || t(e.sessionKey)) return {};
11
- let r = e.channel === "yoyo" ? n(e) : void 0;
12
- return r ? { prependSystemContext: `## 定时任务投递目标
10
+ function a(e) {
11
+ let t = e ? n(e.sessionKey) : void 0, a = t || (e ? i(e) : void 0);
12
+ return !e || !a ? (r.debug("cron delivery prompt skipped: no resolvable chatId", {
13
+ sessionKey: e?.sessionKey ?? null,
14
+ turnChatId: e?.chatId ?? null
15
+ }), {}) : (r.info("cron delivery prompt injected", {
16
+ sessionKey: e.sessionKey ?? null,
17
+ chatId: a,
18
+ source: t ? "sessionKey" : "turn"
19
+ }), { prependSystemContext: `# 定时任务投递目标
20
+ 当前对话来自 YOYO 手机侧会话(chatId: ${a}),在本会话中创建定时任务时:
21
+ - 创建方式优先使用 automations 或 cron 工具;两者都不可用时再考虑使用 openclaw cron 命令行,尽量不要使用 subagent。
22
+ - 无论用哪种方式创建,delivery 必须完整包含以下三个字段,缺一不可:
23
+ {mode:"announce", channel:"yoyo", to:"chat:${a}"}
24
+ - 特别注意 to 字段必须显式写为 "chat:${a}"。即使工具或命令行看起来能自动推断投递目标,也不省略 to —— 缺少 to 的任务执行结果无法推送回本会话。
25
+ - 当用户显式指定投递给其他手机、设备或者 channel 时,可以不按当前规则处理,to 也可以为目标设备对应的 device:{deviceId}
13
26
 
14
- 当前对话来自 YOYO 手机侧会话(chatId: ${r})。在本会话中创建定时任务时:
15
- - 创建方式优先使用 automations 或 cron 工具;两者都不可用时再使用 openclaw cron 命令行。
16
- - 无论用哪种方式创建,delivery 必须配置为 {mode:"announce", channel:"yoyo", to:"chat:${r}"},确保任务执行结果能自动推送回本会话对应的手机侧。` } : {};
27
+ # 定时任务处理策略
28
+ - 严格聚焦当前用户请求:对上下文中已触发过的定时任务及其结果,未经用户明确要求(如"总结一下""结果怎么样")不主动总结、复述或汇报。
29
+ - 不刻意隐式总结前序定时任务:不用"顺带提醒""补充说明"等方式带出用户未问及的历史任务;任务结果由任务自身投递,无需对话轮次代述。` });
17
30
  }
18
31
  //#endregion
19
- export { r as resolveCronDeliveryPromptContribution };
32
+ export { a as resolveCronDeliveryPromptContribution };
@@ -0,0 +1,34 @@
1
+ import { clawLogger as e } from "../../utils/claw-logger.mjs";
2
+ import { loadYoyoSkillCatalog as t } from "../../provisioning/toolset/skill-catalog.mjs";
3
+ //#region src/core/prompt/skill-fallback.ts
4
+ var n = e("hooks"), r = new Set(["yoyo-update"]);
5
+ async function i(e) {
6
+ if (!e || e.trigger !== "cron" || e.channel !== "yoyo") return n.debug("cron skill fallback skipped: not a yoyo cron turn", {
7
+ trigger: e?.trigger ?? null,
8
+ channel: e?.channel ?? null
9
+ }), {};
10
+ let i = (await t())?.filter((e) => !r.has(e.name)) ?? [];
11
+ return i.length === 0 ? (n.warn("cron skill fallback skipped: empty skill catalog"), {}) : (n.info("cron skill fallback prompt injected", {
12
+ sessionKey: e.sessionKey ?? null,
13
+ skillCount: i.length
14
+ }), { prependSystemContext: a(i) });
15
+ }
16
+ function a(e) {
17
+ return `# 定时任务技能目录
18
+ 当前会话由定时任务触发,系统提示词中可能缺少技能目录。以下是 YOYO 插件自带技能,使用规则与常规会话一致:
19
+ - 先扫描 <available_skills>:与当前任务明确匹配的技能,用 read 工具按 <location> 的绝对路径读取 SKILL.md 全文,并严格遵守其内容执行;没有匹配则不读取。
20
+ - 多个匹配时只选最贴切的一个,最多预读一个;禁止编造路径。
21
+ - 技能正文引用相对路径时,以 SKILL.md 所在目录为基准解析为绝对路径后再调用工具。
22
+
23
+ <available_skills>
24
+ ${e.map((e) => {
25
+ let t = [" <skill>", ` <name>${o(e.name)}</name>`];
26
+ return e.description && t.push(` <description>${o(e.description)}</description>`), t.push(` <location>${o(e.location)}</location>`, " </skill>"), t.join("\n");
27
+ }).join("\n")}
28
+ </available_skills>`;
29
+ }
30
+ function o(e) {
31
+ return e.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
32
+ }
33
+ //#endregion
34
+ export { i as resolveCronSkillFallbackContribution };
@@ -66,7 +66,10 @@ function p(t) {
66
66
  rawBody: n.content,
67
67
  commandBody: n.content
68
68
  },
69
- access: { commands: { authorized: !0 } },
69
+ access: {
70
+ commands: { authorized: !0 },
71
+ toolPolicy: { deny: ["ask_user", "secrets"] }
72
+ },
70
73
  messageId: n.messageId,
71
74
  ...n.resources.length > 0 ? { media: n.resources.map((e) => ({ url: e.url })) } : {},
72
75
  extra: { OwnerAllowFrom: [n.accountId, n.senderId] }
@@ -30,19 +30,23 @@ async function p(e) {
30
30
  count: Object.keys(M).length,
31
31
  mapping: Object.entries(M).map(([e, t]) => `${e} -> ${t}`).join(", ")
32
32
  });
33
- let P = c(t), F = P.changed;
34
- if (!g && !_ && !O && !j && !N && !F && !y) return;
35
- let I = { ...t.plugins };
36
- g && delete I.allow;
37
- let L = {
33
+ let P = c(t), F = P.changed, I = t.plugins?.entries?.[e]?.hooks?.allowConversationAccess !== !0;
34
+ if (!g && !_ && !O && !j && !N && !F && !y && !I) return;
35
+ let L = { ...t.plugins };
36
+ g && delete L.allow;
37
+ let R = {
38
38
  ...t,
39
39
  plugins: {
40
- ...I,
40
+ ...L,
41
41
  entries: {
42
42
  ...t.plugins?.entries,
43
43
  [e]: {
44
44
  ...t.plugins?.entries?.[e],
45
45
  enabled: !0,
46
+ ...I ? { hooks: {
47
+ ...t.plugins?.entries?.[e]?.hooks,
48
+ allowConversationAccess: !0
49
+ } } : {},
46
50
  config: A
47
51
  }
48
52
  }
@@ -52,11 +56,11 @@ async function p(e) {
52
56
  alsoAllow: b
53
57
  } } : {}
54
58
  };
55
- F && (L = {
56
- ...L,
59
+ F && (R = {
60
+ ...R,
57
61
  agents: P.agents
58
- }, d.info("refreshed agents.defaults values", { changes: P.changes.join(", ") })), _ && (L = {
59
- ...L,
62
+ }, d.info("refreshed agents.defaults values", { changes: P.changes.join(", ") })), _ && (R = {
63
+ ...R,
60
64
  skills: {
61
65
  ...r,
62
66
  load: {
@@ -64,7 +68,7 @@ async function p(e) {
64
68
  watch: !1
65
69
  }
66
70
  }
67
- }, d.info("disabled skills.load.watch for plugin")), N && (L = u(L, M), d.info("provider renaming completed")), await a(L);
71
+ }, d.info("disabled skills.load.watch for plugin")), N && (R = u(R, M), d.info("provider renaming completed")), await a(R);
68
72
  } catch (e) {
69
73
  throw t(e, "failed to initialize plugin config");
70
74
  }
@@ -3,3 +3,4 @@ import "./normalize.mjs";
3
3
  import "./processor.mjs";
4
4
  import "./ack.mjs";
5
5
  import "./cleanup.mjs";
6
+ import "./skill-catalog.mjs";
@@ -0,0 +1,61 @@
1
+ import { clawLogger as e } from "../../utils/claw-logger.mjs";
2
+ import { normalizeString as t } from "../../utils/normalize.mjs";
3
+ import { resolveExtensionRoot as n } from "../../utils/home-dir.mjs";
4
+ import r from "node:path";
5
+ import i from "node:fs/promises";
6
+ import { parseDocument as a } from "yaml";
7
+ //#region src/provisioning/toolset/skill-catalog.ts
8
+ var o = e("toolset"), s = "skills", c = "SKILL.md", l;
9
+ async function u() {
10
+ if (l) return l;
11
+ try {
12
+ l = await d();
13
+ } catch (e) {
14
+ o.warn("skill catalog scan failed", { error: String(e) });
15
+ return;
16
+ }
17
+ return l;
18
+ }
19
+ async function d() {
20
+ let e = r.join(n(), s), t = await i.readdir(e, { withFileTypes: !0 }), a = [];
21
+ for (let n of t) {
22
+ if (!n.isDirectory()) continue;
23
+ let t = r.join(e, n.name, c), i = await f(t);
24
+ if (!i) {
25
+ o.warn("skill catalog entry skipped: missing or incomplete frontmatter", { skillPath: t });
26
+ continue;
27
+ }
28
+ a.push({
29
+ ...i,
30
+ location: t
31
+ });
32
+ }
33
+ return a.sort((e, t) => e.name.localeCompare(t.name)), a;
34
+ }
35
+ async function f(e) {
36
+ let t;
37
+ try {
38
+ t = await i.readFile(e, "utf8");
39
+ } catch {
40
+ return;
41
+ }
42
+ return p(t);
43
+ }
44
+ function p(e) {
45
+ let n = /^---\r?\n([\s\S]*?)\r?\n---/.exec(e);
46
+ if (!n) return;
47
+ let r = a(n[1], {
48
+ schema: "core",
49
+ prettyErrors: !1
50
+ });
51
+ if (r.errors.length > 0) return;
52
+ let i = r.toJS();
53
+ if (typeof i != "object" || !i) return;
54
+ let o = i, s = t(o.name) || void 0, c = t(o.description) || void 0;
55
+ return s && c ? {
56
+ name: s,
57
+ description: c
58
+ } : void 0;
59
+ }
60
+ //#endregion
61
+ export { u as loadYoyoSkillCatalog };
@@ -0,0 +1,6 @@
1
+ //#region src/utils/sleep.ts
2
+ function e(e) {
3
+ return new Promise((t) => setTimeout(t, e));
4
+ }
5
+ //#endregion
6
+ export { e as sleep };
@@ -4,7 +4,8 @@
4
4
  "skills": ["./skills"],
5
5
  "enabledByDefault": true,
6
6
  "activation": {
7
- "onStartup": true
7
+ "onStartup": true,
8
+ "onCapabilities": ["hook"]
8
9
  },
9
10
  "contracts": {
10
11
  "tools": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@honor-claw/yoyo",
3
- "version": "2026.9.3-alpha.2",
3
+ "version": "2026.9.4-alpha.1",
4
4
  "description": "OpenClaw Honor Yoyo connection plugin",
5
5
  "keywords": [
6
6
  "ai",
@@ -12,6 +12,7 @@
12
12
  "files": [
13
13
  "dist",
14
14
  "skills",
15
+ "!skills/yoyo-phone-control/mcptools",
15
16
  "openclaw.plugin.json"
16
17
  ],
17
18
  "type": "module",
@@ -48,6 +49,7 @@
48
49
  "undici": "^7.3.0",
49
50
  "winreg": "^1.2.5",
50
51
  "ws": "^8.18.0",
52
+ "yaml": "^2.9.0",
51
53
  "zod": "^4.3.6"
52
54
  },
53
55
  "devDependencies": {