weaver-work-cli 0.1.5 → 0.1.7

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 (225) hide show
  1. package/README.md +14 -9
  2. package/dist/cmd/skills/index.js +60 -0
  3. package/dist/internal/e10/auth/commands.js +48 -32
  4. package/dist/internal/e10/auth/session.js +44 -3
  5. package/dist/internal/e10/auth/xiaoe.js +363 -11
  6. package/dist/internal/e10/context.js +4 -2
  7. package/dist/internal/skills/detector.js +42 -0
  8. package/dist/internal/skills/install.js +50 -3
  9. package/dist/shortcuts/archive/render/search-format.js +12 -3
  10. package/dist/shortcuts/ebuilder-form/continuation.js +70 -0
  11. package/dist/shortcuts/ebuilder-form/errors.js +54 -0
  12. package/dist/shortcuts/ebuilder-form/host.js +1238 -0
  13. package/dist/shortcuts/ebuilder-form/index.js +108 -0
  14. package/dist/shortcuts/ebuilder-form/manifest.js +347 -0
  15. package/dist/shortcuts/ebuilder-form/operations/read.js +157 -0
  16. package/dist/shortcuts/ebuilder-form/operations/registry.js +56 -0
  17. package/dist/shortcuts/ebuilder-form/operations/shared.js +132 -0
  18. package/dist/shortcuts/ebuilder-form/operations/types.js +19 -0
  19. package/dist/shortcuts/ebuilder-form/operations/write.js +277 -0
  20. package/dist/shortcuts/ebuilder-form/operations.js +8 -0
  21. package/dist/shortcuts/ehr/operations/salary.js +2 -140
  22. package/dist/shortcuts/im/continuation.js +70 -0
  23. package/dist/shortcuts/{yimiaoban → im}/errors.js +14 -14
  24. package/dist/shortcuts/{yimiaoban → im}/host.js +26 -26
  25. package/dist/shortcuts/{yimiaoban → im}/index.js +42 -42
  26. package/dist/shortcuts/{yimiaoban → im}/manifest.js +7 -6
  27. package/dist/shortcuts/{yimiaoban → im}/operations/file-user.js +54 -41
  28. package/dist/shortcuts/{yimiaoban → im}/operations/group-read.js +46 -44
  29. package/dist/shortcuts/{yimiaoban → im}/operations/group-write.js +113 -66
  30. package/dist/shortcuts/{yimiaoban → im}/operations/msg-sync.js +164 -141
  31. package/dist/shortcuts/{yimiaoban → im}/operations/msg-write.js +47 -47
  32. package/dist/shortcuts/{yimiaoban → im}/operations/person.js +10 -10
  33. package/dist/shortcuts/{yimiaoban → im}/operations/registry.js +10 -8
  34. package/dist/shortcuts/{yimiaoban → im}/operations/session.js +82 -83
  35. package/dist/shortcuts/im/operations/shared.js +442 -0
  36. package/dist/shortcuts/{yimiaoban → im}/operations/types.js +1 -1
  37. package/dist/shortcuts/im/operations/user-remind.js +201 -0
  38. package/dist/shortcuts/{yimiaoban → im}/operations/write-util.js +7 -7
  39. package/dist/shortcuts/{yimiaoban → im}/operations.js +3 -3
  40. package/dist/shortcuts/index.js +10 -2
  41. package/dist/shortcuts/invoice/manifest.js +113 -10
  42. package/dist/shortcuts/invoice/operations/import.js +39 -14
  43. package/dist/shortcuts/invoice/operations/reim.js +38 -18
  44. package/dist/shortcuts/invoice/operations/shared.js +35 -6
  45. package/dist/shortcuts/jiuchuanhui/manifest.js +3 -3
  46. package/dist/shortcuts/jiuchuanhui/operations/registry.js +2 -2
  47. package/dist/shortcuts/{yimiaoban → okr}/continuation.js +10 -10
  48. package/dist/shortcuts/okr/errors.js +70 -0
  49. package/dist/shortcuts/okr/host.js +169 -0
  50. package/dist/shortcuts/okr/index.js +155 -0
  51. package/dist/shortcuts/okr/manifest.js +70 -0
  52. package/dist/shortcuts/okr/operations/link.js +305 -0
  53. package/dist/shortcuts/okr/operations/read.js +481 -0
  54. package/dist/shortcuts/okr/operations/registry.js +31 -0
  55. package/dist/shortcuts/okr/operations/shared.js +381 -0
  56. package/dist/shortcuts/okr/operations/types.js +88 -0
  57. package/dist/shortcuts/okr/operations/write.js +838 -0
  58. package/dist/shortcuts/okr/operations.js +8 -0
  59. package/dist/shortcuts/project/continuation.js +70 -0
  60. package/dist/shortcuts/project/errors.js +53 -0
  61. package/dist/shortcuts/project/host.js +160 -0
  62. package/dist/shortcuts/project/index.js +106 -0
  63. package/dist/shortcuts/project/manifest.js +36 -0
  64. package/dist/shortcuts/project/operations/read.js +551 -0
  65. package/dist/shortcuts/project/operations/registry.js +31 -0
  66. package/dist/shortcuts/project/operations/shared.js +68 -0
  67. package/dist/shortcuts/project/operations/types.js +39 -0
  68. package/dist/shortcuts/project/operations/write.js +266 -0
  69. package/dist/shortcuts/project/operations.js +8 -0
  70. package/dist/shortcuts/workflow/continuation.js +508 -0
  71. package/dist/shortcuts/workflow/endpoints.js +149 -0
  72. package/dist/shortcuts/workflow/errors.js +112 -0
  73. package/dist/shortcuts/workflow/host.js +224 -0
  74. package/dist/shortcuts/workflow/index.js +116 -0
  75. package/dist/shortcuts/workflow/manifest.js +30 -0
  76. package/dist/shortcuts/workflow/operations/form.js +4159 -0
  77. package/dist/shortcuts/workflow/operations/read.js +3778 -0
  78. package/dist/shortcuts/workflow/operations/registry.js +33 -0
  79. package/dist/shortcuts/workflow/operations/shared.js +167 -0
  80. package/dist/shortcuts/workflow/operations/types.js +44 -0
  81. package/dist/shortcuts/workflow/operations/write.js +1991 -0
  82. package/dist/shortcuts/workflow/operations.js +119 -0
  83. package/dist/shortcuts/workflow/state.js +182 -0
  84. package/docs/SKILL.md +5 -3
  85. package/docs/_catalog.md +10 -1
  86. package/docs/agent-invoice.md +2 -2
  87. package/docs/agent-skill-install.md +2 -2
  88. package/docs/e10-auth.md +3 -1
  89. package/docs/ebuilder-form.md +38 -0
  90. package/docs/im.md +104 -0
  91. package/docs/invoice.md +5 -5
  92. package/docs/okr.md +122 -0
  93. package/docs/operation-manual.md +10 -7
  94. package/docs/project.md +69 -0
  95. package/docs/skill-review-2026-09-19.md +68 -0
  96. package/package.json +3 -2
  97. package/scripts/package-skill.mjs +38 -11
  98. package/scripts/sync-connector-skills.mjs +172 -0
  99. package/skill-template/business-info.json +357 -16
  100. package/skill-template/domains/ebuilder-form.md +5 -0
  101. package/skill-template/domains/okr.md +18 -0
  102. package/skill-template/domains/shijingran.md +3 -0
  103. package/skill-template/domains/skill-maker.md +4 -4
  104. package/skill-template/domains/workflow.md +22 -0
  105. package/skill-template/domains/yepiaotong.md +4 -2
  106. package/skill-template/domains/yimiaoban.md +13 -10
  107. package/skill-template/product.json +5 -0
  108. package/skill-template/skill-template.md +1 -0
  109. package/skills/weaver-e10-calendar/SKILL.md +5 -1
  110. package/skills/weaver-e10-calendar/references/calendar-query.md +7 -0
  111. package/skills/weaver-e10-calendar/references/source-manifest.json +314 -32
  112. package/skills/weaver-e10-ebuilder-form/SKILL.md +123 -0
  113. package/skills/weaver-e10-ebuilder-form/references/context-routing.md +90 -0
  114. package/skills/weaver-e10-ebuilder-form/references/custom-api.md +86 -0
  115. package/skills/weaver-e10-ebuilder-form/references/disabled-capabilities.md +50 -0
  116. package/skills/weaver-e10-ebuilder-form/references/fields-browser.md +100 -0
  117. package/skills/weaver-e10-ebuilder-form/references/list-nlist.md +91 -0
  118. package/skills/weaver-e10-ebuilder-form/references/openapi-read.md +74 -0
  119. package/skills/weaver-e10-ebuilder-form/references/openapi-write.md +86 -0
  120. package/skills/weaver-e10-ebuilder-form/references/source-manifest.json +107 -0
  121. package/skills/weaver-e10-esb/SKILL.md +1 -1
  122. package/skills/weaver-e10-esb/references/source-manifest.json +15 -14
  123. package/skills/weaver-e10-hrm/SKILL.md +1 -1
  124. package/skills/weaver-e10-hrm/references/source-manifest.json +357 -38
  125. package/skills/weaver-e10-jiuchuanhui/SKILL.md +22 -4
  126. package/skills/weaver-e10-jiuchuanhui/references/clue.md +4 -2
  127. package/skills/weaver-e10-jiuchuanhui/references/contact.md +1 -1
  128. package/skills/weaver-e10-jiuchuanhui/references/customer.md +3 -3
  129. package/skills/weaver-e10-jiuchuanhui/references/disabled-capabilities.md +1 -1
  130. package/skills/weaver-e10-jiuchuanhui/references/discovery-config.md +10 -10
  131. package/skills/weaver-e10-jiuchuanhui/references/general-helpers.md +3 -3
  132. package/skills/weaver-e10-jiuchuanhui/references/sale.md +7 -7
  133. package/skills/weaver-e10-jiuchuanhui/references/source-manifest.json +3 -3
  134. package/skills/weaver-e10-jucailin/SKILL.md +2 -2
  135. package/skills/weaver-e10-mail/SKILL.md +22 -6
  136. package/skills/weaver-e10-meeting/SKILL.md +22 -1
  137. package/skills/weaver-e10-okr/SKILL.md +139 -0
  138. package/skills/weaver-e10-okr/references/okr-align.md +59 -0
  139. package/skills/weaver-e10-okr/references/okr-keyresult.md +68 -0
  140. package/skills/weaver-e10-okr/references/okr-link-routing.md +67 -0
  141. package/skills/weaver-e10-okr/references/okr-query.md +105 -0
  142. package/skills/weaver-e10-okr/references/okr-write.md +94 -0
  143. package/skills/weaver-e10-okr/references/source-manifest.json +672 -0
  144. package/skills/weaver-e10-plan/SKILL.md +3 -3
  145. package/skills/weaver-e10-plan/references/plan-report-write.md +1 -1
  146. package/skills/weaver-e10-plan/references/source-manifest.json +20 -20
  147. package/skills/weaver-e10-qiyecheng/SKILL.md +21 -1
  148. package/skills/weaver-e10-qiyecheng/references/source-manifest.json +17 -17
  149. package/skills/weaver-e10-shared/SKILL.md +79 -11
  150. package/skills/weaver-e10-shared/references/e10-auth-and-session.md +41 -8
  151. package/skills/weaver-e10-shared/references/non-interactive-environment.md +78 -0
  152. package/skills/weaver-e10-shared/references/weaver-e10-installation.md +39 -0
  153. package/skills/weaver-e10-shijingran/SKILL.md +83 -0
  154. package/skills/weaver-e10-shijingran/references/field-resolution.md +105 -0
  155. package/skills/weaver-e10-shijingran/references/operations.md +154 -0
  156. package/skills/weaver-e10-shijingran/references/source-manifest.json +1380 -0
  157. package/skills/weaver-e10-shijingran/references/write-operations.md +90 -0
  158. package/skills/weaver-e10-skill-maker/SKILL.md +26 -9
  159. package/skills/weaver-e10-skill-maker/references/business-skill-generation.md +39 -8
  160. package/skills/weaver-e10-skill-maker/references/detector-validation.md +25 -8
  161. package/skills/weaver-e10-skill-maker/references/module-cli-generation.md +66 -5
  162. package/skills/weaver-e10-skill-maker/references/module-gap-audit-and-repair.md +86 -0
  163. package/skills/weaver-e10-skill-maker/references/source-update-detection.md +59 -5
  164. package/skills/weaver-e10-skill-maker/references/weaver-skill-style.md +16 -8
  165. package/skills/weaver-e10-wenshuding/SKILL.md +28 -4
  166. package/skills/weaver-e10-wenshuding/references/archive-search.md +14 -0
  167. package/skills/weaver-e10-wenshuding/references/source-manifest.json +27 -26
  168. package/skills/weaver-e10-workflow/SKILL.md +250 -0
  169. package/skills/weaver-e10-workflow/references/source-manifest.json +1062 -0
  170. package/skills/weaver-e10-workflow/references/workflow-agent-entry.md +96 -0
  171. package/skills/weaver-e10-workflow/references/workflow-batch.md +275 -0
  172. package/skills/weaver-e10-workflow/references/workflow-create.md +182 -0
  173. package/skills/weaver-e10-workflow/references/workflow-edit.md +106 -0
  174. package/skills/weaver-e10-workflow/references/workflow-memory.md +165 -0
  175. package/skills/weaver-e10-workflow/references/workflow-operate.md +153 -0
  176. package/skills/weaver-e10-workflow/references/workflow-query.md +821 -0
  177. package/skills/weaver-e10-workflow/references/workflow-share.md +117 -0
  178. package/skills/weaver-e10-workflow/references/workflow-view.md +189 -0
  179. package/skills/weaver-e10-yepiaotong/SKILL.md +28 -28
  180. package/skills/weaver-e10-yepiaotong/references/invoice-disabled-capabilities.md +11 -5
  181. package/skills/weaver-e10-yepiaotong/references/invoice-import.md +14 -8
  182. package/skills/weaver-e10-yepiaotong/references/invoice-issuing-examples.md +9 -43
  183. package/skills/weaver-e10-yepiaotong/references/invoice-issuing.md +8 -0
  184. package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +13 -17
  185. package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +6 -7
  186. package/skills/weaver-e10-yepiaotong/references/reim-examples.md +2 -2
  187. package/skills/weaver-e10-yepiaotong/references/source-manifest.json +1155 -553
  188. package/skills/weaver-e10-yimiaoban/SKILL.md +56 -38
  189. package/skills/weaver-e10-yimiaoban/references/ding-write.md +8 -8
  190. package/skills/weaver-e10-yimiaoban/references/error-codes.md +16 -0
  191. package/skills/weaver-e10-yimiaoban/references/field-resolution.md +10 -10
  192. package/skills/weaver-e10-yimiaoban/references/file-user-i18n.md +12 -12
  193. package/skills/weaver-e10-yimiaoban/references/group-read.md +16 -16
  194. package/skills/weaver-e10-yimiaoban/references/group-write.md +17 -15
  195. package/skills/weaver-e10-yimiaoban/references/msg-read.md +21 -17
  196. package/skills/weaver-e10-yimiaoban/references/msg-write.md +10 -10
  197. package/skills/weaver-e10-yimiaoban/references/person.md +6 -6
  198. package/skills/weaver-e10-yimiaoban/references/safety-boundaries.md +15 -11
  199. package/skills/weaver-e10-yimiaoban/references/session-sysmsg.md +11 -10
  200. package/skills/weaver-e10-yimiaoban/references/source-manifest.json +2164 -154
  201. package/skills/weaver-e10-yimiaoban/references/user-remind.md +75 -0
  202. package/skills/weaver-e10-ziguanjia/SKILL.md +4 -2
  203. package/skills/weaver-e10-ziguanjia/references/source-manifest.json +99 -29
  204. package/tools/weaver-skill-detector-1.0.13/SKILL.md +253 -0
  205. package/tools/weaver-skill-detector-1.0.13/_meta.json +6 -0
  206. package/tools/weaver-skill-detector-1.0.13/references/checklist.md +298 -0
  207. package/tools/weaver-skill-detector-1.0.13/scripts/validate_skill.py +4190 -0
  208. package/dist/shortcuts/yimiaoban/operations/shared.js +0 -236
  209. package/docs/yimiaoban.md +0 -86
  210. package/skills/weaver-e10-calendar/product.json +0 -8
  211. package/skills/weaver-e10-esb/product.json +0 -8
  212. package/skills/weaver-e10-hrm/product.json +0 -8
  213. package/skills/weaver-e10-jiuchuanhui/product.json +0 -8
  214. package/skills/weaver-e10-jucailin/product.json +0 -8
  215. package/skills/weaver-e10-mail/product.json +0 -8
  216. package/skills/weaver-e10-meeting/product.json +0 -8
  217. package/skills/weaver-e10-plan/product.json +0 -8
  218. package/skills/weaver-e10-qiyecheng/product.json +0 -8
  219. package/skills/weaver-e10-skill-maker/product.json +0 -8
  220. package/skills/weaver-e10-wenshuding/product.json +0 -8
  221. package/skills/weaver-e10-yepiaotong/product.json +0 -8
  222. package/skills/weaver-e10-yepiaotong/references/invoice-red.md +0 -261
  223. package/skills/weaver-e10-yimiaoban/product.json +0 -8
  224. package/skills/weaver-e10-ziguanjia/product.json +0 -8
  225. /package/dist/shortcuts/{yimiaoban → im}/operations/msg-parse.js +0 -0
@@ -1,6 +1,6 @@
1
1
  import { existsSync } from 'node:fs';
2
2
  import { resolve } from 'node:path';
3
- import { ymbValidationError } from '../errors.js';
3
+ import { imValidationError } from '../errors.js';
4
4
  import { schemaOf, } from './types.js';
5
5
  import { assertImOk, compact, extractGroupMembers, str } from './shared.js';
6
6
  import { fileObjToFile, fileObjToImg, makeWritePair } from './write-util.js';
@@ -8,7 +8,7 @@ import { fileObjToFile, fileObjToImg, makeWritePair } from './write-util.js';
8
8
  function assertLocalFile(pathValue, field) {
9
9
  const abs = resolve(String(pathValue ?? ''));
10
10
  if (!existsSync(abs))
11
- throw ymbValidationError('file_not_found', `${field} 文件不存在: ${abs}`);
11
+ throw imValidationError('file_not_found', `${field} 文件不存在: ${abs}`);
12
12
  return abs;
13
13
  }
14
14
  /**
@@ -21,21 +21,21 @@ function normalizeContent(args) {
21
21
  const imgPath = args.img || args.imgPath ? String(args.img || args.imgPath) : undefined;
22
22
  const filePath = args.file || args.filePath ? String(args.file || args.filePath) : undefined;
23
23
  if (!txt && !imgPath && !filePath) {
24
- throw ymbValidationError('content_required', 'txt / img / file 至少提供一种(空白文本不算内容,禁止发送空白消息)');
24
+ throw imValidationError('content_required', 'txt / img / file 至少提供一种(空白文本不算内容,禁止发送空白消息)');
25
25
  }
26
26
  if (imgPath && filePath) {
27
- throw ymbValidationError('content_conflict', 'img 与 file 不能同时提供(一次发一种媒体)');
27
+ throw imValidationError('content_conflict', 'img 与 file 不能同时提供(一次发一种媒体)');
28
28
  }
29
29
  return { txt, imgPath, filePath };
30
30
  }
31
31
  // ── 发单聊 ──
32
32
  const sendSinglePair = makeWritePair({
33
- action: 'yimiaoban.msg.send.single',
33
+ action: 'im.msg.send.single',
34
34
  async plan(args, env) {
35
35
  const toUid = str(args.toUid);
36
36
  const toCid = str(args.toCid);
37
37
  if (!toUid || !toCid || toUid === '0' || toCid === '0') {
38
- throw ymbValidationError('id_invalid', 'toUid/toCid 必须非 0');
38
+ throw imValidationError('id_invalid', 'toUid/toCid 必须非 0');
39
39
  }
40
40
  const content = normalizeContent(args);
41
41
  const summary = {
@@ -79,7 +79,7 @@ const sendSinglePair = makeWritePair({
79
79
  method: 'POST',
80
80
  path: '/api/em/msg/executeIm/send/sendSingleMsg',
81
81
  body,
82
- operation: 'yimiaoban.msg.send.single',
82
+ operation: 'im.msg.send.single',
83
83
  });
84
84
  assertImOk(res, '发送单聊消息');
85
85
  return { toUid: plan.toUid, toCid: plan.toCid, sent: true };
@@ -87,11 +87,11 @@ const sendSinglePair = makeWritePair({
87
87
  });
88
88
  // ── 发群聊 ──
89
89
  const sendGroupPair = makeWritePair({
90
- action: 'yimiaoban.msg.send.group',
90
+ action: 'im.msg.send.group',
91
91
  async plan(args, env) {
92
92
  const groupId = str(args.groupId);
93
93
  if (!groupId || groupId === '0')
94
- throw ymbValidationError('id_invalid', 'groupId 必须非 0');
94
+ throw imValidationError('id_invalid', 'groupId 必须非 0');
95
95
  const content = normalizeContent(args);
96
96
  const summary = { action: '发送群聊消息', groupId, hasTxt: Boolean(content.txt), hasImg: Boolean(content.imgPath), hasFile: Boolean(content.filePath) };
97
97
  const snapshot = { groupId };
@@ -127,7 +127,7 @@ const sendGroupPair = makeWritePair({
127
127
  method: 'POST',
128
128
  path: '/api/em/msg/executeIm/send/sendGroupMsg',
129
129
  body,
130
- operation: 'yimiaoban.msg.send.group',
130
+ operation: 'im.msg.send.group',
131
131
  });
132
132
  assertImOk(res, '发送群聊消息');
133
133
  return { groupId: plan.groupId, sent: true };
@@ -160,21 +160,21 @@ function formatWithdrawInterval(seconds) {
160
160
  return rest > 0 ? `${minutes} 分钟 ${rest} 秒` : `${minutes} 分钟`;
161
161
  }
162
162
  const withdrawPair = makeWritePair({
163
- action: 'yimiaoban.msg.withdraw',
163
+ action: 'im.msg.withdraw',
164
164
  async plan(args, env) {
165
165
  const type = String(args.type || 'single');
166
166
  if (type !== 'single' && type !== 'group')
167
- throw ymbValidationError('type_invalid', 'type 必须是 single 或 group');
167
+ throw imValidationError('type_invalid', 'type 必须是 single 或 group');
168
168
  const msgid = str(args.msgid);
169
169
  if (!msgid || msgid === '0')
170
- throw ymbValidationError('id_invalid', 'msgid 必须非 0');
170
+ throw imValidationError('id_invalid', 'msgid 必须非 0');
171
171
  const snapshot = { type, msgid };
172
172
  let source;
173
173
  if (type === 'single') {
174
174
  const toUid = str(args.toUid);
175
175
  const toCid = str(args.toCid);
176
176
  if (!toUid || !toCid || toUid === '0' || toCid === '0')
177
- throw ymbValidationError('id_invalid', 'toUid/toCid 必须非 0(撤回单聊消息)');
177
+ throw imValidationError('id_invalid', 'toUid/toCid 必须非 0(撤回单聊消息)');
178
178
  snapshot.toUid = toUid;
179
179
  snapshot.toCid = toCid;
180
180
  source = { flag: 0, user: { cid: toCid, uid: toUid } };
@@ -182,7 +182,7 @@ const withdrawPair = makeWritePair({
182
182
  else {
183
183
  const groupId = str(args.groupId);
184
184
  if (!groupId || groupId === '0')
185
- throw ymbValidationError('id_invalid', 'groupId 必须非 0');
185
+ throw imValidationError('id_invalid', 'groupId 必须非 0');
186
186
  snapshot.groupId = groupId;
187
187
  source = { flag: 1, group_id: groupId };
188
188
  }
@@ -217,20 +217,20 @@ const withdrawPair = makeWritePair({
217
217
  method: 'POST',
218
218
  path: '/api/em/msg/executeIm/msg/makeMsgWithdraw',
219
219
  body,
220
- operation: 'yimiaoban.msg.withdraw',
220
+ operation: 'im.msg.withdraw',
221
221
  });
222
222
  const actCode = Number(res?.data?.actionMsg?.code ?? res?.code ?? -1);
223
223
  const timeOut = findWithdrawTimeOut(res);
224
224
  const interval = timeOut !== null ? formatWithdrawInterval(timeOut) : '';
225
225
  if (actCode === 1505) {
226
- throw ymbValidationError('withdraw_timeout', `撤销超时${interval ? `(撤回时限 ${interval})` : '(发出超过约 2 分钟)'}:消息发送已超过可撤回时限,无法撤回`, { code: 1505, details: interval ? { withdrawInterval: interval } : undefined });
226
+ throw imValidationError('withdraw_timeout', `撤销超时${interval ? `(撤回时限 ${interval})` : '(发出超过约 2 分钟)'}:消息发送已超过可撤回时限,无法撤回`, { code: 1505, details: interval ? { withdrawInterval: interval } : undefined });
227
227
  }
228
228
  if (actCode === 1506)
229
- throw ymbValidationError('withdraw_not_owner', '消息不是自己发送的,无法撤回', { code: 1506 });
229
+ throw imValidationError('withdraw_not_owner', '消息不是自己发送的,无法撤回', { code: 1506 });
230
230
  if (actCode === 1507)
231
- throw ymbValidationError('withdraw_edit_timeout', '编辑撤回超时', { code: 1507 });
231
+ throw imValidationError('withdraw_edit_timeout', '编辑撤回超时', { code: 1507 });
232
232
  if (actCode !== 0)
233
- throw ymbValidationError('withdraw_failed', `撤回失败(code=${actCode})`, { code: actCode });
233
+ throw imValidationError('withdraw_failed', `撤回失败(code=${actCode})`, { code: actCode });
234
234
  return {
235
235
  msgid: plan.msgid,
236
236
  withdrawn: true,
@@ -240,21 +240,21 @@ const withdrawPair = makeWritePair({
240
240
  });
241
241
  // ── 群置顶/取消置顶 ──
242
242
  const topSetPair = makeWritePair({
243
- action: 'yimiaoban.msg.top.set',
243
+ action: 'im.msg.top.set',
244
244
  async plan(args, env) {
245
245
  const groupId = str(args.groupId);
246
246
  if (!groupId || groupId === '0')
247
- throw ymbValidationError('id_invalid', 'groupId 必须非 0');
247
+ throw imValidationError('id_invalid', 'groupId 必须非 0');
248
248
  const msgid = str(args.msgid);
249
249
  if (!msgid || msgid === '0')
250
- throw ymbValidationError('id_invalid', 'msgid 必须非 0');
250
+ throw imValidationError('id_invalid', 'msgid 必须非 0');
251
251
  let type;
252
252
  if (args.cancel === true)
253
253
  type = 2;
254
254
  else if (args.type !== undefined) {
255
255
  type = Number(args.type);
256
256
  if (type !== 1 && type !== 2)
257
- throw ymbValidationError('type_invalid', 'type 必须是 1(置顶)或 2(取消置顶)');
257
+ throw imValidationError('type_invalid', 'type 必须是 1(置顶)或 2(取消置顶)');
258
258
  }
259
259
  else
260
260
  type = 1;
@@ -269,7 +269,7 @@ const topSetPair = makeWritePair({
269
269
  method: 'POST',
270
270
  path: '/api/em/msg/executeIm/msg/setGroupTopMsg',
271
271
  body,
272
- operation: 'yimiaoban.msg.top.set',
272
+ operation: 'im.msg.top.set',
273
273
  });
274
274
  assertImOk(res, plan.type === 1 ? '置顶消息' : '取消置顶');
275
275
  return { groupId: plan.groupId, msgid: plan.msgid, type: plan.type };
@@ -277,24 +277,24 @@ const topSetPair = makeWritePair({
277
277
  });
278
278
  // ── 必达 sendDing ──
279
279
  const dingSendPair = makeWritePair({
280
- action: 'yimiaoban.ding.send',
280
+ action: 'im.ding.send',
281
281
  async plan(args, env) {
282
282
  const groupId = args.groupId !== undefined && args.groupId !== '' ? str(args.groupId) : '';
283
283
  const toUid = args.toUid !== undefined && args.toUid !== '' ? str(args.toUid) : '';
284
284
  const convertMsgid = args.convertMsgid !== undefined && args.convertMsgid !== '' ? str(args.convertMsgid) : '';
285
285
  if (!groupId && !toUid)
286
- throw ymbValidationError('target_required', 'groupId(群必达)与 toUid(单聊必达)至少其一');
286
+ throw imValidationError('target_required', 'groupId(群必达)与 toUid(单聊必达)至少其一');
287
287
  if (groupId && groupId === '0')
288
- throw ymbValidationError('id_invalid', 'groupId 必须非 0');
288
+ throw imValidationError('id_invalid', 'groupId 必须非 0');
289
289
  const txtRaw = args.txt !== undefined && args.txt !== null ? String(args.txt) : '';
290
290
  const txt = txtRaw.trim() !== '' ? txtRaw : '';
291
291
  if (!convertMsgid && !txt)
292
- throw ymbValidationError('content_required', '普通必达需 txt;转必达需 convertMsgid');
292
+ throw imValidationError('content_required', '普通必达需 txt;转必达需 convertMsgid');
293
293
  if (args.unreadOnly === true && !groupId) {
294
- throw ymbValidationError('unread_only_group_only', 'unreadOnly 仅支持群聊转必达(需提供 groupId)');
294
+ throw imValidationError('unread_only_group_only', 'unreadOnly 仅支持群聊转必达(需提供 groupId)');
295
295
  }
296
296
  if (!groupId && convertMsgid && !str(args.toCid)) {
297
- throw ymbValidationError('to_cid_required', '单聊转必达需提供 toCid(用于按消息 id 拉取源消息)');
297
+ throw imValidationError('to_cid_required', '单聊转必达需提供 toCid(用于按消息 id 拉取源消息)');
298
298
  }
299
299
  const summary = {
300
300
  action: convertMsgid ? '已有消息转必达' : '发送必达消息',
@@ -331,7 +331,7 @@ const dingSendPair = makeWritePair({
331
331
  const map = await env.host.resolveUsersByIds(requested);
332
332
  const failed = requested.filter((uid) => !map[uid]?.cid || map[uid].cid === '0');
333
333
  if (failed.length && snapshot.removeFailed !== true) {
334
- throw ymbValidationError('members_resolve_failed', `指定接收人信息获取失败(cid 缺失或为 0):${failed.map((uid) => map[uid]?.name || uid).join('、')};确认跳过请传 removeFailed:true`, { details: failed });
334
+ throw imValidationError('members_resolve_failed', `指定接收人信息获取失败(cid 缺失或为 0):${failed.map((uid) => map[uid]?.name || uid).join('、')};确认跳过请传 removeFailed:true`, { details: failed });
335
335
  }
336
336
  for (const uid of requested) {
337
337
  const cid = map[uid]?.cid;
@@ -346,7 +346,7 @@ const dingSendPair = makeWritePair({
346
346
  method: 'POST',
347
347
  path: '/api/em/msg/executeIm/group/syncGroupReadStatus',
348
348
  body: { trans_id: 0, group_id: groupId, msgid: convertMsgid || '0' },
349
- operation: 'yimiaoban.ding.send.unread',
349
+ operation: 'im.ding.send.unread',
350
350
  });
351
351
  const readDatas = readRes?.data?.data?.datas || [];
352
352
  const unread = readDatas.filter((d) => Number(d.status) === 0);
@@ -354,7 +354,7 @@ const dingSendPair = makeWritePair({
354
354
  ...new Set(unread.map((d) => String(d?.user?.uid)).filter((uid) => Boolean(uid) && uid !== myUid)),
355
355
  ];
356
356
  if (uidArr.length === 0) {
357
- throw ymbValidationError('unread_empty', '群内没有未读人员(unreadOnly=true 不自动回退全员):请确认改发全体成员、指定人员,或放弃发送');
357
+ throw imValidationError('unread_empty', '群内没有未读人员(unreadOnly=true 不自动回退全员):请确认改发全体成员、指定人员,或放弃发送');
358
358
  }
359
359
  const map = await env.host.resolveUsersByIds(uidArr);
360
360
  for (const uid of uidArr) {
@@ -368,7 +368,7 @@ const dingSendPair = makeWritePair({
368
368
  method: 'POST',
369
369
  path: '/api/em/msg/executeIm/group/getGroupUsers',
370
370
  body: { group_id: groupId, type: 0, sync_type: 0, member_mask: 6, client_uc: '0' },
371
- operation: 'yimiaoban.ding.send.members',
371
+ operation: 'im.ding.send.members',
372
372
  });
373
373
  const uidArr = [...new Set(extractGroupMembers(memRes?.data?.data)
374
374
  .map((m) => String(m?.uid))
@@ -381,7 +381,7 @@ const dingSendPair = makeWritePair({
381
381
  }
382
382
  }
383
383
  if (groupUsers.length === 0) {
384
- throw ymbValidationError('members_empty', '群内没有可接收必达消息的成员(已排除本人;指定/未读人员可能为空)');
384
+ throw imValidationError('members_empty', '群内没有可接收必达消息的成员(已排除本人;指定/未读人员可能为空)');
385
385
  }
386
386
  snapshot.groupUsers = groupUsers;
387
387
  snapshot.receiveUserIds = groupUsers.map((u) => u.uid).join(',');
@@ -416,16 +416,16 @@ const dingSendPair = makeWritePair({
416
416
  ? { trans_id: 0, dev: 4, type: 0, enc_type: 0, datas: [{ group_id: plan.groupId, start: plan.convertMsgid, end: '0', max_num: 1 }] }
417
417
  : { trans_id: 0, dev: 4, enc_type: 0, datas: [{ from_cid: plan.toCid, from_uid: plan.toUid, start: plan.convertMsgid, end: '0', max_num: 1 }] };
418
418
  const sourcePath = plan.groupId ? '/api/em/msg/executeIm/chat/syncGroupMsg' : '/api/em/msg/executeIm/msg/syncSingleMsg';
419
- const srcRes = await env.host.request({ method: 'POST', path: sourcePath, body: sourceReq, operation: 'yimiaoban.ding.send.source' });
419
+ const srcRes = await env.host.request({ method: 'POST', path: sourcePath, body: sourceReq, operation: 'im.ding.send.source' });
420
420
  const srcMsg = srcRes?.data?.data?.datas?.[0]?.datas?.[0] ?? srcRes?.data?.data?.datas?.[0];
421
421
  if (!srcMsg?.msg)
422
- throw ymbValidationError('source_not_found', `未找到源消息 ${plan.convertMsgid}`);
422
+ throw imValidationError('source_not_found', `未找到源消息 ${plan.convertMsgid}`);
423
423
  let msgObj;
424
424
  try {
425
425
  msgObj = typeof srcMsg.msg === 'string' ? JSON.parse(srcMsg.msg) : srcMsg.msg;
426
426
  }
427
427
  catch {
428
- throw ymbValidationError('source_invalid', '源消息内容无法解析');
428
+ throw imValidationError('source_invalid', '源消息内容无法解析');
429
429
  }
430
430
  const mtype = Number(msgObj.type ?? 0);
431
431
  let tag;
@@ -481,7 +481,7 @@ const dingSendPair = makeWritePair({
481
481
  groupUsers = Array.isArray(plan.groupUsers) ? plan.groupUsers : [];
482
482
  receiveUserIds = str(plan.receiveUserIds) || groupUsers.map((u) => u.uid).join(',');
483
483
  if (!receiveUserIds)
484
- throw ymbValidationError('members_empty', '群内没有可接收必达消息的成员');
484
+ throw imValidationError('members_empty', '群内没有可接收必达消息的成员');
485
485
  }
486
486
  else {
487
487
  targetType = 1;
@@ -507,11 +507,11 @@ const dingSendPair = makeWritePair({
507
507
  method: 'POST',
508
508
  path: '/api/em/msg/createDing',
509
509
  body,
510
- operation: 'yimiaoban.ding.send',
510
+ operation: 'im.ding.send',
511
511
  });
512
512
  const code = Number(res?.code ?? -1);
513
513
  if (code !== 200 || !res?.status) {
514
- throw ymbValidationError('ding_failed', `必达发送失败:code=${code} msg=${res?.msg ?? ''}`, { code });
514
+ throw imValidationError('ding_failed', `必达发送失败:code=${code} msg=${res?.msg ?? ''}`, { code });
515
515
  }
516
516
  return { id: str(res?.data?.id ?? ''), msg: res?.data?.msg ?? '' };
517
517
  },
@@ -552,33 +552,33 @@ function buildMsgWriteDefinition(name, method, summary, inputProps, pair) {
552
552
  ];
553
553
  }
554
554
  const msgWriteOps = [
555
- ...buildMsgWriteDefinition('yimiaoban.msg.send.single', 'msg.send.single', '发送单聊消息(文本/图片/文件)', {
555
+ ...buildMsgWriteDefinition('im.msg.send.single', 'msg.send.single', '发送单聊消息(文本/图片/文件)', {
556
556
  toUid: { type: 'string', pattern: '^\\d+$', description: '接收人 uid' },
557
557
  toCid: { type: 'string', pattern: '^\\d+$', description: '接收人 cid' },
558
558
  txt: { type: 'string', description: '文本内容' },
559
559
  img: { type: 'string', description: '本地图片路径(发送前会上传到 E10 文件服务)' },
560
560
  file: { type: 'string', description: '本地文件路径' },
561
561
  }, sendSinglePair),
562
- ...buildMsgWriteDefinition('yimiaoban.msg.send.group', 'msg.send.group', '发送群聊消息(文本/图片/文件)', {
562
+ ...buildMsgWriteDefinition('im.msg.send.group', 'msg.send.group', '发送群聊消息(文本/图片/文件)', {
563
563
  groupId: { type: 'string', pattern: '^\\d+$', description: '群 id' },
564
564
  txt: { type: 'string', description: '文本内容' },
565
565
  img: { type: 'string', description: '本地图片路径' },
566
566
  file: { type: 'string', description: '本地文件路径' },
567
567
  }, sendGroupPair),
568
- ...buildMsgWriteDefinition('yimiaoban.msg.withdraw', 'msg.withdraw', '撤回消息(单聊/群聊,限本人 2 分钟内)', {
568
+ ...buildMsgWriteDefinition('im.msg.withdraw', 'msg.withdraw', '撤回消息(单聊/群聊,限本人 2 分钟内)', {
569
569
  type: { type: 'string', enum: ['single', 'group'], description: 'single 或 group' },
570
570
  msgid: { type: 'string', pattern: '^\\d+$', description: '消息 id(ser_msgid)' },
571
571
  toUid: { type: 'string', pattern: '^\\d+$', description: '单聊:对方 uid' },
572
572
  toCid: { type: 'string', pattern: '^\\d+$', description: '单聊:对方 cid' },
573
573
  groupId: { type: 'string', pattern: '^\\d+$', description: '群聊:群 id' },
574
574
  }, withdrawPair),
575
- ...buildMsgWriteDefinition('yimiaoban.msg.top.set', 'msg.top.set', '群消息置顶 / 取消置顶', {
575
+ ...buildMsgWriteDefinition('im.msg.top.set', 'msg.top.set', '群消息置顶 / 取消置顶', {
576
576
  groupId: { type: 'string', pattern: '^\\d+$', description: '群 id' },
577
577
  msgid: { type: 'string', pattern: '^\\d+$', description: '目标消息 id' },
578
578
  type: { type: 'integer', enum: [1, 2], description: '1 置顶 / 2 取消' },
579
579
  cancel: { type: 'boolean', description: '等价 type=2' },
580
580
  }, topSetPair),
581
- ...buildMsgWriteDefinition('yimiaoban.ding.send', 'ding.send', '发送必达消息 / 已有消息转必达(createDing)', {
581
+ ...buildMsgWriteDefinition('im.ding.send', 'ding.send', '发送必达消息 / 已有消息转必达(createDing)', {
582
582
  groupId: { type: 'string', pattern: '^\\d+$', description: '群场景群 id' },
583
583
  toUid: { type: 'string', pattern: '^\\d+$', description: '单聊场景对方 uid' },
584
584
  toCid: { type: 'string', pattern: '^\\d+$', description: '单聊转必达对方 cid' },
@@ -1,12 +1,12 @@
1
- import { ymbValidationError } from '../errors.js';
2
- import { READ, schemaOf, ymbSuccess, } from './types.js';
1
+ import { imValidationError } from '../errors.js';
2
+ import { READ, schemaOf, imSuccess, } from './types.js';
3
3
  import { splitIds } from './shared.js';
4
4
  /** 姓名 → 人员解析(数据采集走 hrm,不用 IM 群成员姓名接口)。 */
5
5
  const personResolve = {
6
- name: 'yimiaoban.person.resolve',
6
+ name: 'im.person.resolve',
7
7
  resource: 'person',
8
8
  method: 'person.resolve',
9
- action: 'yimiaoban.person.resolve',
9
+ action: 'im.person.resolve',
10
10
  summary: '按姓名/工号/手机/邮箱模糊查询在职员工,返回 uid/cid/部门等(供发消息与成员解析)',
11
11
  capability: 'person',
12
12
  risk: READ,
@@ -16,7 +16,7 @@ const personResolve = {
16
16
  handler: async (args, { host }) => {
17
17
  const name = String(args.name ?? '').trim();
18
18
  if (!name)
19
- throw ymbValidationError('name_required', 'name 必填');
19
+ throw imValidationError('name_required', 'name 必填');
20
20
  const employees = await host.searchEmployeeByName(name);
21
21
  const rows = employees.map((e) => ({
22
22
  uid: e.uid,
@@ -30,7 +30,7 @@ const personResolve = {
30
30
  cid: e.cid,
31
31
  ok: Boolean(e.uid && e.cid && e.uid !== '0' && e.cid !== '0'),
32
32
  }));
33
- return ymbSuccess('yimiaoban.person.resolve', {
33
+ return imSuccess('im.person.resolve', {
34
34
  total: rows.length,
35
35
  keyword: name,
36
36
  employees: rows,
@@ -39,10 +39,10 @@ const personResolve = {
39
39
  };
40
40
  /** uid 批量解析(emp-by-ids 语义)。 */
41
41
  const personResolveByIds = {
42
- name: 'yimiaoban.person.resolveByIds',
42
+ name: 'im.person.resolveByIds',
43
43
  resource: 'person',
44
44
  method: 'person.resolveByIds',
45
- action: 'yimiaoban.person.resolveByIds',
45
+ action: 'im.person.resolveByIds',
46
46
  summary: '按 uid 列表批量解析人员姓名/部门/岗位/cid(一次最多 100,超出自动分批)',
47
47
  capability: 'person',
48
48
  risk: READ,
@@ -52,9 +52,9 @@ const personResolveByIds = {
52
52
  handler: async (args, { host }) => {
53
53
  const ids = Array.isArray(args.ids) ? args.ids.map((x) => String(x)).filter(Boolean) : [];
54
54
  if (ids.length === 0)
55
- throw ymbValidationError('ids_required', 'ids 不能为空');
55
+ throw imValidationError('ids_required', 'ids 不能为空');
56
56
  const map = await host.resolveUsersByIds(ids);
57
- return ymbSuccess('yimiaoban.person.resolveByIds', {
57
+ return imSuccess('im.person.resolveByIds', {
58
58
  requested: ids.length,
59
59
  resolved: Object.keys(map).length,
60
60
  employees: ids
@@ -1,4 +1,4 @@
1
- import { ymbValidationError } from '../errors.js';
1
+ import { imValidationError } from '../errors.js';
2
2
  import { groupReadOperations } from './group-read.js';
3
3
  import { groupWriteOperations } from './group-write.js';
4
4
  import { msgReadOperations } from './msg-sync.js';
@@ -6,6 +6,7 @@ import { msgWriteOperations } from './msg-write.js';
6
6
  import { sessionOperations } from './session.js';
7
7
  import { personOperations } from './person.js';
8
8
  import { fileUserOperations } from './file-user.js';
9
+ import { userRemindOperations } from './user-remind.js';
9
10
  function buildRegistry() {
10
11
  const registry = new Map();
11
12
  const definitions = [
@@ -16,23 +17,24 @@ function buildRegistry() {
16
17
  ...groupWriteOperations,
17
18
  ...sessionOperations,
18
19
  ...fileUserOperations,
20
+ ...userRemindOperations,
19
21
  ];
20
22
  for (const definition of definitions) {
21
23
  if (registry.has(definition.name)) {
22
- throw new Error(`duplicate yimiaoban operation: ${definition.name}`);
24
+ throw new Error(`duplicate im operation: ${definition.name}`);
23
25
  }
24
26
  registry.set(definition.name, definition);
25
27
  }
26
28
  return registry;
27
29
  }
28
- const ymbOperationRegistry = buildRegistry();
29
- export function ymbOperationDefinitions() {
30
- return [...ymbOperationRegistry.values()];
30
+ const imOperationRegistry = buildRegistry();
31
+ export function imOperationDefinitions() {
32
+ return [...imOperationRegistry.values()];
31
33
  }
32
- export function getYmbOperation(operation) {
33
- const definition = ymbOperationRegistry.get(operation);
34
+ export function getImOperation(operation) {
35
+ const definition = imOperationRegistry.get(operation);
34
36
  if (!definition) {
35
- throw ymbValidationError('operation_unknown', `易秒办不支持操作:${operation}`);
37
+ throw imValidationError('operation_unknown', `易秒办不支持操作:${operation}`);
36
38
  }
37
39
  return definition;
38
40
  }