weaver-work-cli 0.1.1 → 0.1.4

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 (351) hide show
  1. package/README.md +187 -76
  2. package/dist/cmd/setup/index.js +5 -5
  3. package/dist/cmd/skills/index.js +1 -1
  4. package/dist/core/hooks.js +7 -0
  5. package/dist/index.js +0 -0
  6. package/dist/internal/e10/auth/commands.js +160 -55
  7. package/dist/internal/e10/auth/crypto.js +7 -22
  8. package/dist/internal/e10/auth/session.js +1 -1
  9. package/dist/internal/e10/auth/xiaoe.js +268 -0
  10. package/dist/internal/e10/context.js +16 -2
  11. package/dist/internal/e10/index.js +1 -0
  12. package/dist/internal/e10/request-runtime.js +344 -0
  13. package/dist/internal/skills/install.js +48 -6
  14. package/dist/internal/skills/reader.js +27 -0
  15. package/dist/shortcuts/archive/continuation.js +70 -0
  16. package/dist/shortcuts/archive/errors.js +53 -0
  17. package/dist/shortcuts/archive/host.js +197 -0
  18. package/dist/shortcuts/archive/index.js +363 -0
  19. package/dist/shortcuts/archive/manifest.js +45 -0
  20. package/dist/shortcuts/archive/operations/archive-info.js +55 -0
  21. package/dist/shortcuts/archive/operations/borrow-car.js +146 -0
  22. package/dist/shortcuts/archive/operations/borrow-list.js +200 -0
  23. package/dist/shortcuts/archive/operations/confirm.js +46 -0
  24. package/dist/shortcuts/archive/operations/download.js +238 -0
  25. package/dist/shortcuts/archive/operations/flow-url.js +240 -0
  26. package/dist/shortcuts/archive/operations/fonds.js +95 -0
  27. package/dist/shortcuts/archive/operations/getPageUrl.js +137 -0
  28. package/dist/shortcuts/archive/operations/registry.js +43 -0
  29. package/dist/shortcuts/archive/operations/search.js +88 -0
  30. package/dist/shortcuts/archive/operations/shared.js +120 -0
  31. package/dist/shortcuts/archive/operations/types.js +23 -0
  32. package/dist/shortcuts/archive/operations/upload.js +182 -0
  33. package/dist/shortcuts/archive/operations.js +13 -0
  34. package/dist/shortcuts/archive/render/search-format.js +276 -0
  35. package/dist/shortcuts/archive/render/search-view.js +125 -0
  36. package/dist/shortcuts/asset/continuation.js +70 -0
  37. package/dist/shortcuts/asset/errors.js +67 -0
  38. package/dist/shortcuts/asset/host.js +438 -0
  39. package/dist/shortcuts/asset/index.js +255 -0
  40. package/dist/shortcuts/asset/manifest.js +471 -0
  41. package/dist/shortcuts/asset/operations/query.js +249 -0
  42. package/dist/shortcuts/asset/operations/registry.js +85 -0
  43. package/dist/shortcuts/asset/operations/shared.js +100 -0
  44. package/dist/shortcuts/asset/operations/type-cache.js +49 -0
  45. package/dist/shortcuts/asset/operations/types.js +1 -0
  46. package/dist/shortcuts/asset/operations/viewlink.js +117 -0
  47. package/dist/shortcuts/asset/operations/write.js +435 -0
  48. package/dist/shortcuts/asset/operations.js +9 -0
  49. package/dist/shortcuts/calendar/continuation.js +70 -0
  50. package/dist/shortcuts/calendar/errors.js +53 -0
  51. package/dist/shortcuts/calendar/host.js +148 -0
  52. package/dist/shortcuts/calendar/index.js +125 -0
  53. package/dist/shortcuts/calendar/manifest.js +26 -0
  54. package/dist/shortcuts/calendar/operations/read.js +259 -0
  55. package/dist/shortcuts/calendar/operations/registry.js +31 -0
  56. package/dist/shortcuts/calendar/operations/shared.js +132 -0
  57. package/dist/shortcuts/calendar/operations/types.js +25 -0
  58. package/dist/shortcuts/calendar/operations/write.js +439 -0
  59. package/dist/shortcuts/calendar/operations.js +8 -0
  60. package/dist/shortcuts/ehr/continuation.js +70 -0
  61. package/dist/shortcuts/ehr/errors.js +53 -0
  62. package/dist/shortcuts/ehr/host.js +213 -0
  63. package/dist/shortcuts/ehr/index.js +205 -0
  64. package/dist/shortcuts/ehr/manifest.js +47 -0
  65. package/dist/shortcuts/ehr/operations/attend-read.js +373 -0
  66. package/dist/shortcuts/ehr/operations/attend-write.js +514 -0
  67. package/dist/shortcuts/ehr/operations/hr-contact.js +363 -0
  68. package/dist/shortcuts/ehr/operations/hr-ds.js +298 -0
  69. package/dist/shortcuts/ehr/operations/hr-report.js +386 -0
  70. package/dist/shortcuts/ehr/operations/recruit-write.js +1629 -0
  71. package/dist/shortcuts/ehr/operations/recruit.js +803 -0
  72. package/dist/shortcuts/ehr/operations/registry.js +43 -0
  73. package/dist/shortcuts/ehr/operations/salary.js +319 -0
  74. package/dist/shortcuts/ehr/operations/shared.js +246 -0
  75. package/dist/shortcuts/ehr/operations/types.js +25 -0
  76. package/dist/shortcuts/ehr/operations.js +25 -0
  77. package/dist/shortcuts/esb/continuation.js +70 -0
  78. package/dist/shortcuts/esb/errors.js +65 -0
  79. package/dist/shortcuts/esb/host.js +187 -0
  80. package/dist/shortcuts/esb/index.js +112 -0
  81. package/dist/shortcuts/esb/manifest.js +91 -0
  82. package/dist/shortcuts/esb/operations/input-format.js +31 -0
  83. package/dist/shortcuts/esb/operations/registry.js +48 -0
  84. package/dist/shortcuts/esb/operations/shared.js +152 -0
  85. package/dist/shortcuts/esb/operations/trigger.js +76 -0
  86. package/dist/shortcuts/esb/operations/types.js +21 -0
  87. package/dist/shortcuts/esb/operations.js +15 -0
  88. package/dist/shortcuts/fna/continuation.js +70 -0
  89. package/dist/shortcuts/fna/errors.js +59 -0
  90. package/dist/shortcuts/fna/host.js +146 -0
  91. package/dist/shortcuts/fna/index.js +111 -0
  92. package/dist/shortcuts/fna/manifest.js +41 -0
  93. package/dist/shortcuts/fna/operations/budget.js +124 -0
  94. package/dist/shortcuts/fna/operations/expense-center.js +148 -0
  95. package/dist/shortcuts/fna/operations/invoice-writeoff.js +212 -0
  96. package/dist/shortcuts/fna/operations/loan.js +195 -0
  97. package/dist/shortcuts/fna/operations/registry.js +35 -0
  98. package/dist/shortcuts/fna/operations/shared.js +210 -0
  99. package/dist/shortcuts/fna/operations/types.js +25 -0
  100. package/dist/shortcuts/fna/operations.js +19 -0
  101. package/dist/shortcuts/hrm/errors.js +38 -0
  102. package/dist/shortcuts/hrm/host.js +156 -0
  103. package/dist/shortcuts/hrm/index.js +111 -0
  104. package/dist/shortcuts/hrm/manifest.js +32 -0
  105. package/dist/shortcuts/hrm/operations/employee.js +338 -0
  106. package/dist/shortcuts/hrm/operations/org.js +110 -0
  107. package/dist/shortcuts/hrm/operations/position.js +176 -0
  108. package/dist/shortcuts/hrm/operations/registry.js +33 -0
  109. package/dist/shortcuts/hrm/operations/shared.js +143 -0
  110. package/dist/shortcuts/hrm/operations/types.js +23 -0
  111. package/dist/shortcuts/hrm/operations.js +19 -0
  112. package/dist/shortcuts/index.js +20 -0
  113. package/dist/shortcuts/invoice/host.js +99 -94
  114. package/dist/shortcuts/invoice/index.js +65 -61
  115. package/dist/shortcuts/invoice/manifest.js +222 -14
  116. package/dist/shortcuts/invoice/operations/browse-field.js +17 -0
  117. package/dist/shortcuts/invoice/operations/issuing.js +198 -0
  118. package/dist/shortcuts/invoice/operations/ocr-preview.js +6 -3
  119. package/dist/shortcuts/invoice/operations/registry.js +17 -0
  120. package/dist/shortcuts/invoice/operations/reim.js +401 -0
  121. package/dist/shortcuts/invoice/operations/shared.js +271 -6
  122. package/dist/shortcuts/invoice/operations/validate-preview.js +1 -1
  123. package/dist/shortcuts/jiuchuanhui/cache.js +441 -0
  124. package/dist/shortcuts/jiuchuanhui/continuation.js +70 -0
  125. package/dist/shortcuts/jiuchuanhui/errors.js +59 -0
  126. package/dist/shortcuts/jiuchuanhui/host.js +159 -0
  127. package/dist/shortcuts/jiuchuanhui/index.js +109 -0
  128. package/dist/shortcuts/jiuchuanhui/manifest.js +469 -0
  129. package/dist/shortcuts/jiuchuanhui/operations/datajson.js +214 -0
  130. package/dist/shortcuts/jiuchuanhui/operations/esb.js +157 -0
  131. package/dist/shortcuts/jiuchuanhui/operations/generic.js +146 -0
  132. package/dist/shortcuts/jiuchuanhui/operations/registry.js +133 -0
  133. package/dist/shortcuts/jiuchuanhui/operations/shared.js +158 -0
  134. package/dist/shortcuts/jiuchuanhui/operations/types.js +1 -0
  135. package/dist/shortcuts/jiuchuanhui/operations.js +8 -0
  136. package/dist/shortcuts/mail/continuation.js +70 -0
  137. package/dist/shortcuts/mail/errors.js +53 -0
  138. package/dist/shortcuts/mail/host.js +182 -0
  139. package/dist/shortcuts/mail/index.js +519 -0
  140. package/dist/shortcuts/mail/manifest.js +38 -0
  141. package/dist/shortcuts/mail/operations/mail-blacklist.js +79 -0
  142. package/dist/shortcuts/mail/operations/mail-contacts.js +195 -0
  143. package/dist/shortcuts/mail/operations/mail-manage.js +335 -0
  144. package/dist/shortcuts/mail/operations/mail-read.js +508 -0
  145. package/dist/shortcuts/mail/operations/mail-send.js +474 -0
  146. package/dist/shortcuts/mail/operations/mail-sign.js +203 -0
  147. package/dist/shortcuts/mail/operations/mail-template.js +170 -0
  148. package/dist/shortcuts/mail/operations/registry.js +41 -0
  149. package/dist/shortcuts/mail/operations/shared.js +64 -0
  150. package/dist/shortcuts/mail/operations/types.js +27 -0
  151. package/dist/shortcuts/mail/operations.js +19 -0
  152. package/dist/shortcuts/plan/continuation.js +70 -0
  153. package/dist/shortcuts/plan/errors.js +70 -0
  154. package/dist/shortcuts/plan/host.js +180 -0
  155. package/dist/shortcuts/plan/index.js +150 -0
  156. package/dist/shortcuts/plan/manifest.js +53 -0
  157. package/dist/shortcuts/plan/operations/link.js +256 -0
  158. package/dist/shortcuts/plan/operations/read.js +259 -0
  159. package/dist/shortcuts/plan/operations/registry.js +33 -0
  160. package/dist/shortcuts/plan/operations/shared.js +246 -0
  161. package/dist/shortcuts/plan/operations/types.js +49 -0
  162. package/dist/shortcuts/plan/operations/version.js +49 -0
  163. package/dist/shortcuts/plan/operations/write.js +710 -0
  164. package/dist/shortcuts/plan/operations.js +8 -0
  165. package/docs/SKILL.md +11 -7
  166. package/docs/_catalog.md +23 -5
  167. package/docs/agent-invoice.md +31 -10
  168. package/docs/agent-skill-install.md +211 -0
  169. package/docs/calendar.md +87 -0
  170. package/docs/e10-auth.md +28 -9
  171. package/docs/ehr.md +186 -0
  172. package/docs/esb.md +64 -0
  173. package/docs/fna.md +72 -0
  174. package/docs/hrm.md +89 -0
  175. package/docs/invoice.md +66 -20
  176. package/docs/jiuchuanhui.md +131 -0
  177. package/docs/operation-manual.md +443 -0
  178. package/docs/plan.md +82 -0
  179. package/docs/wenshuding.md +129 -0
  180. package/docs/ziguanjia.md +89 -0
  181. package/package.json +4 -4
  182. package/scripts/package-skill.mjs +127 -34
  183. package/scripts/postbuild.mjs +13 -0
  184. package/skill-template/business-info.json +13 -2
  185. package/skill-template/domains/calendar.md +15 -0
  186. package/skill-template/domains/esb.md +13 -0
  187. package/skill-template/domains/hrm.md +16 -0
  188. package/skill-template/domains/jiuchuanhui.md +23 -0
  189. package/skill-template/domains/jucailin.md +22 -0
  190. package/skill-template/domains/mail.md +21 -0
  191. package/skill-template/domains/plan.md +17 -0
  192. package/skill-template/domains/qiyecheng.md +17 -0
  193. package/skill-template/domains/shared.md +9 -3
  194. package/skill-template/domains/skill-maker.md +10 -0
  195. package/skill-template/domains/wenshuding.md +22 -0
  196. package/skill-template/domains/{invoice.md → yepiaotong.md} +4 -0
  197. package/skill-template/domains/ziguanjia.md +21 -0
  198. package/skill-template/master-skill-template.md +12 -6
  199. package/skill-template/skill-template.md +40 -9
  200. package/skills/weaver-e10-calendar/SKILL.md +101 -0
  201. package/skills/weaver-e10-calendar/product.json +8 -0
  202. package/skills/weaver-e10-calendar/references/calendar-app-check.md +65 -0
  203. package/skills/weaver-e10-calendar/references/calendar-dict.md +55 -0
  204. package/skills/weaver-e10-calendar/references/calendar-query.md +70 -0
  205. package/skills/weaver-e10-calendar/references/calendar-write.md +97 -0
  206. package/skills/weaver-e10-calendar/references/source-manifest.json +54 -0
  207. package/skills/weaver-e10-esb/SKILL.md +102 -0
  208. package/skills/weaver-e10-esb/product.json +8 -0
  209. package/skills/weaver-e10-esb/references/input-format.md +52 -0
  210. package/skills/weaver-e10-esb/references/source-manifest.json +242 -0
  211. package/skills/weaver-e10-esb/references/trigger.md +99 -0
  212. package/skills/weaver-e10-hrm/SKILL.md +87 -0
  213. package/skills/weaver-e10-hrm/product.json +8 -0
  214. package/skills/weaver-e10-hrm/references/employee.md +109 -0
  215. package/skills/weaver-e10-hrm/references/org.md +95 -0
  216. package/skills/weaver-e10-hrm/references/position.md +95 -0
  217. package/skills/weaver-e10-hrm/references/source-manifest.json +121 -0
  218. package/skills/weaver-e10-jiuchuanhui/SKILL.md +174 -0
  219. package/skills/weaver-e10-jiuchuanhui/product.json +8 -0
  220. package/skills/weaver-e10-jiuchuanhui/references/cache.md +110 -0
  221. package/skills/weaver-e10-jiuchuanhui/references/clue.md +61 -0
  222. package/skills/weaver-e10-jiuchuanhui/references/contact-plan.md +56 -0
  223. package/skills/weaver-e10-jiuchuanhui/references/contact-records.md +48 -0
  224. package/skills/weaver-e10-jiuchuanhui/references/contact.md +56 -0
  225. package/skills/weaver-e10-jiuchuanhui/references/customer.md +69 -0
  226. package/skills/weaver-e10-jiuchuanhui/references/disabled-capabilities.md +24 -0
  227. package/skills/weaver-e10-jiuchuanhui/references/discovery-config.md +60 -0
  228. package/skills/weaver-e10-jiuchuanhui/references/general-helpers.md +59 -0
  229. package/skills/weaver-e10-jiuchuanhui/references/jiuchuanhui-entry.md +60 -0
  230. package/skills/weaver-e10-jiuchuanhui/references/sale.md +72 -0
  231. package/skills/weaver-e10-jiuchuanhui/references/source-manifest.json +2632 -0
  232. package/skills/weaver-e10-jucailin/SKILL.md +101 -0
  233. package/skills/weaver-e10-jucailin/product.json +8 -0
  234. package/skills/weaver-e10-jucailin/references/attend-read.md +73 -0
  235. package/skills/weaver-e10-jucailin/references/attend-write.md +82 -0
  236. package/skills/weaver-e10-jucailin/references/hr-contact.md +92 -0
  237. package/skills/weaver-e10-jucailin/references/hr-datasource.md +104 -0
  238. package/skills/weaver-e10-jucailin/references/hr-report.md +76 -0
  239. package/skills/weaver-e10-jucailin/references/recruit-read.md +76 -0
  240. package/skills/weaver-e10-jucailin/references/recruit-write.md +70 -0
  241. package/skills/weaver-e10-jucailin/references/safety-boundaries.md +35 -0
  242. package/skills/weaver-e10-jucailin/references/salary.md +110 -0
  243. package/skills/weaver-e10-jucailin/references/source-manifest.json +152 -0
  244. package/skills/weaver-e10-mail/SKILL.md +151 -0
  245. package/skills/weaver-e10-mail/product.json +8 -0
  246. package/skills/weaver-e10-mail/references/mail-agent-entry.md +47 -0
  247. package/skills/weaver-e10-mail/references/mail-attachment.md +30 -0
  248. package/skills/weaver-e10-mail/references/mail-blacklist.md +27 -0
  249. package/skills/weaver-e10-mail/references/mail-contacts.md +33 -0
  250. package/skills/weaver-e10-mail/references/mail-manage.md +44 -0
  251. package/skills/weaver-e10-mail/references/mail-read.md +76 -0
  252. package/skills/weaver-e10-mail/references/mail-send.md +43 -0
  253. package/skills/weaver-e10-mail/references/mail-sign.md +33 -0
  254. package/skills/weaver-e10-mail/references/mail-template.md +31 -0
  255. package/skills/weaver-e10-mail/references/safety-boundaries.md +32 -0
  256. package/skills/weaver-e10-plan/SKILL.md +139 -0
  257. package/skills/weaver-e10-plan/product.json +8 -0
  258. package/skills/weaver-e10-plan/references/plan-collect-and-compose.md +123 -0
  259. package/skills/weaver-e10-plan/references/plan-overview-and-routing.md +138 -0
  260. package/skills/weaver-e10-plan/references/plan-report-query.md +154 -0
  261. package/skills/weaver-e10-plan/references/plan-report-remind.md +104 -0
  262. package/skills/weaver-e10-plan/references/plan-report-write.md +162 -0
  263. package/skills/weaver-e10-plan/references/source-manifest.json +858 -0
  264. package/skills/weaver-e10-qiyecheng/SKILL.md +118 -0
  265. package/skills/weaver-e10-qiyecheng/product.json +8 -0
  266. package/skills/weaver-e10-qiyecheng/references/budget.md +65 -0
  267. package/skills/weaver-e10-qiyecheng/references/catalog.md +56 -0
  268. package/skills/weaver-e10-qiyecheng/references/expense-center.md +51 -0
  269. package/skills/weaver-e10-qiyecheng/references/invoice-writeoff.md +57 -0
  270. package/skills/weaver-e10-qiyecheng/references/loan-management.md +59 -0
  271. package/skills/weaver-e10-qiyecheng/references/source-manifest.json +698 -0
  272. package/skills/weaver-e10-shared/SKILL.md +86 -0
  273. package/skills/weaver-e10-shared/references/e10-auth-and-session.md +127 -0
  274. package/skills/weaver-e10-shared/references/json-output-contract.md +120 -0
  275. package/skills/weaver-e10-shared/references/weaver-e10-installation.md +110 -0
  276. package/skills/weaver-e10-skill-maker/SKILL.md +77 -0
  277. package/skills/weaver-e10-skill-maker/product.json +8 -0
  278. package/skills/weaver-e10-skill-maker/references/business-skill-generation.md +124 -0
  279. package/skills/weaver-e10-skill-maker/references/detector-validation.md +101 -0
  280. package/skills/weaver-e10-skill-maker/references/module-cli-generation.md +230 -0
  281. package/skills/weaver-e10-skill-maker/references/post-generation-install.md +105 -0
  282. package/skills/weaver-e10-skill-maker/references/source-update-detection.md +261 -0
  283. package/skills/weaver-e10-skill-maker/references/weaver-skill-style.md +141 -0
  284. package/skills/weaver-e10-wenshuding/SKILL.md +157 -0
  285. package/skills/weaver-e10-wenshuding/product.json +8 -0
  286. package/skills/weaver-e10-wenshuding/references/archive-agent-entry.md +63 -0
  287. package/skills/weaver-e10-wenshuding/references/archive-borrow-car.md +52 -0
  288. package/skills/weaver-e10-wenshuding/references/archive-borrow-list.md +52 -0
  289. package/skills/weaver-e10-wenshuding/references/archive-disabled-capabilities.md +22 -0
  290. package/skills/weaver-e10-wenshuding/references/archive-download.md +48 -0
  291. package/skills/weaver-e10-wenshuding/references/archive-flow.md +46 -0
  292. package/skills/weaver-e10-wenshuding/references/archive-fonds.md +34 -0
  293. package/skills/weaver-e10-wenshuding/references/archive-info.md +33 -0
  294. package/skills/weaver-e10-wenshuding/references/archive-search.md +52 -0
  295. package/skills/weaver-e10-wenshuding/references/archive-upload.md +41 -0
  296. package/skills/weaver-e10-wenshuding/references/source-manifest.json +517 -0
  297. package/skills/weaver-e10-yepiaotong/SKILL.md +184 -0
  298. package/skills/{weaver-work-cli-invoice → weaver-e10-yepiaotong}/references/invoice-add.md +1 -1
  299. package/skills/weaver-e10-yepiaotong/references/invoice-agent-entry.md +47 -0
  300. package/skills/weaver-e10-yepiaotong/references/invoice-browse-field-data.md +204 -0
  301. package/skills/{weaver-work-cli-invoice → weaver-e10-yepiaotong}/references/invoice-delete.md +1 -1
  302. package/skills/{weaver-work-cli-invoice → weaver-e10-yepiaotong}/references/invoice-detail.md +13 -5
  303. package/skills/weaver-e10-yepiaotong/references/invoice-disabled-capabilities.md +28 -0
  304. package/skills/weaver-e10-yepiaotong/references/invoice-download.md +31 -0
  305. package/skills/weaver-e10-yepiaotong/references/invoice-enterprise-list.md +45 -0
  306. package/skills/{weaver-work-cli-invoice → weaver-e10-yepiaotong}/references/invoice-file-upload.md +15 -4
  307. package/skills/weaver-e10-yepiaotong/references/invoice-import.md +45 -0
  308. package/skills/weaver-e10-yepiaotong/references/invoice-issuing-examples.md +120 -0
  309. package/skills/weaver-e10-yepiaotong/references/invoice-issuing-field-rules.md +161 -0
  310. package/skills/weaver-e10-yepiaotong/references/invoice-issuing.md +99 -0
  311. package/skills/{weaver-work-cli-invoice → weaver-e10-yepiaotong}/references/invoice-ocr-preview.md +14 -4
  312. package/skills/weaver-e10-yepiaotong/references/invoice-personal-list.md +58 -0
  313. package/skills/weaver-e10-yepiaotong/references/invoice-red.md +261 -0
  314. package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +97 -0
  315. package/skills/{weaver-work-cli-invoice → weaver-e10-yepiaotong}/references/invoice-update.md +1 -1
  316. package/skills/{weaver-work-cli-invoice → weaver-e10-yepiaotong}/references/invoice-validation-preview.md +10 -3
  317. package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +1340 -0
  318. package/skills/weaver-e10-yepiaotong/references/reim-examples.md +845 -0
  319. package/skills/weaver-e10-yepiaotong/references/reim-expense-subject-rules.md +94 -0
  320. package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +449 -0
  321. package/skills/weaver-e10-yepiaotong/references/reim-matching-rules.md +266 -0
  322. package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +494 -0
  323. package/skills/weaver-e10-yepiaotong/references/source-manifest.json +1103 -0
  324. package/skills/weaver-e10-ziguanjia/SKILL.md +162 -0
  325. package/skills/weaver-e10-ziguanjia/product.json +8 -0
  326. package/skills/weaver-e10-ziguanjia/references/source-manifest.json +147 -0
  327. package/skills/weaver-e10-ziguanjia/references/ziguanjia-agent-entry.md +65 -0
  328. package/skills/weaver-e10-ziguanjia/references/ziguanjia-create.md +45 -0
  329. package/skills/weaver-e10-ziguanjia/references/ziguanjia-depre.md +48 -0
  330. package/skills/weaver-e10-ziguanjia/references/ziguanjia-disabled-capabilities.md +22 -0
  331. package/skills/weaver-e10-ziguanjia/references/ziguanjia-purch.md +57 -0
  332. package/skills/weaver-e10-ziguanjia/references/ziguanjia-query.md +62 -0
  333. package/skills/weaver-e10-ziguanjia/references/ziguanjia-repair.md +83 -0
  334. package/skills/weaver-e10-ziguanjia/references/ziguanjia-resolve.md +49 -0
  335. package/skills/weaver-e10-ziguanjia/references/ziguanjia-return.md +70 -0
  336. package/skills/weaver-e10-ziguanjia/references/ziguanjia-update.md +45 -0
  337. package/skills/weaver-e10-ziguanjia/references/ziguanjia-use.md +60 -0
  338. package/skills/weaver-e10-ziguanjia/references/ziguanjia-viewlink.md +81 -0
  339. package/skills/weaver-work-cli-invoice/SKILL.md +0 -103
  340. package/skills/weaver-work-cli-invoice/references/invoice-agent-entry.md +0 -38
  341. package/skills/weaver-work-cli-invoice/references/invoice-disabled-capabilities.md +0 -26
  342. package/skills/weaver-work-cli-invoice/references/invoice-download.md +0 -22
  343. package/skills/weaver-work-cli-invoice/references/invoice-enterprise-list.md +0 -35
  344. package/skills/weaver-work-cli-invoice/references/invoice-import.md +0 -28
  345. package/skills/weaver-work-cli-invoice/references/invoice-personal-list.md +0 -47
  346. package/skills/weaver-work-cli-shared/SKILL.md +0 -53
  347. package/skills/weaver-work-cli-shared/references/e10-auth-and-session.md +0 -83
  348. package/skills/weaver-work-cli-shared/references/json-output-contract.md +0 -61
  349. package/skills/weaver-work-cli-shared/references/weaver-work-cli-installation.md +0 -61
  350. /package/skills/{weaver-work-cli-shared → weaver-e10-shared}/references/high-risk-write.md +0 -0
  351. /package/skills/{weaver-work-cli-invoice → weaver-e10-yepiaotong}/product.json +0 -0
@@ -0,0 +1,474 @@
1
+ import { randomBytes } from 'node:crypto';
2
+ import { mailValidationError } from '../errors.js';
3
+ import { WRITE, mailSuccess, schemaOf, SCHEMA_STRING } from './types.js';
4
+ const CONTINUATION_TTL_MS = 600_000;
5
+ function b64(s) {
6
+ return Buffer.from(s, 'utf8').toString('base64');
7
+ }
8
+ function splitNames(s) {
9
+ if (!s)
10
+ return [];
11
+ return String(s).split(/[,,;;、\s]+/).map((x) => x.trim()).filter(Boolean);
12
+ }
13
+ function looksLikeEmail(s) {
14
+ return /@/.test(s);
15
+ }
16
+ class CandidateError extends Error {
17
+ pending;
18
+ constructor(pending) {
19
+ super('收件人存在重名/多候选,需用户确认后以 toId/ccId/bccId 精确指定');
20
+ this.pending = pending;
21
+ }
22
+ }
23
+ async function mailAdd(env, flag, mailResourceId) {
24
+ const params = { flag: String(flag) };
25
+ if (mailResourceId)
26
+ params.mailResourceId = String(mailResourceId);
27
+ if (flag === '3')
28
+ params.emlMailResourceIds = String(mailResourceId);
29
+ const rk = randomBytes(3).toString('hex').slice(0, 6);
30
+ const value = (await env.host.request({
31
+ path: '/api/mail/base/add/mailAdd',
32
+ method: 'POST',
33
+ query: { v: rk },
34
+ form: params,
35
+ }));
36
+ const d = value?.data || {};
37
+ if (!d.sessionUuid)
38
+ throw new Error('mailAdd 未返回 sessionUuid:' + JSON.stringify(value).slice(0, 300));
39
+ return d;
40
+ }
41
+ async function searchInternal(env, keyword) {
42
+ const value = (await env.host.request({
43
+ path: '/api/mail/base/common/browser/complete/resource',
44
+ method: 'POST',
45
+ body: {
46
+ browserMultiple: true,
47
+ authWecahtBook: false,
48
+ wxDepNeedConvertCount: 0,
49
+ wxEmpNeedConvertCount: 0,
50
+ wxTotalNeedConvertCount: 0,
51
+ secretLevel: '',
52
+ newly: 1,
53
+ searchValue: keyword,
54
+ },
55
+ }));
56
+ return value?.data?.data || [];
57
+ }
58
+ async function searchExternal(env, keyword) {
59
+ const value = (await env.host.request({
60
+ path: '/api/mail/base/add/addressFullsearch',
61
+ method: 'POST',
62
+ query: { keyword: encodeURIComponent(keyword), sf_request_type: 'ajax' },
63
+ }));
64
+ return value?.data || [];
65
+ }
66
+ async function resolveInternal(env, names) {
67
+ const out = [];
68
+ const pending = [];
69
+ for (const n of names) {
70
+ if (/^\d+$/.test(n)) {
71
+ out.push({ id: n, type: 'resource', userids: n, name: n });
72
+ continue;
73
+ }
74
+ const list = await searchInternal(env, n);
75
+ const exact = list.filter((x) => x.name === n || x.content === n);
76
+ const toItem = (x) => ({ id: x.id, type: 'resource', userids: x.id, name: x.name || x.content || n });
77
+ const cand = (x) => ({ id: x.id, name: x.name || x.content, department: x.department, position: x.position });
78
+ if (exact.length === 1)
79
+ out.push(toItem(exact[0]));
80
+ else if (exact.length > 1)
81
+ pending.push({ keyword: n, reason: '重名', candidates: exact.map(cand) });
82
+ else if (list.length === 1)
83
+ out.push(toItem(list[0]));
84
+ else if (list.length > 1)
85
+ pending.push({ keyword: n, reason: '多候选(无精确匹配)', candidates: list.slice(0, 5).map(cand) });
86
+ else
87
+ throw new Error('未找到内部人员:' + n + '(可尝试姓名/工号;若是部门请用 to-dep/cc-dep/bcc-dep 指定)');
88
+ }
89
+ if (pending.length)
90
+ throw new CandidateError(pending);
91
+ return out;
92
+ }
93
+ async function searchDepartmentTree(env, parentId) {
94
+ const body = {
95
+ browserMultiple: true,
96
+ authWecahtBook: false,
97
+ wxDepNeedConvertCount: 0,
98
+ wxEmpNeedConvertCount: 0,
99
+ wxTotalNeedConvertCount: 0,
100
+ secretLevel: '',
101
+ cmd: 'teams',
102
+ containsPartTimeEmployee: false,
103
+ browserLeftTreeDefaultExpandedLevel: '1',
104
+ pageSize: 30,
105
+ current: 1,
106
+ };
107
+ if (parentId)
108
+ Object.assign(body, { leftCompanyId: '1', type: 'department', id: parentId });
109
+ const value = (await env.host.request({
110
+ path: '/api/mail/base/common/browser/leftData/resource',
111
+ method: 'POST',
112
+ body,
113
+ }));
114
+ return value?.data?.data || [];
115
+ }
116
+ async function collectDepartmentMatches(env, name) {
117
+ const matches = [];
118
+ async function walk(nodes, depth) {
119
+ for (const n of nodes || []) {
120
+ const nm = n.content || n.contentDesc || '';
121
+ if (nm === name)
122
+ matches.push({ id: n.id, name: nm, isLeaf: !!n.isLeaf });
123
+ if (!n.isLeaf) {
124
+ if (n.children?.length)
125
+ await walk(n.children, depth + 1);
126
+ else if (depth < 5) {
127
+ try {
128
+ await walk(await searchDepartmentTree(env, n.id), depth + 1);
129
+ }
130
+ catch {
131
+ /* ignore */
132
+ }
133
+ }
134
+ }
135
+ }
136
+ }
137
+ await walk(await searchDepartmentTree(env, undefined), 0);
138
+ return matches;
139
+ }
140
+ async function resolveDepartmentMemberIds(env, deptId) {
141
+ const value = (await env.host.request({
142
+ path: '/api/mail/base/common/browser/data/resource',
143
+ method: 'POST',
144
+ body: {
145
+ browserMultiple: true,
146
+ authWecahtBook: false,
147
+ wxDepNeedConvertCount: 0,
148
+ wxEmpNeedConvertCount: 0,
149
+ wxTotalNeedConvertCount: 0,
150
+ secretLevel: '',
151
+ cmd: 'teams',
152
+ current: 1,
153
+ leftTreeSelectedId: String(deptId),
154
+ pageSize: 200,
155
+ formDatas: {
156
+ username: [{ usernameOpt: 'in' }],
157
+ status: [{ statusSelect: ['normal'] }],
158
+ subcompany: [{ subcompanyOpt: 'in' }],
159
+ department: [{ departmentOpt: 'in' }],
160
+ role: [{ roleOpt: 'in' }],
161
+ position: [{ positionOpt: 'in' }],
162
+ },
163
+ },
164
+ }));
165
+ const arr = value?.data?.data || [];
166
+ return arr.map((x) => x.id).filter(Boolean);
167
+ }
168
+ async function resolveDepartment(env, names) {
169
+ const out = [];
170
+ const pending = [];
171
+ for (const n of names) {
172
+ const matches = await collectDepartmentMatches(env, n);
173
+ if (matches.length === 1) {
174
+ const ids = await resolveDepartmentMemberIds(env, matches[0].id);
175
+ out.push({
176
+ id: matches[0].id,
177
+ type: 'department',
178
+ userids: ids.join(','),
179
+ leftAllLevel: true,
180
+ name: matches[0].name,
181
+ memberCount: ids.length,
182
+ });
183
+ }
184
+ else if (matches.length > 1) {
185
+ pending.push({ keyword: n, reason: '同名部门(请在结果中选择)', candidates: matches.map((x) => ({ id: x.id, name: x.name, type: '部门' })) });
186
+ }
187
+ else {
188
+ throw new Error('未找到部门:' + n + '(请确认部门名称,或用 to 指定人员)');
189
+ }
190
+ }
191
+ if (pending.length)
192
+ throw new CandidateError(pending);
193
+ return out;
194
+ }
195
+ async function resolveExternal(env, emails) {
196
+ const out = [];
197
+ for (const e of emails) {
198
+ if (looksLikeEmail(e)) {
199
+ out.push({ mailAddress: e, mailNickName: e.split('@')[0] });
200
+ continue;
201
+ }
202
+ const list = await searchExternal(env, e);
203
+ const hit = list.find((x) => x.mailAddress?.includes(e)) || list[0];
204
+ if (!hit)
205
+ throw new Error('未找到外部邮箱:' + e + '(可尝试完整邮箱地址)');
206
+ out.push({ mailAddress: hit.mailAddress, mailNickName: hit.mailNickName });
207
+ }
208
+ return out;
209
+ }
210
+ function wrapContent(userHtml, clobContent) {
211
+ const u = userHtml ? '<div>' + userHtml + '</div><div>&nbsp;</div><div>&nbsp;</div>' : '';
212
+ return '<div class="cke__pc cke_editable cke_editable_themed cke_contents_ltr" style="font-size: 12px;">' + u + (clobContent || '') + '</div>';
213
+ }
214
+ async function parseRecipients(env, add, args) {
215
+ const flag = String(args.flag ?? '-1');
216
+ const explicit = args.external === true ? 'external' : (args.internal === true ? 'internal' : null);
217
+ const toList = splitNames(args.to);
218
+ const ccList = splitNames(args.cc);
219
+ const bccList = splitNames(args.bcc);
220
+ const toIdList = splitNames(args.toId);
221
+ const ccIdList = splitNames(args.ccId);
222
+ const bccIdList = splitNames(args.bccId);
223
+ const toDepList = splitNames(args.toDep);
224
+ const ccDepList = splitNames(args.ccDep);
225
+ const bccDepList = splitNames(args.bccDep);
226
+ let prefilled = null;
227
+ if ((flag === '1' || flag === '4') && toList.length === 0) {
228
+ const inner = (add.sendTo_internal || []).map((x) => ({ id: x.id, type: 'resource', userids: x.id }));
229
+ const outer = add.sendTo_outer || [];
230
+ if (outer.length)
231
+ prefilled = { kind: 'external', to: outer.map((x) => x.mailAddress), cc: [], bcc: [] };
232
+ else if (inner.length)
233
+ prefilled = { kind: 'internal', to: inner.map((x) => x.id), cc: [], bcc: [] };
234
+ }
235
+ let kind = explicit || (prefilled ? prefilled.kind : null);
236
+ if (!kind) {
237
+ const hasDep = toDepList.length || ccDepList.length || bccDepList.length;
238
+ const hasId = toIdList.length || ccIdList.length || bccIdList.length;
239
+ if (hasDep || hasId)
240
+ kind = 'internal';
241
+ else {
242
+ const all = [...toList, ...ccList, ...bccList];
243
+ const hasEmail = all.some(looksLikeEmail);
244
+ const hasName = all.some((x) => !looksLikeEmail(x));
245
+ if (hasEmail && hasName) {
246
+ throw new Error('收件人内外部混用:邮箱地址=外部邮件、姓名=内部邮件,请统一,或用 --internal/--external 明确邮件类型');
247
+ }
248
+ if (!all.length)
249
+ throw new Error('请先说明收件人(姓名=内部邮件 / 邮箱地址=外部邮件 / 部门用 to-dep)');
250
+ kind = hasEmail ? 'external' : 'internal';
251
+ }
252
+ }
253
+ const to = prefilled ? prefilled.to : toList;
254
+ const cc = prefilled ? prefilled.cc : ccList;
255
+ const bcc = prefilled ? prefilled.bcc : bccList;
256
+ if (kind === 'internal') {
257
+ const resolveGroup = async (nameList, idList, depList) => {
258
+ const persons = idList.length ? await resolveInternal(env, idList) : nameList.length ? await resolveInternal(env, nameList) : [];
259
+ const deps = depList.length ? await resolveDepartment(env, depList) : [];
260
+ return [...persons, ...deps];
261
+ };
262
+ const rawTo = await resolveGroup(to, toIdList, toDepList);
263
+ const rawCc = await resolveGroup(cc, ccIdList, ccDepList);
264
+ const rawBcc = await resolveGroup(bcc, bccIdList, bccDepList);
265
+ const clean = (arr) => arr.map((x) => (x.type === 'department'
266
+ ? { id: x.id, type: 'department', userids: x.userids, leftAllLevel: x.leftAllLevel }
267
+ : { id: x.id, type: 'resource', userids: x.userids }));
268
+ const ids = (arr) => [...new Set(arr.flatMap((x) => String(x.userids || '').split(',').filter(Boolean)))].join(',');
269
+ const names = (arr) => arr.map((x) => (x.type === 'department' ? `${x.name}(${x.memberCount}人)` : x.name)).join('、');
270
+ const totalCount = ids([...rawTo, ...rawCc, ...rawBcc]).split(',').filter(Boolean).length;
271
+ return {
272
+ fields: {
273
+ isInternal: 1,
274
+ internalTo: clean(rawTo),
275
+ internalCc: clean(rawCc),
276
+ internalBcc: clean(rawBcc),
277
+ internaltonewIds: ids(rawTo),
278
+ internalccnewIds: ids(rawCc),
279
+ internalbccnewIds: ids(rawBcc),
280
+ usernameTo: JSON.stringify(clean(rawTo)),
281
+ usernameCc: JSON.stringify(clean(rawCc)),
282
+ usernameBcc: JSON.stringify(clean(rawBcc)),
283
+ },
284
+ display: { to: names(rawTo), cc: names(rawCc), bcc: names(rawBcc) },
285
+ recipientCount: totalCount,
286
+ };
287
+ }
288
+ const rawTo = to.length ? await resolveExternal(env, to) : [];
289
+ const rawCc = cc.length ? await resolveExternal(env, cc) : [];
290
+ const rawBcc = bcc.length ? await resolveExternal(env, bcc) : [];
291
+ const emails = (arr) => arr.map((x) => x.mailAddress).join(',');
292
+ const names = (arr) => arr.map((x) => x.mailNickName || x.mailAddress).join('、');
293
+ const from = (add.sendFrom_outer || []).find((x) => x.selected) || (add.sendFrom_outer || [])[0];
294
+ if (!from || !from.mailAddress) {
295
+ throw new Error('当前账号未配置外部邮箱发件账号(mailAdd.sendFrom_outer 为空),无法发送外部邮件;请先在邮件设置中绑定外部邮箱账号');
296
+ }
297
+ const totalCount = [...rawTo, ...rawCc, ...rawBcc].length;
298
+ return {
299
+ fields: {
300
+ isInternal: 0,
301
+ sendTo: emails(rawTo),
302
+ sendCc: emails(rawCc),
303
+ sendBcc: emails(rawBcc),
304
+ usernameTo: JSON.stringify(rawTo),
305
+ usernameCc: JSON.stringify(rawCc),
306
+ usernameBcc: JSON.stringify(rawBcc),
307
+ mailAccountId: from.id ? String(from.id) : '',
308
+ sendFrom: from.mailAddress || '',
309
+ },
310
+ display: { to: names(rawTo) || '(未指定收件人)', cc: names(rawCc), bcc: names(rawBcc) },
311
+ recipientCount: totalCount,
312
+ };
313
+ }
314
+ async function checkMailConfig(env, isInternal) {
315
+ const value = (await env.host.request({
316
+ path: '/api/mail/base/getEmailAllConfig',
317
+ method: 'POST',
318
+ query: { from: 'mailadd' },
319
+ }));
320
+ const sys = value?.data?.sysConfig || {};
321
+ if (isInternal === 1) {
322
+ if (sys.innerMail !== undefined && Number(sys.innerMail) !== 1) {
323
+ throw new Error('当前环境未启用内部邮件(getEmailAllConfig.sysConfig.innerMail=' + sys.innerMail + '),无法发送内部邮件');
324
+ }
325
+ }
326
+ else {
327
+ if (sys.outterMail !== undefined && Number(sys.outterMail) !== 1) {
328
+ throw new Error('当前环境未启用外部邮件(getEmailAllConfig.outterMail=0),无法发送外部邮件');
329
+ }
330
+ }
331
+ if (sys.innerMail !== undefined && sys.outterMail !== undefined && Number(sys.innerMail) !== 1 && Number(sys.outterMail) !== 1) {
332
+ throw new Error('系统未启用邮件功能(内部/外部邮件均未开启),无法发送邮件');
333
+ }
334
+ }
335
+ async function precheckSend(env, body) {
336
+ const c = (await env.host.request({ path: '/api/mail/send/canSendMail', method: 'POST', body }));
337
+ const cdata = c?.data || {};
338
+ if (cdata.success !== undefined && cdata.success !== 1) {
339
+ throw new Error('发送前校验未通过:' + (cdata.msg || '未知拦截(canSendMail)'));
340
+ }
341
+ }
342
+ async function buildBody(env, add, args, draft) {
343
+ const flag = String(args.flag ?? '-1');
344
+ const isReply = flag === '1' || flag === '3';
345
+ const fullHtml = wrapContent(String(args.content || ''), isReply ? (add.clobContent || '') : '');
346
+ const { fields, display, recipientCount } = await parseRecipients(env, add, args);
347
+ const body = {
348
+ saveDraft: draft,
349
+ content: b64(fullHtml),
350
+ sessionUuid: add.sessionUuid,
351
+ subject: args.subject || add.mailSubject || '',
352
+ mailResourceId: args.id ? String(args.id) : '',
353
+ isInternal: fields.isInternal,
354
+ flag: Number(flag),
355
+ files: args.files || '',
356
+ filesizes: args.filesizes || '',
357
+ ...fields,
358
+ mailPriority: '0',
359
+ saveToSent: true,
360
+ isHtmlMode: '1',
361
+ op_isTimingSend: args.timing ? '1' : '0',
362
+ timingdate: args.timing || '',
363
+ secretLevel: '40',
364
+ fromModule: 'mail',
365
+ };
366
+ if (isReply)
367
+ body.oldMailId = String(args.id);
368
+ return { body, display, recipientCount };
369
+ }
370
+ // ---------------------------------------------------------------------------
371
+ // prepare / apply
372
+ // ---------------------------------------------------------------------------
373
+ const SEND_SCHEMA = schemaOf({
374
+ flag: { type: 'string', description: '新建 -1 / 回复 1 / 转发 3 / 编辑草稿 4' },
375
+ id: SCHEMA_STRING,
376
+ to: SCHEMA_STRING,
377
+ cc: SCHEMA_STRING,
378
+ bcc: SCHEMA_STRING,
379
+ toDep: SCHEMA_STRING,
380
+ ccDep: SCHEMA_STRING,
381
+ bccDep: SCHEMA_STRING,
382
+ toId: SCHEMA_STRING,
383
+ ccId: SCHEMA_STRING,
384
+ bccId: SCHEMA_STRING,
385
+ external: { type: 'boolean' },
386
+ internal: { type: 'boolean' },
387
+ subject: SCHEMA_STRING,
388
+ content: SCHEMA_STRING,
389
+ timing: SCHEMA_STRING,
390
+ files: SCHEMA_STRING,
391
+ filesizes: SCHEMA_STRING,
392
+ draft: { type: 'boolean' },
393
+ confirm: { type: 'boolean' },
394
+ continuation: SCHEMA_STRING,
395
+ }, { description: '邮件发送(prepare/apply)' });
396
+ const opSendPrepare = {
397
+ name: 'mail.send.prepare',
398
+ resource: 'mail/base/add/mailAdd',
399
+ method: 'POST',
400
+ action: 'mail.send.prepare',
401
+ summary: '准备发送(组装请求 + 安全预检 + 输出摘要,不发送)',
402
+ risk: WRITE,
403
+ requiresConfirmation: true,
404
+ inputSchema: SEND_SCHEMA,
405
+ async handler(args, env) {
406
+ const flag = String(args.flag ?? '-1');
407
+ const draft = args.draft === true;
408
+ const session = await env.host.getSession();
409
+ const add = await mailAdd(env, flag, args.id ? String(args.id) : undefined);
410
+ const { body, display, recipientCount } = await buildBody(env, add, args, draft);
411
+ await checkMailConfig(env, body.isInternal);
412
+ await precheckSend(env, body);
413
+ const flagText = { '-1': '新建', '1': '回复', '3': '转发', '4': '编辑草稿' }[flag] || flag;
414
+ const continuation = await env.continuation.issue({
415
+ operation: 'mail.send.apply',
416
+ baseUrl: session.baseUrl,
417
+ profile: session.profile,
418
+ userId: session.userId,
419
+ body,
420
+ draft,
421
+ subject: body.subject,
422
+ }, CONTINUATION_TTL_MS);
423
+ return mailSuccess('mail.send.prepare', {
424
+ action: flagText,
425
+ type: body.isInternal === 1 ? '内部邮件' : '外部邮件',
426
+ subject: body.subject,
427
+ to: display.to || '(未指定收件人)',
428
+ cc: display.cc || '',
429
+ bcc: display.bcc || '',
430
+ recipientCount: recipientCount || 0,
431
+ contentPreview: String(args.content || '').slice(0, 100),
432
+ includeOriginal: flag === '1' || flag === '3' ? '是(含原邮件引用)' : '否',
433
+ timing: args.timing ? String(args.timing) : '即时发送',
434
+ tip: '发送前安全预检已通过;用户确认后以 mail send apply --continuation <token> --yes 执行',
435
+ }, { continuation });
436
+ },
437
+ };
438
+ const opSendApply = {
439
+ name: 'mail.send.apply',
440
+ resource: 'mail/send/sendMail',
441
+ method: 'POST',
442
+ action: 'mail.send.apply',
443
+ summary: '执行发送(需 continuation 与 confirm)',
444
+ risk: WRITE,
445
+ requiresConfirmation: true,
446
+ inputSchema: SEND_SCHEMA,
447
+ async handler(args, env) {
448
+ if (args.confirm !== true) {
449
+ throw mailValidationError('confirm_required', 'mail.send.apply 必须传入 confirm=true 与 prepare 返回的 continuation');
450
+ }
451
+ if (!args.continuation) {
452
+ throw mailValidationError('continuation_required', 'mail.send.apply 必须传入 prepare 返回的 continuation');
453
+ }
454
+ const lease = await env.continuation.verify(String(args.continuation), 'mail.send.apply');
455
+ const session = await env.host.getSession();
456
+ if (lease.baseUrl !== session.baseUrl || lease.profile !== session.profile || lease.userId !== session.userId) {
457
+ throw mailValidationError('context_mismatch', '确认上下文已变化(租户或登录账号不同),请重新执行 prepare');
458
+ }
459
+ const body = lease.body;
460
+ const draft = lease.draft === true;
461
+ // 兜底再次校验:配置开关 + canSendMail
462
+ await checkMailConfig(env, body.isInternal);
463
+ if (!draft)
464
+ await precheckSend(env, body);
465
+ const path = draft ? '/api/mail/send/saveDraft' : '/api/mail/send/sendMail';
466
+ const value = (await env.host.request({ path, method: 'POST', body }));
467
+ const d = value?.data || {};
468
+ if (draft) {
469
+ return mailSuccess('mail.send.apply', { success: d.status === 1, draft: true, mailResourceId: d.mailResourceId, subject: lease.subject }, { savedDraft: true });
470
+ }
471
+ return mailSuccess('mail.send.apply', { success: d.success === 1, msg: d.msg || '邮件已发送', subject: lease.subject }, { sent: true });
472
+ },
473
+ };
474
+ export const mailSendOperations = [opSendPrepare, opSendApply];
@@ -0,0 +1,203 @@
1
+ import { mailValidationError } from '../errors.js';
2
+ import { READ, WRITE, mailSuccess, schemaOf, SCHEMA_STRING } from './types.js';
3
+ const CONTINUATION_TTL_MS = 600_000;
4
+ const SIGN_SCHEMA = schemaOf({
5
+ id: SCHEMA_STRING,
6
+ signName: SCHEMA_STRING,
7
+ clobContent: SCHEMA_STRING,
8
+ signDesc: SCHEMA_STRING,
9
+ defaultUse: SCHEMA_STRING,
10
+ signType: SCHEMA_STRING,
11
+ electronSignEnable: SCHEMA_STRING,
12
+ confirm: { type: 'boolean' },
13
+ continuation: SCHEMA_STRING,
14
+ }, { description: '签名保存(prepare/apply)' });
15
+ function buildSignBody(args) {
16
+ const signName = String(args.signName || '').trim();
17
+ const clobContent = String(args.clobContent || '').trim();
18
+ if (!signName)
19
+ throw new Error('signName(签名名称)必填');
20
+ if (!clobContent)
21
+ throw new Error('clobContent(Base64 编码的 HTML 内容)必填');
22
+ const body = {
23
+ signName,
24
+ clobContent,
25
+ signDesc: args.signDesc ? String(args.signDesc) : '',
26
+ defaultUse: args.defaultUse !== undefined ? Number(args.defaultUse) : 0,
27
+ signType: args.signType ? String(args.signType) : '0',
28
+ electronSignEnable: args.electronSignEnable !== undefined ? Number(args.electronSignEnable) : 0,
29
+ };
30
+ if (args.id)
31
+ body.id = String(args.id);
32
+ return body;
33
+ }
34
+ const opSignSavePrepare = {
35
+ name: 'mail.sign.save.prepare',
36
+ resource: 'mail/base/setting/sign/saveMailSign',
37
+ method: 'POST',
38
+ action: 'mail.sign.save.prepare',
39
+ summary: '新增签名(prepare,不保存)',
40
+ risk: WRITE,
41
+ requiresConfirmation: true,
42
+ inputSchema: SIGN_SCHEMA,
43
+ async handler(args, env) {
44
+ const body = buildSignBody(args);
45
+ const session = await env.host.getSession();
46
+ const continuation = await env.continuation.issue({
47
+ operation: 'mail.sign.save.apply',
48
+ baseUrl: session.baseUrl,
49
+ profile: session.profile,
50
+ userId: session.userId,
51
+ body,
52
+ }, CONTINUATION_TTL_MS);
53
+ return mailSuccess('mail.sign.save.prepare', {
54
+ signName: body.signName,
55
+ defaultUse: body.defaultUse,
56
+ tip: '确认后以 mail sign save --apply --continuation <token> --yes 执行保存',
57
+ }, { continuation });
58
+ },
59
+ };
60
+ const opSignSaveApply = {
61
+ name: 'mail.sign.save.apply',
62
+ resource: 'mail/base/setting/sign/saveMailSign',
63
+ method: 'POST',
64
+ action: 'mail.sign.save.apply',
65
+ summary: '执行新增签名',
66
+ risk: WRITE,
67
+ requiresConfirmation: true,
68
+ inputSchema: SIGN_SCHEMA,
69
+ async handler(args, env) {
70
+ if (args.confirm !== true)
71
+ throw new Error('mail.sign.save.apply 必须传入 confirm=true 与 prepare 返回的 continuation');
72
+ if (!args.continuation)
73
+ throw new Error('mail.sign.save.apply 必须传入 prepare 返回的 continuation');
74
+ const lease = await env.continuation.verify(String(args.continuation), 'mail.sign.save.apply');
75
+ const session = await env.host.getSession();
76
+ if (lease.baseUrl !== session.baseUrl || lease.profile !== session.profile || lease.userId !== session.userId) {
77
+ throw mailValidationError('context_mismatch', '确认上下文已变化(租户或登录账号不同),请重新执行 prepare');
78
+ }
79
+ const value = (await env.host.request({ path: '/api/mail/base/setting/sign/saveMailSign', method: 'POST', body: lease.body }));
80
+ return mailSuccess('mail.sign.save.apply', { id: value?.data ?? 'SUCCESS' }, {});
81
+ },
82
+ };
83
+ const opSignUpdate = {
84
+ name: 'mail.sign.update',
85
+ resource: 'mail/base/setting/sign/updateMailSign',
86
+ method: 'POST',
87
+ action: 'mail.sign.update',
88
+ summary: '编辑签名(GET 全量 + 保存)',
89
+ risk: WRITE,
90
+ inputSchema: schemaOf({
91
+ id: { type: 'string', description: '签名 id' },
92
+ signName: SCHEMA_STRING,
93
+ clobContent: SCHEMA_STRING,
94
+ signDesc: SCHEMA_STRING,
95
+ defaultUse: SCHEMA_STRING,
96
+ signType: SCHEMA_STRING,
97
+ electronSignEnable: SCHEMA_STRING,
98
+ }, { required: ['id'], description: '编辑签名' }),
99
+ async handler(args, env) {
100
+ const id = String(args.id || '').trim();
101
+ if (!id)
102
+ throw new Error('id(签名 id)必填');
103
+ const form = (await env.host.request({ path: '/api/mail/base/setting/sign/getMailSignForm', method: 'POST', body: { id } }));
104
+ const cur = form?.data?.formData || {};
105
+ const body = {
106
+ id,
107
+ signName: args.signName ? String(args.signName) : (cur.signName ?? ''),
108
+ clobContent: args.clobContent ? String(args.clobContent) : (cur.clobContent ?? ''),
109
+ signDesc: args.signDesc ? String(args.signDesc) : (cur.signDesc ?? ''),
110
+ defaultUse: args.defaultUse !== undefined ? Number(args.defaultUse) : (cur.defaultUse ?? 0),
111
+ signType: args.signType ? String(args.signType) : (cur.signType ?? '0'),
112
+ electronSignEnable: args.electronSignEnable !== undefined ? Number(args.electronSignEnable) : (cur.electronSignEnable ?? 0),
113
+ };
114
+ if (!body.signName)
115
+ throw new Error('签名名称为空(原值缺失且未提供 signName)');
116
+ if (!body.clobContent)
117
+ throw new Error('签名内容为空(原值缺失且未提供 clobContent)');
118
+ const value = (await env.host.request({ path: '/api/mail/base/setting/sign/updateMailSign', method: 'POST', body }));
119
+ return mailSuccess('mail.sign.update', value?.data ?? 'SUCCESS', { id });
120
+ },
121
+ };
122
+ const opSignDelete = {
123
+ name: 'mail.sign.delete',
124
+ resource: 'mail/base/setting/sign/deleteMailSign',
125
+ method: 'POST',
126
+ action: 'mail.sign.delete',
127
+ summary: '删除签名',
128
+ risk: WRITE,
129
+ inputSchema: schemaOf({ id: { type: 'string', description: '签名 id' } }, { required: ['id'], description: '删除签名' }),
130
+ async handler(args, env) {
131
+ const id = String(args.id || '').trim();
132
+ if (!id)
133
+ throw new Error('id(签名 id)必填');
134
+ const value = (await env.host.request({ path: '/api/mail/base/setting/sign/deleteMailSign', method: 'POST', body: { id } }));
135
+ return mailSuccess('mail.sign.delete', value?.data ?? 'SUCCESS', { id });
136
+ },
137
+ };
138
+ const opSignDefault = {
139
+ name: 'mail.sign.default',
140
+ resource: 'mail/base/setting/sign/defaultMailSign',
141
+ method: 'POST',
142
+ action: 'mail.sign.default',
143
+ summary: '设为默认签名',
144
+ risk: WRITE,
145
+ inputSchema: schemaOf({ id: { type: 'string', description: '签名 id' } }, { required: ['id'], description: '设默认签名' }),
146
+ async handler(args, env) {
147
+ const id = String(args.id || '').trim();
148
+ if (!id)
149
+ throw new Error('id(签名 id)必填');
150
+ const value = (await env.host.request({ path: '/api/mail/base/setting/sign/defaultMailSign', method: 'POST', body: { id } }));
151
+ return mailSuccess('mail.sign.default', value?.data ?? 'SUCCESS', { id });
152
+ },
153
+ };
154
+ const opSignQrcode = {
155
+ name: 'mail.sign.qrcode',
156
+ resource: 'mail/base/setting/sign/createQRcode',
157
+ method: 'POST',
158
+ action: 'mail.sign.qrcode',
159
+ summary: '生成二维码名片',
160
+ risk: READ,
161
+ inputSchema: schemaOf({
162
+ id: SCHEMA_STRING,
163
+ userName: SCHEMA_STRING,
164
+ jobtitle: SCHEMA_STRING,
165
+ email: SCHEMA_STRING,
166
+ signLocation: SCHEMA_STRING,
167
+ mobile: SCHEMA_STRING,
168
+ telephone: SCHEMA_STRING,
169
+ fax: SCHEMA_STRING,
170
+ selected: SCHEMA_STRING,
171
+ }, { description: '二维码名片' }),
172
+ async handler(args, env) {
173
+ let userName = args.userName ? String(args.userName) : '';
174
+ if (!userName && args.id) {
175
+ try {
176
+ const form = (await env.host.request({ path: '/api/mail/base/setting/sign/getMailSignForm', method: 'POST', body: { id: String(args.id) } }));
177
+ const cur = form?.data?.formData || {};
178
+ userName = cur.signName || '';
179
+ }
180
+ catch { /* 忽略,后续校验 */ }
181
+ }
182
+ const body = {
183
+ userName,
184
+ jobtitle: args.jobtitle ? String(args.jobtitle) : '',
185
+ email: args.email ? String(args.email) : '',
186
+ signLocation: args.signLocation ? String(args.signLocation) : '',
187
+ mobile: args.mobile ? String(args.mobile) : '',
188
+ telephone: args.telephone ? String(args.telephone) : '',
189
+ fax: args.fax ? String(args.fax) : '',
190
+ selected: args.selected ? String(args.selected) : (userName ? '1,2,3,5' : '1'),
191
+ };
192
+ const value = (await env.host.request({ path: '/api/mail/base/setting/sign/createQRcode', method: 'POST', body }));
193
+ return mailSuccess('mail.sign.qrcode', { qrcode: value?.data ?? '' }, {});
194
+ },
195
+ };
196
+ export const mailSignOperations = [
197
+ opSignSavePrepare,
198
+ opSignSaveApply,
199
+ opSignUpdate,
200
+ opSignDelete,
201
+ opSignDefault,
202
+ opSignQrcode,
203
+ ];