@rezti/dsh-rez-suite 0.1.49 → 0.1.51

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 (142) hide show
  1. package/CHANGELOG.md +13 -2
  2. package/README.md +3 -3
  3. package/README.zh.md +2 -2
  4. package/cordis.patch.yml +1 -1
  5. package/lib/client.d.ts +31 -3
  6. package/lib/client.js +343 -7
  7. package/lib/index.js +244 -15
  8. package/lib/style.css +7 -0
  9. package/package.json +12 -11
  10. package/src/boss/mount.ts +4 -3
  11. package/src/boss/register.ts +1 -1
  12. package/src/boss/seed.ts +34 -0
  13. package/src/changelog.ts +48 -0
  14. package/src/channel-board.ts +55 -0
  15. package/src/client/locales.ts +62 -6
  16. package/src/client/panel/BoardTab.tsx +136 -0
  17. package/src/client/panel/ConfigTab.tsx +2 -2
  18. package/src/client/panel/StatusTab.tsx +31 -0
  19. package/src/client/panel/panel.module.css +7 -0
  20. package/src/client/settings-card.tsx +4 -1
  21. package/src/index.ts +3 -2
  22. package/src/protocol.ts +14 -0
  23. package/src/routes.ts +7 -1
  24. package/src/tools.ts +49 -6
  25. package/src/wecom-cli.ts +125 -0
  26. package/templates/boss/ops/AGENTS.md +2 -0
  27. package/templates/shared/wecom-cli.SOURCE.md +9 -0
  28. package/templates/shared/wecom-office/SKILL.md +32 -0
  29. package/templates/shared/wecomcli-calendar/SKILL.md +303 -0
  30. package/templates/shared/wecomcli-calendar/references/calendar-agenda.md +224 -0
  31. package/templates/shared/wecomcli-calendar/references/calendar-cancel.md +108 -0
  32. package/templates/shared/wecomcli-calendar/references/calendar-create.md +238 -0
  33. package/templates/shared/wecomcli-calendar/references/calendar-freebusy.md +207 -0
  34. package/templates/shared/wecomcli-calendar/references/calendar-meeting-room.md +170 -0
  35. package/templates/shared/wecomcli-calendar/references/calendar-search.md +206 -0
  36. package/templates/shared/wecomcli-calendar/references/calendar-update.md +272 -0
  37. package/templates/shared/wecomcli-contact/SKILL.md +58 -0
  38. package/templates/shared/wecomcli-disk/SKILL.md +389 -0
  39. package/templates/shared/wecomcli-doc/SKILL.md +137 -0
  40. package/templates/shared/wecomcli-doc/references/doc-contents-append.md +20 -0
  41. package/templates/shared/wecomcli-doc/references/doc-contents-overwrite.md +27 -0
  42. package/templates/shared/wecomcli-doc/references/doc-create.md +161 -0
  43. package/templates/shared/wecomcli-doc/scripts/build_docx.py +1375 -0
  44. package/templates/shared/wecomcli-doc-manage/SKILL.md +132 -0
  45. package/templates/shared/wecomcli-doc-manage/references/doc-members-update.md +24 -0
  46. package/templates/shared/wecomcli-doc-manage/references/doc-names-update.md +20 -0
  47. package/templates/shared/wecomcli-doc-manage/references/doc-rules-update.md +22 -0
  48. package/templates/shared/wecomcli-email/SKILL.md +218 -0
  49. package/templates/shared/wecomcli-email/references/forward-mail.md +131 -0
  50. package/templates/shared/wecomcli-email/references/get-mail.md +166 -0
  51. package/templates/shared/wecomcli-email/references/reply-mail.md +138 -0
  52. package/templates/shared/wecomcli-email/references/search-mail.md +111 -0
  53. package/templates/shared/wecomcli-email/references/security.md +53 -0
  54. package/templates/shared/wecomcli-email/references/send-mail.md +186 -0
  55. package/templates/shared/wecomcli-email/references/send-schedule.md +83 -0
  56. package/templates/shared/wecomcli-media/SKILL.md +98 -0
  57. package/templates/shared/wecomcli-meeting/SKILL.md +373 -0
  58. package/templates/shared/wecomcli-meeting/references/meeting-cancel.md +113 -0
  59. package/templates/shared/wecomcli-meeting/references/meeting-create.md +167 -0
  60. package/templates/shared/wecomcli-meeting/references/meeting-list.md +226 -0
  61. package/templates/shared/wecomcli-meeting/references/meeting-original-get.md +98 -0
  62. package/templates/shared/wecomcli-meeting/references/meeting-search.md +173 -0
  63. package/templates/shared/wecomcli-meeting/references/meeting-update.md +217 -0
  64. package/templates/shared/wecomcli-message/SKILL.md +200 -0
  65. package/templates/shared/wecomcli-shared/SKILL.md +73 -0
  66. package/templates/shared/wecomcli-sheet/SKILL.md +172 -0
  67. package/templates/shared/wecomcli-sheet/references/sheet-contents-update.md +47 -0
  68. package/templates/shared/wecomcli-sheet/references/sheet-ranges-get.md +45 -0
  69. package/templates/shared/wecomcli-sheet/references/sheet-rows-append.md +45 -0
  70. package/templates/shared/wecomcli-sheet/references/sheet-subsheets-add.md +26 -0
  71. package/templates/shared/wecomcli-sheet/references/sheet-subsheets-delete.md +20 -0
  72. package/templates/shared/wecomcli-smartpage/SKILL.md +170 -0
  73. package/templates/shared/wecomcli-smartpage/references/data-driven-pages.md +50 -0
  74. package/templates/shared/wecomcli-smartpage/references/formula/arraylist.md +369 -0
  75. package/templates/shared/wecomcli-smartpage/references/formula/datetime.md +283 -0
  76. package/templates/shared/wecomcli-smartpage/references/formula/logic.md +247 -0
  77. package/templates/shared/wecomcli-smartpage/references/formula/math.md +362 -0
  78. package/templates/shared/wecomcli-smartpage/references/formula/operators.md +246 -0
  79. package/templates/shared/wecomcli-smartpage/references/formula/pageblock.md +76 -0
  80. package/templates/shared/wecomcli-smartpage/references/formula/templates.md +410 -0
  81. package/templates/shared/wecomcli-smartpage/references/formula/text.md +377 -0
  82. package/templates/shared/wecomcli-smartpage/references/formula/user.md +22 -0
  83. package/templates/shared/wecomcli-smartpage/references/formula-reference.md +192 -0
  84. package/templates/shared/wecomcli-smartpage/references/mdx-syntax.md +739 -0
  85. package/templates/shared/wecomcli-smartpage/references/smartpage-edit.md +506 -0
  86. package/templates/shared/wecomcli-smartsheet/SKILL.md +154 -0
  87. package/templates/shared/wecomcli-smartsheet/assets/templates/README.md +53 -0
  88. package/templates/shared/wecomcli-smartsheet/assets/templates/ai_efficiency.md +709 -0
  89. package/templates/shared/wecomcli-smartsheet/assets/templates/connect_to_app.md +380 -0
  90. package/templates/shared/wecomcli-smartsheet/assets/templates/financial_accounting.md +369 -0
  91. package/templates/shared/wecomcli-smartsheet/assets/templates/hr_and_administration.md +475 -0
  92. package/templates/shared/wecomcli-smartsheet/assets/templates/ledger_records.md +156 -0
  93. package/templates/shared/wecomcli-smartsheet/assets/templates/manufacturing.md +395 -0
  94. package/templates/shared/wecomcli-smartsheet/assets/templates/marketing.md +186 -0
  95. package/templates/shared/wecomcli-smartsheet/assets/templates/office_essentials.md +299 -0
  96. package/templates/shared/wecomcli-smartsheet/assets/templates/personal_efficiency.md +70 -0
  97. package/templates/shared/wecomcli-smartsheet/assets/templates/procurement_logistics.md +325 -0
  98. package/templates/shared/wecomcli-smartsheet/assets/templates/project_management.md +564 -0
  99. package/templates/shared/wecomcli-smartsheet/assets/templates/rd_process_customer.md +222 -0
  100. package/templates/shared/wecomcli-smartsheet/assets/templates/rd_process_ops.md +105 -0
  101. package/templates/shared/wecomcli-smartsheet/assets/templates/rd_process_project.md +109 -0
  102. package/templates/shared/wecomcli-smartsheet/assets/templates/rd_process_research.md +92 -0
  103. package/templates/shared/wecomcli-smartsheet/assets/templates/sales_and_operations.md +446 -0
  104. package/templates/shared/wecomcli-smartsheet/assets/templates/store_management.md +431 -0
  105. package/templates/shared/wecomcli-smartsheet/assets/templates/team_tasks.md +274 -0
  106. package/templates/shared/wecomcli-smartsheet/assets/templates/wechat_customer.md +384 -0
  107. package/templates/shared/wecomcli-smartsheet/assets/templates/work_report.md +100 -0
  108. package/templates/shared/wecomcli-smartsheet/references/common.md +143 -0
  109. package/templates/shared/wecomcli-smartsheet/references/smart-sheet-chart-types.md +95 -0
  110. package/templates/shared/wecomcli-smartsheet/references/smart-sheet-edit.md +589 -0
  111. package/templates/shared/wecomcli-smartsheet/references/smart-sheet-field-types.md +438 -0
  112. package/templates/shared/wecomcli-smartsheet/references/smart-sheet-formula.md +845 -0
  113. package/templates/shared/wecomcli-smartsheet/references/smart-sheet-read.md +391 -0
  114. package/templates/shared/wecomcli-smartsheet/references/smart-sheet-record-values.md +201 -0
  115. package/templates/shared/wecomcli-smartsheet/references/smart-sheet-view-types.md +356 -0
  116. package/templates/shared/wecomcli-smartsheet/references/smart-sheet-webhook-examples.md +176 -0
  117. package/templates/shared/wecomcli-smartsheet/references/smart-sheet-webhook.md +169 -0
  118. package/templates/shared/wecomcli-todo/SKILL.md +76 -0
  119. package/templates/shared/wecomcli-todo/references/todo-create.md +137 -0
  120. package/templates/shared/wecomcli-todo/references/todo-delete.md +63 -0
  121. package/templates/shared/wecomcli-todo/references/todo-finish.md +72 -0
  122. package/templates/shared/wecomcli-todo/references/todo-get.md +66 -0
  123. package/templates/shared/wecomcli-todo/references/todo-list.md +133 -0
  124. package/templates/shared/wecomcli-todo/references/todo-update.md +112 -0
  125. package/templates/staff/design/AGENTS.md +2 -1
  126. package/templates/staff/ecommerce/.agents/skills/ops-ecommerce/SKILL.md +6 -0
  127. package/templates/staff/ecommerce/AGENTS.md +49 -0
  128. package/templates/staff/ecommerce/BOOTSTRAP.md +23 -0
  129. package/templates/staff/ecommerce/IDENTITY.md +8 -0
  130. package/templates/staff/ecommerce/MEMORY.md +9 -0
  131. package/templates/staff/ecommerce/PRIORITIES.md +3 -0
  132. package/templates/staff/ecommerce/SOUL.md +5 -0
  133. package/templates/staff/ecommerce/USER.md +8 -0
  134. package/templates/staff/hr/.agents/skills/staff-onboard-keys/SKILL.md +3 -3
  135. package/templates/staff/publish/.agents/skills/ops-publish/SKILL.md +6 -0
  136. package/templates/staff/publish/AGENTS.md +59 -0
  137. package/templates/staff/publish/BOOTSTRAP.md +23 -0
  138. package/templates/staff/publish/IDENTITY.md +8 -0
  139. package/templates/staff/publish/MEMORY.md +9 -0
  140. package/templates/staff/publish/PRIORITIES.md +3 -0
  141. package/templates/staff/publish/SOUL.md +6 -0
  142. package/templates/staff/publish/USER.md +8 -0
@@ -0,0 +1,76 @@
1
+ ---
2
+ name: wecomcli-todo
3
+ description: 管理企业微信待办,支持创建、删除或退出、完成、查询和筛选,以及修改标题、描述、参与人名单和截止时间。
4
+
5
+ metadata:
6
+ requires:
7
+ bins: ["wecom-cli"]
8
+ ---
9
+
10
+ # 企业微信待办管理
11
+
12
+ > 执行任何 `wecom-cli` 命令前,必须先读取并完成 `wecomcli-shared` 技能的公共前置检查。
13
+
14
+ 使用 `wecom-cli` 管理企业微信待办。
15
+
16
+ ## 查询与定位
17
+
18
+ - 查询范围仅限企业微信待办系统中已经存在的记录。
19
+ - 可按创建时间、截止时间、完成状态和标题/描述关键词查询;关键词是字面匹配,不是语义搜索。
20
+ - 用户问"我有哪些待办""未完成待办有哪些"或"接下来有哪些待办"时,使用 `todo list` 查询待办系统中的记录。
21
+ - 删除、完成或更新时,若上下文没有 `todo_id`,先用 `todo list` 定位;已有 `todo_id` 且需要确认最新详情或状态时,使用 `todo get`。
22
+
23
+ ## 接口路由表
24
+
25
+ **[重要事项]** 执行任何操作前,必须先定位「接口路由表」指向的参考文档并完整读取,再执行命令,避免出现参数错误。严禁凭路由表描述或自身记忆猜测拼参数。
26
+
27
+ | 用户意图 | 参考位置 |
28
+ |---|---|
29
+ | 创建待办(可选分派) | references/todo-create.md |
30
+ | 删除待办 / 退出待办 / 从我的待办中移除 | references/todo-delete.md |
31
+ | 完成当前用户自己的部分 / 将整条待办全部完成 | references/todo-finish.md |
32
+ | 已有 `todo_id` 时确认待办详情和最新状态 | references/todo-get.md |
33
+ | 查看待办列表;按创建时间、截止时间、完成状态或关键词筛选;为后续操作定位待办 | references/todo-list.md |
34
+ | 修改待办内容 / 分派人名单 / 截止时间(不含参与人状态) | references/todo-update.md |
35
+
36
+ ## `deadline` 对象规范
37
+
38
+ 待办的截止时间统一以 `deadline` 对象表达。涉及"设置截止时间"、"修改截止时间"、"清空截止时间"或读取待办的截止信息时,按本节规范处理。
39
+
40
+ ### 结构
41
+
42
+ | 字段 | 类型 | 必填 | 语义 |
43
+ |---|---|---|---|
44
+ | `type` | string | 是 | 枚举:`date`(仅日期,如果用户没有提及具体时分秒,则一定选择`date`) / `datetime`(用户提及了具体时刻) |
45
+ | `value` | string | 是 | `type=date` 时格式 `YYYY-MM-DD`;`type=datetime` 时格式 `YYYY-MM-DD HH:mm:ss` |
46
+
47
+ ### 在 deadline / remind_at_deadline 字段上的语义
48
+
49
+ - **设置或修改 `deadline`**:整体可选;若提供则其内部 `type` 与 `value` 必填。
50
+ - **清空已设置的截止时间**:将 `deadline` 字段更新为空对象 `{}`;不更新该字段则保持原值不变。
51
+ - **作为返回字段**:未设置截止时间的待办,`deadline` 字段不返回或为 `null`。
52
+ - **提醒时机(`remind_at_deadline`)**:`remind_at_deadline` 与 `deadline` 是一对,必须一起出现——脱离 `deadline` 单独传 `remind_at_deadline` 不会生效,不要这么传。`remind_at_deadline` 只决定提醒**时机**,入参层面**没有"关闭提醒"这一档**(是否真正提醒由后台判断,可能因不满足条件而不提醒,以返回的 `extra_info` 为准):
53
+ - `remind_at_deadline=true`(仅 `deadline.type=datetime` 可传)→ 在**截止时刻**提醒。
54
+ - `remind_at_deadline=false` 或不传 → 按**后台默认的提前时间**提醒(**不是关闭提醒**)。
55
+ - `deadline.type=date` 或未传 `deadline` 时不要传 `true`。
56
+
57
+ ### 从用户输入推断 `deadline`
58
+
59
+ 日期/星期直接限定待办中的任务或事件时,也视为截止日期。例如"周三开会要带笔记本"应将周三写入 `deadline`。
60
+
61
+ 1. **待办提醒时间 = 截止时间**:明确要"定时提醒的待办 / 到某时提醒的待办 / 待办提醒"且给出具体时刻时,用户预期提醒时间落为 `deadline.type=datetime`,并传 `remind_at_deadline=true`;只给日期或未给提醒/截止时间时不追问,不传 `remind_at_deadline=true`。
62
+ 2. **普通截止时间**:只说截止/到期时间,或给出任务发生日期时,仅填写 `deadline`、不传 `remind_at_deadline`;此时按后台默认提前时间提醒。
63
+ 3. **时间格式**:具体截止/提醒时刻 → `deadline.type=datetime`、`value="YYYY-MM-DD HH:mm:ss"`;只有截止日期 → `type=date`、`value="YYYY-MM-DD"`。
64
+ 4. **未提截止/提醒或任务发生时间**:`deadline` 整体不传,`remind_at_deadline` 也不传,不追问。
65
+ 5. **xx 时间截止,并提前 yy 提醒**:`deadline` 永远填用户说的 xx 截止时间,不要填提前后的提醒时间。当前入参不能直接设置"提前 yy";创建/更新后用返回的 `extra_info` 判断系统提醒时间是否刚好满足 yy,不满足或无 `extra_info` 时回复:`目前不支持直接创建您需要的提醒时间,已为您设置截止时间为 XX,请到企业微信待办功能中手动修改提醒时间。`(XX 填本次 `deadline.value`)
66
+
67
+
68
+ ### 示例
69
+
70
+ ```json
71
+ { "type": "date", "value": "2026-05-08" }
72
+ { "type": "datetime", "value": "2026-05-08 09:00:00" }
73
+ ```
74
+
75
+ ### 特别注意
76
+ - 禁止将 `todo_id`(待办 ID)展示给用户。
@@ -0,0 +1,137 @@
1
+ # 创建待办 — `wecom-cli todo create`
2
+
3
+ 以当前用户为发起人创建待办,可指定分派人并设置截止时间。
4
+
5
+ ## 意图前置判断(在调用接口之前必须做)
6
+
7
+ "创建"类请求进入本技能前,先判断它是否真的属于待办:
8
+
9
+ - **消息里显式出现"待办"二字**(如"创建一条待办"、"添加待办"、"帮我记一个待办"、"把这事记到待办里")→ 在本技能内执行创建。
10
+ - **全局提醒路由已选"待办",或明确是"定时提醒的待办 / 待办提醒 / 创建待办并提醒"** → 在本技能内执行创建;若原话给出具体提醒时刻,则该时刻 = `deadline.type=datetime`,并传 `remind_at_deadline=true`;只给日期则可填 `deadline.type=date`,不追问且不传 `remind_at_deadline=true`;未给提醒/截止时间则不传 `deadline` / `remind_at_deadline`。
11
+ - **泛提醒但未明确要求创建企业微信待办** → 不要在本技能内擅自创建待办;先由上层路由确定承载方式。
12
+
13
+ ## 命令
14
+
15
+ ```bash
16
+ wecom-cli todo create --json '<JSON 参数>'
17
+ ```
18
+
19
+ ## 参数
20
+
21
+ 外层为对象,待办放在 `items` 数组中:
22
+
23
+ | 字段 | 类型 | 必填 | 语义 |
24
+ |---|---|---|---|
25
+ | `items` | array | 是 | 待办数组,每项结构见下,支持批量,单次最多 20 条;超出需分批 |
26
+
27
+ `items[]` 元素结构:
28
+
29
+ | 字段 | 类型 | 必填 | 默认值 | 语义 |
30
+ |---|---|---|---|---|
31
+ | `title` | string | 是 | — | 短标题,长度 >= 1 |
32
+ | `description` | string | 否 | — | 详细描述(可选的展开说明,不是标题)|
33
+ | `follower_ids` | string[] | 否 | `[]` | 分派人 userid 列表(前缀 `wo`),最多 50 人;用户给姓名时先通过 `wecomcli-contact` 技能查 `userid` |
34
+ | `deadline` | object | 否 | — | 截止时间。结构见 SKILL.md `deadline` 对象规范 |
35
+ | `remind_at_deadline` | boolean | 否 | `false` | 提醒时机,须与 `deadline` 同传:`true`=截止时刻提醒(仅 `datetime`);`false`/不传=按后台默认提前时间提醒(**非关闭提醒**)。脱离 `deadline` 单独传无效 |
36
+
37
+ `deadline` 整体可选;若提供则其内部 `type` 与 `value` 必填。
38
+
39
+ ## 从用户消息推断字段
40
+
41
+ 调用本命令前,按以下规则从用户原话里提取参数。除非真的提不出,**不要**用追问让用户重新说一遍——他刚才已经把事情讲清楚了,再问一次是劣体验。
42
+
43
+ ### 推断 `title`(必填)
44
+
45
+ 绝大多数情况下能从用户消息里提炼出标题。优先采用"动宾"结构,尽量保持用户的原始表达。当标题过长,非常细节的背景细节才放进 `description`。
46
+
47
+ **只有当用户消息里完全没有任何任务内容时**(例如只说"帮我记个待办"、"加一条待办",完全没讲事情本身),才向用户追问"要记什么事?"。哪怕只有一个动作或一个对象,也要先自己提炼,不要追问。
48
+
49
+ ### 推断 `description`(可选,多数情况不传)
50
+
51
+ `description` 是**标题之外的补充说明**,只在用户给了标题装不下的额外细节(背景、要求、上下文)时才填写。
52
+
53
+ - **禁止把 `description` 写成与 `title` 相同或仅是 title 的复述**。如果提炼完标题后没有任何额外信息,就**不传** `description`——一条只有标题的待办是完全正常的,硬塞一个和标题一样的 description 属于冗余噪声。
54
+ - 用户用"内容是 / 就是 / 记一下 XX"等方式描述事情时,这通常就是在给**标题**,不是在额外补充描述:先把它提炼成 `title`;只有当它明显比标题多出独立信息时,多出来的部分才放进 `description`。
55
+ - 从当前会话上下文或待办查询结果批量创建待办时,不要只沿用概括标题;若上下文里已有明确的下一步动作、对接人、时间节点、链接或单号,应压缩写入 `description`。不确定的信息不要编造,也不要为了补全而反复追问。
56
+
57
+ ### 推断 `follower_ids`
58
+
59
+ 用户提到要分派给自己时(如"分派给我"、"我和 vincentwei 一起"),要把当前用户自己的 `userid` 也放进 `follower_ids`,因为后台不会自动把创建者算作分派人。但是如果是给我自己创建,没有其他参与人,就不用把我自己也放进去。
60
+
61
+ 当用户表述中暗示某人与待办有参与或关联关系(如"与某人相关的待办""关于某人""和某人一起跟进"),应将关联人加入 `follower_ids`。
62
+
63
+ ### 推断 `deadline` 与待办提醒
64
+
65
+ - `remind_at_deadline` 必须与 `deadline` 一起传,只用来选提醒时机("提前"还是"截止时");脱离 `deadline` 单独传无效。入参层面没有"关闭提醒"这一档,但是否真正提醒由后台判断,以返回的 `extra_info` 为准。
66
+ - 用户只说**截止时间/到期时间**,或给出任务发生日期时,填写 `deadline`,不要传 `remind_at_deadline`(即按后台默认提前时间提醒)。
67
+ - 用户明确要**提醒/到点提醒/截止时提醒/待办提醒**且给出具体时刻时,提醒时刻即 `deadline.type=datetime`,同时传 `remind_at_deadline=true`;只给日期时不传 `remind_at_deadline=true`。
68
+ - 用户说"xx 时间截止的待办,并提前 yy 提醒"时,`deadline` 永远填 **xx 截止时间**,不要填提前后的提醒时间。当前入参不能直接设置"提前 yy";创建后用返回的 `extra_info` 判断系统提醒时间是否刚好满足 yy。
69
+ - 未提任何与任务完成节点相关的时间时才不传 `deadline` / `remind_at_deadline`;不要追问,走默认参数。
70
+
71
+ `type` / `value` 的完整格式与示例见 SKILL.md `deadline` 对象规范。
72
+
73
+ ## 示例入参
74
+
75
+ 创建带截止时提醒的待办:
76
+
77
+ ```json
78
+ {
79
+ "items": [
80
+ {
81
+ "title": "准备周会材料",
82
+ "description": "本周三上午周会需要的销售数据 PPT",
83
+ "follower_ids": ["wo_xxx"],
84
+ "deadline": {
85
+ "type": "datetime",
86
+ "value": "2026-05-13 09:00:00"
87
+ },
88
+ "remind_at_deadline": true
89
+ }
90
+ ]
91
+ }
92
+ ```
93
+
94
+ ## 返回
95
+
96
+ 外层为对象,结果在 `items` 数组中,与入参 `items` 一一对应:
97
+
98
+ | 字段 | 类型 | 语义 |
99
+ |---|---|---|
100
+ | `items` | array | 创建结果数组 |
101
+
102
+ `items[]` 元素结构:
103
+
104
+ | 字段 | 类型 | 语义 |
105
+ |---|---|---|
106
+ | `success` | boolean | 此待办是否创建成功 |
107
+ | `todo_id` | string | 待办 ID(前缀 `td`),仅成功时返回 |
108
+ | `title` | string | 待办标题 |
109
+ | `followers` | array | 分派人列表,每项含 `userid` 和 `user_name`(格式 `英文名(中文名)`)|
110
+ | `extra_info` | string | 提醒时刻只读信息,可能不提醒 |
111
+ | `errmsg` | string | 单条创建失败原因,仅 `success=false` 时存在 |
112
+
113
+ ## 给用户的反馈
114
+
115
+ ### 回显创建结果
116
+
117
+ 创建成功后,回复里要把这条待办回显给用户便于核对,**标题、参与人、截止时间**这三项都要体现(不存在的项缺省即可,不要硬写"无"):
118
+
119
+ - **标题**:取返回的 `title`。
120
+ - **参与人**:取返回 `followers[].user_name`,多人用 `、` 拼接;无分派人或仅创建者本人时缺省。只展示人名,不要出现 `userid`。
121
+ - **截止时间**:取**本次入参**的 `deadline.value`——返回体不回传 `deadline`,必须用刚提交的值;未设置截止时间时缺省。
122
+
123
+ 批量创建时逐条回显。示例:
124
+
125
+ > 已创建待办「准备周会材料」,参与人:张三、李四,截止时间:2026-05-13 09:00:00。
126
+
127
+ ### 提醒说明
128
+
129
+ 创建成功且本次传了 `remind_at_deadline=true` 或用户提到提醒诉求时,**必须**在回显之后附上提醒说明(注意 `remind_at_deadline` 只对 datetime 生效):
130
+
131
+ - 用户要求"提前 X 提醒"时,核对 `extra_info` 是否为用户要求的提前提醒时间(即截止时间提前 X 后的时刻);匹配则说明已满足,不匹配或无 `extra_info` 则按固定话术说明:`目前不支持直接创建您需要的提醒时间,已为您设置截止时间为 XX,请到企业微信待办功能中手动修改提醒时间。`(XX 填本次 `deadline.value`)。
132
+ - 用户要求"截止时/到点提醒"时,只有 `deadline.type=datetime` 才应传 `remind_at_deadline=true`;若 `extra_info` 不等于 `deadline.value` 或缺失,仍需引导到企业微信待办功能中修改提醒时间。
133
+ - 返回里有 `extra_info`(且非"提前 X 提醒"场景)→ 引用 `extra_info` 里的时刻告诉用户届时会自动提醒。
134
+ - 返回里没有 `extra_info`(且非"提前 X 提醒"场景)→ 说明返回未确认提醒时间,引导用户到企业微信待办应用中检查/修改提醒时间。
135
+ - 不要另建定时任务来模拟待办提醒,避免重复提醒。
136
+
137
+ 仅带 `deadline` 但未要求提醒的普通待办,无需额外提醒说明。
@@ -0,0 +1,63 @@
1
+ # 删除/退出待办 — `wecom-cli todo delete`
2
+
3
+ 删除或退出指定待办,语义取决于当前用户是否为创建人:
4
+
5
+ - **当前用户是创建人**:删除整条待办,其他参与人也不再继续看到/处理这条待办。
6
+ - **当前用户不是创建人**:允许调用同一个 `delete` 接口,表现为**当前用户退出待办 / 从自己的待办中移除**,不是删除整条待办,也不会影响其他参与人。
7
+
8
+ ## 命令
9
+
10
+ ```bash
11
+ wecom-cli todo delete --json '<JSON 参数>'
12
+ ```
13
+
14
+ ## 参数
15
+
16
+ 外层为对象,待办放在 `items` 数组中:
17
+
18
+ | 字段 | 类型 | 必填 | 语义 |
19
+ |---|---|---|---|
20
+ | `items` | array | 是 | 待办数组,每项结构见下,单次最多 20 条;超出需分批 |
21
+
22
+ `items[]` 元素结构:
23
+
24
+ | 字段 | 类型 | 必填 | 默认值 | 语义 |
25
+ |---|---|---|---|---|
26
+ | `todo_id` | string | 是 | — | 待办 ID,前缀 `td` |
27
+
28
+ 示例入参:
29
+
30
+ ```json
31
+ {
32
+ "items": [
33
+ { "todo_id": "td_xxx" },
34
+ { "todo_id": "td_yyy" }
35
+ ]
36
+ }
37
+ ```
38
+
39
+ ## 返回
40
+
41
+ 外层为对象,结果在 `items` 数组中,与入参 `items` 一一对应:
42
+
43
+ | 字段 | 类型 | 语义 |
44
+ |---|---|---|
45
+ | `items` | array | 删除/退出结果数组 |
46
+
47
+ `items[]` 元素结构:
48
+
49
+ | 字段 | 类型 | 语义 |
50
+ |---|---|---|
51
+ | `success` | boolean | 是否删除成功 |
52
+ | `todo_id` | string | 待办 ID |
53
+ | `title` | string | 待办标题 |
54
+ | `errmsg` | string | 失败原因,仅 `success=false` 时存在 |
55
+
56
+ ## 使用规则
57
+
58
+ - 用户说某待办"已完成"时,默认是完成操作,不等于删除;只有用户明确说删除,才调用本接口删除。
59
+ - **非创建人也可以删除,语义是退出待办**:不要因为 `creator.userid` 不是当前用户就拒绝,也不要回复"创建人之外无权删除"之类的话术。调用 `delete` 前仍应核对创建人,但目的只是理解本次操作语义和做幂等判断:
60
+ - `creator.userid` 等于当前用户 → 调用 `wecom-cli todo delete`,语义是删除整条待办。
61
+ - `creator.userid` 不等于当前用户 → 调用 `wecom-cli todo delete`,语义是当前用户退出该待办 / 从自己的待办中移除。
62
+ - **如果上下文没有对应待办 ID**:**必须**先阅读 `references/todo-list.md`,学习如何获取待办列表,在待办列表中找到需要删除/退出的待办(列表返回里带 `creator` 和 `user_status`,用于判断最终话术和幂等)。查询时需要同时查找未完成和已完成的待办。
63
+ - **禁止将 `todo_id` 展示给用户**。
@@ -0,0 +1,72 @@
1
+ # 完成待办 — `wecom-cli todo finish`
2
+
3
+ 将**当前用户**在该待办中的部分标记为"已完成"。如果当前用户同时是创建人,后台会返回 `ask_finish_all` 提示,可选择把所有参与人一并标记完成。
4
+
5
+ ## 命令
6
+
7
+ ```bash
8
+ wecom-cli todo finish --json '<JSON 参数>'
9
+ ```
10
+
11
+ ## 参数
12
+
13
+ 外层为对象,待办放在 `items` 数组中:
14
+
15
+ | 字段 | 类型 | 必填 | 语义 |
16
+ |---|---|---|---|
17
+ | `items` | array | 是 | 待办数组,每项结构见下,单次最多 20 条;超出需分批 |
18
+
19
+ `items[]` 元素结构:
20
+
21
+ | 字段 | 类型 | 必填 | 默认值 | 语义 |
22
+ |---|---|---|---|---|
23
+ | `todo_id` | string | 是 | — | 待办 ID |
24
+ | `finished_all` | boolean | 否 | `false` | 创建人可设为 `true` 全部完成该待办。默认 `false` 仅完成自己的部分 |
25
+
26
+ 示例入参:
27
+
28
+ ```json
29
+ {
30
+ "items": [
31
+ {
32
+ "todo_id": "td_xxx",
33
+ "finished_all": false
34
+ }
35
+ ]
36
+ }
37
+ ```
38
+
39
+ ## 返回
40
+
41
+ 外层为对象,结果在 `items` 数组中,与入参 `items` 一一对应:
42
+
43
+ | 字段 | 类型 | 语义 |
44
+ |---|---|---|
45
+ | `items` | array | 完成结果数组 |
46
+
47
+ `items[]` 元素结构:
48
+
49
+ | 字段 | 类型 | 语义 |
50
+ |---|---|---|
51
+ | `success` | boolean | 是否完成成功 |
52
+ | `todo_id` | string | 待办 ID |
53
+ | `title` | string | 待办标题 |
54
+ | `ask_finish_all` | string | 当后台检测到用户既是创建人又是参与人时返回,提示模型询问用户是否标记为"全部完成" |
55
+ | `errmsg` | string | 失败原因,仅 `success=false` 时存在 |
56
+
57
+ ## 使用规则
58
+
59
+ - **如果上下文没有对应待办 ID**:**必须**先阅读 `references/todo-list.md`,学习如何获取待办列表,在待办列表中找到需要完成的待办;此时应同时查 `finished` 和 `proceed`。如果已有 `todo_id` 但需要确认最新状态,使用 `wecom-cli todo get`。
60
+ - **完成操作要幂等**:定位待办时如果发现该待办整体 `status=finished` 或当前用户 `user_status=finished`,说明已完成,直接告知用户"这条待办已完成",不要再调用 `finish`。只有用户本次或本会话前文明确要求"完成后删除/清掉/自动删除"时,才继续按删除流程处理。
61
+ - 调用前先按用户语义决定 `finished_all`:
62
+ - 用户明确表达"仅我完成自己的部分"("我这边搞完了"、"我自己的部分先完成"、"先把我那块标了")→ **显式**传 `finished_all: false`。显式 false 才能让后端跳过 `ask_finish_all` 兜底,避免再次询问完成范围。
63
+ - 用户明确表达"全部完成"("完成了"、"这条结掉"、"都搞完了"),或本会话此前对同一个 `todo_id` 已经调过一次 `finished_all=false`、用户现在又一次说要完成它 → 传 `finished_all: true`。
64
+ - 表达不明确(只说"完成 XX 待办"、"把那条待办完成了",没有"仅我"或"全部"的语气)→ 不传 `finished_all`,让后端按下方 `ask_finish_all` 流程返回是否需要确认。
65
+ - **`ask_finish_all` 处理流程**:如果返回中出现 `ask_finish_all` 字段,说明当前用户是创建人,第一次调用已把当前用户自己的部分标记完成;**必须**用简洁自然语言向用户确认是否把其他参与人也一并标记完成,并在文字中列出「仅我完成」「已完全完成」两个选项。提问中应包含待办标题和 `followers` 中的参与人中文名(用顿号"、"拼接),例如:
66
+ ```
67
+ 待办「<待办标题>」中您的部分已完成。参与人:<参与人中文名>。请选择完成范围:仅我完成,还是已完全完成?
68
+ ```
69
+ - 用户选 **「仅我完成」** → 不再调用接口(第一次已经完成了自己的部分),告知用户已标记完成。
70
+ - 用户选 **「已完全完成」** → 用同一个 `todo_id` 再次调用 `wecom-cli todo finish`,并传 `finished_all: true`。
71
+ - 结果 `items` 与入参 `items` 一一对应
72
+ - 禁止将 `todo_id`(待办 ID)展示给用户。
@@ -0,0 +1,66 @@
1
+ # 批量获取待办详情 — `wecom-cli todo get`
2
+
3
+ 批量查询 1-20 个待办的完整信息。
4
+
5
+ ## 命令
6
+
7
+ ```bash
8
+ wecom-cli todo get --json '<JSON 参数>'
9
+ ```
10
+
11
+ ## 参数
12
+
13
+ 外层为对象,待查待办放在 `items` 数组中:
14
+
15
+ | 字段 | 类型 | 必填 | 语义 |
16
+ |---|---|---|---|
17
+ | `items` | array | 是 | 待查待办数组,每项结构见下,单次最多 20 个;超出需分批 |
18
+
19
+ `items[]` 元素结构:
20
+
21
+ | 字段 | 类型 | 必填 | 默认值 | 语义 |
22
+ |---|---|---|---|---|
23
+ | `todo_id` | string | 是 | — | 待办 ID(前缀 `td`) |
24
+
25
+ ### 示例入参
26
+
27
+ ```json
28
+ {
29
+ "items": [
30
+ { "todo_id": "td_xxx" },
31
+ { "todo_id": "td_yyy" }
32
+ ]
33
+ }
34
+ ```
35
+
36
+ ## 返回
37
+
38
+ 外层为对象,结果在 `items` 数组中,与入参 `items` 一一对应:
39
+
40
+ | 字段 | 类型 | 语义 |
41
+ |---|---|---|
42
+ | `items` | array | 待办详情数组 |
43
+
44
+ `items[]` 元素结构:
45
+
46
+ | 字段 | 类型 | 语义 |
47
+ |---|---|---|
48
+ | `success` | boolean | 此条查询是否成功 |
49
+ | `todo_id` | string | 待办 ID(前缀 `td`) |
50
+ | `title` | string | 待办标题 |
51
+ | `description` | string | 详细描述 |
52
+ | `status` | string | 待办整体状态:`proceed` / `finished` |
53
+ | `user_status` | string | 当前用户在该待办的状态:`accept` / `reject` / `finished` / `removed` / `notshow` |
54
+ | `creator` | object | 创建人,含 `userid`(前缀 `wo`) / `user_name`(格式 `英文名(中文名)`) |
55
+ | `followers` | array | 分派人列表,每项含 `userid`(前缀 `wo`) / `user_name` / `user_status` / `update_time` |
56
+ | `deadline` | object | 截止时间;结构见 SKILL.md `deadline` 对象规范。无截止时间时不返回或为 `null` |
57
+ | `extra_info` | string | 提醒时刻只读信息,可能不提醒 |
58
+ | `source` | string | 待办来源:`single_chat`(单聊)/ `group_chat`(群聊)/ `doc`(文档)/ `ai_summary`(智能总结)/ `meeting_summary`(会议纪要)/ `face_chat`(「面聊」功能)/ `fused_doc`(融合文档)/ `smart_sheet`(智能表格)/ `smart_doc`(智能文档)/ `JSAPI`(JSAPI) |
59
+ | `create_time` | string | 创建时间,格式 `YYYY-MM-DD HH:mm:ss` |
60
+ | `update_time` | string | 更新时间,格式 `YYYY-MM-DD HH:mm:ss` |
61
+ | `errmsg` | string | 失败原因,仅 `success=false` 时存在 |
62
+
63
+ ## 使用规则
64
+
65
+ - **单次上限 20**:超出需分批请求
66
+ - **已有 `todo_id` 时确认状态用本接口**:需要核对某条待办的最新 `status` / `user_status` 时,使用 `wecom-cli todo get`。
@@ -0,0 +1,133 @@
1
+ # 按时间范围查询待办 — `wecom-cli todo list`
2
+
3
+ 按创建时间或截止时间范围拉取当前用户创建和参与的待办列表,支持按状态过滤。返回含 `title` / `description` / `followers` / `deadline` 等完整字段,多数场景无需再走本技能的「批量查询待办详情」。
4
+
5
+ 本接口用于直接查看待办列表、确认待办状态、查询特定待办,或在修改、完成、删除前定位目标待办。
6
+
7
+ ## 命令
8
+
9
+ ```bash
10
+ wecom-cli todo list --json '<JSON 参数>' [--page-count N]
11
+ ```
12
+
13
+ `--page-count N` 自动翻页并最多拉取 N 页的内容(默认 1,即只拉首页)。不传则只拉首页。注意 `--page-count` 是命令行参数,写在 `--json '...'` 之外,不要塞进 JSON 体里。
14
+
15
+ ## 参数
16
+
17
+ 查询接口不进 `items` 壳,参数直接平铺:
18
+
19
+ | 字段 | 类型 | 必填 | 默认值 | 语义 |
20
+ |---|---|---|---|---|
21
+ | `create_begin_time` | string | 否 | — | 创建时间起始,格式 `YYYY-MM-DD HH:mm:ss` |
22
+ | `create_end_time` | string | 否 | — | 创建时间截止,格式 `YYYY-MM-DD HH:mm:ss` |
23
+ | `deadline_begin_time` | string | 否 | — | 截止时间起始,格式 `YYYY-MM-DD HH:mm:ss` |
24
+ | `deadline_end_time` | string | 否 | — | 截止时间截止,格式 `YYYY-MM-DD HH:mm:ss` |
25
+ | `status_filter` | string[] | 否 | — | 状态过滤,合法枚举值只有 `finished`(已完成)、`proceed`(进行中),可多选;不传时默认只返回 `proceed`(进行中)的待办 |
26
+ | `keywords` | string[] | 否 | — | 关键词过滤,对待办文本(标题/描述)做命中匹配。数组元素之间是 **OR**,单个元素内空格分隔的词是 **AND**。语义与构造方式详见下方「keywords 语义」 |
27
+ | `limit` | integer | 否 | 10 | 单次返回数量,不传为10,最大只能传20,如果需要大量查询,应该使用自动翻页 |
28
+ | `cursor` | string | 否 | — | 分页游标,首次请求不传 |
29
+
30
+ 示例入参(按时间范围 + 状态过滤 + 关键词 + 可选的翻页参数):
31
+
32
+ ```json
33
+ {
34
+ "create_begin_time": "2026-05-01 00:00:00",
35
+ "create_end_time": "2026-05-09 23:59:59",
36
+ "status_filter": ["proceed"],
37
+ "keywords": ["报销"],
38
+ "limit": 20,
39
+ "cursor": "<上次返回的 next_cursor>"
40
+ }
41
+ ```
42
+
43
+ > 各顶层过滤条件之间是 **AND** 关系:一条待办需同时满足时间范围、状态、关键词表达式才会被返回。`keywords` 内部再按下方规则展开自己的 OR/AND 逻辑。
44
+
45
+ ## keywords 语义
46
+
47
+ `keywords` 用两层结构表达"或"与"且":
48
+
49
+ - **数组多个元素之间 = OR**:命中任意一个元素即召回。
50
+ - **单个元素内空格分隔 = AND**:该元素里的每个词都命中,才算命中这个元素。
51
+
52
+ 例:`["service ai", "claw"]` 等价于布尔表达式 `("service" AND "ai") OR "claw"`——"同时包含 service 和 ai"或"包含 claw"的待办都会被召回。
53
+
54
+ 从用户表达构造 `keywords`:
55
+
56
+ | 用户说 | keywords | 含义 |
57
+ |---|---|---|
58
+ | "包含报销的待办" | `["报销"]` | 命中"报销" |
59
+ | "同时提到项目和评审的待办" | `["项目 评审"]` | 一个元素、空格分隔 = "项目" AND "评审" |
60
+ | "提到报销,或者同时提到项目和评审的待办" | `["项目 评审", "报销"]` | `("项目" AND "评审") OR "报销"` |
61
+
62
+ ## 返回
63
+
64
+ | 字段 | 类型 | 语义 |
65
+ |---|---|---|
66
+ | `items` | array | 待办列表,每项结构见下 |
67
+ | `next_cursor` | string | 下一页游标,配合 `has_more=true` 使用 |
68
+ | `has_more` | boolean | 是否还有更多数据 |
69
+
70
+ `items[]` 元素结构:
71
+
72
+ | 字段 | 类型 | 语义 |
73
+ |---|---|---|
74
+ | `todo_id` | string | 待办 ID(前缀 `td`) |
75
+ | `title` | string | 待办标题 |
76
+ | `description` | string | 详细描述 |
77
+ | `status` | string | 待办整体状态:`finished` / `proceed` |
78
+ | `user_status` | string | 当前用户在该待办的状态:`accept` / `reject` / `finished` / `removed` / `notshow` |
79
+ | `creator` | object | 创建人,含 `userid`(前缀 `wo`) / `user_name`(格式 `英文名(中文名)`) |
80
+ | `followers` | array | 分派人列表,每项含 `userid`(前缀 `wo`) / `user_name` / `user_status` / `update_time` |
81
+ | `deadline` | object | 截止时间;结构见 SKILL.md `deadline` 对象规范。无截止时间时不返回或为 `null` |
82
+ | `extra_info` | string | 提醒时刻只读信息,可能不提醒 |
83
+ | `source` | string | 待办来源:`single_chat`(单聊)/ `group_chat`(群聊)/ `doc`(文档)/ `ai_summary`(智能总结)/ `meeting_summary`(会议纪要)/ `face_chat`(「面聊」功能)/ `fused_doc`(融合文档)/ `smart_sheet`(智能表格)/ `smart_doc`(智能文档)/ `JSAPI`(JSAPI) |
84
+ | `create_time` | string | 创建时间,格式 `YYYY-MM-DD HH:mm:ss` |
85
+ | `update_time` | string | 更新时间,格式 `YYYY-MM-DD HH:mm:ss` |
86
+
87
+ ## 使用规则
88
+
89
+ - **用户按状态查询待办时,`status_filter` 必须显式传对应状态**:本接口不传 `status_filter` 时只会返回进行中(`proceed`)的待办。用户问"已完成的待办"要传 `["finished"]`,问"所有待办(含已完成)"要传 `["finished","proceed"]`。漏传会导致已完成的待办根本不在结果里,进而把"其实有"误判成"没有"。
90
+ - **禁止用 `status_filter` 查询已删除待办**:该字段只接受 `finished` / `proceed`,不得传 `deleted`。用户要求查询已删除待办时,应直接说明当前列表接口不支持按已删除状态查询。
91
+ - **时间范围默认归到创建时间**:用户给了"5 月 1 号到 5 月 9 号""上周""本月"这类时间范围、但没点明是"创建"还是"截止"时,默认填 `create_begin_time` / `create_end_time`。一段时间范围最自然的含义是"这段时间内记下/产生的待办"。只有用户明确带"截止 / 到期 / deadline / ddl / 这之前要做完"等字样时,才改用 `deadline_begin_time` / `deadline_end_time`。
92
+ - **统计、计数、"有哪些"类需求要基于全量数据**:这类需求必须翻完所有分页(`--page-count` 取足够大,直到某页 `has_more` 为 `false`)。若结果过大被转存到文件,要把整个文件读完整再统计——只读开头几页就下结论会严重少算。
93
+ - **如果用户意图是获得所有待办**:应使用 `--page-count N` 快速拉取所有分页,直到 `has_more=false`。
94
+ - **已含完整详情**:`followers` / `creator` 已是包含人名的对象,多数场景无需再走本技能的「批量查询待办详情」或使用 `wecomcli-contact` 反查。
95
+ - **修改和完成待办时**:`status_filter` 可一次传多个状态。修改通常查进行中即可;完成或确认是否已完成时,应传 `["finished","proceed"]`,避免把已完成误判为未找到或再执行后续操作。
96
+ - **删除/退出某个待办时**:`status_filter` 应该传入 `["finished", "proceed"]`,不然可能找不到。删除接口对创建人是删除整条待办,对非创建人是退出/从自己的待办中移除;列表返回的 `creator` / `user_status` 用于判断操作语义和避免重复操作,**不要因为当前用户不是创建人就拒绝删除请求**。
97
+ - **默认只返回 10 条**:如需查全部请显式传 `limit` 为更大值,并关注 `has_more` / `next_cursor` 分页;要一次性拉多页可加 `--page-count N`。
98
+ - **`keywords` 是对待办系统记录的字面命中过滤,不是语义检索**:它只匹配待办自身的标题/描述文本。
99
+
100
+ ## 返回给用户的格式
101
+
102
+ > **适用范围**:仅当用户**直接询问待办列表**(如"我今天创建的待办")时才使用本格式。若 `list` 是被其他操作(修改 / 完成 / 删除待办时为定位 `todo_id`)内部调用,本格式不适用——按对应操作的流程返回,不要把列表展示给用户。
103
+
104
+ 将 `items` **按状态分组**呈现,每个状态分组下用 Markdown 列表展开,每条待办占多行:
105
+
106
+ ```markdown
107
+ ## 进行中(N 条)
108
+
109
+ 1. <title>
110
+ - 创建人:<creator>
111
+ - 参与人:<followers>
112
+ - 截止时间:<deadline>
113
+
114
+ ## 已完成(M 条)
115
+
116
+ 1. <title>
117
+ - 创建人:<creator>
118
+ - 参与人:<followers>
119
+ - 截止时间:<deadline>
120
+ ```
121
+
122
+ 字段映射:
123
+
124
+ - **分组标题**:按 `status` 中文化分组
125
+ - `proceed` → `## 进行中(N 条)`
126
+ - `finished` → `## 已完成(M 条)`
127
+ - 某分组无数据则整个分组省略
128
+ - **标题**:`title`
129
+ - **创建人**:`creator.user_name`,如果创建人是用户自己,则缺省
130
+ - **参与人**:`followers[].user_name` 用 `、` 拼接;无参与人时缺省
131
+ - **截止时间**:`deadline.value`;无截止时间时缺省
132
+
133
+ > 排序:分组内按 `deadline.value` 升序(无截止时间的排在最后);同一组内截止时间相同时按 `update_time` 倒序。