@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,167 @@
1
+ # 操作参考:创建会议
2
+
3
+ ## 命令
4
+
5
+ ```bash
6
+ wecom-cli meeting create --json '{...}'
7
+ ```
8
+
9
+ ## 请求参数
10
+
11
+ | 字段 | 类型 | 必填 | 说明 |
12
+ | ---------------------------- | ------- | ---- | ------------------------------------------------------ |
13
+ | `subject` | string | 是 | 会议主题 |
14
+ | `begin_time` | string | 是 | 开始时间, 格式 `YYYY-MM-DD HH:mm:ss`, 必须晚于当前时间 |
15
+ | `end_time` | string | 是 | 结束时间, 格式 `YYYY-MM-DD HH:mm:ss`, 必须晚于 `begin_time`, 且与 `begin_time` 间隔不超过 24 小时。**用户未给出时长时默认为 `begin_time` 的 1 小时后(不追问)** |
16
+ | `attendees` | array | 否 | 参会人,对象数组,格式 `[{"userid": "woxxx"}, {"userid": "woyyy"}]`(`wo` 前缀)。用户提供的是姓名时通过 `读取 wecomcli-contact 技能` 解析为 userid |
17
+ | `location` | string| 否| 会议地点(文本)。**用户给的地点是某会议室时**:须先经 `rooms search` 预订(见步骤 4),预订成功后**只传 `meeting_room_id`、不再写 `location`**(会议室名由后端关联返回,无需在 `location` 里重复填充)。**用户给的地点不是会议室时**(如"星巴克""客户现场"):直接写入 `location`,不涉及 `meeting_room_id`。禁止把会议室名仅写进 `location` 却不订房——那样不会真正占用会议室 |
18
+ | `meeting_room_id` | string | 否 | 会议室 ID,传入即触发后端"建会议 + 占会议室"原子操作。查询会议室拿此 ID 的能力不在本技能,须 `读取 wecomcli-calendar 技能` 的 [会议室查询参考](../../wecomcli-calendar/references/calendar-meeting-room.md)(`buildings list` + `rooms search`)。订会议室时只传本字段即可,**不需要再把会议室名重复填进 `location`**。**该 ID 仅工具链使用,禁止出现在用户回复正文** |
19
+ | `description` | string | 否 | 会议备注/描述 |
20
+ | `timezone` | object | 否 | 时区设置,用户指定时区时传入,未指定则不传。格式:`{"timezone_id": "Asia/Shanghai", "timezone_offset": 28800}`,`timezone_id` 为 IANA 时区标识,`timezone_offset` 为 UTC 偏移量(秒) |
21
+
22
+ > **会议室预订能力在 wecomcli-calendar 技能 [CRITICAL]**:本技能不直接定义会议室查询接口——用户提出"订会议室 / 在 1605 开 / 找个会议室 / 某栋楼的会议室"等诉求时,须 `读取 wecomcli-calendar 技能` 的 [会议室查询参考](../../wecomcli-calendar/references/calendar-meeting-room.md)(`buildings list` + `rooms search`)查到真实会议室,拿 `meeting_room_id` 传入本创建(见步骤 4)。禁止把会议室名仅写进 `location`(那样不会真正占用会议室),也禁止凭记忆 / 猜测编造 `meeting_room_id`。仅当用户给的是非会议室的普通文本地点时,才只写 `location`。
23
+
24
+ ## 返回字段
25
+
26
+ | 字段 | 说明 |
27
+ | -------------- | ------------------------ |
28
+ | `meeting_id` | 会议唯一标识 |
29
+ | `meeting_link` | 入会链接, 可分享给参会人 |
30
+ | `meeting_code` | 9 位会议号 |
31
+
32
+ ## 约束
33
+
34
+ - 开始时间必须晚于当前时间, 否则创建失败
35
+ - 结束时间 `end_time` 必须晚于 `begin_time`, 且与 `begin_time` 间隔不超过 24 小时(86400 秒)。用户要建超过 24h 的单场会议时,直接告知不支持并拒绝,禁止自行拆分成多场会议或用其他方式变通绕过;如确需多天安排,由用户明确拆分要求后再分别创建
36
+ - 参会人总数不超过 100 人
37
+ - **不支持创建周期/重复会议**:API 仅支持创建单次会议。用户希望创建"每周/每月/每天重复"等周期会议时,**直接告知用户目前不支持创建周期会议,并引导用户在企业微信客户端手动预订周期会议**;不要尝试任何变通绕过的做法——包括但不限于:批量调用 create 接口创建多条单次会议模拟周期效果、传入参数表中未列出的字段、创建后再用 update 改造为周期会议。原因:API 层根本无此能力,伪造的"周期"会议在企微客户端中也无法被识别为周期,反而会造成多条独立会议难以批量管理。
38
+ - userid(前缀为 `wo`)不接受姓名直接传入;用户提供的是姓名时通过 `读取 wecomcli-contact 技能` 解析为 userid,禁止把姓名当 userid 拼接,禁止凭记忆或猜测编造
39
+ - 时区字段(`timezone`)仅在用户明确指定时区时传入,否则省略
40
+
41
+ ## 工作流
42
+
43
+ ### 正常路径
44
+
45
+ 0. **日程 / 会议消歧(仅当用户说"会议/会/开会/约会/xx会"且未明确时)**:用户未明确是日程还是会议(会议含在线会议链接、可远程/视频参会)时,必须先用文字追问,禁止默认直接创建会议。已明确是会议的场景(如"发个入会链接""要会议号""视频会议""远程参会")时才跳过本步骤。
46
+
47
+ > **注意 1**:用户只说"会议/会/开会"等泛称,本身不构成"明确"——这些词没有表明是日程还是会议,**禁止仅因 query 里有"会议"二字就默认走会议创建、跳过本步骤**,必须先用文字追问。
48
+ >
49
+ > **注意 2**:仅给出地点/会议室号的表述(如"在 1605 开会""到 A 座会议室碰一下""订个会议室开会")不构成"明确是会议"——会议室里同样可能只是纯线下安排,是日程还是会议仍未知。此类"只有地点"的表述仍需先用文字询问消歧,不要因为带了地点就跳过本步骤。
50
+ > **问题与选项固定 [CRITICAL]**:消歧确认时,问题与可选项都必须原文照用、严格禁止修改任何内容——问题固定为 `"需要创建日程还是会议?"`,可选项固定为 `日程` / `会议`;不得改写问题措辞、增减或改写选项、翻译,或自行设计其他表述(如"在线会议 / 线上会议 / 视频会议 / 线下会议"等)。
51
+
52
+ 用文字向用户提问:`需要创建日程还是会议?(请回复:日程 / 会议)`
53
+
54
+ - 用户答「会议」→ 留在本技能,继续步骤 1。
55
+ - 用户答「日程」→ 停止本工作流,改用 `读取 wecomcli-calendar 技能` 创建日程。
56
+ - 若用户同时要线下与远程参会,因含在线会议链接,留在本技能创建即可(创建会议会同时生成对应日程,无需再去 wecomcli-calendar 技能另建日程)。
57
+ 1. **参数补全**:从对话中提取主题、时间、时长、参会人信息。
58
+ - `subject` 缺失时,用文字询问会议主题。仅描述参会方式或动作的词(如「视频会议 / 开个会 / 会面 / 远程接入」)不构成有效 `subject`,一律按缺失处理走文字询问,禁止把它们当主题直接创建——否则用户事后补主题需额外调一次修改会议工具,效率非常低。文字提问如:`会议主题是什么?`(可举例"项目同步 / 需求评审 / 周例会 / 一对一沟通"供参考,最多举 4 个)
59
+ - `begin_time` 缺失时,用文字一步询问,直接列出具体的"日期+时刻"候选项让用户选(结合当前时间动态推断,所有候选项必须晚于当前时刻,禁止使用"上午/下午/傍晚"等模糊表述,最多列 4 个)。文字提问如:`会议什么时候开始?`(候选按当前时刻动态生成、均须晚于现在,例如当前 19:40 可列 "明天 09:00 / 明天 14:00 / 明天 16:00 / 后天 09:00")
60
+ - `end_time` / 时长缺失时,**默认时长 60 分钟(1 小时),不追问**,按 `end_time = begin_time + 60 分钟` 换算为结束时间。仅当用户明确说了时长(如"开半小时""聊俩小时")时按其值换算。
61
+ - `attendees` 缺失时,用文字追问参会人,禁止默认创建无参会人的会议或自行猜测;地点、会议室等非必填参数用户未明确指定时不追问,也不传该字段。文字提问如:`需要邀请哪些人参会?`(可列出"仅自己"及根据对话语境补充的 1-3 个候选人名供参考)
62
+ 2. **参会人解析**:上下文中已有合法 userid(`wo` 前缀)则直接使用,跳过本步骤;用户提供的是人名时,通过 `读取 wecomcli-contact 技能` 将所有姓名批量搜索,逐个关键词独立处理结果:
63
+ - 某关键词唯一匹配 → 直接使用,无需确认
64
+ - 某关键词多个匹配 → 用文字让用户选择:`搜索到多个「{姓名}」,请确认要邀请哪一位?` 并列出候选(来自 wecomcli-contact 技能搜索结果,如"张三 - 产品部 - 产品经理 / 张三 - 技术部 - 前端工程师",最多 4 条,超出取前 4 并提示用户缩小范围)
65
+ - 某关键词无结果 → 用文字提示用户重新输入:`未找到「{姓名}」,请确认姓名是否正确`
66
+ - 所有姓名确认完毕后,汇总 userid 组装为对象数组一并传入 `attendees`
67
+ 3. **参会人忙闲检查(新建一律必做)[REQUIRED]**:新建会议的查询对象必含当前用户自己(`wo` 前缀),故创建前必须先查忙闲,避免约到冲突时间(**含只有自己的会议——避免约到自己已占用的时段**);**本步骤是步骤 5(调用创建接口)的前置阻塞项——未完成忙闲检查、或检测到冲突但未经用户拍板,一律禁止进入创建(仅接口失败的降级例外,见下)**;外部联系人(`wm` 前缀,忙闲不可查)不纳入查询对象、但**不因此跳过**整体检查。忙闲接口不在本技能 —— 须 `读取 wecomcli-calendar 技能` 的 [忙闲查询参考](../../wecomcli-calendar/references/calendar-freebusy.md),调 `free list`(窗口 ≤ 24h,跨天需分段;**查询对象 = 自己 + 其他内部参会人,新建会议时自己也要纳入,避免约到自己已占用的时段**):
68
+ - **推荐时段长度 ≠ 会议时长(精确 / 范围时间均适用)**:忙闲返回的推荐时段只用于确定会议**开始时间**,其长度不代表会议时长;用户选定时段后,会议时长仍以用户明确指定的为准,用户未明确时长时一律默认 1 小时(`begin_time + 1h`),禁止把推荐时段的长度直接当作会议时长。
69
+ - **精确时间**(用户已给定具体开始时间):用 `[begin_time, end_time]` 查忙闲。有人占线时,必须用文字让用户在「坚持这个时间 / 换一个时间」二选一,禁止自行改期或劝阻:`该时间段{姓名}有冲突,如何处理?(请回复:坚持这个时间 / 换一个时间)`
70
+ - **范围时间**(如"明天下午"):调 `free list` 拿共同空闲 `slots`,按 `slots[0].available_count` 与 `total_count` 判断全员空闲 / 降级 / 全忙(详见忙闲查询参考),挑前几个时段让用户选定后再继续。
71
+ - **接口失败**:告知"忙闲查询暂时不可用",确认时间后继续创建,不阻塞。
72
+ 4. **会议室预订(仅当用户有订房意图时触发)**:用户提到"订会议室 / 在 1605 / 找个会议室 / 某栋楼的会议室"等意图时才走本步骤,没提则跳过。会议室的查询接口定义不在本技能 —— 须 `读取 wecomcli-calendar 技能` 的 [会议室查询参考](../../wecomcli-calendar/references/calendar-meeting-room.md),按其编排执行。**五条硬性规则不可跳过**:① **先查询、后推荐、后创建**——`meeting_room_id` 必须来自 `rooms search` 的真实返回值,禁止跳过查询直接 create,禁止凭记忆 / 猜测编造;且在成功调用 `rooms search` 之前,禁止凭记忆 / 上下文 / 想象向用户罗列或推荐任何具体会议室(含用文字给出的候选、正文里的房间名 / 号 / 楼层 / 容量),要让用户选会议室必须先查到真实候选再组装选项;② **存在多个会议室必须让用户选**——命中多个候选时必须用文字让用户选择或指定具体会议室,禁止自动替用户挑选;③ **会议室必须订房、且只传 `meeting_room_id`**——只要用户给的地点是会议室,就必须经 `rooms search` 查到真实会议室并通过 `meeting_room_id` 传入,严禁把会议室名 / 房间号仅塞进 `location` 字段就创建(那样不会真正占用会议室);预订成功后创建时**只传 `meeting_room_id`**(占用),**不需要再把会议室名重复填进 `location`**(会议室名由后端关联返回),仅当用户给的是非会议室的普通地点时才只写 `location`、不走订房;④ **优先先订房、后建会**——用户在创建时就提到会议室的,应先把会议室敲定(拿到用户确认的 `meeting_room_id`)再进入步骤 5 创建会议,本步骤是步骤 5 的前置阻塞项,避免创建后会议室被抢占。若会议室查询 / 选择尚未完成(如等待用户在候选中选择),必须停在本步骤等待,不得提前调用 create;⑤ **指定会议室查无/不可用必须先告知、禁止静默替换**——用户指定的会议室 `not_found`(查无此名)或 `unavailable`(被占)时,先告知用户"未查到 / 无法预订你指定的『xxx』会议室",再让用户决定改订其他会议室或换时间,禁止静默替代(候选仅 1 个也须用户确认)。若创建时漏订或事后要换会议室,可走 [meeting-update](meeting-update.md) 传入新 `meeting_room_id` 改订(须先经 `rooms search` 确认 `status=bookable`),不必取消重建。
73
+ - 用户提了楼名 → `buildings list` + LLM 匹配得到楼;没提楼则跳过(后端用当前所在楼兜底)
74
+ - `rooms search`(带已定 `begin_time`/`end_time` + 可选楼 + 可选 `room_keyword` + `min_capacity = len(attendees) + 1`)
75
+ - 按结果决策:用户**指定了具体会议室**(传了 `room_keyword`)且 `target` 中有 `bookable` 项 → 取该项 `meeting_room_id`(仅 1 个直接用,多个则用文字让用户选);指定的会议室 `target=[]`(查无此名)或命中项均 `unavailable`(被占)时——先告知用户"未查到 / 无法预订你指定的『xxx』会议室",再用文字让用户决定改订其他会议室或换时间,禁止静默替代(候选仅 1 个也须用户确认);用户**未指定具体会议室**(`target` 为 `[]`)时——`recommendations` 有**多个**候选则必须用文字让用户选择,只有 **1 个**候选可直接使用,**为空**则问是否跨楼或换时间
76
+ - 选定后将用户确认的 `meeting_room_id` 带入下一步的 create
77
+ 5. **调用创建接口**:参数就绪后直接执行 `wecom-cli meeting create --json '{...}'`。
78
+ > **创建前置门禁(CRITICAL)**:
79
+ > ① **忙闲门禁**——新建会议查询对象必含当前用户自己(`wo` 前缀),故调用 create 前**必须已完成步骤 3 的忙闲检查**;若检测到冲突,必须已通过文字询问让用户在「坚持这个时间 / 换一个时间」中拍板。禁止在"未查忙闲"或"冲突未经用户决定"的情况下直接 create(仅忙闲接口失败时按降级继续,不阻塞)。
80
+ > ② **会议室门禁**——若用户提到过会议室相关内容,则调用 create 前**必须已持有一个来自 `rooms search`、并经用户确认的真实 `meeting_room_id`**,且该 ID 已写入创建参数。只要"提到会议室但 `meeting_room_id` 仍为空",就禁止调用 create——先回到步骤 4 完成查询 / 选择拿到 ID。严禁以"先把会议建起来、忙闲/会议室随后补"的方式跳过本门禁。
81
+ 6. **查询详情并展示**:使用返回的 `meeting_id` 调用 `meeting get`(见 [meeting-list](meeting-list.md))获取 `subject`、`begin_time`/`end_time`、`attendees[].name`。**创建成功后输出内容只包含三部分:主题、时间、参会人**,禁止输出其他任何内容和额外语句(不展示地点、会议室、会议号、入会链接、meeting_id 等字段,也不附加说明、建议或寒暄);参会人原样取接口返回的 `attendees[].name` 展示(完全与接口返回的格式保持一致,如返回 `zhangsan(张三)` 就展示 `zhangsan(张三)`),禁止暴露 userid。
82
+
83
+ ### 异常路径
84
+
85
+ | 异常情况 | 处理方式 |
86
+ |---------|---------|
87
+ | `begin_time` 早于当前时间 | 提示用户时间已过, 请重新选择未来时间 |
88
+ | `end_time` 与 `begin_time` 间隔超过 24 小时 | 提示用户会议时长不可超过 24 小时, 请调整;禁止自行拆分成多场会议 |
89
+ | 参会人数超过 100 | 提示用户参会人数已达上限, 需减少人数 |
90
+ | wecomcli-contact 技能搜索无结果 | 用文字提示用户重新输入:`未找到「{姓名}」,请确认姓名是否正确` |
91
+ | wecomcli-contact 技能返回多个候选人 | 用文字询问用户(列出候选姓名 + 部门),等待用户选择后汇总继续 |
92
+ | 创建接口返回错误 | 检查参数格式, 重新阅读本文档确认用法 |
93
+ | `meeting_room_taken`(会议室被抢占) | 查询通过后、create 前被他人占走。用文字告知"{会议室名} 刚被占用",让用户在「换会议室 / 换时间」二选一;换会议室则重走步骤 4 的 `rooms search`,禁止静默重试同一会议室 |
94
+ | `meeting_room_not_found`(会议室无效) | `meeting_room_id` 不存在或上下文过期,重新走步骤 4 的会议室查询 |
95
+ | 换会议室需求 | 走 [meeting-update](meeting-update.md) 传入新 `meeting_room_id` 改订(须先经 `rooms search` 确认新会议室 `status=bookable`),无需取消重建 |
96
+
97
+ ## 典型场景
98
+
99
+ ### 1. 信息完整(正常路径)
100
+
101
+ ```
102
+ 用户:帮我约一个明天下午两点和张三的项目对齐会,30 分钟
103
+ → 通过 wecomcli-contact 技能搜索「张三」→ 返回 2 个候选
104
+ → 用文字询问:搜索到多个「张三」,请确认要邀请哪一位?(列出:张三 - 产品部 - 产品经理 / 张三 - 技术部 - 前端工程师)
105
+ → 用户选择后,获得对应 userid
106
+ → attendees 含他人内部成员(张三)→ 忙闲检查:用 [begin_time, end_time] 调 free list(自己 + 张三);无冲突则继续,占线则用文字让用户「坚持这个时间 / 换一个时间」
107
+ → 调用 meeting create(subject="项目对齐", begin_time="<明天日期> 14:00:00", end_time="<明天日期> 14:30:00", attendees=[{"userid": "userid1"}])
108
+ → 调用 meeting get 获取主题、时间、参会人姓名
109
+ → 只展示三部分:主题、时间、参会人
110
+ ```
111
+
112
+ ### 2. 参数缺失(逐步补全)
113
+
114
+ ```
115
+ 用户:帮我开个会
116
+ → 未明确是日程还是会议 → 用文字追问(请回复:日程 / 会议)
117
+ → 用户答「会议」→ 留在本技能继续;若答「日程」→ 改用 wecomcli-calendar 技能
118
+ → subject 缺失 → 用文字询问会议主题
119
+ → begin_time 缺失 → 用文字询问开始时间(结合当前时间动态推荐候选项)
120
+ → end_time 缺失 → 默认时长 1 小时(不追问),按 begin_time + 1h 推算
121
+ → attendees 缺失 → 用文字追问参会人(地点、会议室等非必填项不追问)
122
+ → attendees 含他人内部成员 → 忙闲检查(free list,占线则用文字问坚持/换时间)
123
+ → 参数就绪 → 调用 meeting create → 展示结果
124
+ ```
125
+
126
+ ### 3. 通讯录多候选人
127
+
128
+ ```
129
+ 用户:帮我约张三、李四参加明天 10 点的需求评审,1 小时
130
+ → 通过 wecomcli-contact 技能批量搜索「张三」「李四」
131
+ → "张三" 返回 2 条(产品部 / 技术部)→ 用文字让用户选择
132
+ → "李四" 返回 1 条 → 直接使用,无需确认
133
+ → 汇总 userid → 忙闲检查:调 free list(自己 + 张三 + 李四)查 [begin_time, end_time];占线则用文字让用户「坚持这个时间 / 换一个时间」 → 调用 meeting create → 展示结果
134
+ ```
135
+
136
+ ## 示例请求
137
+
138
+ ```json
139
+ {
140
+ "subject": "产品需求评审",
141
+ "begin_time": "<明天日期> 14:00:00",
142
+ "end_time": "<明天日期> 15:00:00",
143
+ "attendees": [
144
+ {"userid": "userid1"},
145
+ {"userid": "userid2"},
146
+ {"userid": "userid3"}
147
+ ],
148
+ "description": "评审Q2需求文档",
149
+ "meeting_room_id": "mrmxxxx",
150
+ "timezone": {
151
+ "timezone_id": "Asia/Shanghai",
152
+ "timezone_offset": 28800
153
+ }
154
+ }
155
+ ```
156
+
157
+ > `meeting_room_id` 为可选,订会议室时才传,来自 `读取 wecomcli-calendar 技能` 的会议室查询(`rooms search`,见 [会议室查询参考](../../wecomcli-calendar/references/calendar-meeting-room.md));订会议室时只传 `meeting_room_id` 即可,无需再把会议室名重复填进 `location`(会议室名由后端关联返回)。`location`仅在用户给的是非会议室的普通文本地点时才填。
158
+
159
+ ## 示例输出
160
+
161
+ > 创建成功后只输出三部分:主题、时间、参会人,禁止输出地点、会议号、入会链接等其他内容和额外语句。
162
+
163
+ ```
164
+ 主题:产品需求评审
165
+ 时间:<明天日期> 14:00:00 - 15:00:00
166
+ 参会人:张三、李四
167
+ ```
@@ -0,0 +1,226 @@
1
+ # 操作参考:查询会议列表
2
+
3
+ > [!CAUTION]
4
+ > **`meeting get` 单次最多查询 10 个会议**:`meeting_ids` 数组长度上限为 10。超过 10 个 meeting_id 时必须分批多次调用(每批 ≤ 10),分别拿到结果后在 Agent 侧合并;禁止一次性传入 > 10 个 ID(会被服务端拒绝)。例如:拉取了 25 个 meeting_id,需拆成 10 + 10 + 5 三批。
5
+ >
6
+ > **`meeting list` 必须翻页到底**:`meeting list` 返回中只要 `has_more == true`,就必须携带 `next_cursor` 再次调用 list,循环直到 `has_more == false`,否则会漏数据。
7
+
8
+ ## 命令
9
+
10
+ ```bash
11
+ wecom-cli meeting list --json '{...}'
12
+ wecom-cli meeting get --json '{...}'
13
+ ```
14
+
15
+ ## 请求参数(list)
16
+
17
+ | 字段 | 类型 | 必填 | 说明 |
18
+ | ------------ | ------- | ---- | ---------------------------------------------------------------------------------------------- |
19
+ | `begin_time` | string | 否 | 查询区间开始时间, 格式 `YYYY-MM-DD HH:mm:ss`, 与 `end_time` 必须同时提供或同时不提供, 不可只传其一 |
20
+ | `end_time` | string | 否 | 查询区间结束时间, 格式 `YYYY-MM-DD HH:mm:ss`, 与 `begin_time` 必须同时提供或同时不提供, 不可只传其一 |
21
+ | `cursor` | string | 否 | 分页游标, 首次请求不传 |
22
+ | `limit` | integer | 否 | 单次返回数量, 默认 20 |
23
+
24
+ ## 返回字段(list)
25
+
26
+ > 返回结果分为两个列表: `created_meetings`(当前用户创建的会议)和 `attended_meetings`(当前用户参加但非创建的会议),两个列表结构相同。
27
+
28
+ | 字段 | 说明 |
29
+ | ---------------------------------------------- | ---------------------------------------- |
30
+ | `created_meetings[].meeting_id` | 会议唯一标识 |
31
+ | `created_meetings[].sub_meeting_id` | 子会议 ID, 周期会议涉及 |
32
+ | `created_meetings[].subject` | 会议主题 |
33
+ | `created_meetings[].begin_time` | 会议开始时间, 格式 `YYYY-MM-DD HH:mm:ss` |
34
+ | `created_meetings[].end_time` | 会议结束时间, 格式 `YYYY-MM-DD HH:mm:ss` |
35
+ | `created_meetings[].attendee_count` | 参会人数 |
36
+ | `created_meetings[].meeting_room` | 会议室名称 |
37
+ | `created_meetings[].location` | 会议地点 |
38
+ | `created_meetings[].is_repeat_meeting` | 是否为周期性会议 |
39
+ | `created_meetings[].timezone.timezone_id` | 时区 ID, 如 `"Asia/Shanghai"` |
40
+ | `created_meetings[].timezone.timezone_offset` | 时区偏移量(秒), 如 28800 |
41
+ | `attended_meetings[].meeting_id` | 会议唯一标识 |
42
+ | `attended_meetings[].sub_meeting_id` | 子会议 ID, 周期会议涉及 |
43
+ | `attended_meetings[].subject` | 会议主题 |
44
+ | `attended_meetings[].begin_time` | 会议开始时间, 格式 `YYYY-MM-DD HH:mm:ss` |
45
+ | `attended_meetings[].end_time` | 会议结束时间, 格式 `YYYY-MM-DD HH:mm:ss` |
46
+ | `attended_meetings[].attendee_count` | 参会人数 |
47
+ | `attended_meetings[].meeting_room` | 会议室名称 |
48
+ | `attended_meetings[].location` | 会议地点 |
49
+ | `attended_meetings[].is_repeat_meeting` | 是否为周期性会议 |
50
+ | `attended_meetings[].timezone.timezone_id` | 时区 ID, 如 `"Asia/Shanghai"` |
51
+ | `attended_meetings[].timezone.timezone_offset` | 时区偏移量(秒), 如 28800 |
52
+ | `attended_meetings[].creator_name` | 会议创建人名称 |
53
+ | `created_meetings_count` | `created_meetings` 数组元素数量 |
54
+ | `attended_meetings_count` | `attended_meetings` 数组元素数量 |
55
+ | `next_cursor` | 下一页游标, `has_more` 为 true 时有效 |
56
+ | `has_more` | 是否还有更多数据 |
57
+
58
+ ## 请求参数(get)
59
+
60
+ > **输入格式强制要求**:`meeting_ids` 必须使用以下嵌套对象数组结构传入,不可简化为字符串数组:
61
+ > ```json
62
+ > {
63
+ > "meeting_ids": [
64
+ > {
65
+ > "meeting_id": "会议ID",
66
+ > "sub_meeting_id": "子会议ID"
67
+ > }
68
+ > ]
69
+ > }
70
+ > ```
71
+ > 每个元素必须是包含 `meeting_id`(必填)和可选 `sub_meeting_id` 的对象,**不得直接传字符串**。
72
+
73
+ | 字段 | 类型 | 必填 | 说明 |
74
+ | ------------------------------ | ------ | ---- | ---------------------------------------------------- |
75
+ | `meeting_ids` | array | 是 | 会议 ID 列表,最少 1 个,最多 10 个。超过 10 个时必须分批请求,每批不超过 10 个。**每个元素必须是对象(含 `meeting_id` 字段),不可传字符串** |
76
+ | `meeting_ids[].meeting_id` | string | 是 | 会议 ID(长字符串, 如 `mtkSFfCg...`), 非 9 位会议号 |
77
+ | `meeting_ids[].sub_meeting_id` | string | 否 | 子会议 ID, 周期会议需指定 |
78
+
79
+ ## 返回字段(get)
80
+
81
+ | 字段 | 说明 |
82
+ | --------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
83
+ | `meetings[].meeting_id` | 会议 ID |
84
+ | `meetings[].sub_meeting_id` | 子会议 ID, 周期会议当前子会议 ID |
85
+ | `meetings[].subject` | 会议主题 |
86
+ | `meetings[].begin_time` | 开始时间, 格式 `YYYY-MM-DD HH:mm:ss` |
87
+ | `meetings[].end_time` | 结束时间, 格式 `YYYY-MM-DD HH:mm:ss` |
88
+ | `meetings[].current_user_enter_time` | 当前调用用户的入会时间, 格式 `YYYY-MM-DD HH:mm:ss`, 取最早一次入会时间; **仅会议结束后返回, 未入会时为空** |
89
+ | `meetings[].current_user_quit_time` | 当前调用用户的离会时间, 格式 `YYYY-MM-DD HH:mm:ss`, 取最晚一次离会时间; **仅会议结束后返回, 未入会时为空** |
90
+ | `meetings[].timezone.timezone_id` | 时区 ID, 如 `"Asia/Shanghai"` |
91
+ | `meetings[].timezone.timezone_offset` | 时区偏移量(秒), 如 28800 |
92
+ | `meetings[].meeting_room` | 会议室名称 |
93
+ | `meetings[].location` | 会议地点 |
94
+ | `meetings[].description` | 会议备注描述 |
95
+ | `meetings[].repeat_rule` | 周期规则, 非周期会议为空 |
96
+ | `meetings[].repeat_rule.repeat_type` | 周期类型: `"daily"`-每天, `"weekday"`-每个工作日, `"weekly"`-每周, `"biweekly"`-每两周, `"monthly"`-每月 |
97
+ | `meetings[].repeat_rule.repeat_days` | 重复天数 |
98
+ | `meetings[].repeat_rule.until_type` | 结束方式: `"by_date"`-按日期结束, `"by_times"`-按次数结束 |
99
+ | `meetings[].repeat_rule.until_date` | 周期结束日期, 格式 `YYYY-MM-DD HH:mm:ss`(until_type=`"by_date"` 时有效) |
100
+ | `meetings[].repeat_rule.until_times` | 结束次数(until_type=`"by_times"` 时有效) |
101
+ | `meetings[].repeat_rule.version` | 重复规则版本, 默认 0 |
102
+ | `meetings[].repeat_rule.first_begin_time` | 第一次开始时间, 格式 `YYYY-MM-DD HH:mm:ss` |
103
+ | `meetings[].repeat_rule.first_end_time` | 第一次结束时间, 格式 `YYYY-MM-DD HH:mm:ss` |
104
+ | `meetings[].repeat_rule.repeat_step` | 每 n(天/周/月)重复一次, 与 repeat_type 配合使用; 例如 repeat_step=3, repeat_type=`"daily"` 表示每 3 天重复一次 |
105
+ | `meetings[].meeting_status` | 会议状态: `"init"`-未开始, `"started"`-进行中, `"end"`-已结束(终止态, 不回退) |
106
+ | `meetings[].attendees` | 参会人列表,扁平对象数组,企业内部成员与外部成员混在同一数组,通过 `is_external` 区分 |
107
+ | `meetings[].attendees[].userid` | 成员 userid,内部成员与外部联系人统一用此字段,由 `is_external` 区分(内部 `wo` 前缀、外部 `wm` 前缀) |
108
+ | `meetings[].attendees[].name` | 参会人名称(如 `"zhangsan(张三)"`),展示时**原样取此字段**(完全与接口返回的格式保持一致),禁止展示 userid |
109
+ | `meetings[].attendees[].is_external` | 是否为外部联系人(bool) |
110
+ | `meetings[].attendees[].is_attended` | 是否已入会(bool) |
111
+ | `meetings[].attendees[].duration` | 参会时长(秒) |
112
+ | `meetings[].notes[].note_content` | 智能纪要文字内容(每个媒体房间一条,最多 10 条) |
113
+ | `meetings[].notes[].todo_content` | 智能纪要待办内容 |
114
+ | `meetings[].note_url` | 会议智能纪要 URL(如 `"https://xxx"`)。**仅当用户明确询问会议链接 / 纪要链接时才展示**,其余情况不主动输出;**只要展示链接,就必须用 markdown 跳转链接格式 `[会议主题](链接)`**,`[]` 内放该会议主题(`subject`,如 `[产品评审周会](https://xxx)`),禁止裸贴 URL、禁止用固定文案 |
115
+ | `meetings[].has_note_permission` | 是否有会议纪要权限 |
116
+ | `meetings[].record_url` | 会议录制地址 URL(如 `"https://xxx"`)。**仅当用户明确询问录制链接 / 回放链接时才展示**,其余情况不主动输出;**只要展示链接,就必须用 markdown 跳转链接格式 `[会议主题](链接)`**,`[]` 内放该会议主题(`subject`,如 `[产品评审周会](https://xxx)`),禁止裸贴 URL、禁止用固定文案 |
117
+ | `meetings[].is_except_meet` | 是否是例外(周期会议中被单独修改的子会议) |
118
+ | `meetings_count` | `meetings` 数组元素数量 |
119
+
120
+ ## 约束
121
+
122
+ - `begin_time` 和 `end_time` 必须同时提供或同时不提供,不可只传其中一个
123
+ - `meeting get` 单次传入 1~10 个会议 ID,超出需分批请求
124
+ - `meeting_ids` 必须传入对象数组(每个元素含 `meeting_id` 字段),**禁止简化为字符串数组**,如 `["id1","id2"]` 格式是错误的
125
+ - `meeting_id` 是长字符串(如 `mtkSFfCg...`), 不要误传 9 位数字会议号
126
+ - 参会人 `name` 由接口直接返回,正常无需通讯录反查;`name` 为空时用 `userid` 通过 `读取 wecomcli-contact 技能` 反查姓名,禁止直接展示 userid
127
+ - `notes` 字段包含文字版智能纪要内容,每个媒体房间一条,最多 10 条;`has_note_permission` 为 false 时不展示纪要内容
128
+ - **作为「会议总结」用途时 [REQUIRED]**:**只有用户纯粹地说"总结下 / 讲了啥 / 纪要发我 / 看待办"、不带任何自定义描述时,才走本 get 返回现成内容**;取目标字段——要纪要看 `notes[].note_content`、要待办看 `notes[].todo_content`;`has_note_permission == true` 且目标字段有实质内容时**直接返回该现成内容**(无需再调用转写原文接口);目标字段为空或 `has_note_permission == false` 时,转 [meeting-original-get](meeting-original-get.md) 拉转写原文兜底再总结。**只要用户附带了任何自定义要求/描述**(指定结构/角度/范围/风格/长度等),就跳过本 get、直接走原文加工(详见 [SKILL.md 核心场景 7](../SKILL.md))。
129
+ - **链接展示格式(`note_url` 会议纪要链接、`record_url` 会议录制链接)[CRITICAL]**:
130
+ - **默认不展示**:`note_url` 仅当用户明确询问会议链接 / 纪要链接时才输出;`record_url` 仅当用户明确询问录制链接 / 回放链接时才输出;其余情况一律不主动输出。
131
+ - **展示格式强约束**:**只要要展示这两类链接,就必须用 markdown 跳转链接格式 `[会议主题](链接)`**——`[]` 内放该会议主题(`subject`),`()` 内放对应 URL,如 `[产品评审周会](https://xxx)`。
132
+ - **严禁**:直接裸贴 URL、用「点击查看」等固定文案代替会议主题、或以纯文本形式输出链接。
133
+
134
+ ## 工作流
135
+
136
+ > **模糊查询前置 [REQUIRED]**:若本次是"会 / xx会 / xx会议 / 有什么会 / 最近有哪些会"等模糊查询(见 [SKILL.md 查询消歧](../SKILL.md)),除按下面拉会议 `list` 外,必须同时 `读取 wecomcli-calendar 技能` 用相同时间范围拉日程 `list`,把两边结果合并、分「(会议)」「(日程)」两部分汇总展示(同一场会议按主题 + 时间去重)——不论会议是否查到都要查日程。仅当用户明确指向在线会议(入会链接 / 会议号 / 视频会议等)时才只查会议。
137
+
138
+ ### 正常路径
139
+
140
+ 1. **确认时间范围**:从用户意图提取时间范围。
141
+ - 用户已明确时间(如"今天"、"本周"、"4月15日到4月20日")→ 直接映射为 `begin_time`/`end_time`
142
+ - 用户未明确时间(如"查一下我的会议")→ **使用默认策略:今天起未来 7 天**(无需追问)
143
+ - 用户说"最近"或"近期" → 使用"过去 3 天到未来 7 天"
144
+ - 用户只提供了模糊但有意义的范围(如"上个月")→ 解析为对应日期范围
145
+ 2. **拉取会议列表**:调用 `wecom-cli meeting list --json '{...}'`, 获取 `created_meetings` 和 `attended_meetings`。若 `has_more` 为 true, 携带 `next_cursor` 继续翻页, 直至获取全部 `meeting_id`(用于统计总条数 N)。
146
+ 3. **获取详情**:按开始时间升序排序后,**只对要展示的前 10 条** `meeting_id` 调用 `wecom-cli meeting get --json '{...}'` 反查详情(每批 ≤ 10 个);其余条数计入"还有 N 条",不必逐一取详情。
147
+ 4. **展示参会人名称**:原样使用详情中 `attendees[].name`(完全与接口返回的格式保持一致);`name` 为空时用该参会人 `userid` 通过 `读取 wecomcli-contact 技能` 反查姓名,禁止直接展示 userid。
148
+ 5. **顺序输出**:禁止 markdown 表格,每条会议作为独立条目顺序输出,每个条目只含主题/时间/参会人;超过 10 条只展示前 10 条,末尾告知"还有 N 条,需要查看更多吗?"。
149
+
150
+ ### 异常路径
151
+
152
+ | 异常情况 | 处理方式 |
153
+ |---------|---------|
154
+ | 列表为空 | 不要直接告知"无会议"——企微里「会」有「含在线会议链接的会议」和「日程」两种载体,团队聚一起的会常落在日程而非会议。先主动 `读取 wecomcli-calendar 技能` 用相同时间范围(及用户提及的关键词/参会人)在日程里查一把:命中则一并呈现并说明「这是一条日程,未关联在线会议链接」;日程也无果,再告知用户该时间段内会议和日程均无安排,并建议扩大时间范围 |
155
+ | 翻页过程中出错 | 展示已获取的部分结果, 告知用户可能有更多未加载的数据 |
156
+ | 详情获取失败(部分 ID) | 展示成功获取的会议, 标注获取失败的条目 |
157
+ | 参会人 `name` 字段为空 | 用该参会人 `userid` 通过 `读取 wecomcli-contact 技能` 反查姓名;反查不到再告知该参会人信息暂时无法获取。禁止直接展示 userid |
158
+
159
+ ## 翻页策略
160
+
161
+ - `meeting list` 使用 `cursor`/`next_cursor` + `has_more` 分页
162
+ - `has_more` 为 true 时必须携带 `next_cursor` 继续翻页, 直至获取全部数据
163
+ - 周期会议需同时传入 `sub_meeting_id` 才能获取正确的子会议详情
164
+
165
+ ## 示例请求
166
+
167
+ **list 请求**:
168
+ ```json
169
+ {
170
+ "begin_time": "2026-04-07 00:00:00",
171
+ "end_time": "2026-04-07 23:59:59",
172
+ "limit": 20
173
+ }
174
+ ```
175
+
176
+ **get 请求**:
177
+ ```json
178
+ {
179
+ "meeting_ids": [
180
+ { "meeting_id": "<meeting_id_1>" },
181
+ { "meeting_id": "<meeting_id_2>", "sub_meeting_id": "<sub_meeting_id>" }
182
+ ]
183
+ }
184
+ ```
185
+
186
+ ## 典型场景
187
+
188
+ ### 1. 明确指定时间范围
189
+
190
+ ```
191
+ 用户:帮我看看今天有什么会议
192
+ → 用户已明确"今天",直接映射:begin_time=今天 00:00:00,end_time=今天 23:59:59
193
+ → 调用 meeting list 获取 created_meetings + attended_meetings 列表
194
+ → 按开始时间升序,对前 10 条调用 meeting get 反查参会人姓名
195
+ → 顺序输出每条会议(主题/时间/参会人,禁止 markdown 表格):
196
+
197
+ 1. 项目复盘
198
+ 时间:4月7日(周二)09:00-10:00
199
+ 参会人:赵六、钱七
200
+
201
+ 2. 产品评审
202
+ 时间:4月7日(周二)14:00-15:00
203
+ 参会人:张三、李四、王五
204
+ ```
205
+
206
+ ### 2. 未指定时间范围,使用默认策略
207
+
208
+ ```
209
+ 用户:帮我看看有什么会议
210
+ → 未指定时间范围,直接使用默认策略:今天起未来 7 天
211
+ begin_time = 今天 00:00:00,end_time = 7 天后 23:59:59
212
+ → 调用 meeting list,对前 10 条调用 meeting get 反查参会人姓名
213
+ → 顺序输出每条会议(主题/时间/参会人,禁止 markdown 表格),超过 10 条只展示前 10 条 + "还有 N 条,需要查看更多吗?"
214
+ ```
215
+
216
+ ### 3. 查询结果为空(用日程兜底)
217
+
218
+ ```
219
+ 用户:帮我看看这周有什么会
220
+ → 用户已明确"这周",映射为本周一 00:00:00 ~ 本周日 23:59:59
221
+ → 调用 meeting list → created_meetings 和 attended_meetings 均为空
222
+ → 软性兜底:「会」在企微可能是日程,主动 `读取 wecomcli-calendar 技能` 用同样时间范围在日程里查一把
223
+ - 日程命中 → 一并呈现并说明:在「日程」里找到了本周的安排(这是日程,未关联在线会议链接),随后展示日程列表
224
+ - 日程也无果 → 告知用户:本周(4月7日-4月13日)会议和日程里都没有安排。
225
+ ```
226
+
@@ -0,0 +1,98 @@
1
+ # 操作参考:查询会议转写原文
2
+
3
+ > [!CAUTION]
4
+ > **转写原文 ≠ 智能纪要**:本接口返回的是逐句原始发言记录(`original_data`,含时间戳 + 说话人),**不是** `meeting get` 里经 AI 总结的 `notes`。用户要"纪要 / 要点 / 待办"用 `meeting get`;要"原话 / 逐字记录 / 完整对话 / 转写"才用本接口,二者禁止相互替代。
5
+ >
6
+ > **输出方式取决于调用目的**:用户要的是"原话/逐字记录/转写"时,`original_data` **原样输出**(下方约束的默认要求);但当本接口是被「会议总结」场景调用(get 无现成纪要/待办需兜底,或用户带自定义总结要求,详见 [SKILL.md 核心场景 7](../SKILL.md))时,`original_data` 作为**素材**可按默认或用户指定的结构加工总结,不受"原样输出"约束限制。
7
+ >
8
+ > **必须翻页到底**:返回 `has_more == true` 时,必须携带 `next_cursor` 再次调用,循环直到 `has_more == false`,并把各页 `original_data` 按返回顺序拼接,否则会漏掉后半段转写。
9
+
10
+ ## 命令
11
+
12
+ ```bash
13
+ wecom-cli meeting original get --json '{...}'
14
+ ```
15
+
16
+ ## 请求参数
17
+
18
+ | 字段 | 类型 | 必填 | 说明 |
19
+ | ---------------- | ------- | ---- | ------------------------------------------------------------------------------------------------------------------------ |
20
+ | `meeting_id` | string | 是 | 会议 ID(`mt` 前缀长字符串,如 `mtkSFfCg...`),非 9 位数字会议号 |
21
+ | `sub_meeting_id` | string | 否 | 子会议 ID,周期会议查某一场时指定 |
22
+ | `media_index` | integer | 否 | 媒体索引,指定拉取第几段转写,从 0 开始。**不传则返回全部段的转写**;仅当用户明确要"第 N 段"时才传 `N-1`(第 1 段传 0、第 2 段传 1) |
23
+ | `cursor` | string | 否 | 分页游标,首次请求不传 |
24
+ | `limit` | integer | 否 | 每页数量,默认 100,上限 500 |
25
+
26
+ ## 返回字段
27
+
28
+ | 字段 | 说明 |
29
+ | ------------- | ----------------------------------------------------------------------- |
30
+ | `media_index` | 当前返回的是第几段转写的原文 |
31
+ | `original_data` | 转写原文文本,逐行格式 `序号 时间 说话人(姓名): 内容`,多行以换行符分隔 |
32
+ | `next_cursor` | 下一页游标,`has_more` 为 true 时有效 |
33
+ | `has_more` | 是否还有更多数据 |
34
+
35
+ ## 约束
36
+
37
+ - **前置依赖**:需先通过 `list` / `search` 定位到 `meeting_id`(周期会议还需 `sub_meeting_id`)。
38
+ - **`media_index` 默认不传**:不传时接口返回全部段的转写;**只有用户明确指定"第 N 段"时才传 `N-1`**(从 0 开始计数),禁止在用户未指定时自行传入或主动追问"要哪一段"。
39
+ - `limit` 未传按 100,超过 500 按 500 处理。
40
+ - `meeting_id` 是 `mt` 前缀长字符串,禁止误传 9 位会议号(`meeting_code`)。
41
+ - 无权限 / 无转写等异常由接口返回错误信息,按 SKILL.md 通用错误处理呈现,不静默失败。
42
+
43
+ ## 工作流
44
+
45
+ ### 正常路径
46
+
47
+ 1. **定位会议**:从上下文或 `list` / `search` 取得 `meeting_id`(周期会议带 `sub_meeting_id`)。
48
+ 2. **确定段落**:用户明确指定"第 N 段" → `media_index = N-1`;**未指定 → 不传 `media_index`**(接口返回全部段),不主动追问。
49
+ 3. **拉取转写**:调用 `wecom-cli meeting original get --json '{...}'`。
50
+ 4. **翻页拼接**:`has_more == true` 时携带 `next_cursor` 续拉,直到 `false`,按返回顺序拼接 `original_data`。
51
+ 5. **输出**:
52
+ - **要原话/逐字记录**(默认)→ 保留时间戳 + 说话人的逐行格式,**不改写、不总结、不裁剪**。
53
+ - **作为「会议总结」兜底或带自定义要求**(见 [SKILL.md 核心场景 7](../SKILL.md))→ 以拼接后的 `original_data` 为素材,按默认或用户指定结构加工总结。
54
+
55
+ ### 异常路径
56
+
57
+ | 异常情况 | 处理方式 |
58
+ | --------------- | ---------------------------------------------------------------------------- |
59
+ | 接口返回错误 | 原样呈现错误含义(如无权限 / 会议不存在),并给出可行建议,不静默失败 |
60
+ | `original_data` 为空 | 告知该会议暂无转写原文(可能未开启转写、会议未开始或该段无内容) |
61
+ | 翻页中途出错 | 展示已拼接的部分,并提示内容可能不完整 |
62
+
63
+ ## 翻页策略
64
+
65
+ - 使用 `cursor` / `next_cursor` + `has_more` 分页;`has_more` 为 true 时必须携带 `next_cursor` 续拉,直至 `false`。
66
+ - 各页 `original_data` 按返回顺序拼接为完整转写文本。
67
+
68
+ ## 示例请求
69
+
70
+ **默认(返回全部段转写)**:
71
+ ```json
72
+ { "meeting_id": "<meeting_id>", "limit": 100 }
73
+ ```
74
+
75
+ **指定第 2 段 + 周期会议某场**:
76
+ ```json
77
+ { "meeting_id": "<meeting_id>", "sub_meeting_id": "<sub_meeting_id>", "media_index": 1, "limit": 100 }
78
+ ```
79
+
80
+ ## 典型场景
81
+
82
+ ### 1. 查会议转写原文
83
+
84
+ ```
85
+ 用户:把上午产品评审会说了什么原话发我
86
+ → 先 list/search 定位到该会议 meeting_id
87
+ → 用户未指定段落,不传 media_index(接口返回全部段)
88
+ → 调用 meeting original get,has_more 时带 next_cursor 翻页到底
89
+ → 按序拼接 original_data,原样输出逐行转写(不总结、不改写)
90
+ ```
91
+
92
+ ### 2. 指定第几段
93
+
94
+ ```
95
+ 用户:这个会第二段转写发我
96
+ → 用户明确"第二段" → media_index = 1(从 0 开始)
97
+ → 调用 meeting original get,翻页到底后原样输出
98
+ ```