weaver-work-cli 0.1.40 → 0.1.44

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 (401) hide show
  1. package/README.md +17 -0
  2. package/dist/chunks/{archive-JHTONRST.js → archive-P6TBQGKL.js} +13 -5
  3. package/dist/chunks/{archive-oa-FCHLCPHC.js → archive-oa-7TQ2NXOH.js} +12 -5
  4. package/dist/chunks/{asset-RLIHC7DB.js → asset-3ELRG37G.js} +11 -4
  5. package/dist/chunks/{asset-idle-KVOFTLCP.js → asset-idle-WIGMUFMD.js} +7 -3
  6. package/dist/chunks/{attachment-content-RZYDB3MB.js → attachment-content-E3276UOV.js} +5 -4
  7. package/dist/chunks/{blog-42OZTJNP.js → blog-C5NMZAAC.js} +11 -4
  8. package/dist/chunks/{caizhilian-KRK547K5.js → caizhilian-5XSM2DFP.js} +13 -6
  9. package/dist/chunks/{calendar-RTWAMKHD.js → calendar-FI2WNSBO.js} +71 -26
  10. package/dist/chunks/{chunk-CXRQWOZ5.js → chunk-3YBDYOC4.js} +3 -3
  11. package/dist/chunks/{chunk-OOUTBLZ4.js → chunk-56EZERK4.js} +1 -1
  12. package/dist/chunks/chunk-6N4JPNFL.js +76 -0
  13. package/dist/chunks/{chunk-ZUX3P6BQ.js → chunk-727FH2NI.js} +1 -1
  14. package/dist/chunks/chunk-7BDPM5ST.js +11 -0
  15. package/dist/chunks/{chunk-LN447PY2.js → chunk-BCVYBYYT.js} +432 -2247
  16. package/dist/chunks/{chunk-7E6MUOEK.js → chunk-CWYGFU5B.js} +2 -2
  17. package/dist/chunks/{chunk-NOODWMCL.js → chunk-D4ADSZ7H.js} +1 -1
  18. package/dist/chunks/{chunk-WFFNM65B.js → chunk-ETNJSKMM.js} +281 -29
  19. package/dist/chunks/{chunk-CAQNBBQA.js → chunk-F4E4EM35.js} +3 -3
  20. package/dist/chunks/{chunk-4CTESSKI.js → chunk-FAZTGX7S.js} +6 -6
  21. package/dist/chunks/chunk-FRZKBMSW.js +2562 -0
  22. package/dist/chunks/{chunk-BYBSCN4X.js → chunk-G7PQWD4L.js} +6 -3
  23. package/dist/chunks/{chunk-NJKREDA3.js → chunk-GAMZLAG2.js} +1 -1
  24. package/dist/chunks/{chunk-FLS4DPGP.js → chunk-GM6J7Q4B.js} +28 -15
  25. package/dist/chunks/{chunk-NETCCARD.js → chunk-GRDRG6HP.js} +3 -3
  26. package/dist/chunks/chunk-HIT4Y6OI.js +1238 -0
  27. package/dist/chunks/{chunk-EZALDOQH.js → chunk-HP7JIYMT.js} +5 -2
  28. package/dist/chunks/{chunk-IZSSVYAG.js → chunk-IAZ3UPY6.js} +3 -3
  29. package/dist/chunks/{chunk-ZEDWSH32.js → chunk-IC62NFM5.js} +1 -1
  30. package/dist/chunks/{chunk-P26ZWSKU.js → chunk-KIHNAS25.js} +5 -2
  31. package/dist/chunks/{chunk-57IECMWX.js → chunk-N4M2DDFE.js} +29 -15
  32. package/dist/chunks/{chunk-JWRZM2H2.js → chunk-OF4S23UB.js} +4 -4
  33. package/dist/chunks/{chunk-VNBU55SL.js → chunk-PC7VKEB5.js} +80 -2458
  34. package/dist/chunks/{chunk-G2JSIUWF.js → chunk-PUQS5MWL.js} +91 -2
  35. package/dist/chunks/{chunk-E7OK5WD5.js → chunk-Q4OYAQYH.js} +5 -5
  36. package/dist/chunks/{chunk-7BRU4EFH.js → chunk-QVSWRLLU.js} +35 -6
  37. package/dist/chunks/{chunk-T6EGVBKU.js → chunk-TA7FXXJD.js} +6 -3
  38. package/dist/chunks/{chunk-GPMFD4RD.js → chunk-TXUG266F.js} +1 -1
  39. package/dist/chunks/{chunk-4TEDNCON.js → chunk-UFIT2UU3.js} +354 -56
  40. package/dist/chunks/{chunk-LUSPKZKY.js → chunk-UG5G54VL.js} +1 -0
  41. package/dist/chunks/{chunk-NIAJ5ZCG.js → chunk-UL5XUQ25.js} +5 -2
  42. package/dist/chunks/{chunk-FMPJJYYI.js → chunk-WRXSAVKO.js} +1 -1
  43. package/dist/chunks/{chunk-7U577Q7U.js → chunk-WSF4NNMR.js} +3 -3
  44. package/dist/chunks/chunk-XHK4MDR5.js +2497 -0
  45. package/dist/chunks/{chunk-LFMSDBZN.js → chunk-XNIK66I4.js} +326 -161
  46. package/dist/chunks/{chunk-3SO6QL6U.js → chunk-YWX377BY.js} +5 -2
  47. package/dist/chunks/{chunk-BYATLLEF.js → chunk-Z3GDFVJR.js} +1 -1
  48. package/dist/chunks/{chunk-I566ZYNF.js → chunk-Z7VYWPZV.js} +1 -1
  49. package/dist/chunks/{conflict-VR55AOOO.js → conflict-ARLSZJ6V.js} +4 -3
  50. package/dist/chunks/{continuation-2CKSBLA6.js → continuation-3S37AUSH.js} +4 -3
  51. package/dist/chunks/{continuation-RN6PZN2M.js → continuation-3XLYYTKV.js} +4 -3
  52. package/dist/chunks/{continuation-HZIZRZBX.js → continuation-HFW2YT5S.js} +4 -3
  53. package/dist/chunks/{continuation-NLECEJPX.js → continuation-KI7DRRZN.js} +4 -3
  54. package/dist/chunks/{contract-HI4FNPYE.js → contract-DNIIW5VJ.js} +13 -5
  55. package/dist/chunks/{cowork-HJLI353D.js → cowork-GMLRGVIW.js} +31 -14
  56. package/dist/chunks/create-flow-J22BO65E.js +56 -0
  57. package/dist/chunks/{ebuilder-form-HTGI63UU.js → ebuilder-form-ANV2FHYV.js} +12 -7
  58. package/dist/chunks/{ehr-GYXIYH3A.js → ehr-GSTGAIY3.js} +695 -1255
  59. package/dist/chunks/{employee-SAK2QYXX.js → employee-22BGJ3QS.js} +3 -3
  60. package/dist/chunks/{env-DW3G4HUO.js → env-BX3VRFS7.js} +4 -3
  61. package/dist/chunks/{esb-I5INCEFE.js → esb-ATAIASX2.js} +12 -7
  62. package/dist/chunks/{factory-TKXGXS6L.js → factory-PETTFME6.js} +3 -2
  63. package/dist/chunks/{fna-K2MHTQ24.js → fna-YEKBSFSX.js} +14 -8
  64. package/dist/chunks/{group-chat-VYBNMJLG.js → group-chat-BFVXAYFX.js} +7 -4
  65. package/dist/chunks/{host-D5SERMAJ.js → host-HRBXEPDQ.js} +5 -5
  66. package/dist/chunks/{host-JM4YVHFM.js → host-LR55CTHP.js} +5 -5
  67. package/dist/chunks/{host-L3VLITMT.js → host-SUOY6VYQ.js} +5 -5
  68. package/dist/chunks/{host-ZUQTJYYK.js → host-SZGV4UNT.js} +5 -5
  69. package/dist/chunks/{host-256GVCAH.js → host-WIKN2EJ5.js} +5 -5
  70. package/dist/chunks/{hrm-VLRBKTZB.js → hrm-NRDO4W5G.js} +11 -7
  71. package/dist/chunks/{im-QK3VTLXK.js → im-IQ2HN23S.js} +11 -10
  72. package/dist/chunks/{invoice-T5JTA32H.js → invoice-MNRW76PP.js} +636 -1768
  73. package/dist/chunks/{jiuchuanhui-P2FNEQVZ.js → jiuchuanhui-DTRBAX4N.js} +14 -6
  74. package/dist/chunks/{lazy-dispatch-XRRI46M6.js → lazy-dispatch-ZVWAI25B.js} +7 -6
  75. package/dist/chunks/{mail-3Y7MJ6PS.js → mail-ZVAUXOJA.js} +16 -14
  76. package/dist/chunks/{meeting-M7LTXGJE.js → meeting-FEVPZ67S.js} +21 -13
  77. package/dist/chunks/{okr-OBC6S67L.js → okr-SDH3E5RA.js} +12 -5
  78. package/dist/chunks/{operations-5QL3AECO.js → operations-62N6EP3C.js} +4 -3
  79. package/dist/chunks/{plan-5H6I53SK.js → plan-E35JFDI7.js} +12 -5
  80. package/dist/chunks/{project-L75QZV4S.js → project-73QXBAB2.js} +49 -25
  81. package/dist/chunks/reception-UWZVACBN.js +1899 -0
  82. package/dist/chunks/recruit-stage-4MAOCKFY.js +4770 -0
  83. package/dist/chunks/registry-IM5G23LS.js +24 -0
  84. package/dist/chunks/{registry-UGRBCBHO.js → registry-JDUS4E7D.js} +7 -6
  85. package/dist/chunks/{registry-RXPN6BBT.js → registry-KNKSCJNT.js} +7 -6
  86. package/dist/chunks/{registry-NYPYMZXG.js → registry-PO7SI256.js} +4 -4
  87. package/dist/chunks/{registry-QGHFNUWS.js → registry-PVUZQDDQ.js} +3 -3
  88. package/dist/chunks/{room-recommend-A3UDC3CA.js → room-recommend-H7KLXA5R.js} +6 -5
  89. package/dist/chunks/{schedule-5GCACCK7.js → schedule-ESZIBAUO.js} +6 -5
  90. package/dist/chunks/{workflow-M5ZJ7DWF.js → workflow-CWJFJLQU.js} +15 -10
  91. package/dist/cmd/action.js +6 -0
  92. package/dist/cmd/identity/index.js +45 -0
  93. package/dist/cmd/index.js +2 -0
  94. package/dist/core/continuation-ttl.js +18 -0
  95. package/dist/core/error-codes.js +85 -0
  96. package/dist/core/logger.js +11 -0
  97. package/dist/index.js +41 -30
  98. package/dist/internal/e10/auth/commands.js +164 -8
  99. package/dist/internal/e10/auth/error-log.js +182 -0
  100. package/dist/internal/e10/auth/messages.js +6 -0
  101. package/dist/internal/e10/auth/session.js +34 -3
  102. package/dist/internal/e10/auth/xiaoe.js +286 -44
  103. package/dist/internal/e10/auth-recovery.js +72 -14
  104. package/dist/internal/e10/context.js +72 -13
  105. package/dist/internal/e10/index.js +1 -1
  106. package/dist/internal/e10/network-error.js +93 -0
  107. package/dist/internal/e10/request-runtime.js +6 -0
  108. package/dist/internal/skills/install.js +9 -1
  109. package/dist/shortcuts/archive/continuation.js +2 -1
  110. package/dist/shortcuts/archive/index.js +3 -0
  111. package/dist/shortcuts/archive/operations/confirm.js +2 -1
  112. package/dist/shortcuts/archive-oa/continuation.js +2 -1
  113. package/dist/shortcuts/archive-oa/index.js +2 -0
  114. package/dist/shortcuts/archive-oa/operations/confirm.js +2 -1
  115. package/dist/shortcuts/asset/continuation.js +2 -1
  116. package/dist/shortcuts/asset/index.js +2 -0
  117. package/dist/shortcuts/asset-idle/index.js +2 -0
  118. package/dist/shortcuts/blog/continuation.js +2 -1
  119. package/dist/shortcuts/blog/index.js +2 -0
  120. package/dist/shortcuts/caizhilian/continuation.js +2 -1
  121. package/dist/shortcuts/caizhilian/index.js +2 -0
  122. package/dist/shortcuts/caizhilian/operations/confirm.js +3 -2
  123. package/dist/shortcuts/calendar/continuation.js +2 -1
  124. package/dist/shortcuts/calendar/index.js +2 -0
  125. package/dist/shortcuts/calendar/operations/read.js +31 -22
  126. package/dist/shortcuts/calendar/operations/write.js +46 -2
  127. package/dist/shortcuts/contract/continuation.js +2 -1
  128. package/dist/shortcuts/contract/index.js +2 -0
  129. package/dist/shortcuts/contract/operations/write.js +2 -1
  130. package/dist/shortcuts/cowork/continuation.js +2 -1
  131. package/dist/shortcuts/cowork/index.js +2 -0
  132. package/dist/shortcuts/cowork/operations/discuss-write.js +5 -1
  133. package/dist/shortcuts/cowork/operations/item-write.js +1 -7
  134. package/dist/shortcuts/cowork/operations/member-write.js +3 -1
  135. package/dist/shortcuts/cowork/operations/permission-write.js +5 -1
  136. package/dist/shortcuts/cowork/operations/shared.js +7 -0
  137. package/dist/shortcuts/ebuilder-form/continuation.js +2 -1
  138. package/dist/shortcuts/ebuilder-form/index.js +2 -0
  139. package/dist/shortcuts/ebuilder-form/operations/write.js +3 -2
  140. package/dist/shortcuts/ehr/continuation.js +2 -1
  141. package/dist/shortcuts/ehr/index.js +2 -0
  142. package/dist/shortcuts/ehr/operations/attend-write.js +44 -2
  143. package/dist/shortcuts/ehr/operations/hr-contact.js +7 -4
  144. package/dist/shortcuts/ehr/operations/hr-report.js +13 -7
  145. package/dist/shortcuts/ehr/operations/recruit-candidate-import.js +317 -63
  146. package/dist/shortcuts/ehr/operations/recruit-position.js +134 -2
  147. package/dist/shortcuts/ehr/operations/recruit-write.js +263 -18
  148. package/dist/shortcuts/ehr/operations/recruit.js +10 -4
  149. package/dist/shortcuts/ehr/operations/shared.js +47 -0
  150. package/dist/shortcuts/esb/continuation.js +2 -1
  151. package/dist/shortcuts/esb/index.js +2 -0
  152. package/dist/shortcuts/esb/operations/trigger.js +2 -1
  153. package/dist/shortcuts/fna/continuation.js +2 -1
  154. package/dist/shortcuts/fna/index.js +2 -0
  155. package/dist/shortcuts/fna/operations/invoice-writeoff.js +1 -1
  156. package/dist/shortcuts/fna/operations/loan.js +1 -1
  157. package/dist/shortcuts/hrm/index.js +2 -0
  158. package/dist/shortcuts/hrm/operations/org.js +118 -0
  159. package/dist/shortcuts/im/continuation.js +2 -1
  160. package/dist/shortcuts/index.js +10 -0
  161. package/dist/shortcuts/invoice/continuation.js +2 -1
  162. package/dist/shortcuts/invoice/index.js +14 -15
  163. package/dist/shortcuts/invoice/invoice-record.js +93 -0
  164. package/dist/shortcuts/invoice/manifest.js +190 -393
  165. package/dist/shortcuts/invoice/operations/add.js +2 -1
  166. package/dist/shortcuts/invoice/operations/delete.js +2 -1
  167. package/dist/shortcuts/invoice/operations/import.js +2 -1
  168. package/dist/shortcuts/invoice/operations/issuing-contract-detail.js +86 -0
  169. package/dist/shortcuts/invoice/operations/issuing-contracts.js +210 -0
  170. package/dist/shortcuts/invoice/operations/registry.js +17 -17
  171. package/dist/shortcuts/invoice/operations/reim-auto.js +4 -569
  172. package/dist/shortcuts/invoice/operations/reim.js +52 -341
  173. package/dist/shortcuts/invoice/operations/shared.js +21 -4
  174. package/dist/shortcuts/invoice/operations/update.js +2 -1
  175. package/dist/shortcuts/invoice/projection.js +10 -62
  176. package/dist/shortcuts/jiuchuanhui/continuation.js +2 -1
  177. package/dist/shortcuts/jiuchuanhui/index.js +2 -0
  178. package/dist/shortcuts/jiuchuanhui/operations/datajson.js +2 -1
  179. package/dist/shortcuts/jiuchuanhui/operations/esb.js +2 -1
  180. package/dist/shortcuts/mail/continuation.js +2 -1
  181. package/dist/shortcuts/mail/index.js +2 -0
  182. package/dist/shortcuts/mail/operations/mail-blacklist.js +1 -1
  183. package/dist/shortcuts/mail/operations/mail-contacts.js +1 -1
  184. package/dist/shortcuts/mail/operations/mail-send.js +1 -1
  185. package/dist/shortcuts/mail/operations/mail-sign.js +1 -1
  186. package/dist/shortcuts/mail/operations/mail-template.js +1 -1
  187. package/dist/shortcuts/meeting/continuation.js +2 -1
  188. package/dist/shortcuts/meeting/index.js +2 -0
  189. package/dist/shortcuts/meeting/operations/change.js +1 -1
  190. package/dist/shortcuts/meeting/operations/create.js +1 -1
  191. package/dist/shortcuts/meeting/operations/eb/catalog.js +4 -1
  192. package/dist/shortcuts/meeting/operations/eb/create-flow.js +101 -35
  193. package/dist/shortcuts/meeting/operations/eb/decision.js +1 -1
  194. package/dist/shortcuts/meeting/operations/eb/factory.js +34 -1
  195. package/dist/shortcuts/meeting/operations/eb/group-chat.js +25 -3
  196. package/dist/shortcuts/meeting/operations/eb/person-cache.js +96 -0
  197. package/dist/shortcuts/meeting/operations/eb/room-recommend.js +33 -11
  198. package/dist/shortcuts/meeting/operations/lifecycle.js +1 -1
  199. package/dist/shortcuts/meeting/operations/receipts.js +1 -1
  200. package/dist/shortcuts/meeting/operations/signs.js +1 -1
  201. package/dist/shortcuts/okr/continuation.js +2 -1
  202. package/dist/shortcuts/okr/index.js +2 -0
  203. package/dist/shortcuts/okr/operations/write.js +1 -1
  204. package/dist/shortcuts/plan/continuation.js +2 -1
  205. package/dist/shortcuts/plan/index.js +2 -0
  206. package/dist/shortcuts/plan/operations/write.js +1 -1
  207. package/dist/shortcuts/project/continuation.js +2 -1
  208. package/dist/shortcuts/project/index.js +2 -0
  209. package/dist/shortcuts/project/operations/read.js +6 -25
  210. package/dist/shortcuts/project/operations/shared.js +22 -0
  211. package/dist/shortcuts/project/operations/write.js +28 -2
  212. package/dist/shortcuts/reception/constants.js +53 -0
  213. package/dist/shortcuts/reception/errors.js +54 -0
  214. package/dist/shortcuts/reception/host.js +125 -0
  215. package/dist/shortcuts/reception/index.js +198 -0
  216. package/dist/shortcuts/reception/manifest.js +177 -0
  217. package/dist/shortcuts/reception/operations/ask.js +71 -0
  218. package/dist/shortcuts/reception/operations/browsertool.js +58 -0
  219. package/dist/shortcuts/reception/operations/compose.js +129 -0
  220. package/dist/shortcuts/reception/operations/customparams.js +74 -0
  221. package/dist/shortcuts/reception/operations/doc.js +238 -0
  222. package/dist/shortcuts/reception/operations/docrender.js +36 -0
  223. package/dist/shortcuts/reception/operations/panels.js +179 -0
  224. package/dist/shortcuts/reception/operations/registry.js +26 -0
  225. package/dist/shortcuts/reception/operations/render-assets.js +184 -0
  226. package/dist/shortcuts/reception/operations/render.js +123 -0
  227. package/dist/shortcuts/reception/operations/runs.js +38 -0
  228. package/dist/shortcuts/reception/operations/schedule.js +127 -0
  229. package/dist/shortcuts/reception/operations/shared.js +196 -0
  230. package/dist/shortcuts/reception/operations/snapshot.js +68 -0
  231. package/dist/shortcuts/reception/operations/types.js +1 -0
  232. package/dist/shortcuts/reception/operations.js +33 -0
  233. package/dist/shortcuts/reception/upload.js +218 -0
  234. package/dist/shortcuts/recruit-stage/context.js +231 -0
  235. package/dist/shortcuts/recruit-stage/continuation.js +74 -0
  236. package/dist/shortcuts/recruit-stage/errors.js +65 -0
  237. package/dist/shortcuts/recruit-stage/host.js +109 -0
  238. package/dist/shortcuts/recruit-stage/index.js +115 -0
  239. package/dist/shortcuts/recruit-stage/manifest.js +29 -0
  240. package/dist/shortcuts/recruit-stage/operations/interview-arrange.js +722 -0
  241. package/dist/shortcuts/recruit-stage/operations/interview-feedback.js +269 -0
  242. package/dist/shortcuts/recruit-stage/operations/jd-create.js +719 -0
  243. package/dist/shortcuts/recruit-stage/operations/list.js +431 -0
  244. package/dist/shortcuts/recruit-stage/operations/registry.js +38 -0
  245. package/dist/shortcuts/recruit-stage/operations/resume-import.js +1354 -0
  246. package/dist/shortcuts/recruit-stage/operations/search.js +158 -0
  247. package/dist/shortcuts/recruit-stage/operations/types.js +25 -0
  248. package/dist/shortcuts/recruit-stage/school-tiers.json +318 -0
  249. package/dist/shortcuts/recruit-stage/shared.js +608 -0
  250. package/dist/shortcuts/workflow/continuation.js +2 -1
  251. package/dist/shortcuts/workflow/index.js +2 -0
  252. package/dist/shortcuts/workflow/operations/form.js +32 -8
  253. package/dist/shortcuts/workflow/operations/todoSmartConvert/detailFieldRules.js +4 -2
  254. package/dist/shortcuts/workflow/operations/todoSmartConvert/summaryCache.js +13 -6
  255. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailCache.js +17 -24
  256. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailFetcher.js +14 -9
  257. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.collect.js +50 -8
  258. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.core.js +2 -1
  259. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.detail.js +17 -11
  260. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.group.js +7 -39
  261. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.groupSummary.js +3 -2
  262. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.js +51 -15
  263. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.pipeline.js +16 -1
  264. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.smartGroup.js +151 -63
  265. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.subGroup.js +56 -0
  266. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.summary.js +39 -14
  267. package/dist/shortcuts/workflow/operations/write.js +1 -1
  268. package/docs/_catalog.md +3 -0
  269. package/docs/agent-invoice.md +1 -1
  270. package/docs/archive-oa.md +1 -1
  271. package/docs/caizhilian.md +1 -1
  272. package/docs/calendar.md +1 -1
  273. package/docs/contract.md +1 -1
  274. package/docs/e10-auth.md +23 -1
  275. package/docs/ehr.md +2 -2
  276. package/docs/esb.md +1 -1
  277. package/docs/im.md +1 -1
  278. package/docs/invoice.md +8 -12
  279. package/docs/okr.md +1 -1
  280. package/docs/operation-manual.md +8 -0
  281. package/docs/reception.md +119 -0
  282. package/package.json +1 -1
  283. package/scripts/clean.mjs +43 -2
  284. package/scripts/install-skill-to-xiaoe.mjs +105 -0
  285. package/scripts/package-skill.mjs +4 -2
  286. package/skill-template/business-info.json +42 -2
  287. package/skill-template/domains/caizhilian.md +1 -1
  288. package/skill-template/domains/reception-flow.md +18 -0
  289. package/skill-template/domains/recruit-stage.md +29 -0
  290. package/skill-template/domains/yepiaotong.md +4 -7
  291. package/skills/weaver-e10-archive-oa/references/source-manifest.json +14 -14
  292. package/skills/weaver-e10-blog/references/blog-publish.md +1 -1
  293. package/skills/weaver-e10-blog/references/source-manifest.json +7 -7
  294. package/skills/weaver-e10-caizhilian/references/source-manifest.json +21 -21
  295. package/skills/weaver-e10-caizhilian/references/write-protocol.md +2 -2
  296. package/skills/weaver-e10-calendar/SKILL.md +2 -1
  297. package/skills/weaver-e10-calendar/references/calendar-write.md +55 -1
  298. package/skills/weaver-e10-cowork/SKILL.md +1 -1
  299. package/skills/weaver-e10-cowork/references/cowork-write.md +3 -1
  300. package/skills/weaver-e10-ebuilder-form/SKILL.md +1 -1
  301. package/skills/weaver-e10-ebuilder-form/references/custom-api.md +1 -1
  302. package/skills/weaver-e10-ebuilder-form/references/openapi-write.md +1 -1
  303. package/skills/weaver-e10-esb/SKILL.md +2 -2
  304. package/skills/weaver-e10-esb/references/source-manifest.json +22 -22
  305. package/skills/weaver-e10-esb/references/trigger.md +2 -2
  306. package/skills/weaver-e10-jinchengda/references/contract-clause-library-crud.md +1 -1
  307. package/skills/weaver-e10-jinchengda/references/contract-clause-reference-save.md +1 -1
  308. package/skills/weaver-e10-jinchengda/references/contract-request-write.md +1 -1
  309. package/skills/weaver-e10-jinchengda/references/source-manifest.json +29 -29
  310. package/skills/weaver-e10-jucailin/SKILL.md +1 -1
  311. package/skills/weaver-e10-jucailin/references/attend-write.md +10 -2
  312. package/skills/weaver-e10-jucailin/references/hr-contact.md +8 -0
  313. package/skills/weaver-e10-jucailin/references/hr-report.md +8 -0
  314. package/skills/weaver-e10-jucailin/references/recruit-create.md +14 -5
  315. package/skills/weaver-e10-jucailin/references/recruit-read.md +1 -1
  316. package/skills/weaver-e10-jucailin/references/recruit-write.md +5 -4
  317. package/skills/weaver-e10-mail/SKILL.md +1 -1
  318. package/skills/weaver-e10-meeting/SKILL.md +39 -7
  319. package/skills/weaver-e10-meeting/references/meeting-change.md +1 -1
  320. package/skills/weaver-e10-meeting/references/meeting-create.md +1 -1
  321. package/skills/weaver-e10-meeting/references/meeting-lifecycle.md +1 -1
  322. package/skills/weaver-e10-meeting/references/meeting-verification.md +1 -1
  323. package/skills/weaver-e10-okr/references/okr-align.md +1 -1
  324. package/skills/weaver-e10-okr/references/okr-keyresult.md +1 -1
  325. package/skills/weaver-e10-okr/references/okr-write.md +1 -1
  326. package/skills/weaver-e10-okr/references/source-manifest.json +8 -8
  327. package/skills/weaver-e10-plan/references/plan-report-write.md +1 -1
  328. package/skills/weaver-e10-plan/references/source-manifest.json +20 -20
  329. package/skills/weaver-e10-qiyecheng/references/loan-management.md +1 -1
  330. package/skills/weaver-e10-qiyecheng/references/source-manifest.json +18 -18
  331. package/skills/weaver-e10-reception-flow/SKILL.md +173 -0
  332. package/skills/weaver-e10-reception-flow/assets//350/241/214/347/250/213/345/215/225/346/250/241/346/235/277-/346/263/233/345/276/256.docx +0 -0
  333. package/skills/weaver-e10-reception-flow/data/fields-snapshot.json +213 -0
  334. package/skills/weaver-e10-reception-flow/references/browsertool.md +68 -0
  335. package/skills/weaver-e10-reception-flow/references/env-pitfalls.md +51 -0
  336. package/skills/weaver-e10-reception-flow/references/fields-snapshot.md +227 -0
  337. package/skills/weaver-e10-reception-flow/references/guide.md +179 -0
  338. package/skills/weaver-e10-reception-flow/scripts/locate.sh +14 -0
  339. package/skills/weaver-e10-reception-flow/scripts/render.py +724 -0
  340. package/skills/weaver-e10-recruit-stage/SKILL.md +230 -0
  341. package/skills/weaver-e10-recruit-stage/agents/openai.yaml +119 -0
  342. package/skills/weaver-e10-recruit-stage/lib/recruit-xiaoe-file.mjs +188 -0
  343. package/skills/weaver-e10-recruit-stage/lib/xiaoe-session.mjs +66 -0
  344. package/skills/weaver-e10-recruit-stage/references/position-templates.md +202 -0
  345. package/skills/weaver-e10-recruit-stage/references/recruit-arrange-interview.md +322 -0
  346. package/skills/weaver-e10-recruit-stage/references/recruit-capability-check.md +127 -0
  347. package/skills/weaver-e10-recruit-stage/references/recruit-check-install.md +65 -0
  348. package/skills/weaver-e10-recruit-stage/references/recruit-detail-process.md +63 -0
  349. package/skills/weaver-e10-recruit-stage/references/recruit-edit-interview-feedback.md +142 -0
  350. package/skills/weaver-e10-recruit-stage/references/recruit-jd-create.md +95 -0
  351. package/skills/weaver-e10-recruit-stage/references/recruit-jd-template.md +56 -0
  352. package/skills/weaver-e10-recruit-stage/references/recruit-list-candidate.md +101 -0
  353. package/skills/weaver-e10-recruit-stage/references/recruit-list-interview.md +148 -0
  354. package/skills/weaver-e10-recruit-stage/references/recruit-match-candidates.md +77 -0
  355. package/skills/weaver-e10-recruit-stage/references/recruit-output-links.md +59 -0
  356. package/skills/weaver-e10-recruit-stage/references/recruit-resolve-creator.md +69 -0
  357. package/skills/weaver-e10-recruit-stage/references/recruit-resolve-metadata.md +241 -0
  358. package/skills/weaver-e10-recruit-stage/references/recruit-resume-import.md +451 -0
  359. package/skills/weaver-e10-recruit-stage/references/recruit-resume-parse.md +128 -0
  360. package/skills/weaver-e10-recruit-stage/references/recruit-search-candidate.md +146 -0
  361. package/skills/weaver-e10-recruit-stage/references/recruit-urge-feedback.md +69 -0
  362. package/skills/weaver-e10-shared/SKILL.md +1 -1
  363. package/skills/weaver-e10-shared/references/e10-auth-and-session.md +10 -2
  364. package/skills/weaver-e10-shijingran/SKILL.md +7 -6
  365. package/skills/weaver-e10-shijingran/references/operations.md +3 -1
  366. package/skills/weaver-e10-shijingran/references/source-manifest.json +30 -28
  367. package/skills/weaver-e10-shijingran/references/write-operations.md +2 -0
  368. package/skills/weaver-e10-skill-maker/references/module-cli-generation.md +2 -0
  369. package/skills/weaver-e10-wenshuding/references/source-manifest.json +3 -3
  370. package/skills/weaver-e10-workflow/SKILL.md +4 -2
  371. package/skills/weaver-e10-workflow/aigroup/default.json +11 -9
  372. package/skills/weaver-e10-workflow/references/source-manifest.json +32 -32
  373. package/skills/weaver-e10-workflow/references/todo-smart-convert.md +23 -13
  374. package/skills/weaver-e10-workflow/tools/todo-summary.cjs +62 -20
  375. package/skills/weaver-e10-yepiaotong/SKILL.md +28 -36
  376. package/skills/weaver-e10-yepiaotong/references/invoice-agent-entry.md +6 -3
  377. package/skills/weaver-e10-yepiaotong/references/invoice-detail.md +13 -10
  378. package/skills/weaver-e10-yepiaotong/references/invoice-enterprise-list.md +2 -0
  379. package/skills/weaver-e10-yepiaotong/references/invoice-issuing-workflow.md +194 -155
  380. package/skills/weaver-e10-yepiaotong/references/invoice-output-view.md +28 -32
  381. package/skills/weaver-e10-yepiaotong/references/invoice-personal-list.md +5 -1
  382. package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +8 -10
  383. package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +211 -616
  384. package/skills/weaver-e10-yepiaotong/references/reim-examples.md +149 -117
  385. package/skills/weaver-e10-yepiaotong/references/reim-expense-subject-rules.md +17 -20
  386. package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +20 -39
  387. package/skills/weaver-e10-yepiaotong/references/reim-matching-rules.md +55 -22
  388. package/skills/weaver-e10-yepiaotong/references/reim-phone-subsidy-rules.md +7 -17
  389. package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +88 -92
  390. package/skills/weaver-e10-yepiaotong/references/source-manifest.json +144 -354
  391. package/skills/weaver-e10-yimiaoban/SKILL.md +1 -1
  392. package/skills/weaver-e10-yimiaoban/references/msg-write.md +1 -1
  393. package/skills/weaver-e10-yimiaoban/references/safety-boundaries.md +1 -1
  394. package/skills/weaver-e10-yimiaoban/references/source-manifest.json +7 -7
  395. package/dist/chunks/chunk-SPRHHSVC.js +0 -465
  396. package/dist/chunks/registry-KMHCPAAD.js +0 -22
  397. package/dist/shortcuts/invoice/markdown.js +0 -172
  398. package/dist/shortcuts/invoice/operations/issuing-qys.js +0 -424
  399. package/skills/weaver-e10-meeting.zip +0 -0
  400. package/skills/weaver-e10-yepiaotong/references/invoice-issuing-examples.md +0 -131
  401. package/skills/weaver-e10-yepiaotong/references/invoice-issuing-form-fill-rules.md +0 -179
@@ -0,0 +1,184 @@
1
+ import { spawnSync, execFile } from 'node:child_process';
2
+ import { existsSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import { PYTHON_CACHE_TTL_MS } from '../constants.js';
5
+ import { receptionBusinessError, receptionEnvironmentError } from '../errors.js';
6
+ import { ensureDir, mtimeMs, readJson, writeJson } from './shared.js';
7
+ import { skillRootFromSnapshot } from './snapshot.js';
8
+ /**
9
+ * docx / md 渲染外壳。
10
+ *
11
+ * 边界:这里只负责「找到 python、找到 render.py、解析它吐的 JSON」,
12
+ * 产物口径全在技能包的 `scripts/render.py` 里(模板也在技能包 `assets/` 下,由 py 自己定位)。
13
+ * CLI 不打包 render.py,也不打包模板——字段与版式调整不该触发 CLI 发版。
14
+ */
15
+ const PYTHON_CACHE_FILE = 'python.json';
16
+ let pythonCache;
17
+ function runSync(file, args, options = {}) {
18
+ const result = spawnSync(file, args, { encoding: 'utf8', maxBuffer: 16 * 1024 * 1024, ...options });
19
+ return {
20
+ stdout: String(result.stdout || ''),
21
+ stderr: String(result.stderr || ''),
22
+ status: result.status,
23
+ };
24
+ }
25
+ function runAsync(file, args) {
26
+ return new Promise((resolve) => {
27
+ execFile(file, args, { encoding: 'utf8', maxBuffer: 16 * 1024 * 1024 }, (error, stdout, stderr) => {
28
+ resolve({
29
+ stdout: String(stdout || ''),
30
+ stderr: String(stderr || ''),
31
+ status: error ? (typeof error.code === 'number' ? error.code : 1) : 0,
32
+ });
33
+ });
34
+ });
35
+ }
36
+ /** 从混杂输出里取最后一个合法 JSON(render.py 可能先打印日志)。 */
37
+ function lastJsonLine(text) {
38
+ const lines = String(text || '').split(/\r?\n/).filter((line) => line.trim().startsWith('{'));
39
+ for (let index = lines.length - 1; index >= 0; index -= 1) {
40
+ try {
41
+ return JSON.parse(lines[index]);
42
+ }
43
+ catch {
44
+ // 继续往上找
45
+ }
46
+ }
47
+ return null;
48
+ }
49
+ /**
50
+ * 依次探测 RECEPTION_PY / python3 / python,要求能 `import docx`。
51
+ * 探测结果落盘 7 天省掉每次 0.3~1s;磁盘缓存也要能真跑起来才认(避免升级后命中死路径)。
52
+ */
53
+ export function pickPython(stateDir) {
54
+ if (pythonCache !== undefined)
55
+ return pythonCache;
56
+ if (process.env.RECEPTION_PY) {
57
+ pythonCache = process.env.RECEPTION_PY;
58
+ return pythonCache;
59
+ }
60
+ const cachePath = join(stateDir, PYTHON_CACHE_FILE);
61
+ const disk = readJson(cachePath);
62
+ if (disk?.py && Date.now() - Number(disk.at || 0) < PYTHON_CACHE_TTL_MS) {
63
+ if (runSync(disk.py, ['-c', 'import docx'], { stdio: 'ignore' }).status === 0) {
64
+ pythonCache = disk.py;
65
+ return pythonCache;
66
+ }
67
+ }
68
+ for (const candidate of ['python3', 'python', 'py']) {
69
+ const args = candidate === 'py' ? ['-3', '-c', 'import docx'] : ['-c', 'import docx'];
70
+ if (runSync(candidate, args, { stdio: 'ignore' }).status === 0) {
71
+ pythonCache = candidate;
72
+ try {
73
+ writeJson(cachePath, { py: candidate, at: Date.now() });
74
+ }
75
+ catch {
76
+ // 缓存写不进不阻断
77
+ }
78
+ return candidate;
79
+ }
80
+ }
81
+ pythonCache = null;
82
+ return null;
83
+ }
84
+ /** 测试用:清掉进程内缓存。 */
85
+ export function resetPythonCache() {
86
+ pythonCache = undefined;
87
+ }
88
+ /**
89
+ * 定位 render.py。优先级:显式参数 → 环境变量 → 技能包内固定相对位置。
90
+ *
91
+ * 技能包布局固定为 `<skill>/scripts/render.py` + `<skill>/data/fields-snapshot.json`,
92
+ * 因此拿到快照路径就能反推脚本位置,调用方不必传两个参数。
93
+ */
94
+ export function resolveRenderPy(explicitPath = '', snapshotPath = '') {
95
+ const candidates = [
96
+ explicitPath,
97
+ process.env.RECEPTION_RENDER_PY || '',
98
+ snapshotPath ? join(skillRootFromSnapshot(snapshotPath), 'scripts', 'render.py') : '',
99
+ join(process.cwd(), 'scripts', 'render.py'),
100
+ ].filter(Boolean);
101
+ for (const path of candidates) {
102
+ if (existsSync(path))
103
+ return path;
104
+ }
105
+ throw receptionEnvironmentError('RENDER_PY_MISSING', '找不到 render.py:请传 --render-py,或确保技能包 scripts/render.py 存在', { candidates });
106
+ }
107
+ function parseRenderOutput(result, outDir) {
108
+ const parsed = lastJsonLine(result.stdout);
109
+ if (!parsed) {
110
+ throw receptionBusinessError('RENDER_NO_JSON', '渲染失败:render.py 未返回 JSON', {
111
+ hint: `检查 ${outDir} 是否可写、render.py 是否完整`,
112
+ detail: String(result.stderr || '').split(/\r?\n/).filter(Boolean).slice(-12).join('\n').slice(-1200),
113
+ });
114
+ }
115
+ if (!parsed.ok) {
116
+ throw receptionBusinessError('RENDER_FAILED', `渲染失败: ${parsed.error || '未知错误'}`, {
117
+ hint: '多为字段类型不匹配(日期需 yyyy-MM-dd、金额为数字);按 detail 修数据后重跑',
118
+ detail: String(result.stderr || '').split(/\r?\n/).filter(Boolean).slice(-12).join('\n').slice(-1200),
119
+ });
120
+ }
121
+ return parsed;
122
+ }
123
+ /** 单份渲染(异步):供 docx 与 md 并行调用。 */
124
+ export async function renderOnly(options) {
125
+ ensureDir(options.outDir);
126
+ const args = [options.renderPy, '--data', options.dataPath, '--out-dir', options.outDir, '--only', options.only];
127
+ const raw = await runAsync(options.python, args);
128
+ return parseRenderOutput(raw, options.outDir);
129
+ }
130
+ function mergeTwo(docx, md) {
131
+ const files = [...(docx.files || []), ...(md.files || [])];
132
+ const qa = { ...(docx.qa || {}), ...(md.qa || {}) };
133
+ if (docx.qa && docx.qa.external)
134
+ qa.external = docx.qa.external;
135
+ const warnings = [
136
+ ...((docx.qa && docx.qa.warnings) || []),
137
+ ...((md.qa && md.qa.warnings) || []),
138
+ ];
139
+ if (warnings.length)
140
+ qa.warnings = warnings;
141
+ const verify = { ...(docx.verify || {}), ...(md.verify || {}) };
142
+ verify.fileCount = files.length;
143
+ return {
144
+ ok: true,
145
+ files,
146
+ qa,
147
+ verify,
148
+ agendaRows: docx.agendaRows || md.agendaRows || [],
149
+ scheduleRows: docx.scheduleRows || md.scheduleRows || [],
150
+ };
151
+ }
152
+ /** 并行渲染两份并合并。两份都落盘后再上传,因为要挂到同一个附件字段。 */
153
+ export async function renderBoth(options) {
154
+ ensureDir(options.outDir);
155
+ const startedAt = Date.now();
156
+ let docxMs = 0;
157
+ let mdMs = 0;
158
+ const docxPromise = renderOnly({ ...options, only: 'docx' }).then((result) => {
159
+ docxMs = Date.now() - startedAt;
160
+ return result;
161
+ });
162
+ const mdPromise = renderOnly({ ...options, only: 'md' }).then((result) => {
163
+ mdMs = Date.now() - startedAt;
164
+ return result;
165
+ });
166
+ const [docxResult, mdResult] = await Promise.all([docxPromise, mdPromise]);
167
+ return {
168
+ result: mergeTwo(docxResult, mdResult),
169
+ docxResult,
170
+ mdResult,
171
+ docxMs,
172
+ mdMs,
173
+ parallelMs: Date.now() - startedAt,
174
+ };
175
+ }
176
+ /** 供 doc 用:缺 python 时给出可执行的提示而不是堆栈。 */
177
+ export function requirePython(stateDir) {
178
+ const python = pickPython(stateDir);
179
+ if (!python) {
180
+ throw receptionEnvironmentError('NO_PYTHON_DOCX', '缺 python3 + python-docx,无法渲染 docx', { hint: 'pip install python-docx;离线环境只能交付 md' });
181
+ }
182
+ return python;
183
+ }
184
+ export { mtimeMs };
@@ -0,0 +1,123 @@
1
+ import { mkdirSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { receptionEnvironmentError } from '../errors.js';
4
+ import { renderBrowsertool, resolveRenderType } from './browsertool.js';
5
+ import { composeInitialValues } from './compose.js';
6
+ import { mergeAnswers } from './panels.js';
7
+ import { loadRun, runsDir } from './runs.js';
8
+ import { nameList } from './shared.js';
9
+ import { resolveSnapshot } from './snapshot.js';
10
+ export async function render(input, ctx) {
11
+ const startedAt = Date.now();
12
+ const run = loadRun(ctx.stateDir, String(input.runId || '').trim());
13
+ // 快照优先级:显式参数 → doc 记在 run 里的路径。重建的 run 没有记录,仍需显式传。
14
+ const snapshotPath = String(input.snapshot || '').trim() || run.snapshotPath || '';
15
+ const resolved = resolveSnapshot(snapshotPath);
16
+ if (!resolved.snapshot) {
17
+ throw receptionEnvironmentError('SNAPSHOT_MISSING', '未找到字段快照 data/fields-snapshot.json', {
18
+ hint: '传 --snapshot "<技能目录>/data/fields-snapshot.json";doc 传过的话通常已记在 run 里,不必重复传',
19
+ snapshotPath,
20
+ });
21
+ }
22
+ const answers = input.answers ?? run.answers ?? {};
23
+ const data = mergeAnswers(run, answers);
24
+ // 附件:显式 --attachment-fileid(可逗号分隔多个)优先,否则用 doc 落盘的附件数组
25
+ const argAttachment = String(input.attachmentFileid || '').trim();
26
+ const runAttachments = Array.isArray(run.attachmentFileids) ? run.attachmentFileids : [];
27
+ // 「参与人员」兜底:一个人名都没有时,才用当前登录人填。
28
+ // 读会话要解 keyring(~300ms),有人名的正常流程不该为它付代价。
29
+ const hasCompanions = Array.isArray(data.companions) && data.companions.length > 0;
30
+ const hasEscorts = nameList(data.escorts).length > 0;
31
+ if (!data.empId && !hasCompanions && !hasEscorts) {
32
+ const session = await ctx.host.getSession();
33
+ data.empId = session.userId || '';
34
+ }
35
+ const composed = composeInitialValues({
36
+ snapshot: resolved.snapshot,
37
+ data,
38
+ attachmentFileid: argAttachment || run.attachmentFileid || '',
39
+ attachmentFileids: argAttachment ? null : runAttachments,
40
+ });
41
+ // 主联络人一致性:用户明确指定了对接人(escorts),但实际填入的是别人时提前报警。
42
+ // 修复不彻底或调用方传参有误时,这是最后一道防线。
43
+ const escortNames = nameList(data.escorts);
44
+ const filledNames = (Array.isArray(data.companions) ? data.companions : [])
45
+ .map((item) => (typeof item === 'string' ? item : (item && (item.name || item.id)) || ''))
46
+ .map((item) => String(item || '').trim())
47
+ .filter(Boolean);
48
+ if (escortNames.length && filledNames.length && !escortNames.some((name) => filledNames.includes(name))) {
49
+ composed.warnings.push([
50
+ '主联络人可能填错:',
51
+ `指定对接人为 ${escortNames.join(',')},实际填入 ${filledNames.join(',')}。`,
52
+ '请在页面上核对「泛微分支机构参与人员(主联络人)」字段。',
53
+ ].join(''));
54
+ }
55
+ if (!composed.keys.length) {
56
+ return {
57
+ state: 'empty',
58
+ ok: false,
59
+ data: { customParams: {}, fieldAssignKeys: '', todos: composed.todos },
60
+ warnings: composed.warnings,
61
+ next: {
62
+ command: 'weaver-work-cli reception render --run-id … --answers \'{...}\'',
63
+ reason: '没有任何字段有值,先补齐 answers',
64
+ },
65
+ };
66
+ }
67
+ // baseUrl 优先级:run 记录 → 当前会话 → 快照环境值。
68
+ // run.base 是 doc 上传时回填的,与本次执行同机同环境;先取它能省掉一次会话解析(~228ms)。
69
+ // run 被重建(RUN_NOT_FOUND)时 run.base 为空,才回落到会话。
70
+ const baseUrl = run.base
71
+ || (await ctx.host.getSession()).baseUrl
72
+ || (resolved.snapshot.env && resolved.snapshot.env.baseUrl)
73
+ || '';
74
+ const browsertool = renderBrowsertool({
75
+ baseUrl,
76
+ workflowId: (resolved.snapshot.workflow && resolved.snapshot.workflow.workflowId) || '',
77
+ workflowName: (resolved.snapshot.workflow && resolved.snapshot.workflow.name) || run.workflow,
78
+ customParams: { values: composed.values, keys: composed.keys },
79
+ sdkRenderType: input.sdkRender,
80
+ });
81
+ // browsertool 落盘:宿主若支持文件引用,模型就不必逐字复述这 2.5KB 结构化 JSON
82
+ // (那是整条链路里最贵的一段生成)。`data.browsertool` 仍然保留,宿主不支持时照旧整段输出。
83
+ let browsertoolFile = '';
84
+ try {
85
+ const dir = runsDir(ctx.stateDir);
86
+ mkdirSync(dir, { recursive: true, mode: 0o700 });
87
+ const file = join(dir, `${run.runId}.browsertool.json`);
88
+ // 落纯 JSON(不含 <browsertool> 标签):标签由宿主按自己的解析规则包上
89
+ const payload = browsertool
90
+ .replace(/^<browsertool>\s*/u, '')
91
+ .replace(/\s*<\/browsertool>$/u, '');
92
+ writeFileSync(file, payload, 'utf8');
93
+ // 统一正斜杠:JSON 里不用转义,Windows 前端也能直接读
94
+ browsertoolFile = file.replace(/\\/gu, '/');
95
+ }
96
+ catch (error) {
97
+ composed.warnings.push(`browsertool 落盘失败(${error.message}):按整段 browsertool 输出即可`);
98
+ }
99
+ return {
100
+ state: 'rendered',
101
+ ok: true,
102
+ data: {
103
+ customParams: composed.values,
104
+ fieldAssignKeys: composed.keys.join(','),
105
+ detailRowCount: composed.detailRowCount,
106
+ attachmentPending: composed.attachmentPending,
107
+ sdkRenderType: resolveRenderType(input.sdkRender),
108
+ todos: composed.todos,
109
+ browsertool,
110
+ browsertoolFile,
111
+ browsertoolRef: browsertoolFile ? `<browsertool-file path="${browsertoolFile}" />` : '',
112
+ timings: { totalMs: Date.now() - startedAt },
113
+ },
114
+ warnings: composed.warnings,
115
+ next: {
116
+ command: '把 data.browsertool 整段原样作为回复正文(不包代码块)',
117
+ reason: '宿主会打开新建页并带值;用户自己提交',
118
+ },
119
+ };
120
+ }
121
+ export const renderOperation = {
122
+ execute: (input, ctx) => render(input, ctx),
123
+ };
@@ -0,0 +1,38 @@
1
+ import { randomBytes } from 'node:crypto';
2
+ import { join } from 'node:path';
3
+ import { receptionRunNotFound, receptionValidationError } from '../errors.js';
4
+ import { ensureDir, readJson, writeJson } from './shared.js';
5
+ function pad(value) {
6
+ return String(value).padStart(2, '0');
7
+ }
8
+ export function newRunId(now = new Date()) {
9
+ const stamp = `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}`
10
+ + `${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
11
+ return `rc-${stamp}-${randomBytes(2).toString('hex')}`;
12
+ }
13
+ export function runsDir(stateDir) {
14
+ return join(stateDir, 'runs');
15
+ }
16
+ export function runPath(stateDir, runId) {
17
+ return join(runsDir(stateDir), `${runId}.json`);
18
+ }
19
+ export function saveRun(stateDir, run) {
20
+ ensureDir(runsDir(stateDir));
21
+ writeJson(runPath(stateDir, run.runId), run);
22
+ return run;
23
+ }
24
+ export function loadRun(stateDir, runId) {
25
+ if (!runId) {
26
+ throw receptionValidationError('RUN_ID_MISSING', '缺少 --run-id(正常流程先用 ask 取 runId;run 已失效时改用 --known 现场重建)', { hint: 'reception doc --known \'{"customer":"…","visitDate":"…"}\' --answers \'{…}\'' });
27
+ }
28
+ const found = readJson(runPath(stateDir, runId));
29
+ if (!found)
30
+ throw receptionRunNotFound(runId, stateDir);
31
+ return found;
32
+ }
33
+ /** 尝试读取;不存在返回 null,不抛。doc 的"现场重建"分支用它。 */
34
+ export function tryLoadRun(stateDir, runId) {
35
+ if (!runId)
36
+ return null;
37
+ return readJson(runPath(stateDir, runId));
38
+ }
@@ -0,0 +1,127 @@
1
+ import { nameList } from './shared.js';
2
+ /**
3
+ * 日程明细口径:四种来源(scheduleRows / schedule / agenda / 标准议程兜底)+ 7 列按字段 ID 映射。
4
+ *
5
+ * 这张表是表单 subForm 的真实结构,改动必须先在真机核对快照;
6
+ * 口径与 `data/fields-snapshot.json` 的 details 段一一对应。
7
+ */
8
+ export const SCHEDULE_DETAIL = {
9
+ subFormId: '100003690000000143',
10
+ dataKey: 'formtable_main_23_dt2',
11
+ switch: { fieldId: '100003720000014930', on: '启用' },
12
+ columns: {
13
+ date: '100003720000014936',
14
+ time: '100003720000014937',
15
+ item: '100003720000014938',
16
+ place: '100003720000014939',
17
+ person: '100003720000014940',
18
+ activity: '100003720000014941',
19
+ remark: '100003720000014942',
20
+ },
21
+ };
22
+ export const STANDARD_AGENDA = [
23
+ { offset: 0, item: '公司参观', activity: '参观泛微上海总部展厅与办公区,了解公司发展历程与产品能力' },
24
+ { offset: 45, item: '方案介绍', activity: '' },
25
+ { offset: 120, item: '讨论交流', activity: '双方围绕关注点交流答疑,明确后续推进节奏' },
26
+ ];
27
+ const SEVEN = ['date', 'time', 'item', 'place', 'person', 'activity', 'remark'];
28
+ export function hhmmPlus(start, mins) {
29
+ const base = /^\d{1,2}:\d{2}$/.test(String(start || '')) ? String(start) : '09:30';
30
+ const [hour, minute] = base.split(':').map(Number);
31
+ const total = (((hour * 60 + minute + mins) % 1440) + 1440) % 1440;
32
+ return `${String(Math.floor(total / 60)).padStart(2, '0')}:${String(total % 60).padStart(2, '0')}`;
33
+ }
34
+ function pick7(row) {
35
+ if (!row || typeof row !== 'object' || Array.isArray(row))
36
+ return null;
37
+ const source = row;
38
+ const out = {};
39
+ for (const key of SEVEN) {
40
+ const value = source[key];
41
+ if (value !== null && value !== undefined && String(value).trim())
42
+ out[key] = String(value).trim();
43
+ }
44
+ return Object.keys(out).length ? out : null;
45
+ }
46
+ export function normalizeScheduleRows(data = {}) {
47
+ const rows = [];
48
+ const push = (row) => {
49
+ if (row)
50
+ rows.push(row);
51
+ };
52
+ const companions = Array.isArray(data.companions) ? data.companions : [];
53
+ // 接待人员优先取用户指定的对接人(escorts);companions 可能被 --user 覆盖成当前操作人
54
+ const escortNames = nameList(data.escorts);
55
+ const mainPerson = escortNames[0] || companions
56
+ .map((item) => (typeof item === 'string' ? item : (item && item.name) || ''))
57
+ .filter(Boolean)[0] || data.contact || '';
58
+ if (Array.isArray(data.scheduleRows))
59
+ data.scheduleRows.forEach((row) => push(pick7(row)));
60
+ if (!rows.length && Array.isArray(data.schedule)) {
61
+ data.schedule.forEach((row) => {
62
+ if (Array.isArray(row)) {
63
+ const [time, item, place] = row;
64
+ push(pick7({ date: data.visitDate || data.arrivalDate || '', time, item, place, person: mainPerson }));
65
+ }
66
+ else {
67
+ push(pick7(row));
68
+ }
69
+ });
70
+ }
71
+ if (!rows.length && Array.isArray(data.agenda)) {
72
+ data.agenda.forEach((row) => push(pick7({
73
+ date: data.visitDate || data.arrivalDate || '',
74
+ time: (row && (row.start || row.time)) || '',
75
+ item: row && row.item,
76
+ place: row && row.place,
77
+ person: (row && row.person) || mainPerson,
78
+ activity: row && row.activity,
79
+ remark: row && row.remark,
80
+ })));
81
+ }
82
+ if (!rows.length) {
83
+ const date = data.visitDate || data.arrivalDate || '';
84
+ const start = /^\d{1,2}:\d{2}$/.test(String(data.agendaStart || '')) ? String(data.agendaStart) : '09:30';
85
+ const room = data.meetingRoom || '总部129/130/131会议室(按人数择一)';
86
+ for (const item of STANDARD_AGENDA) {
87
+ push(pick7({
88
+ date,
89
+ time: hhmmPlus(start, item.offset),
90
+ item: item.item,
91
+ place: item.item === '公司参观' ? '泛微上海总部' : room,
92
+ person: mainPerson,
93
+ activity: item.item === '方案介绍' ? (data.demand || '产品与方案介绍') : item.activity,
94
+ }));
95
+ }
96
+ }
97
+ for (const row of rows)
98
+ if (!row.person && mainPerson)
99
+ row.person = mainPerson;
100
+ return rows;
101
+ }
102
+ export function buildDetailsPayload(rows) {
103
+ const list = Array.isArray(rows) ? rows : [];
104
+ const out = [];
105
+ for (const item of list) {
106
+ const row = {};
107
+ for (const [semantic, fieldId] of Object.entries(SCHEDULE_DETAIL.columns)) {
108
+ const value = item && item[semantic];
109
+ if (value === null || value === undefined)
110
+ continue;
111
+ const text = String(value).trim();
112
+ if (text)
113
+ row[fieldId] = text;
114
+ }
115
+ if (Object.keys(row).length)
116
+ out.push(row);
117
+ }
118
+ if (!out.length)
119
+ return null;
120
+ return {
121
+ details: { [SCHEDULE_DETAIL.subFormId]: out },
122
+ switchField: SCHEDULE_DETAIL.switch,
123
+ subFormId: SCHEDULE_DETAIL.subFormId,
124
+ dataKey: SCHEDULE_DETAIL.dataKey,
125
+ rowCount: out.length,
126
+ };
127
+ }
@@ -0,0 +1,196 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { chmodSync, mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
3
+ import { dirname } from 'node:path';
4
+ import { receptionValidationError } from '../errors.js';
5
+ /** 稳定序列化:键排序,保证同数据同哈希。 */
6
+ export function canonical(value) {
7
+ if (value === null || typeof value !== 'object')
8
+ return JSON.stringify(value ?? null);
9
+ if (Array.isArray(value))
10
+ return `[${value.map(canonical).join(',')}]`;
11
+ const record = value;
12
+ const keys = Object.keys(record).sort();
13
+ return `{${keys.map((key) => `${JSON.stringify(key)}:${canonical(record[key])}`).join(',')}}`;
14
+ }
15
+ export function sha256(text) {
16
+ return createHash('sha256').update(String(text)).digest('hex');
17
+ }
18
+ export function ensureDir(path) {
19
+ try {
20
+ mkdirSync(path, { recursive: true });
21
+ }
22
+ catch {
23
+ // 已存在或不可写;可写性交给后续真实写入报错
24
+ }
25
+ }
26
+ export function readJson(path, fallback = null) {
27
+ try {
28
+ return JSON.parse(readFileSync(path, 'utf8'));
29
+ }
30
+ catch {
31
+ return fallback;
32
+ }
33
+ }
34
+ export function writeJson(path, value) {
35
+ ensureDir(dirname(path));
36
+ writeFileSync(path, JSON.stringify(value, null, 2));
37
+ }
38
+ /** 最近修改时间,取不到算 0(用于 Python 缓存新鲜度判断)。 */
39
+ export function mtimeMs(path) {
40
+ try {
41
+ return statSync(path).mtimeMs;
42
+ }
43
+ catch {
44
+ return 0;
45
+ }
46
+ }
47
+ export function fileSize(path) {
48
+ try {
49
+ return statSync(path).size;
50
+ }
51
+ catch {
52
+ return 0;
53
+ }
54
+ }
55
+ /** 只有存在且未超过 ttl 才算新鲜。 */
56
+ export function fresh(path, ttlMs) {
57
+ const mtime = mtimeMs(path);
58
+ return Boolean(mtime) && Date.now() - mtime < ttlMs;
59
+ }
60
+ /** 严紧权限落盘;Windows 上 chmod 无效,忽略即可。 */
61
+ export function writeJsonSecure(path, value, mode = 0o600) {
62
+ writeJson(path, value);
63
+ try {
64
+ chmodSync(path, mode);
65
+ }
66
+ catch {
67
+ // Windows 无 POSIX 权限位
68
+ }
69
+ }
70
+ // ---------------------------------------------------------------------------
71
+ // JSON 入参
72
+ //
73
+ // 三条铁律(2026-11-02 事故的产物,不要简化):
74
+ // 1. 文件优先(--xxx-file),彻底绕开 shell 转义;
75
+ // 2. 解析前清 BOM / 零宽字符,失败再试中文引号 + 尾随逗号;
76
+ // 3. 报错必须自证:区分 missing / file_unreadable / invalid,invalid 带 preview + hasBom。
77
+ // ---------------------------------------------------------------------------
78
+ const BOM = /^\uFEFF/;
79
+ const ZERO_WIDTH = /[\u200B-\u200D\uFEFF]/g;
80
+ /** 纯文本 → 对象。不做 IO,便于单测。 */
81
+ export function parseJsonText(raw) {
82
+ const src = String(raw ?? '');
83
+ const hasBom = src.charCodeAt(0) === 0xfeff;
84
+ const cleaned = src.replace(BOM, '').replace(ZERO_WIDTH, '').trim();
85
+ try {
86
+ return { ok: true, value: JSON.parse(cleaned), hasBom };
87
+ }
88
+ catch (firstError) {
89
+ const fixed = cleaned
90
+ .replace(/[\u201C\u201D]/g, '"')
91
+ .replace(/[\u2018\u2019]/g, "'")
92
+ .replace(/,\s*([}\]])/g, '$1');
93
+ try {
94
+ return { ok: true, value: JSON.parse(fixed), hasBom, autoFixed: true };
95
+ }
96
+ catch {
97
+ return {
98
+ ok: false,
99
+ reason: 'invalid',
100
+ error: firstError.message,
101
+ preview: cleaned.slice(0, 120),
102
+ hasBom,
103
+ };
104
+ }
105
+ }
106
+ }
107
+ /** 从选项对象读 JSON:`--<name>-file` 优先,其次 `--<name>` 内联。 */
108
+ export function readJsonArg(options, name) {
109
+ const filePath = textOf(options, `${name}File`) || textOf(options, `${name}-file`);
110
+ if (filePath) {
111
+ let raw;
112
+ try {
113
+ raw = readFileSync(filePath, 'utf8');
114
+ }
115
+ catch (error) {
116
+ return {
117
+ ok: false,
118
+ reason: 'file_unreadable',
119
+ path: filePath,
120
+ error: error.message,
121
+ };
122
+ }
123
+ return { ...parseJsonText(raw), source: 'file', path: filePath };
124
+ }
125
+ const inline = options[name];
126
+ if (inline === undefined || inline === null || inline === true) {
127
+ return { ok: false, reason: 'missing' };
128
+ }
129
+ return { ...parseJsonText(String(inline)), source: 'inline' };
130
+ }
131
+ /**
132
+ * 取一个 JSON 参数,按语义抛错。
133
+ *
134
+ * @param options commander 收集到的选项对象
135
+ * @param name 逻辑名,如 `known`(对应 --known / --known-file)
136
+ * @param config.code 错误码前缀,如 `KNOWN` → KNOWN_REQUIRED / KNOWN_INVALID / KNOWN_FILE_UNREADABLE
137
+ */
138
+ export function jsonArg(options, name, config = {}) {
139
+ const prefix = config.code || name.toUpperCase().replace(/-/g, '_');
140
+ const result = readJsonArg(options, name);
141
+ if (result.ok)
142
+ return result.value;
143
+ if (result.reason === 'missing') {
144
+ if (!config.required)
145
+ return null;
146
+ throw receptionValidationError(`${prefix}_REQUIRED`, `缺少 --${name} <JSON> 或 --${name}-file <path>`, {
147
+ hint: config.hint || `推荐用文件传参:先写 ${name}.json,再 --${name}-file ${name}.json`,
148
+ });
149
+ }
150
+ if (result.reason === 'file_unreadable') {
151
+ throw receptionValidationError(`${prefix}_FILE_UNREADABLE`, `读不到 --${name}-file:${result.path}`, {
152
+ path: result.path,
153
+ detail: result.error,
154
+ hint: '检查文件是否存在、路径是否正确、是否有读权限;不要因此改回内联传参',
155
+ });
156
+ }
157
+ throw receptionValidationError(`${prefix}_INVALID`, `--${name} 不是合法 JSON:${result.error}`, {
158
+ hint: '常见原因:UTF-8 BOM(hasBom:true)、中文引号、尾随逗号、shell 吃掉双引号。'
159
+ + '请看 preview 定位,修 JSON 本身,不要换传参方式重试',
160
+ preview: result.preview,
161
+ hasBom: result.hasBom,
162
+ });
163
+ }
164
+ /** 从选项对象取字符串;commander 对未传的选项给 undefined,对布尔开关给 true。 */
165
+ export function textOf(options, key) {
166
+ const value = options[key];
167
+ if (value === undefined || value === null || value === true || value === false)
168
+ return '';
169
+ return String(value).trim();
170
+ }
171
+ /** 姓名归一:数组 / 逗号分隔串 / {name} 对象都吃。 */
172
+ export function nameList(value) {
173
+ const list = Array.isArray(value) ? value : String(value ?? '').split(/[,,、;;\s]+/);
174
+ return list
175
+ .map((item) => (typeof item === 'string' ? item : (item && (item.name || item.id)) || ''))
176
+ .map((item) => String(item).trim())
177
+ .filter(Boolean);
178
+ }
179
+ const hasValue = (value) => !(value === undefined || value === null || value === ''
180
+ || (Array.isArray(value) && value.length === 0));
181
+ /** 7 项缺口:只判「有没有」,语义判断仍由模型完成。 */
182
+ export function computeGaps(data = {}) {
183
+ const filled = [];
184
+ const gap = [];
185
+ const push = (key, value) => (hasValue(value) ? filled.push(key) : gap.push(key));
186
+ push('customer', data.customer || data.customerId);
187
+ push('headcount', data.headcount);
188
+ push('visitDate', data.visitDate);
189
+ push('visitType', data.visitType);
190
+ push('companions', data.companions);
191
+ push('demand', data.demand);
192
+ const logistics = ['headcount', 'meetingRoom', 'pickup', 'meal', 'hotel', 'gift'];
193
+ const logisticsMissing = logistics.filter((key) => !hasValue(data[key]));
194
+ push('logistics', logisticsMissing.length ? null : logistics);
195
+ return { filled, gap, logisticsMissing };
196
+ }