weaver-work-cli 0.1.32 → 0.1.33

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 (185) hide show
  1. package/README.md +2 -2
  2. package/dist/chunks/{archive-UMGX72K6.js → archive-FVFY6GZN.js} +2 -2
  3. package/dist/chunks/{archive-oa-N2IYBLF3.js → archive-oa-NW3OD4UV.js} +2 -2
  4. package/dist/chunks/{asset-GLEGKFG5.js → asset-7QJKMIDV.js} +2 -2
  5. package/dist/chunks/{attachment-content-AQNX5N3S.js → attachment-content-OSAVA6K3.js} +3 -2
  6. package/dist/chunks/{blog-E44OTVDA.js → blog-I7SDPNW4.js} +2 -2
  7. package/dist/chunks/{caizhilian-DQUFZXZL.js → caizhilian-O37ZIQNY.js} +2 -2
  8. package/dist/chunks/{calendar-JKPIRKFD.js → calendar-7KXE4ED3.js} +2 -2
  9. package/dist/chunks/{chunk-4YC43QQ4.js → chunk-2FLWXFVS.js} +4 -4
  10. package/dist/chunks/{chunk-QWY6PGL6.js → chunk-2LV74IWP.js} +361 -56
  11. package/dist/chunks/chunk-3SO6QL6U.js +73 -0
  12. package/dist/chunks/{chunk-DW6AUUKS.js → chunk-6ATGWRZM.js} +6 -4
  13. package/dist/chunks/chunk-BYATLLEF.js +68 -0
  14. package/dist/chunks/chunk-BYBSCN4X.js +932 -0
  15. package/dist/chunks/{chunk-2GA5ZIQL.js → chunk-D223PTXU.js} +1 -0
  16. package/dist/chunks/{chunk-H7J4DC5R.js → chunk-EEWPQE3O.js} +2 -2
  17. package/dist/chunks/{chunk-6RKD4DRZ.js → chunk-GFPXQIY2.js} +2 -2
  18. package/dist/chunks/{chunk-C6R3B2ML.js → chunk-HEL5XTYI.js} +12 -6
  19. package/dist/chunks/{chunk-CVZ2JOSW.js → chunk-IHUYP6LO.js} +1 -1
  20. package/dist/chunks/{chunk-YRVDW4WN.js → chunk-ILMBNVSG.js} +2 -2
  21. package/dist/chunks/{chunk-G3QJULO2.js → chunk-KAS45KNR.js} +1 -1
  22. package/dist/chunks/{chunk-H6XSTSLM.js → chunk-MEEFGWTM.js} +54 -196
  23. package/dist/chunks/{chunk-GCG2NMWR.js → chunk-MQ2I5AA3.js} +4 -2
  24. package/dist/chunks/chunk-NHA62QD7.js +774 -0
  25. package/dist/chunks/{chunk-WKI2FBIQ.js → chunk-OCU4RLHC.js} +641 -309
  26. package/dist/chunks/{chunk-WSKBSQ2U.js → chunk-PRHJGPMA.js} +2 -2
  27. package/dist/chunks/{chunk-6EFWDL7Y.js → chunk-Q6LWB5HX.js} +2 -2
  28. package/dist/chunks/{chunk-IURUFGZK.js → chunk-RBGOMK4Y.js} +50 -33
  29. package/dist/chunks/chunk-VBCFFFGT.js +226 -0
  30. package/dist/chunks/{ebuilder-form-V5FG2EHC.js → chunk-WRRJ4GG2.js} +22 -1148
  31. package/dist/chunks/{chunk-E4Z23GHM.js → chunk-WY74UBJ6.js} +264 -750
  32. package/dist/chunks/conflict-SFNEVJY5.js +21 -0
  33. package/dist/chunks/continuation-RN6PZN2M.js +11 -0
  34. package/dist/chunks/cowork-CKWYHXYB.js +2508 -0
  35. package/dist/chunks/ebuilder-form-KOLJRVZD.js +121 -0
  36. package/dist/chunks/{ehr-HMFY6VIL.js → ehr-WFOC3B4D.js} +1174 -20
  37. package/dist/chunks/{esb-ZYSVB7SG.js → esb-LJZTN663.js} +4 -4
  38. package/dist/chunks/{fna-B7RKPAZD.js → fna-F7QRIIZC.js} +2 -2
  39. package/dist/chunks/{host-45WED2KK.js → host-BCGUVEWX.js} +3 -3
  40. package/dist/chunks/host-BQBRHVR3.js +23 -0
  41. package/dist/chunks/{host-I4Z6BFYX.js → host-DGE2TZD4.js} +3 -3
  42. package/dist/chunks/{host-KNZ52LJZ.js → host-KXPTEWFS.js} +3 -3
  43. package/dist/chunks/{host-OCH2BCCV.js → host-VQ6JJXGQ.js} +3 -3
  44. package/dist/chunks/{hrm-2KAZGUHI.js → hrm-NI6XAKW5.js} +3 -3
  45. package/dist/chunks/{im-ACJJWH4U.js → im-7TRTF3KT.js} +88 -12
  46. package/dist/chunks/{invoice-ZK3WCX2U.js → invoice-AOXWJKYT.js} +3 -3
  47. package/dist/chunks/{jiuchuanhui-5PQD3IL2.js → jiuchuanhui-7NQWEZAW.js} +2 -2
  48. package/dist/chunks/{lazy-dispatch-JQXBW3GM.js → lazy-dispatch-RNS4EE4S.js} +4 -4
  49. package/dist/chunks/{mail-S2HDDXO2.js → mail-VDHJAB4O.js} +3 -3
  50. package/dist/chunks/{meeting-QVN3I37L.js → meeting-GA7XCNNP.js} +214 -43
  51. package/dist/chunks/{okr-QNG4VC2Q.js → okr-TQIRERPQ.js} +2 -2
  52. package/dist/chunks/operations-5QL3AECO.js +11 -0
  53. package/dist/chunks/{plan-A25EMW6U.js → plan-4RY4LN2P.js} +2 -2
  54. package/dist/chunks/{project-G6XV66DZ.js → project-D6XT2OC5.js} +2 -2
  55. package/dist/chunks/{registry-DC6KR3NH.js → registry-JHRIDQ3A.js} +4 -4
  56. package/dist/chunks/{registry-2VLUAESA.js → registry-OZSMDVPP.js} +2 -2
  57. package/dist/chunks/{registry-TI3CIUXF.js → registry-QKMI43Q6.js} +8 -6
  58. package/dist/chunks/{registry-7C5UMIPL.js → registry-VOGKFFTR.js} +2 -2
  59. package/dist/chunks/{room-recommend-WRTHO6Y2.js → room-recommend-D4EUOOWY.js} +4 -3
  60. package/dist/chunks/{schedule-KFIITGSK.js → schedule-XPFBHPCV.js} +4 -3
  61. package/dist/chunks/{workflow-DJ7SYWAF.js → workflow-HLBZRWIY.js} +172 -6
  62. package/dist/index.js +30 -25
  63. package/dist/internal/e10/auth-recovery.js +14 -4
  64. package/dist/shortcuts/contract/host.js +34 -59
  65. package/dist/shortcuts/cowork/continuation.js +70 -0
  66. package/dist/shortcuts/cowork/errors.js +59 -0
  67. package/dist/shortcuts/cowork/host.js +172 -0
  68. package/dist/shortcuts/cowork/index.js +166 -0
  69. package/dist/shortcuts/cowork/manifest.js +65 -0
  70. package/dist/shortcuts/cowork/operations/discuss-write.js +277 -0
  71. package/dist/shortcuts/cowork/operations/item-write.js +380 -0
  72. package/dist/shortcuts/cowork/operations/member-write.js +283 -0
  73. package/dist/shortcuts/cowork/operations/permission-write.js +286 -0
  74. package/dist/shortcuts/cowork/operations/read.js +423 -0
  75. package/dist/shortcuts/cowork/operations/registry.js +39 -0
  76. package/dist/shortcuts/cowork/operations/review-write.js +157 -0
  77. package/dist/shortcuts/cowork/operations/shared.js +215 -0
  78. package/dist/shortcuts/cowork/operations/types.js +24 -0
  79. package/dist/shortcuts/cowork/operations.js +19 -0
  80. package/dist/shortcuts/ehr/host.js +4 -1
  81. package/dist/shortcuts/ehr/operations/recruit-candidate-import.js +757 -0
  82. package/dist/shortcuts/ehr/operations/recruit-position.js +367 -0
  83. package/dist/shortcuts/ehr/operations/recruit-stats.js +133 -0
  84. package/dist/shortcuts/ehr/operations/recruit-write.js +8 -16
  85. package/dist/shortcuts/ehr/operations/recruit.js +35 -10
  86. package/dist/shortcuts/ehr/operations/registry.js +6 -0
  87. package/dist/shortcuts/im/diagnostics.js +97 -0
  88. package/dist/shortcuts/im/host.js +58 -31
  89. package/dist/shortcuts/im/index.js +7 -2
  90. package/dist/shortcuts/im/operations/at-mention.js +127 -0
  91. package/dist/shortcuts/im/operations/file-user.js +10 -2
  92. package/dist/shortcuts/im/operations/group-read.js +26 -5
  93. package/dist/shortcuts/im/operations/group-write.js +35 -28
  94. package/dist/shortcuts/im/operations/msg-sync.js +7 -2
  95. package/dist/shortcuts/im/operations/msg-write.js +76 -10
  96. package/dist/shortcuts/im/operations/quote-mention.js +119 -0
  97. package/dist/shortcuts/im/operations/session.js +1 -1
  98. package/dist/shortcuts/im/operations/shared.js +10 -0
  99. package/dist/shortcuts/im/operations/types.js +13 -0
  100. package/dist/shortcuts/index.js +5 -0
  101. package/dist/shortcuts/mail/host.js +4 -1
  102. package/dist/shortcuts/meeting/host.js +27 -34
  103. package/dist/shortcuts/meeting/operations/create.js +4 -1
  104. package/dist/shortcuts/meeting/operations/eb/catalog.js +5 -0
  105. package/dist/shortcuts/meeting/operations/eb/conflict.js +78 -7
  106. package/dist/shortcuts/meeting/operations/eb/create-flow.js +168 -26
  107. package/dist/shortcuts/meeting/operations/eb/factory.js +69 -1
  108. package/dist/shortcuts/meeting/operations/eb/index.js +16 -3
  109. package/dist/shortcuts/meeting/operations/eb/room-recommend.js +14 -3
  110. package/dist/shortcuts/meeting/operations/eb-fallback.js +159 -0
  111. package/dist/shortcuts/meeting/operations/env.js +93 -46
  112. package/dist/shortcuts/meeting/operations/form-fields.js +110 -0
  113. package/dist/shortcuts/meeting/operations/registry.js +2 -0
  114. package/dist/shortcuts/meeting/operations/standard-guard.js +71 -0
  115. package/dist/shortcuts/meeting/operations.js +16 -0
  116. package/dist/shortcuts/workflow/index.js +110 -1
  117. package/dist/shortcuts/workflow/operations/form.js +24 -3
  118. package/dist/shortcuts/workflow/operations/read.js +104 -23
  119. package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupRules.js +448 -0
  120. package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupStore.js +106 -0
  121. package/dist/shortcuts/workflow/operations/todoSmartConvert/businessRules.js +47 -0
  122. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.collect.js +30 -23
  123. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.core.js +1 -0
  124. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.group.js +1 -0
  125. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.groupSummary.js +2 -1
  126. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.js +2 -4
  127. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.smartGroup.js +138 -181
  128. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.summary.js +12 -7
  129. package/docs/e10-auth.md +1 -1
  130. package/docs/im.md +8 -1
  131. package/docs/todo-smart-convert/README.md +1 -1
  132. package/docs/todo-smart-convert/data-contract.md +2 -2
  133. package/docs/todo-smart-convert/subgroup-rules.md +6 -0
  134. package/package.json +1 -1
  135. package/skill-template/domains/yimiaoban.md +3 -3
  136. package/skill-template/skill-template.md +1 -1
  137. package/skills/weaver-e10-blog/SKILL.md +5 -5
  138. package/skills/weaver-e10-caizhilian/SKILL.md +5 -5
  139. package/skills/weaver-e10-calendar/SKILL.md +5 -5
  140. package/skills/weaver-e10-esb/SKILL.md +5 -5
  141. package/skills/weaver-e10-hrm/SKILL.md +5 -5
  142. package/skills/weaver-e10-jinchengda/SKILL.md +2 -2
  143. package/skills/weaver-e10-jiuchuanhui/SKILL.md +5 -5
  144. package/skills/weaver-e10-jucailin/SKILL.md +18 -12
  145. package/skills/weaver-e10-jucailin/references/recruit-create.md +104 -0
  146. package/skills/weaver-e10-mail/SKILL.md +5 -5
  147. package/skills/weaver-e10-meeting/SKILL.md +171 -25
  148. package/skills/weaver-e10-meeting/references/meeting-eb.md +4 -3
  149. package/skills/weaver-e10-meeting/references/meeting-queries.md +9 -6
  150. package/skills/weaver-e10-meeting/references/meeting-verification.md +8 -6
  151. package/skills/weaver-e10-meeting.zip +0 -0
  152. package/skills/weaver-e10-okr/SKILL.md +5 -5
  153. package/skills/weaver-e10-okr/references/source-manifest.json +3 -3
  154. package/skills/weaver-e10-plan/SKILL.md +5 -5
  155. package/skills/weaver-e10-shared/SKILL.md +12 -12
  156. package/skills/weaver-e10-shared/references/e10-auth-and-session.md +4 -4
  157. package/skills/weaver-e10-wenshuding/SKILL.md +5 -5
  158. package/skills/weaver-e10-workflow/SKILL.md +29 -5
  159. package/skills/weaver-e10-workflow/aigroup/default.json +88 -0
  160. package/skills/weaver-e10-workflow/references/todo-smart-convert.md +66 -14
  161. package/skills/weaver-e10-workflow/references/workflow-agent-entry.md +1 -1
  162. package/skills/weaver-e10-workflow/references/workflow-memory.md +1 -1
  163. package/skills/weaver-e10-workflow/references/workflow-query.md +12 -10
  164. package/skills/weaver-e10-workflow/references/workflow-view.md +2 -2
  165. package/skills/weaver-e10-workflow/tools/todo-serve.cjs +239 -0
  166. package/skills/weaver-e10-workflow/{scripts → tools}/todo-summary.cjs +218 -28
  167. package/skills/weaver-e10-yepiaotong/SKILL.md +10 -8
  168. package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +7 -7
  169. package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +10 -10
  170. package/skills/weaver-e10-yepiaotong/references/reim-examples.md +40 -37
  171. package/skills/weaver-e10-yepiaotong/references/reim-expense-subject-rules.md +4 -4
  172. package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +27 -38
  173. package/skills/weaver-e10-yepiaotong/references/reim-phone-subsidy-rules.md +4 -4
  174. package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +37 -29
  175. package/skills/weaver-e10-yimiaoban/SKILL.md +156 -33
  176. package/skills/weaver-e10-yimiaoban/references/ding-write.md +1 -1
  177. package/skills/weaver-e10-yimiaoban/references/error-codes.md +5 -1
  178. package/skills/weaver-e10-yimiaoban/references/group-read.md +5 -1
  179. package/skills/weaver-e10-yimiaoban/references/group-write.md +6 -4
  180. package/skills/weaver-e10-yimiaoban/references/msg-read.md +1 -0
  181. package/skills/weaver-e10-yimiaoban/references/msg-write.md +34 -2
  182. package/skills/weaver-e10-yimiaoban/references/safety-boundaries.md +5 -2
  183. package/skills/weaver-e10-yimiaoban/references/source-manifest.json +79 -58
  184. package/skills/weaver-e10-yimiaoban/references/user-remind.md +2 -2
  185. package/skills/weaver-e10-ziguanjia/SKILL.md +5 -5
@@ -1,5 +1,10 @@
1
1
  import { createRequire as __esbuildCreateRequire } from 'node:module';
2
2
  const require = __esbuildCreateRequire(import.meta.url);
3
+ import {
4
+ imBusinessError,
5
+ imConfirmationError,
6
+ imValidationError
7
+ } from "./chunk-ZEDWSH32.js";
3
8
  import {
4
9
  collapseNewlines,
5
10
  collectI18nIds,
@@ -9,13 +14,9 @@ import {
9
14
  extractImgs,
10
15
  extractVideos,
11
16
  parseContent,
17
+ parseMsg,
12
18
  senderName
13
19
  } from "./chunk-YLCYX7LE.js";
14
- import {
15
- imBusinessError,
16
- imConfirmationError,
17
- imValidationError
18
- } from "./chunk-ZEDWSH32.js";
19
20
 
20
21
  // src/shortcuts/im/operations/types.ts
21
22
  var READ = "read";
@@ -26,11 +27,17 @@ function imSuccess(action, data, meta) {
26
27
  return payload;
27
28
  }
28
29
  function schemaOf(properties, options = {}) {
30
+ const clauses = [];
31
+ if (options.requiredAny?.length) clauses.push({ anyOf: options.requiredAny.map((key) => ({ required: [key] })) });
32
+ if (options.anyOf?.length) clauses.push({ anyOf: options.anyOf });
33
+ if (options.allOf?.length) clauses.push(...options.allOf);
34
+ const condition = clauses.length === 1 ? clauses[0] : clauses.length > 1 ? { allOf: clauses } : {};
29
35
  return {
30
36
  type: "object",
31
37
  additionalProperties: false,
32
38
  properties,
33
39
  ...options.required?.length ? { required: options.required } : {},
40
+ ...condition,
34
41
  ...options.description ? { description: options.description } : {}
35
42
  };
36
43
  }
@@ -202,6 +209,10 @@ function assertImOk(value, actionLabel) {
202
209
  function unwrapInner(value) {
203
210
  return value?.data?.data ?? value?.data;
204
211
  }
212
+ var SYSTEM_MEMBER_CID = "10002";
213
+ function isSystemMember(member) {
214
+ return str(member?.cid) === SYSTEM_MEMBER_CID;
215
+ }
205
216
  function isMemberRow(value) {
206
217
  return Boolean(value) && typeof value === "object" && (value.uid !== void 0 || value.user !== void 0);
207
218
  }
@@ -326,7 +337,7 @@ function str(value) {
326
337
  if (value === void 0 || value === null) return "";
327
338
  return String(value);
328
339
  }
329
- function parseMsg(value) {
340
+ function parseMsg2(value) {
330
341
  if (!value) return null;
331
342
  if (typeof value === "string") {
332
343
  try {
@@ -488,7 +499,7 @@ var groupInfo = {
488
499
  inputSchema: schemaOf({
489
500
  groupIds: { type: "array", items: { type: "string" }, description: "\u7FA4 id \u5217\u8868\uFF08\u9017\u53F7\u4E32\u6216\u6570\u7EC4\uFF09" },
490
501
  groupId: { type: "string", description: "\u5355\u7FA4 id\uFF08groupIds \u7684\u4FBF\u6377\u5F62\u5F0F\uFF09" }
491
- }, { description: "groupIds / groupId \u81F3\u5C11\u5176\u4E00" }),
502
+ }, { requiredAny: ["groupIds", "groupId"], description: "\u6309\u7FA4 id \u67E5\u57FA\u7840\u4FE1\u606F\uFF08groupIds / groupId \u81F3\u5C11\u5176\u4E00\uFF09" }),
492
503
  handler: async (args, { host }) => {
493
504
  let ids = [];
494
505
  if (Array.isArray(args.groupIds)) ids = args.groupIds.map((x) => String(x));
@@ -516,12 +527,23 @@ var groupInfo = {
516
527
  maskName: maskTypeName(Number(g.mask ?? 0)),
517
528
  userNum: g.user_num,
518
529
  maxNum: g.max_num,
519
- hostUid: str(g.host_uid ?? g.hostUid ?? ""),
530
+ /** 群创建者 uid(服务端字段 host_uid);**不是群主**,群主以 group.users 的 role=3 为准。 */
531
+ creatorUid: str(g.host_uid ?? g.hostUid ?? ""),
532
+ /** 群创建者 cid(服务端字段 host_cid),与 creatorUid 配对。 */
533
+ creatorCid: str(g.host_cid ?? g.hostCid ?? ""),
520
534
  state: Number(g.state ?? -1),
521
535
  stateName: stateName(Number(g.state ?? -1)),
522
536
  createTime: formatFullTime(g.create_time ?? g.createTime)
523
537
  }));
524
- return imSuccess("im.group.info", { total: groups.length, groups });
538
+ return imSuccess("im.group.info", {
539
+ total: groups.length,
540
+ groups,
541
+ fieldNotes: {
542
+ creatorUid: "\u7FA4\u521B\u5EFA\u8005\uFF08host_uid\uFF09\uFF0C\u4E0D\u662F\u7FA4\u4E3B\uFF1B\u521B\u5EFA\u540E\u8F6C\u8BA9\u7FA4\u4E3B\u4E5F\u4E0D\u4F1A\u53D8\u3002",
543
+ creatorCid: "\u7FA4\u521B\u5EFA\u8005 cid\uFF08host_cid\uFF09\u3002",
544
+ owner: "\u7FA4\u4E3B\u8BF7\u7528 im.group.users \u7684 role=3\uFF08\u6216 im.group.admins\uFF09\u83B7\u53D6\uFF0C\u4E0D\u8981\u7528 creatorUid \u5224\u65AD\u3002"
545
+ }
546
+ });
525
547
  }
526
548
  };
527
549
  var groupUsers = {
@@ -562,7 +584,7 @@ var groupUsers = {
562
584
  const hasCid = (memberMask & 2) !== 0;
563
585
  const hasUid = (memberMask & 4) !== 0;
564
586
  const roleNames = { 0: "\u4E0D\u53EF\u7528", 1: "\u666E\u901A\u6210\u5458", 2: "\u7BA1\u7406\u5458", 3: "\u7FA4\u4E3B", 4: "\u5BA2\u6237", 5: "\u8D1F\u8D23\u4EBA", 6: "\u534F\u52A9\u4EBA\u5458" };
565
- const personIds = members.map((m) => String(m?.uid ?? "")).filter((x) => x && x !== "0");
587
+ const personIds = members.filter((m) => !isSystemMember(m)).map((m) => String(m?.uid ?? "")).filter((x) => x && x !== "0");
566
588
  const personMap = personIds.length ? await host.resolveUsersByIds([...new Set(personIds)]) : {};
567
589
  const rows = members.map((m) => ({
568
590
  uid: hasUid ? str(m.uid) : void 0,
@@ -570,11 +592,17 @@ var groupUsers = {
570
592
  name: personMap[str(m.uid)]?.name || str(m.uid),
571
593
  role: hasRole ? Number(m.role_type ?? m.role ?? -1) : void 0,
572
594
  roleName: hasRole ? roleNames[Number(m.role_type ?? m.role ?? -1)] ?? "-" : void 0,
573
- addTime: hasAddTime ? formatFullTime(m.add_time ?? m.addTime) : void 0
595
+ addTime: hasAddTime ? formatFullTime(m.add_time ?? m.addTime) : void 0,
596
+ /** 服务端自动补入的系统成员(可选功能,不是真实员工),统计真实成员时排除。 */
597
+ isSystem: hasCid ? isSystemMember(m) : void 0
574
598
  }));
599
+ const personRows = rows.filter((row) => row.isSystem !== true);
575
600
  return imSuccess("im.group.users", {
576
601
  groupId,
602
+ /** 成员总数(含系统成员,即服务端返回的原始条数) */
577
603
  totalNum: inner?.total_num ?? rows.length,
604
+ /** 真实成员数(排除系统成员 cid=10002),判断「只剩自己」请用这个 */
605
+ personNum: personRows.length,
578
606
  endFlag: inner?.end_flag,
579
607
  serverUc: str(inner?.server_uc ?? ""),
580
608
  members: rows
@@ -910,7 +938,7 @@ var groupCreatePair = makeWritePair({
910
938
  }
911
939
  const { users, failed, names: resolvedNames } = await resolveMembers(args, env);
912
940
  if (failed.length && args.removeFailed !== true) {
913
- throw imValidationError("members_resolve_failed", `\u4EE5\u4E0B\u6210\u5458\u4FE1\u606F\u83B7\u53D6\u5931\u8D25\uFF08cid/uid \u7F3A\u5931\u6216\u4E3A 0\uFF09\uFF1A${failed.map((f) => f.name || f.uid).join("\u3001")}\uFF1B\u786E\u8BA4\u79FB\u9664\u8BF7\u4F20 removeFailed:true`, { details: failed });
941
+ throw imValidationError("members_resolve_failed", `\u4EE5\u4E0B\u6210\u5458\u4FE1\u606F\u83B7\u53D6\u5931\u8D25\uFF08cid/uid \u7F3A\u5931\u6216\u4E3A 0\uFF09\uFF1A${failed.map((f) => f.name || f.uid).join("\u3001")}\uFF1B\u786E\u8BA4\u79FB\u9664\u8BF7\u4F20 removeFailed:true`, failed);
914
942
  }
915
943
  if (users.length === 0) throw imValidationError("members_empty", "\u6CA1\u6709\u53EF\u5165\u7FA4\u7684\u6210\u5458");
916
944
  const selfUid = str((await env.host.getSession()).userId);
@@ -950,7 +978,9 @@ var groupCreatePair = makeWritePair({
950
978
  memberCount: users.length,
951
979
  members: users.map((u) => u.uid),
952
980
  adminCount: admins.length,
953
- removeFailed: args.removeFailed === true ? failed.map((f) => f.uid) : []
981
+ removeFailed: args.removeFailed === true ? failed.map((f) => f.uid) : [],
982
+ /** 服务端可选能力:建群时会自动补入系统成员(cid=10002),实际成员数可能比 users 多 1。 */
983
+ systemMemberNote: "\u5EFA\u7FA4\u540E\u670D\u52A1\u7AEF\u53EF\u80FD\u81EA\u52A8\u8865\u5165 1 \u4E2A\u7CFB\u7EDF\u6210\u5458\uFF08cid=10002\uFF0C\u7FA4\u5185\u7CFB\u7EDF\u6D88\u606F\u8F7D\u4F53\uFF0C\u79DF\u6237\u4FA7\u53EF\u9009\u5F00\u542F\uFF09\uFF1B\u5B83\u4E0D\u662F\u771F\u5B9E\u5458\u5DE5\uFF0C\u4E5F\u4E0D\u662F\u672C\u6B21\u4F20\u5165\u7684\u6210\u5458\uFF0C\u4E0D\u9700\u8981\u4E5F\u4E0D\u5EFA\u8BAE\u5355\u72EC\u8E22\u51FA\u3002"
954
984
  },
955
985
  snapshot: { name, users, admins, failed, removeFailed: args.removeFailed === true }
956
986
  };
@@ -1040,21 +1070,18 @@ var groupExitPair = makeWritePair({
1040
1070
  let memberCount;
1041
1071
  let isOwner = false;
1042
1072
  try {
1043
- const infoRes = await env.host.request({
1073
+ const usersRes = await env.host.request({
1044
1074
  method: "POST",
1045
- path: "/api/em/msg/executeIm/group/queryGroupInfo",
1046
- body: { trans_id: 0, type: 0, mask: 0, group_id: [groupId], flag: 0 },
1047
- operation: "im.group.exit.plan.info"
1075
+ path: "/api/em/msg/executeIm/group/getGroupUsers",
1076
+ body: { group_id: groupId, type: 0, sync_type: 0, member_mask: 142, client_uc: "0" },
1077
+ operation: "im.group.exit.plan.members"
1048
1078
  });
1049
- const info = (unwrapInner(infoRes)?.datas || [])[0];
1050
- if (info) {
1051
- const raw = info.user_num ?? info.userNum;
1052
- memberCount = raw === void 0 || raw === null ? void 0 : Number(raw);
1053
- const hostUid = str(info.host_uid ?? info.hostUid ?? "");
1054
- if (hostUid) {
1055
- const self = await env.host.getSelfIdentity();
1056
- isOwner = hostUid === String(self.uid);
1057
- }
1079
+ const members = extractGroupMembers(unwrapInner(usersRes));
1080
+ if (members.length) {
1081
+ const self = await env.host.getSelfIdentity();
1082
+ const selfRow = members.find((m) => str(m?.uid) === String(self.uid));
1083
+ isOwner = Number(selfRow?.role_type ?? selfRow?.role ?? -1) === 3;
1084
+ memberCount = members.filter((m) => !isSystemMember(m)).length;
1058
1085
  }
1059
1086
  } catch {
1060
1087
  }
@@ -1063,7 +1090,7 @@ var groupExitPair = makeWritePair({
1063
1090
  throw imValidationError(
1064
1091
  "owner_exit_ack_required",
1065
1092
  `\u9000\u7FA4\u98CE\u9669\u786E\u8BA4\u7F3A\u5931\uFF1A${isOwner ? "\u4F60\u662F\u8BE5\u7FA4\u7FA4\u4E3B" : "\u4F60\u662F\u8BE5\u7FA4\u6700\u540E\u4E00\u4E2A\u6210\u5458"}\uFF0C\u9000\u7FA4\u540E\u8BE5\u7FA4\u4F1A\u53D8\u6210\u65E0\u4E3B\u7A7A\u7FA4\uFF0C\u4E4B\u540E join/destroy \u90FD\u4F1A\u88AB\u670D\u52A1\u7AEF\u62D2\u7EDD\uFF081210\uFF09\uFF0C\u53EA\u80FD\u7531\u5BA2\u6237\u7AEF\u6216\u7BA1\u7406\u5458\u5904\u7406\u3002\u786E\u8BA4\u4ECD\u8981\u9000\u7FA4\u8BF7\u4F20 acknowledgeOrphanRisk:true`,
1066
- { details: { groupId, isOwner, memberCount } }
1093
+ { groupId, isOwner, memberCount }
1067
1094
  );
1068
1095
  }
1069
1096
  return {
@@ -1346,14 +1373,18 @@ var groupAnnounceModifyPair = makeWritePair({
1346
1373
  };
1347
1374
  }
1348
1375
  });
1349
- function buildWriteDefinition(name, method, summary, inputProps, pair) {
1376
+ function buildWriteDefinition(name, method, summary, inputProps, pair, condition = {}) {
1350
1377
  const requiredInput = Object.keys(inputProps).filter((k) => {
1351
1378
  const prop = inputProps[k];
1352
1379
  return prop?.required === true;
1353
1380
  });
1354
1381
  const prepareSchema2 = schemaOf(
1355
1382
  { ...inputProps, removeFailed: { type: "boolean", description: "\u786E\u8BA4\u79FB\u9664\u89E3\u6790\u5931\u8D25\u6210\u5458" } },
1356
- { required: requiredInput, description: summary }
1383
+ {
1384
+ ...condition,
1385
+ required: [.../* @__PURE__ */ new Set([...condition.required || [], ...requiredInput])],
1386
+ description: summary
1387
+ }
1357
1388
  );
1358
1389
  return [
1359
1390
  {
@@ -1391,30 +1422,30 @@ var groupWriteOps = [
1391
1422
  name: { type: "string", description: "\u7FA4\u540D\uFF08\u7F3A\u7701\u81EA\u52A8\u751F\u6210\uFF09" },
1392
1423
  names: { type: "array", items: { type: "string" }, description: "\u4E0E users \u987A\u5E8F\u5BF9\u5E94\u59D3\u540D\uFF08\u7528\u4E8E\u9ED8\u8BA4\u7FA4\u540D\uFF09" },
1393
1424
  admins: { type: "array", items: { type: "string" }, description: "\u7BA1\u7406\u5458 uid" }
1394
- }, groupCreatePair),
1425
+ }, groupCreatePair, { required: ["users"] }),
1395
1426
  ...buildWriteDefinition("im.group.invite", "group.invite", "\u9080\u8BF7\u6210\u5458\u5165\u7FA4", {
1396
1427
  groupId: { type: "string", pattern: "^\\d+$", description: "\u7FA4 id" },
1397
1428
  users: { type: "array", items: { type: "string" }, description: "\u88AB\u9080\u8BF7 uid" }
1398
- }, groupInvitePair),
1429
+ }, groupInvitePair, { required: ["groupId", "users"] }),
1399
1430
  ...buildWriteDefinition("im.group.kick", "group.kick", "\u8E22\u51FA\u7FA4\u6210\u5458", {
1400
1431
  groupId: { type: "string", pattern: "^\\d+$", description: "\u7FA4 id" },
1401
1432
  users: { type: "array", items: { type: "string" }, description: "\u88AB\u8E22 uid" }
1402
- }, groupKickPair),
1433
+ }, groupKickPair, { required: ["groupId", "users"] }),
1403
1434
  ...buildWriteDefinition("im.group.exit", "group.exit", "\u9000\u51FA\u7FA4\u804A", {
1404
1435
  groupId: { type: "string", pattern: "^\\d+$", description: "\u7FA4 id" },
1405
1436
  acknowledgeOrphanRisk: {
1406
1437
  type: "boolean",
1407
1438
  description: "\u7FA4\u4E3B\u6216\u6700\u540E\u4E00\u4E2A\u6210\u5458\u9000\u7FA4\u65F6\u5FC5\u987B\u663E\u5F0F\u4F20 true\uFF08\u9000\u7FA4\u540E\u8BE5\u7FA4\u4F1A\u53D8\u6210\u65E0\u4E3B\u7A7A\u7FA4\uFF0C\u65E0\u6CD5\u518D join/destroy\uFF09"
1408
1439
  }
1409
- }, groupExitPair),
1440
+ }, groupExitPair, { required: ["groupId"] }),
1410
1441
  ...buildWriteDefinition("im.group.destroy", "group.destroy", "\u89E3\u6563\u7FA4\u804A\uFF08\u4EC5\u7FA4\u4E3B\uFF0C\u4E0D\u53EF\u6062\u590D\uFF09", {
1411
1442
  groupId: { type: "string", pattern: "^\\d+$", description: "\u7FA4 id" }
1412
- }, groupDestroyPair),
1443
+ }, groupDestroyPair, { required: ["groupId"] }),
1413
1444
  ...buildWriteDefinition("im.group.join", "group.join", "\u7533\u8BF7\u52A0\u5165\u7FA4\u804A", {
1414
1445
  groupId: { type: "string", pattern: "^\\d+$", description: "\u7FA4 id\uFF08token \u4E8C\u9009\u4E00\uFF09" },
1415
1446
  token: { type: "string", description: "\u7FA4 token/\u4E8C\u7EF4\u7801\u52A0\u5165" },
1416
1447
  mark: { type: "string", maxLength: 100, description: "\u7533\u8BF7\u7406\u7531" }
1417
- }, groupJoinPair),
1448
+ }, groupJoinPair, { requiredAny: ["groupId", "token"] }),
1418
1449
  ...buildWriteDefinition("im.group.modify", "group.modify", "\u6279\u91CF\u4FEE\u6539\u7FA4\u5C5E\u6027\uFF08batModGroupInfo\uFF09", {
1419
1450
  groupId: { type: "string", pattern: "^\\d+$", description: "\u7FA4 id" },
1420
1451
  num: { type: "integer", description: "\u6700\u5927\u4EBA\u6570" },
@@ -1426,7 +1457,7 @@ var groupWriteOps = [
1426
1457
  creator: { type: "string", description: "\u8F6C\u8BA9\u7FA4\u4E3B\uFF08\u5355 uid\uFF09" },
1427
1458
  copyGroupids: { type: "array", items: { type: "string" }, description: "\u62F7\u8D1D\u7FA4\u5217\u8868" },
1428
1459
  gtId: { type: "string", description: "\u5173\u8054\u7FA4\u7C7B\u578B id" }
1429
- }, groupModifyPair),
1460
+ }, groupModifyPair, { required: ["groupId"] }),
1430
1461
  ...buildWriteDefinition("im.group.rename", "group.rename", "\u4FEE\u6539\u7FA4\u4FE1\u606F\uFF08\u4E00\u6B21\u4E00\u9879\uFF1A\u7FA4\u540D/\u5386\u53F2/\u7FA4\u4E3B/\u663E\u793A/\u6253\u6270/\u6807\u8BB0/gtid\uFF09", {
1431
1462
  groupId: { type: "string", pattern: "^\\d+$", description: "\u7FA4 id" },
1432
1463
  name: { type: "string", description: "\u6539\u7FA4\u540D" },
@@ -1436,7 +1467,7 @@ var groupWriteOps = [
1436
1467
  msgSetting: { type: "integer", description: "\u6D88\u606F\u6253\u6270\u8BBE\u7F6E" },
1437
1468
  mark: { type: "integer", description: "\u6807\u8BB0\u4F4D" },
1438
1469
  gtid: { type: "string", description: "GTID" }
1439
- }, groupRenamePair),
1470
+ }, groupRenamePair, { required: ["groupId"] }),
1440
1471
  ...buildWriteDefinition("im.group.announce.modify", "group.announce.modify", "\u65B0\u589E/\u4FEE\u6539/\u5220\u9664\u7FA4\u516C\u544A", {
1441
1472
  groupId: { type: "string", pattern: "^\\d+$", description: "\u7FA4 id" },
1442
1473
  annouce: { type: "string", description: "\u516C\u544A\u5185\u5BB9\uFF08\u5220\u9664\u65F6\u4E0D\u9700\u8981\uFF09" },
@@ -1445,10 +1476,112 @@ var groupWriteOps = [
1445
1476
  notice: { type: "integer", enum: [0, 1, 2], description: "0 \u53D1\u901A\u77E5(\u9ED8\u8BA4)/1 \u4E0D\u53D1/2 \u53D1\u5E76@\u5168\u4F53" },
1446
1477
  fmark: { type: "integer", enum: [0, 1], description: "\u65B0\u4EBA\u5FC5\u770B" },
1447
1478
  related: { type: "string", description: "\u5173\u8054\u9644\u4EF6 id" }
1448
- }, groupAnnounceModifyPair)
1479
+ }, groupAnnounceModifyPair, { required: ["groupId"] })
1449
1480
  ];
1450
1481
  var groupWriteOperations = groupWriteOps;
1451
1482
 
1483
+ // src/shortcuts/im/operations/quote-mention.ts
1484
+ function hasQuoteInput(args) {
1485
+ return args.quoteMsgId !== void 0 || args.replyMsgId !== void 0;
1486
+ }
1487
+ function quotedId(value) {
1488
+ const id = str(value);
1489
+ if (!id || !/^\d+$/.test(id) || id === "0") {
1490
+ throw imValidationError("quote_id_invalid", "quoteMsgId/replyMsgId \u5FC5\u987B\u662F\u975E 0 \u7684\u7EAF\u6570\u5B57\u6D88\u606F id");
1491
+ }
1492
+ return id;
1493
+ }
1494
+ function quotedContentText(msgObj) {
1495
+ if (!msgObj) return "";
1496
+ const parsed = parseContent(msgObj);
1497
+ return str(parsed.content).trim();
1498
+ }
1499
+ async function resolveQuotedRef(args, env, target) {
1500
+ const hasQuote = args.quoteMsgId !== void 0 && args.quoteMsgId !== null && args.quoteMsgId !== "";
1501
+ const hasReply = args.replyMsgId !== void 0 && args.replyMsgId !== null && args.replyMsgId !== "";
1502
+ if (hasQuote && hasReply) {
1503
+ throw imValidationError("quote_conflict", "quoteMsgId\uFF08\u5F15\u7528\uFF09\u4E0E replyMsgId\uFF08\u56DE\u590D\uFF09\u53EA\u80FD\u4E8C\u9009\u4E00");
1504
+ }
1505
+ if (!hasQuote && !hasReply) return null;
1506
+ const kind = hasQuote ? "quote" : "reply";
1507
+ const msgId = quotedId(hasQuote ? args.quoteMsgId : args.replyMsgId);
1508
+ const isSingle = !target.groupId;
1509
+ if (isSingle && (!target.toUid || !target.toCid)) {
1510
+ throw imValidationError("quote_target_required", "\u5355\u804A\u5F15\u7528\u9700\u8981 toUid + toCid \u624D\u80FD\u5B9A\u4F4D\u88AB\u5F15\u6D88\u606F");
1511
+ }
1512
+ const scopeLabel = isSingle ? `\u4E0E ${target.toUid} \u7684\u5355\u804A` : `\u7FA4 ${target.groupId}`;
1513
+ let rows = [];
1514
+ try {
1515
+ const idBig = BigInt(msgId);
1516
+ const window = { start: String(idBig + 1000000000n), end: String(idBig - 1000000000n), max_num: 5 };
1517
+ const res = isSingle ? await env.host.request({
1518
+ method: "POST",
1519
+ path: "/api/em/msg/executeIm/msg/syncSingleMsg",
1520
+ body: { trans_id: 0, dev: 4, enc_type: 0, datas: [{ from_cid: String(target.toCid), from_uid: String(target.toUid), ...window }] },
1521
+ operation: "im.msg.send.single.quoteResolve"
1522
+ }) : await env.host.request({
1523
+ method: "POST",
1524
+ path: "/api/em/msg/executeIm/chat/syncGroupMsg",
1525
+ body: { trans_id: 0, dev: 4, type: 0, enc_type: 0, datas: [{ group_id: String(target.groupId), ...window }] },
1526
+ operation: "im.msg.send.group.quoteResolve"
1527
+ });
1528
+ assertImOk(res, "\u5B9A\u4F4D\u88AB\u5F15\u6D88\u606F");
1529
+ const outer = unwrapInner(res)?.datas || [];
1530
+ for (const group of outer) rows.push(...group?.datas || group?.data || []);
1531
+ } catch (error) {
1532
+ throw imValidationError(
1533
+ "quote_msg_not_found",
1534
+ `\u65E0\u6CD5\u5B9A\u4F4D\u88AB\u5F15\u6D88\u606F ${msgId}\uFF1A${error instanceof Error ? error.message : String(error)}`,
1535
+ { ...target, quotedMsgId: msgId }
1536
+ );
1537
+ }
1538
+ const row = rows.find((r) => str(r?.ser_msgid) === msgId);
1539
+ if (!row) {
1540
+ throw imValidationError("quote_msg_not_found", `\u6D88\u606F ${msgId} \u4E0D\u5728${scopeLabel}\u5185\uFF08\u6216\u5DF2\u88AB\u64A4\u56DE\uFF09\uFF0C\u65E0\u6CD5\u5F15\u7528`, {
1541
+ ...target,
1542
+ quotedMsgId: msgId
1543
+ });
1544
+ }
1545
+ const msgObj = parseMsg(row.msg);
1546
+ const fromUid = str(row.from_uid) || str(msgObj?.suid);
1547
+ const fromCid = str(row.from_cid) || str(msgObj?.scid);
1548
+ let fromName = str(msgObj?.sname);
1549
+ if (fromUid) {
1550
+ try {
1551
+ const personMap = await env.host.resolveUsersByIds([fromUid]);
1552
+ fromName = personMap[fromUid]?.name || fromName;
1553
+ } catch {
1554
+ }
1555
+ }
1556
+ const ref = {
1557
+ id: msgId,
1558
+ t: str(msgObj?.type ?? row.kind ?? "1") || "1",
1559
+ f: "0",
1560
+ time: Number(row.msgtime) > 0 ? Number(row.msgtime) * 1e3 : Date.now(),
1561
+ fname: fromName || fromUid || "",
1562
+ fuser: { cid: fromCid, uid: fromUid },
1563
+ rcon: quotedContentText(msgObj),
1564
+ display: "",
1565
+ ...kind === "reply" ? { oid: msgId } : {}
1566
+ };
1567
+ return { kind, quotedMsgId: msgId, fromName: ref.fname, fromUid, text: ref.rcon, ref };
1568
+ }
1569
+ function extractQuoteSummary(msgObj) {
1570
+ const raw = msgObj ? msgObj.rmsg ?? msgObj.ref : void 0;
1571
+ if (!raw || typeof raw !== "object") return void 0;
1572
+ const kind = msgObj?.rmsg ? "reply" : "quote";
1573
+ return {
1574
+ kind,
1575
+ id: str(raw.id),
1576
+ msgType: str(raw.t),
1577
+ fromName: str(raw.fname),
1578
+ fromUid: str(raw.fuser?.uid),
1579
+ fromCid: str(raw.fuser?.cid),
1580
+ msgtime: raw.time,
1581
+ text: str(raw.rcon)
1582
+ };
1583
+ }
1584
+
1452
1585
  // src/shortcuts/im/operations/msg-sync.ts
1453
1586
  var MAX_MSG_ID = String((1n << 63n) - 1n);
1454
1587
  function resolveRange(args, idKeys = { start: "start", end: "end" }) {
@@ -1512,7 +1645,7 @@ async function enrichMessages(rawRows, host, options = {}) {
1512
1645
  for (const [uid, p] of Object.entries(personMap)) nameMap[uid] = p.name;
1513
1646
  const enriched = [];
1514
1647
  for (const row of rows) {
1515
- const msgObj = parseMsg(row.msg);
1648
+ const msgObj = parseMsg2(row.msg);
1516
1649
  const parsed = parseContent(msgObj, { i18nMap, nameMap });
1517
1650
  const imgs = msgObj ? extractImgs(msgObj) : [];
1518
1651
  const videos = msgObj ? extractVideos(msgObj) : [];
@@ -1583,6 +1716,7 @@ async function enrichMessages(rawRows, host, options = {}) {
1583
1716
  });
1584
1717
  }
1585
1718
  const sender = senderName(msgObj || {}, row.from_uid, options.authUid, nameMap);
1719
+ const quoteSummary = extractQuoteSummary(msgObj);
1586
1720
  enriched.push({
1587
1721
  msgid: str(row.ser_msgid),
1588
1722
  sender,
@@ -1593,6 +1727,7 @@ async function enrichMessages(rawRows, host, options = {}) {
1593
1727
  typeName: parsed.typeName,
1594
1728
  title: options.titleFirst ? parsed.title : void 0,
1595
1729
  content: collapseNewlines(parsed.content),
1730
+ ...quoteSummary ? { quote: quoteSummary, quoteTime: Number(quoteSummary.msgtime) > 0 ? formatFullTime(Math.floor(Number(quoteSummary.msgtime) / 1e3)) : void 0 } : {},
1596
1731
  must: parsed.must,
1597
1732
  fileName: parsed.fileName,
1598
1733
  media,
@@ -1820,7 +1955,7 @@ var msgReadSingle = {
1820
1955
  toCid: { type: "string", pattern: "^\\d+$", description: "\u5BF9\u65B9 cid" },
1821
1956
  msgids: { type: "array", items: { type: "string" }, description: "\u81EA\u5DF1\u53D1\u51FA\u7684\u6D88\u606F id\uFF08\u6700\u591A 50\uFF09" },
1822
1957
  recvMsgids: { type: "array", items: { type: "string" }, description: "\u81EA\u5DF1\u63A5\u6536\u7684\u6D88\u606F id\uFF08\u6700\u591A 50\uFF09" }
1823
- }, { required: ["toUid", "toCid"], description: "\u67E5\u8BE2\u5355\u804A\u9605\u8BFB\u72B6\u6001\uFF08msgids/recvMsgids \u81F3\u5C11\u5176\u4E00\uFF09" }),
1958
+ }, { required: ["toUid", "toCid"], requiredAny: ["msgids", "recvMsgids"], description: "\u67E5\u8BE2\u5355\u804A\u9605\u8BFB\u72B6\u6001\uFF08msgids / recvMsgids \u81F3\u5C11\u5176\u4E00\uFF09" }),
1824
1959
  handler: async (args, { host }) => {
1825
1960
  const hasSent = Array.isArray(args.msgids) && args.msgids.length > 0;
1826
1961
  const hasRecv = Array.isArray(args.recvMsgids) && args.recvMsgids.length > 0;
@@ -1864,7 +1999,7 @@ var msgReadGroup = {
1864
1999
  groupId: { type: "string", pattern: "^\\d+$", description: "\u7FA4 id" },
1865
2000
  msgids: { type: "array", items: { type: "string" }, description: "\u81EA\u5DF1\u53D1\u51FA\u7684\u6D88\u606F id\uFF08\u6700\u591A 50\uFF09" },
1866
2001
  recvMsgids: { type: "array", items: { type: "string" }, description: "\u522B\u4EBA\u53D1\u51FA\u7684\u6D88\u606F id\uFF08\u6700\u591A 50\uFF09" }
1867
- }, { required: ["groupId"], description: "\u67E5\u8BE2\u7FA4\u6D88\u606F\u9605\u8BFB\u72B6\u6001" }),
2002
+ }, { required: ["groupId"], requiredAny: ["msgids", "recvMsgids"], description: "\u67E5\u8BE2\u7FA4\u6D88\u606F\u9605\u8BFB\u72B6\u6001\uFF08msgids / recvMsgids \u81F3\u5C11\u5176\u4E00\uFF09" }),
1868
2003
  handler: async (args, { host }) => {
1869
2004
  const hasSent = Array.isArray(args.msgids) && args.msgids.length > 0;
1870
2005
  const hasRecv = Array.isArray(args.recvMsgids) && args.recvMsgids.length > 0;
@@ -1956,6 +2091,109 @@ var msgReadOperations = [
1956
2091
  // src/shortcuts/im/operations/msg-write.ts
1957
2092
  import { existsSync } from "node:fs";
1958
2093
  import { resolve } from "node:path";
2094
+
2095
+ // src/shortcuts/im/operations/at-mention.ts
2096
+ var AT_ALL_ENTRY = { cid: "10000", fd: "@", id: "88", nm: "\u5168\u4F53\u6210\u5458", t: "2" };
2097
+ function truthy(value) {
2098
+ return value === true || value === "true" || value === "1";
2099
+ }
2100
+ function uidList(value) {
2101
+ if (value === void 0 || value === null || value === "") return [];
2102
+ const raw = Array.isArray(value) ? value.map((x) => str(x)) : String(value).split(/[,,;;\s]+/);
2103
+ return raw.map((x) => x.trim()).filter((x) => x && x !== "0");
2104
+ }
2105
+ function hasAtInput(args) {
2106
+ return args.atAll !== void 0 || args.atUids !== void 0;
2107
+ }
2108
+ async function resolveAtMentions(args, env, groupId) {
2109
+ const atAll = truthy(args.atAll);
2110
+ const atUids = uidList(args.atUids);
2111
+ if (!atAll && !atUids.length) return [];
2112
+ const entries = [];
2113
+ if (atAll) entries.push({ ...AT_ALL_ENTRY });
2114
+ if (atUids.length) {
2115
+ let members = [];
2116
+ try {
2117
+ const res = await env.host.request({
2118
+ method: "POST",
2119
+ path: "/api/em/msg/executeIm/group/getGroupUsers",
2120
+ body: { group_id: groupId, type: 0, sync_type: 0, member_mask: 6, client_uc: "0" },
2121
+ operation: "im.msg.send.group.atMembers"
2122
+ });
2123
+ members = extractGroupMembers(unwrapInner(res));
2124
+ } catch (error) {
2125
+ throw imValidationError(
2126
+ "at_members_unavailable",
2127
+ `\u65E0\u6CD5\u6838\u5B9E @ \u76EE\u6807\u662F\u5426\u5728\u7FA4\u5185\uFF1A\u62C9\u53D6\u7FA4\u6210\u5458\u5931\u8D25\uFF08${error instanceof Error ? error.message : String(error)}\uFF09`,
2128
+ { groupId, atUids }
2129
+ );
2130
+ }
2131
+ const inGroup = /* @__PURE__ */ new Map();
2132
+ for (const m of members) {
2133
+ if (isSystemMember(m)) continue;
2134
+ inGroup.set(str(m.uid), str(m.cid));
2135
+ }
2136
+ const missing = atUids.filter((uid) => !inGroup.has(uid));
2137
+ if (missing.length) {
2138
+ throw imValidationError(
2139
+ "at_member_not_in_group",
2140
+ `\u4EE5\u4E0B @ \u76EE\u6807\u4E0D\u5728\u7FA4 ${groupId} \u5185\uFF0C\u5DF2\u62D2\u7EDD\u53D1\u9001\uFF1A${missing.join(", ")}`,
2141
+ { groupId, missing, atUids }
2142
+ );
2143
+ }
2144
+ const personMap = await env.host.resolveUsersByIds([...new Set(atUids)]);
2145
+ for (const uid of atUids) {
2146
+ entries.push({ cid: inGroup.get(uid) || "", fd: "@", id: uid, nm: personMap[uid]?.name || uid, t: "1" });
2147
+ }
2148
+ }
2149
+ return entries;
2150
+ }
2151
+ function escapeRegExp(value) {
2152
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2153
+ }
2154
+ function buildAtText(text, entries) {
2155
+ let v = String(text ?? "");
2156
+ const used = /* @__PURE__ */ new Set();
2157
+ for (const entry of entries) {
2158
+ const names = entry.t === "2" ? ["\u5168\u4F53\u6210\u5458", "\u6240\u6709\u4EBA"] : [entry.nm];
2159
+ for (const nm of names) {
2160
+ const re = new RegExp(`@${escapeRegExp(nm)}`, "g");
2161
+ if (!re.test(v)) continue;
2162
+ v = v.replace(re, () => `:@${entry.id};`);
2163
+ used.add(entry);
2164
+ break;
2165
+ }
2166
+ }
2167
+ const rest = entries.filter((e) => !used.has(e));
2168
+ if (rest.length) {
2169
+ const prefix = rest.map((e) => `:@${e.id};`).join(" ");
2170
+ v = v.trim() ? `${prefix} ${v}` : prefix;
2171
+ }
2172
+ const aus = [...used, ...rest];
2173
+ return { v, aus };
2174
+ }
2175
+ function buildAtMsgJson(v, aus, self, extra = {}) {
2176
+ return JSON.stringify({
2177
+ bgc: "",
2178
+ cnt: "0",
2179
+ dev: 5,
2180
+ display: "",
2181
+ dt: [{ txt: { aus, ft: "china", next: "0", v } }],
2182
+ guid: "0",
2183
+ idx: "0",
2184
+ opb: ["received", "reply"],
2185
+ scid: self.cid,
2186
+ sname: self.name,
2187
+ suid: self.uid,
2188
+ sysId: "",
2189
+ type: "1",
2190
+ ver: "1.0",
2191
+ weaOaId: "",
2192
+ ...extra
2193
+ });
2194
+ }
2195
+
2196
+ // src/shortcuts/im/operations/msg-write.ts
1959
2197
  function assertLocalFile(pathValue, field) {
1960
2198
  const abs = resolve(String(pathValue ?? ""));
1961
2199
  if (!existsSync(abs)) throw imValidationError("file_not_found", `${field} \u6587\u4EF6\u4E0D\u5B58\u5728: ${abs}`);
@@ -1982,7 +2220,17 @@ var sendSinglePair = makeWritePair({
1982
2220
  if (!toUid || !toCid || toUid === "0" || toCid === "0") {
1983
2221
  throw imValidationError("id_invalid", "toUid/toCid \u5FC5\u987B\u975E 0");
1984
2222
  }
2223
+ if (hasAtInput(args)) {
2224
+ throw imValidationError("at_not_supported", "@ \u63D0\u53CA\u4EC5\u7FA4\u804A\u6D88\u606F\u652F\u6301\uFF08\u5355\u804A\u53D1\u9001\u4E0D\u63A5\u53D7 atAll/atUids\uFF09");
2225
+ }
2226
+ if (args.replyMsgId !== void 0 && args.replyMsgId !== null && args.replyMsgId !== "") {
2227
+ throw imValidationError("reply_not_supported", "\u5355\u804A\u4EC5\u652F\u6301\u5F15\u7528\uFF08quoteMsgId\uFF09\uFF0C\u4E0D\u652F\u6301\u56DE\u590D\uFF08replyMsgId\uFF09");
2228
+ }
1985
2229
  const content = normalizeContent(args);
2230
+ const quote = hasQuoteInput(args) ? await resolveQuotedRef(args, env, { toUid, toCid }) : null;
2231
+ if (quote && !content.txt) {
2232
+ throw imValidationError("quote_requires_txt", "quoteMsgId \u4EC5\u652F\u6301\u6587\u672C\u6D88\u606F\uFF08txt\uFF09");
2233
+ }
1986
2234
  const summary = {
1987
2235
  action: "\u53D1\u9001\u5355\u804A\u6D88\u606F",
1988
2236
  toUid,
@@ -1996,6 +2244,11 @@ var sendSinglePair = makeWritePair({
1996
2244
  snapshot.txt = content.txt;
1997
2245
  summary.textPreview = content.txt.length > 60 ? `${content.txt.slice(0, 60)}\u2026` : content.txt;
1998
2246
  }
2247
+ if (quote) {
2248
+ snapshot.quoteKind = quote.kind;
2249
+ snapshot.quoteRef = quote.ref;
2250
+ summary.quote = { kind: quote.kind, quotedMsgId: quote.quotedMsgId, fromName: quote.fromName, textPreview: quote.text.length > 40 ? `${quote.text.slice(0, 40)}\u2026` : quote.text };
2251
+ }
1999
2252
  if (content.imgPath) {
2000
2253
  const abs = assertLocalFile(content.imgPath, "img");
2001
2254
  snapshot.imgPath = abs;
@@ -2010,7 +2263,13 @@ var sendSinglePair = makeWritePair({
2010
2263
  },
2011
2264
  async execute(plan, env) {
2012
2265
  const body = { reciver: { cid: plan.toCid, uid: plan.toUid } };
2013
- if (plan.txt !== void 0) body.txt = plan.txt;
2266
+ const quoteRef = plan.quoteRef ?? null;
2267
+ if (quoteRef) {
2268
+ const self = await env.host.getSelfIdentity();
2269
+ body.msg = buildAtMsgJson(String(plan.txt ?? ""), [], self, { ref: quoteRef });
2270
+ } else if (plan.txt !== void 0) {
2271
+ body.txt = plan.txt;
2272
+ }
2014
2273
  if (plan.imgPath) {
2015
2274
  const fileObj = await env.host.uploadFile(plan.imgPath, { shareUsers: plan.toUid });
2016
2275
  body.img = fileObjToImg(fileObj);
@@ -2035,12 +2294,29 @@ var sendGroupPair = makeWritePair({
2035
2294
  const groupId = str(args.groupId);
2036
2295
  if (!groupId || groupId === "0") throw imValidationError("id_invalid", "groupId \u5FC5\u987B\u975E 0");
2037
2296
  const content = normalizeContent(args);
2297
+ const atEntries = await resolveAtMentions(args, env, groupId);
2298
+ if (atEntries.length && !content.txt) {
2299
+ throw imValidationError("at_requires_txt", "atAll/atUids \u4EC5\u652F\u6301\u6587\u672C\u6D88\u606F\uFF08txt\uFF09");
2300
+ }
2301
+ const quote = hasQuoteInput(args) ? await resolveQuotedRef(args, env, { groupId }) : null;
2302
+ if (quote && !content.txt) {
2303
+ throw imValidationError("quote_requires_txt", "quoteMsgId/replyMsgId \u4EC5\u652F\u6301\u6587\u672C\u6D88\u606F\uFF08txt\uFF09");
2304
+ }
2038
2305
  const summary = { action: "\u53D1\u9001\u7FA4\u804A\u6D88\u606F", groupId, hasTxt: Boolean(content.txt), hasImg: Boolean(content.imgPath), hasFile: Boolean(content.filePath) };
2039
2306
  const snapshot = { groupId };
2040
2307
  if (content.txt) {
2041
2308
  snapshot.txt = content.txt;
2042
2309
  summary.textPreview = content.txt.length > 60 ? `${content.txt.slice(0, 60)}\u2026` : content.txt;
2043
2310
  }
2311
+ if (atEntries.length) {
2312
+ snapshot.atEntries = atEntries;
2313
+ summary.at = atEntries.map((e) => e.t === "2" ? { target: "ALL", name: e.nm, id: e.id } : { uid: e.id, cid: e.cid, name: e.nm });
2314
+ }
2315
+ if (quote) {
2316
+ snapshot.quoteKind = quote.kind;
2317
+ snapshot.quoteRef = quote.ref;
2318
+ summary.quote = { kind: quote.kind, quotedMsgId: quote.quotedMsgId, fromName: quote.fromName, textPreview: quote.text.length > 40 ? `${quote.text.slice(0, 40)}\u2026` : quote.text };
2319
+ }
2044
2320
  if (content.imgPath) {
2045
2321
  const abs = assertLocalFile(content.imgPath, "img");
2046
2322
  snapshot.imgPath = abs;
@@ -2055,7 +2331,15 @@ var sendGroupPair = makeWritePair({
2055
2331
  },
2056
2332
  async execute(plan, env) {
2057
2333
  const body = { groupId: plan.groupId };
2058
- if (plan.txt !== void 0) body.txt = plan.txt;
2334
+ const atEntries = Array.isArray(plan.atEntries) ? plan.atEntries : [];
2335
+ const quoteRef = plan.quoteRef ?? null;
2336
+ if (atEntries.length || quoteRef) {
2337
+ const { v, aus } = buildAtText(String(plan.txt ?? ""), atEntries);
2338
+ const self = await env.host.getSelfIdentity();
2339
+ body.msg = buildAtMsgJson(v, aus, self, quoteRef ? { [plan.quoteKind === "reply" ? "rmsg" : "ref"]: quoteRef } : {});
2340
+ } else if (plan.txt !== void 0) {
2341
+ body.txt = plan.txt;
2342
+ }
2059
2343
  if (plan.imgPath) {
2060
2344
  const fileObj = await env.host.uploadFile(plan.imgPath, { shareGroups: plan.groupId });
2061
2345
  body.img = fileObjToImg(fileObj);
@@ -2427,7 +2711,7 @@ var dingSendPair = makeWritePair({
2427
2711
  return { id: str(res?.data?.id ?? ""), msg: res?.data?.msg ?? "" };
2428
2712
  }
2429
2713
  });
2430
- function buildMsgWriteDefinition(name, method, summary, inputProps, pair) {
2714
+ function buildMsgWriteDefinition(name, method, summary, inputProps, pair, condition = {}) {
2431
2715
  const requiredInput = Object.keys(inputProps).filter((k) => {
2432
2716
  const prop = inputProps[k];
2433
2717
  return prop?.required === true;
@@ -2442,7 +2726,7 @@ function buildMsgWriteDefinition(name, method, summary, inputProps, pair) {
2442
2726
  capability: "msg",
2443
2727
  risk: "read-before-write",
2444
2728
  requiresConfirmation: true,
2445
- inputSchema: schemaOf(inputProps, { required: requiredInput, description: summary }),
2729
+ inputSchema: schemaOf(inputProps, { required: requiredInput, ...condition, description: summary }),
2446
2730
  handler: pair.prepare
2447
2731
  },
2448
2732
  {
@@ -2463,19 +2747,27 @@ function buildMsgWriteDefinition(name, method, summary, inputProps, pair) {
2463
2747
  ];
2464
2748
  }
2465
2749
  var msgWriteOps = [
2466
- ...buildMsgWriteDefinition("im.msg.send.single", "msg.send.single", "\u53D1\u9001\u5355\u804A\u6D88\u606F\uFF08\u6587\u672C/\u56FE\u7247/\u6587\u4EF6\uFF09", {
2750
+ ...buildMsgWriteDefinition("im.msg.send.single", "msg.send.single", "\u53D1\u9001\u5355\u804A\u6D88\u606F\uFF08\u6587\u672C/\u56FE\u7247/\u6587\u4EF6\uFF0C\u6587\u672C\u652F\u6301\u5F15\u7528\uFF09", {
2467
2751
  toUid: { type: "string", pattern: "^\\d+$", description: "\u63A5\u6536\u4EBA uid" },
2468
2752
  toCid: { type: "string", pattern: "^\\d+$", description: "\u63A5\u6536\u4EBA cid" },
2469
2753
  txt: { type: "string", description: "\u6587\u672C\u5185\u5BB9" },
2754
+ quoteMsgId: { type: "string", pattern: "^\\d+$", description: "\u5F15\u7528\u8BE5\u6D88\u606F\uFF08\u5355\u804A\u4EC5\u652F\u6301\u5F15\u7528\uFF0C\u4E0D\u652F\u6301\u56DE\u590D\uFF1B\u4EC5 txt \u6587\u672C\u6D88\u606F\uFF09\uFF1B\u4F20\u5355\u804A\u4F1A\u8BDD\u5185\u6D88\u606F id\uFF08ser_msgid\uFF09\uFF0Cprepare \u9636\u6BB5\u81EA\u52A8\u5B9A\u4F4D\u5E76\u7EC4\u88C5 ref" },
2470
2755
  img: { type: "string", description: "\u672C\u5730\u56FE\u7247\u8DEF\u5F84\uFF08\u53D1\u9001\u524D\u4F1A\u4E0A\u4F20\u5230 E10 \u6587\u4EF6\u670D\u52A1\uFF09" },
2471
2756
  file: { type: "string", description: "\u672C\u5730\u6587\u4EF6\u8DEF\u5F84" }
2472
- }, sendSinglePair),
2473
- ...buildMsgWriteDefinition("im.msg.send.group", "msg.send.group", "\u53D1\u9001\u7FA4\u804A\u6D88\u606F\uFF08\u6587\u672C/\u56FE\u7247/\u6587\u4EF6\uFF09", {
2757
+ }, sendSinglePair, {
2758
+ required: ["toUid", "toCid"],
2759
+ requiredAny: ["txt", "img", "file"]
2760
+ }),
2761
+ ...buildMsgWriteDefinition("im.msg.send.group", "msg.send.group", "\u53D1\u9001\u7FA4\u804A\u6D88\u606F\uFF08\u6587\u672C/\u56FE\u7247/\u6587\u4EF6\uFF0C\u6587\u672C\u652F\u6301 @ \u63D0\u53CA\u4E0E\u5F15\u7528/\u56DE\u590D\uFF09", {
2474
2762
  groupId: { type: "string", pattern: "^\\d+$", description: "\u7FA4 id" },
2475
- txt: { type: "string", description: "\u6587\u672C\u5185\u5BB9" },
2763
+ txt: { type: "string", description: "\u6587\u672C\u5185\u5BB9\uFF1B@ \u4F4D\u7F6E\u76F4\u63A5\u5199 @<\u59D3\u540D>\uFF08\u5982 @\u5F20\u4E09\uFF09\u6216 @\u5168\u4F53\u6210\u5458/@\u6240\u6709\u4EBA" },
2764
+ atAll: { type: "boolean", description: "@\u5168\u4F53\u6210\u5458\uFF08\u670D\u52A1\u7AEF\u56FA\u5B9A id=88\uFF09\uFF0C\u4EC5\u7FA4\u804A\u3001\u4EC5 txt \u6587\u672C\u6D88\u606F\u751F\u6548" },
2765
+ atUids: { type: "array", items: { type: "string" }, description: "@\u5177\u4F53\u4EBA uid \u5217\u8868\uFF0C\u4EC5\u7FA4\u804A\uFF1Bprepare \u9636\u6BB5\u4F1A\u9010\u4E2A\u6838\u5B9E\u662F\u5426\u5728\u7FA4\u5185\uFF0C\u4E0D\u5728\u7FA4\u5185\u5219\u62D2\u7EDD\u53D1\u9001" },
2766
+ quoteMsgId: { type: "string", pattern: "^\\d+$", description: "\u5F15\u7528\u8BE5\u6D88\u606F\uFF08\u4E0E replyMsgId \u4E92\u65A5\uFF0C\u4EC5\u7FA4\u804A\u3001\u4EC5 txt \u6587\u672C\u6D88\u606F\uFF09\uFF1B\u4F20\u6D88\u606F id\uFF08ser_msgid\uFF09\uFF0Cprepare \u9636\u6BB5\u81EA\u52A8\u5B9A\u4F4D\u88AB\u5F15\u6D88\u606F\u5E76\u7EC4\u88C5 ref" },
2767
+ replyMsgId: { type: "string", pattern: "^\\d+$", description: "\u56DE\u590D\u8BE5\u6D88\u606F\uFF08\u4E0E quoteMsgId \u4E92\u65A5\uFF0C\u4EC5\u7FA4\u804A\u3001\u4EC5 txt \u6587\u672C\u6D88\u606F\uFF09\uFF1B\u4F20\u6D88\u606F id\uFF08ser_msgid\uFF09\uFF0Cprepare \u9636\u6BB5\u81EA\u52A8\u5B9A\u4F4D\u88AB\u5F15\u6D88\u606F\u5E76\u7EC4\u88C5 rmsg" },
2476
2768
  img: { type: "string", description: "\u672C\u5730\u56FE\u7247\u8DEF\u5F84" },
2477
2769
  file: { type: "string", description: "\u672C\u5730\u6587\u4EF6\u8DEF\u5F84" }
2478
- }, sendGroupPair),
2770
+ }, sendGroupPair, { required: ["groupId"], requiredAny: ["txt", "img", "file"] }),
2479
2771
  ...buildMsgWriteDefinition("im.msg.withdraw", "msg.withdraw", "\u64A4\u56DE\u6D88\u606F\uFF08\u5355\u804A/\u7FA4\u804A\uFF0C\u9650\u672C\u4EBA 2 \u5206\u949F\u5185\uFF09", {
2480
2772
  type: { type: "string", enum: ["single", "group"], description: "single \u6216 group" },
2481
2773
  msgid: { type: "string", pattern: "^\\d+$", description: "\u6D88\u606F id\uFF08ser_msgid\uFF09" },
@@ -2499,7 +2791,12 @@ var msgWriteOps = [
2499
2791
  toUids: { type: "array", items: { type: "string" }, description: "\u6307\u5B9A\u63A5\u6536\u4EBA uid" },
2500
2792
  sendMsg: { type: "integer", enum: [0, 1], description: "\u53D1\u77ED\u4FE1\uFF08\u9ED8\u8BA4 1 \u53D1\uFF09" },
2501
2793
  showType: { type: "integer", enum: [0, 1], description: "0 \u5168\u4F53\u53EF\u89C1\uFF08\u9ED8\u8BA4\uFF09/1 \u4EC5\u53D1\u9001\u4EBA\u53EF\u89C1" }
2502
- }, dingSendPair)
2794
+ }, dingSendPair, {
2795
+ allOf: [
2796
+ { anyOf: [{ required: ["groupId"] }, { required: ["toUid"] }] },
2797
+ { anyOf: [{ required: ["txt"] }, { required: ["convertMsgid"] }] }
2798
+ ]
2799
+ })
2503
2800
  ];
2504
2801
  var msgWriteOperations = msgWriteOps;
2505
2802
 
@@ -2607,7 +2904,7 @@ var sessionList = {
2607
2904
  const unread = s?.unread_count ?? s?.unread ?? 0;
2608
2905
  const dontDisturb = Number(s?.reminder ?? s?.reminder_type ?? 0) === 1;
2609
2906
  const titleRaw = s?.title;
2610
- const titleObj = typeof titleRaw === "string" ? parseMsg(titleRaw) : titleRaw && typeof titleRaw === "object" ? titleRaw : null;
2907
+ const titleObj = typeof titleRaw === "string" ? parseMsg2(titleRaw) : titleRaw && typeof titleRaw === "object" ? titleRaw : null;
2611
2908
  let subtitleSender = "";
2612
2909
  let subtitleContent = "";
2613
2910
  let subtitleMedia = "";
@@ -2716,7 +3013,7 @@ var sysmsgTypeSync = {
2716
3013
  inputSchema: schemaOf({
2717
3014
  gids: { type: "array", items: { type: "integer" }, description: "\u7CFB\u7EDF\u5206\u7EC4 id\uFF08\u4E0E tids \u81F3\u5C11\u5176\u4E00\uFF09" },
2718
3015
  tids: { type: "array", items: { type: "integer" }, description: "\u6D88\u606F\u7C7B\u578B id" }
2719
- }, { description: "gids / tids \u81F3\u5C11\u5176\u4E00" }),
3016
+ }, { requiredAny: ["gids", "tids"], description: "\u6309 gids/tids \u62C9\u53D6\u7CFB\u7EDF\u6D88\u606F\u5206\u7EC4/\u7C7B\u578B\u914D\u7F6E\uFF08\u81F3\u5C11\u5176\u4E00\uFF09" }),
2720
3017
  handler: async (args, { host }) => {
2721
3018
  const gids = Array.isArray(args.gids) ? args.gids.map((x) => Number(x)).filter((n) => Number.isInteger(n)) : [];
2722
3019
  const tids = Array.isArray(args.tids) ? args.tids.map((x) => Number(x)).filter((n) => Number.isInteger(n)) : [];
@@ -2857,7 +3154,7 @@ var sysmsgQuery = {
2857
3154
  for (const [uid, p] of Object.entries(personMap)) nameMap[uid] = p.name;
2858
3155
  const authUid = await resolveAuthUid(host);
2859
3156
  const messages = msgRows.map((row) => {
2860
- const msgObj = parseMsg(row.msg);
3157
+ const msgObj = parseMsg2(row.msg);
2861
3158
  const parsed = parseContent(msgObj, { i18nMap, nameMap });
2862
3159
  const sender = senderName(msgObj || {}, row.from_uid, authUid, nameMap);
2863
3160
  const statusLabel = dealMode ? Number(row.deal_status) === 1 ? "\u5DF2\u5904\u7406" : "\u672A\u5904\u7406" : row.read_status === true || row.read_status === 1 ? "\u5DF2\u8BFB" : "\u672A\u8BFB";
@@ -3031,7 +3328,11 @@ var filePreview = {
3031
3328
  toUid: { type: "string", description: "\u5355\u804A\u573A\u666F\u5BF9\u65B9 uid" },
3032
3329
  toCid: { type: "string", description: "\u5355\u804A\u573A\u666F\u5BF9\u65B9 cid" },
3033
3330
  imgFormat: { type: "string", enum: ["small", "large", "original"], description: "\u56FE\u7247\u89C4\u683C\uFF08\u9ED8\u8BA4 small\uFF09" }
3034
- }, { required: ["fileId", "msgid"], description: "\u5A92\u4F53\u9884\u89C8 URL" }),
3331
+ }, {
3332
+ required: ["fileId", "msgid"],
3333
+ anyOf: [{ required: ["groupId"] }, { required: ["toUid", "toCid"] }],
3334
+ description: "\u5A92\u4F53\u9884\u89C8 URL\uFF08groupId \u7FA4\u804A \u6216 toUid+toCid \u5355\u804A\uFF0C\u4E8C\u9009\u4E00\uFF09"
3335
+ }),
3035
3336
  handler: async (args, { host }) => {
3036
3337
  const kind = String(args.kind ?? "img") === "video" ? "video" : "img";
3037
3338
  const fileId = String(args.fileId);
@@ -3090,7 +3391,11 @@ var fileDownload = {
3090
3391
  toCid: { type: "string", description: "\u5355\u804A\u573A\u666F\u5BF9\u65B9 cid\uFF08\u4E0E groupId \u4E8C\u9009\u4E00\uFF09" },
3091
3392
  imgFormat: { type: "string", enum: ["small", "large", "original"], description: "\u56FE\u7247\u89C4\u683C\uFF08\u9ED8\u8BA4 small\uFF1B\u8981\u539F\u56FE\u4F20 original\uFF09" },
3092
3393
  output: { type: "string", minLength: 1, description: "\u672C\u5730\u8F93\u51FA\u6587\u4EF6\u8DEF\u5F84\uFF08\u7236\u76EE\u5F55\u5FC5\u987B\u5B58\u5728\uFF0C\u5DF2\u5B58\u5728\u5219\u62D2\u7EDD\uFF09" }
3093
- }, { required: ["fileId", "msgid", "output"], description: "\u5A92\u4F53/\u6587\u4EF6\u843D\u5730\u5230\u672C\u5730" }),
3394
+ }, {
3395
+ required: ["fileId", "msgid", "output"],
3396
+ anyOf: [{ required: ["groupId"] }, { required: ["toUid", "toCid"] }],
3397
+ description: "\u5A92\u4F53/\u6587\u4EF6\u843D\u5730\u5230\u672C\u5730\uFF08groupId \u7FA4\u804A \u6216 toUid+toCid \u5355\u804A\uFF0C\u4E8C\u9009\u4E00\uFF09"
3398
+ }),
3094
3399
  handler: async (args, { host }) => {
3095
3400
  const fileId = String(args.fileId ?? "");
3096
3401
  const msgid = String(args.msgid ?? "");