weaver-work-cli 0.1.36 → 0.1.39

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 (169) hide show
  1. package/README.md +4 -2
  2. package/dist/chunks/{archive-XBVH7JU7.js → archive-ENZYBBME.js} +559 -68
  3. package/dist/chunks/{archive-oa-MZM3EKFQ.js → archive-oa-YWLEC5V4.js} +4 -3
  4. package/dist/chunks/{asset-4XO7UOUW.js → asset-OOV6DWPA.js} +8 -7
  5. package/dist/chunks/asset-idle-RE632MY5.js +670 -0
  6. package/dist/chunks/{attachment-content-VXSWANAC.js → attachment-content-RWN2FCLL.js} +3 -3
  7. package/dist/chunks/{blog-PGZKOPSC.js → blog-PEPOJAL7.js} +5 -4
  8. package/dist/chunks/{caizhilian-BH4ZVGUN.js → caizhilian-WYIQDVPJ.js} +5 -4
  9. package/dist/chunks/{calendar-MXEMTIO4.js → calendar-CIARBAOX.js} +4 -3
  10. package/dist/chunks/{chunk-NCOVUAZK.js → chunk-36DIFZAH.js} +4 -3
  11. package/dist/chunks/{chunk-I6QGIBDM.js → chunk-BJGXMFGD.js} +4 -3
  12. package/dist/chunks/{chunk-TC6MZAO3.js → chunk-CQHGNCK2.js} +52 -2
  13. package/dist/chunks/{chunk-WXFPWCXG.js → chunk-EINRJHQ3.js} +3 -3
  14. package/dist/chunks/{chunk-JUXVYKII.js → chunk-EZGFHJFW.js} +201 -19
  15. package/dist/chunks/{chunk-VPUTVEMC.js → chunk-F2EQXUEE.js} +436 -290
  16. package/dist/chunks/{chunk-JYKABYCV.js → chunk-GVPJZXJ2.js} +3 -3
  17. package/dist/chunks/{chunk-6LLJFKJE.js → chunk-HJYVHXUQ.js} +1 -1
  18. package/dist/chunks/{chunk-T72N74ZT.js → chunk-I2HB737U.js} +5 -4
  19. package/dist/chunks/{chunk-VPXOPQJI.js → chunk-K3RUEEOL.js} +4 -2
  20. package/dist/chunks/{chunk-HXJQI5NM.js → chunk-KTCB5R5H.js} +3 -2
  21. package/dist/chunks/{chunk-XMGSYD6S.js → chunk-L4N7B7ZD.js} +4 -4
  22. package/dist/chunks/{chunk-QYGO5EE2.js → chunk-MUQUHKPG.js} +4 -3
  23. package/dist/chunks/{chunk-QHFANTX7.js → chunk-NLK2RZKG.js} +1348 -90
  24. package/dist/chunks/{chunk-F746NKNF.js → chunk-P2DAISYW.js} +1 -1
  25. package/dist/chunks/{chunk-BPE37FPB.js → chunk-T7JDJJ7H.js} +3 -3
  26. package/dist/chunks/{chunk-JNG42JKG.js → chunk-XXJOSZTQ.js} +6 -6
  27. package/dist/chunks/{chunk-5DQEEGCC.js → chunk-YS5DPN4T.js} +1 -1
  28. package/dist/chunks/{chunk-EG6ZU444.js → chunk-ZUX3P6BQ.js} +10 -5
  29. package/dist/chunks/{chunk-JCSN3JGM.js → chunk-ZXRNHZTE.js} +7 -6
  30. package/dist/chunks/{conflict-JAB2LJEZ.js → conflict-DRMDOL56.js} +2 -2
  31. package/dist/chunks/{contract-XI2EEIZU.js → contract-73MERZWN.js} +4 -3
  32. package/dist/chunks/{cowork-SCPGLBA4.js → cowork-HNGBPD7A.js} +4 -3
  33. package/dist/chunks/{ebuilder-form-EYLHNOTA.js → ebuilder-form-OY6DVNRK.js} +3 -3
  34. package/dist/chunks/{ehr-EAP77IMT.js → ehr-RAQNEQO7.js} +4 -3
  35. package/dist/chunks/{esb-2TGGXEE7.js → esb-6XV7C7YV.js} +4 -4
  36. package/dist/chunks/{fna-2X7ZE7BU.js → fna-XTSRB7G7.js} +4 -3
  37. package/dist/chunks/{host-Q4LZGCRU.js → host-3F5UM5GN.js} +3 -3
  38. package/dist/chunks/{host-XCLDDXKQ.js → host-A7J6GDUP.js} +3 -3
  39. package/dist/chunks/{host-I4NRK4MX.js → host-VGPVP7YF.js} +3 -3
  40. package/dist/chunks/{host-C6EL2RKL.js → host-YAQAPYNP.js} +3 -3
  41. package/dist/chunks/{host-UEI5FGDM.js → host-YMBXWFWX.js} +3 -3
  42. package/dist/chunks/{hrm-YXERJM76.js → hrm-TLHKC545.js} +3 -3
  43. package/dist/chunks/{im-A4VZN2TQ.js → im-YOUCFMUK.js} +3 -3
  44. package/dist/chunks/{invoice-2Z6YPMIS.js → invoice-WNBS2B4C.js} +3 -3
  45. package/dist/chunks/{jiuchuanhui-AR5GMKZB.js → jiuchuanhui-XABWS5RN.js} +4 -3
  46. package/dist/chunks/{lazy-dispatch-QXW7P4X3.js → lazy-dispatch-NLZ5UQQI.js} +5 -5
  47. package/dist/chunks/{mail-7GZ6CPBJ.js → mail-LRYMBFNL.js} +4 -3
  48. package/dist/chunks/{meeting-3NMGA3MB.js → meeting-ESXL6MFI.js} +13 -12
  49. package/dist/chunks/{okr-BZ6XUOAG.js → okr-EOV65SSF.js} +4 -3
  50. package/dist/chunks/{plan-DR5CMUYP.js → plan-YFPVKW6Y.js} +4 -3
  51. package/dist/chunks/{project-6J63MK33.js → project-MDVZUYQW.js} +4 -3
  52. package/dist/chunks/{registry-VRTNC6UR.js → registry-QCLZEDAP.js} +8 -8
  53. package/dist/chunks/{registry-KDD7DHNK.js → registry-VT5Y2HLA.js} +4 -4
  54. package/dist/chunks/{registry-TKX2E7C7.js → registry-YX4CSEMD.js} +3 -3
  55. package/dist/chunks/{room-recommend-XCWRMB5P.js → room-recommend-L3MWH4JW.js} +4 -4
  56. package/dist/chunks/{schedule-IVBICP32.js → schedule-UASAVDVD.js} +4 -4
  57. package/dist/chunks/{workflow-D74NFK3C.js → workflow-KDGIUCNW.js} +9 -6
  58. package/dist/core/output.js +16 -6
  59. package/dist/index.js +33 -28
  60. package/dist/internal/e10/auth/messages.js +1 -0
  61. package/dist/internal/e10/auth-recovery.js +127 -7
  62. package/dist/internal/e10/client.js +16 -2
  63. package/dist/internal/e10/context.js +16 -3
  64. package/dist/internal/e10/request-runtime.js +106 -8
  65. package/dist/shortcuts/archive/host.js +5 -2
  66. package/dist/shortcuts/archive/manifest.js +1 -1
  67. package/dist/shortcuts/archive/operations/borrow-list.js +13 -1
  68. package/dist/shortcuts/archive/operations/flow-url.js +1 -1
  69. package/dist/shortcuts/archive/operations/prelib.js +472 -0
  70. package/dist/shortcuts/archive/operations/registry.js +2 -0
  71. package/dist/shortcuts/archive/operations/upload.js +1 -1
  72. package/dist/shortcuts/archive-oa/host.js +2 -1
  73. package/dist/shortcuts/asset/host.js +6 -5
  74. package/dist/shortcuts/asset-idle/errors.js +44 -0
  75. package/dist/shortcuts/asset-idle/host.js +161 -0
  76. package/dist/shortcuts/asset-idle/index.js +114 -0
  77. package/dist/shortcuts/asset-idle/manifest.js +159 -0
  78. package/dist/shortcuts/asset-idle/operations/idle.js +47 -0
  79. package/dist/shortcuts/asset-idle/operations/registry.js +33 -0
  80. package/dist/shortcuts/asset-idle/operations/shared.js +142 -0
  81. package/dist/shortcuts/asset-idle/operations/types.js +9 -0
  82. package/dist/shortcuts/asset-idle/operations.js +15 -0
  83. package/dist/shortcuts/blog/host.js +3 -2
  84. package/dist/shortcuts/caizhilian/host.js +3 -2
  85. package/dist/shortcuts/calendar/host.js +2 -1
  86. package/dist/shortcuts/contract/host.js +2 -1
  87. package/dist/shortcuts/cowork/host.js +2 -1
  88. package/dist/shortcuts/ebuilder-form/host.js +3 -1
  89. package/dist/shortcuts/ehr/host.js +2 -1
  90. package/dist/shortcuts/esb/host.js +2 -1
  91. package/dist/shortcuts/fna/host.js +2 -1
  92. package/dist/shortcuts/hrm/host.js +2 -1
  93. package/dist/shortcuts/im/host.js +3 -2
  94. package/dist/shortcuts/index.js +5 -0
  95. package/dist/shortcuts/invoice/host.js +5 -4
  96. package/dist/shortcuts/jiuchuanhui/host.js +2 -1
  97. package/dist/shortcuts/mail/host.js +2 -1
  98. package/dist/shortcuts/meeting/host.js +3 -2
  99. package/dist/shortcuts/meeting/invitation/text.js +71 -0
  100. package/dist/shortcuts/meeting/operations/eb/create-flow.js +1073 -50
  101. package/dist/shortcuts/meeting/operations/eb/crm-search.js +478 -0
  102. package/dist/shortcuts/meeting/operations/eb/factory.js +60 -1
  103. package/dist/shortcuts/meeting/operations/eb/index.js +2 -0
  104. package/dist/shortcuts/meeting/operations/invitation.js +122 -9
  105. package/dist/shortcuts/okr/host.js +2 -1
  106. package/dist/shortcuts/plan/host.js +2 -1
  107. package/dist/shortcuts/project/host.js +2 -1
  108. package/dist/shortcuts/workflow/host.js +3 -0
  109. package/dist/shortcuts/workflow/index.js +1 -1
  110. package/dist/shortcuts/workflow/operations/form.js +44 -11
  111. package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupRules.js +77 -26
  112. package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupStore.js +6 -0
  113. package/dist/shortcuts/workflow/operations/todoSmartConvert/summaryCache.js +59 -117
  114. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailCache.js +44 -7
  115. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailFetcher.js +37 -29
  116. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.collect.js +20 -6
  117. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.detail.js +22 -18
  118. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.groupSummary.js +34 -10
  119. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.js +4 -2
  120. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.smartGroup.js +9 -2
  121. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.summary.js +110 -20
  122. package/docs/_catalog.md +3 -0
  123. package/docs/asset-idle.md +45 -0
  124. package/docs/e10-auth.md +1 -1
  125. package/docs/todo-smart-convert/subgroup-rules.md +1 -1
  126. package/package.json +1 -1
  127. package/scripts/package-skill.mjs +2 -0
  128. package/skill-template/business-info.json +14 -1
  129. package/skill-template/domains/asset-idle.md +13 -0
  130. package/skill-template/domains/wenshuding.md +3 -0
  131. package/skills/weaver-e10-archive-oa/SKILL.md +1 -0
  132. package/skills/weaver-e10-archive-oa/references/my-borrow.md +49 -0
  133. package/skills/weaver-e10-asset-idle/SKILL.md +73 -0
  134. package/skills/weaver-e10-asset-idle/references/idle-list.md +62 -0
  135. package/skills/weaver-e10-asset-idle/references/idle-stats-and-charts.md +65 -0
  136. package/skills/weaver-e10-asset-idle/references/source-manifest.json +193 -0
  137. package/skills/weaver-e10-asset-idle/references/widget-style.md +205 -0
  138. package/skills/weaver-e10-caizhilian/SKILL.md +29 -11
  139. package/skills/weaver-e10-caizhilian/references/auth-and-install.md +12 -0
  140. package/skills/weaver-e10-caizhilian/references/files.md +1 -1
  141. package/skills/weaver-e10-caizhilian/references/setting-encrypt.md +1 -1
  142. package/skills/weaver-e10-caizhilian/references/source-manifest.json +45 -45
  143. package/skills/weaver-e10-cowork/SKILL.md +2 -0
  144. package/skills/weaver-e10-jucailin/SKILL.md +2 -0
  145. package/skills/weaver-e10-jucailin/references/recruit-read.md +2 -0
  146. package/skills/weaver-e10-jucailin/references/recruit-write.md +1 -1
  147. package/skills/weaver-e10-mail/SKILL.md +3 -0
  148. package/skills/weaver-e10-meeting/SKILL.md +250 -301
  149. package/skills/weaver-e10-meeting/references/meeting-eb.md +203 -0
  150. package/skills/weaver-e10-meeting/references/meeting-invitation.md +37 -5
  151. package/skills/weaver-e10-meeting.zip +0 -0
  152. package/skills/weaver-e10-okr/references/source-manifest.json +3 -3
  153. package/skills/weaver-e10-shared/SKILL.md +5 -5
  154. package/skills/weaver-e10-shared/references/e10-auth-and-session.md +3 -3
  155. package/skills/weaver-e10-wenshuding/SKILL.md +29 -6
  156. package/skills/weaver-e10-wenshuding/references/archive-borrow-list.md +14 -0
  157. package/skills/weaver-e10-wenshuding/references/archive-download.md +2 -0
  158. package/skills/weaver-e10-wenshuding/references/archive-flow.md +1 -1
  159. package/skills/weaver-e10-wenshuding/references/archive-prelib-arrange.md +76 -0
  160. package/skills/weaver-e10-wenshuding/references/archive-prelib-list.md +107 -0
  161. package/skills/weaver-e10-wenshuding/references/archive-prelib-open.md +59 -0
  162. package/skills/weaver-e10-wenshuding/references/archive-upload.md +4 -1
  163. package/skills/weaver-e10-wenshuding/references/source-manifest.json +108 -65
  164. package/skills/weaver-e10-workflow/SKILL.md +5 -2
  165. package/skills/weaver-e10-workflow/aigroup/default.json +154 -19
  166. package/skills/weaver-e10-workflow/references/todo-smart-convert.md +59 -27
  167. package/skills/weaver-e10-workflow/tools/todo-serve.cjs +113 -25
  168. package/skills/weaver-e10-workflow/tools/todo-summary.cjs +292 -42
  169. package/skills/weaver-e10-yimiaoban/references/source-manifest.json +3 -3
@@ -782,6 +782,78 @@ video_taskResult 为空 且 parse_content 为空 → 未触
782
782
  实测遇到两次(`update_mt_decision_task` 首次调用、EB 列表接口),**重试即成功**,且数据未被写坏。
783
783
  判定方法:报这个错时先 `list` 回查;没写进去再重试一次,**不要连试三次以上**。
784
784
 
785
+ ## 提交方式:默认直提(2.41.0 起,2026-10-31 真机事故)
786
+
787
+ 小e 的浏览器填单页(`<browsertool>` + `params.customParams`)**只给文本类字段赋值**:
788
+
789
+ | 字段类型 | customParams 传过去的效果 |
790
+ |---|---|
791
+ | 文本 / 多行文本 / 日期 / 数字 | ✅ 正常带出 |
792
+ | 浏览按钮(会议地点) | 未单独核实(用户只报了人员和客户为空) |
793
+ | 浏览按钮(**参会人员**) | ❌ 表单里空着 |
794
+ | 客户浏览按钮(**参会客户**) | ❌ 表单里空着 |
795
+
796
+ 所以"我明明说了参会人和客户,表单里一个都没有"不是 CLI 没传,而是**那一档页面不支持**。
797
+ 2026-10-31 起 `meeting.eb.meeting.create.flow.quick / apply` **默认 `submit_mode=direct`**:
798
+ 直接 `workflow.createRequest action=submit` 写服务端,实测(requestId `1332418264069103616`):
799
+
800
+ - `hrm_members` / `crm_members` 全部落库,`meeting.eb.meeting.detail --id <meetingId>` 回读可见
801
+ (人员回姓名文本「王丹丹」、客户回 id「1258347137804009474」);
802
+ - 会议当场生成(`meetingId` 有值)→ 邀请函 `invitation.pending=false`,是**真实会议数据版**,
803
+ 不再有「客户单位」「召集人」这些【待补充】;
804
+ - 返回里有 `requestId` + `meetingId`,⛔ 判成功看这两个 id,不要看有没有 `finalMarkdown`。
805
+
806
+ `submit_mode=browser` 保留原行为(预填 + 用户点提交),只在用户明确要求"自己核对表单"时用。
807
+
808
+ ## 「召集人 / 联系人」缺省 = 当前登录人(2.43.0)
809
+
810
+ **为什么**:这两个字段以前只有显式传 `caller` / `contacter` 才有值,**换个人用(另一个账号)建会就整块空白** ——
811
+ 流程单上看不出谁召集的,邀请函「召集人」落成【待补充】。现在默认"自己召集、自己联系"。
812
+
813
+ - 取 `session.userId` → `hrm.employee.batch` 换姓名 → 提交 `{id,name}`(Employee 组件要的形态);
814
+ - 各自独立兜底:只传了 `caller` 时,`contacter` 仍补当前登录人;显式传的值**一律不覆盖**;
815
+ - 返回 `preview.autoFilled = {"召集人":"卜伟领(4980…)","联系人":"卜伟领(4980…)"}` +
816
+ 一条 warning「已按当前登录人补齐」;
817
+ - ⛔ 查不到姓名就**不填**(两个都缺时给 warning)—— 在 `userId ≠ 员工 id` 的租户里硬塞 id 会被服务端判
818
+ `NEEDS_CONFIRMATION`,提交直接卡住,比留空更糟。
819
+
820
+ 真机实测(泛微生产 `e-cology.com.cn`,2026-10-31):`prepare` 里两个字段都是 `{id,name}`,
821
+ `apply` 后 `meetingId 1332426188317081604` 回读 `caller=卜伟领`、`contacter=卜伟领`,
822
+ 邀请函正文「卜伟领 诚邀您参加…」。
823
+
824
+ ## 提交前核对 & 客户联系人自动带入(2.44.0)
825
+
826
+ - `create.flow.prepare` 的 `preview.formPreview`:**人话 Markdown 表格**(字段名 → 值),
827
+ 人员/客户都显示姓名不显示 id,空值 `—`。用途 = 替代走不通的浏览器填单核对环节:
828
+ **先贴给用户确认,再 apply/quick**。
829
+ - `create.flow.apply` / `quick` 的 `submittedPreview`:本次实际提交的字段表(同一渲染器),
830
+ 提交后必须贴出来 —— 用户要「看得见填进去了什么」。
831
+ - 客户联系人**全自动**:传 `crm_members` 后,CLI 取该项的 `contacts`(`crm.search` 的 items 原样传过来就有),
832
+ 没有就自己回查一次 `crm.search`,把**全部**联系人写成「参会客户明细」行
833
+ (`姓名` / `手机号码` / `备注=部门:X`)。要只留某几位才用 `crm_member_details` 覆盖。
834
+ - `meeting.eb.meeting.detail` 新增 `personnelText`(`caller`/`contacter`/`hrm_members`/`mt_creator`… → 姓名):
835
+ 原字段是**原始存储值**(页面建单 = id、工作流建单 = 姓名文本),对外表述一律用 `personnelText`。
836
+
837
+ ## 「参会客户」是 eBuilder 组件 —— 这是对的,别再劝人改表单(2.45.0 纠偏)
838
+
839
+ | 流程 | 「参会客户」字段 | 组件 |
840
+ | --- | --- | --- |
841
+ | 会议申请流程 `1326190634427154474`(文档里也写作「旧」) | `1332418251116929025` | `Ebuilder` |
842
+ | 会议申请流程(NEW)`1325677244111462606` | `1332437840406257666` | `Ebuilder` |
843
+
844
+ - ⛔ 2.44.0 及以前这里写的是「组件不吃客户值,要换回 Customer」——**这个判断是错的**(2026-10-31 用户纠正)。
845
+ 同一张表单的「会议地点」也是 `Ebuilder`,一直写得进去;`Ebuilder` 就是吃 `{id,name}` 的浏览按钮。
846
+ - 流程单据 → 会议表的同步**由 ESB 动作流的字段映射负责**(2026-10-31 用户确认:「你发起流程后,
847
+ 字段映射是靠 ESB 来的,这个我已经配置好了」),会议表那边落的是 `ufd_crm_members_new`。
848
+ ⇒ **CLI 不再自己补写**会议表的 `crm_members`:那一列 dataKey 与页面字段不是同一个,
849
+ 写它既不落页面、回读也永远为空,只会多出一条「客户没关联上」的假警报,把验收带偏。
850
+ 需要回退旧行为时置 `WEAVER_MEETING_CRM_PATCH=1`(`patchMeetingCrmMembers` 仍在,只用于调试)。
851
+ - ⛔ 不要用会议表 `crm_members` 的空值判断客户有没有代进去;要看流程单据(`workflow.detail` 的
852
+ fieldValues 里带「客户名(id)」)或会议页面实际显示。
853
+ - 「参会客户明细」不受影响(普通明细表,姓名/手机照常落库)。
854
+ - `create.flow.prepare` 仍会按组件类型给一条说明(点名字段 id 与 `componentKey`),看到**照实转达**,
855
+ 但**不要再建议改表单**。
856
+
785
857
  ## 流程建会字段:datakey(fieldId)固化
786
858
 
787
859
  **为什么**:NEW 建会流程(`1325677244111462606`)的表单字段名带提示语 ——
@@ -889,3 +961,134 @@ weaver-work-cli meeting ops --capability eb.meeting # 按分组看(支持前
889
961
  - **ESB 日程调用失败** → 退化为只看会议回执,`scheduleItems` 为空可判断;
890
962
  - 被剔除的槽在 `skippedSlots` 里("人空闲但没房间"),可以据此解释为什么候选少。
891
963
 
964
+ ## 指定的会议室怎么核验(2.39.3 起)
965
+
966
+ `prepare` 拿到 `address` 后,**先解析成台账里的真实房间**再核验,顺序是:
967
+
968
+ ```
969
+ 解析(id / 名称 / 名称(id)) → 存在性 → 封存状态 → 该时段占用 → 才允许进确认摘要
970
+ ```
971
+
972
+ - **存在性**:名称在台账里找不到 → `selectionType: room` + 文案「没找到名为 X 的会议室」。
973
+ 以前这种情况会被一路放行,地点按纯文本塞进表单,用户到流程页面提交时才被工作流打回
974
+ 「请按名称选择」—— 报错位置离真实原因太远(2026-10-31 真机)。
975
+ - **封存(status=1)**:拦下并要求换房,不拿封存房去建会。
976
+ - **占用**:调 `meeting.eb.conflict.room`(`query_roomusage_list`)。
977
+ ⛔ 2.39.2 及以前**只有纯数字 id 才查**,传名称(用户最常说的「测试会议室1」)整段被跳过,
978
+ 一间已被占用的房照样进确认摘要 —— 这是 2026-10-31 用户质疑"最后一步才校验"时挖到的真因。
979
+ - **台账读失败 ≠ 房间不存在**:此时标记 `lookupFailed`,跳过占用判定但不拦(避免网络抖动被当成"没这间房");
980
+ 能否核验要如实说,不能声称"已确认空闲"。
981
+ - 解析结果复用在三个地方:占用检测、确认摘要里的地点名、房间选项里「(你指定的,待确认)」的匹配。
982
+
983
+ ## 参会客户:从名称到客户 id(2.39.5 定案)
984
+
985
+ 会议流程主表上的「参会客户」是 **客户浏览按钮**(`CustomerComponent`,NEW 流程 fieldId `1326141435517583562`),
986
+ 值必须是客户 id,传客户名称文本会被工作流打回。所以链路是「先查 → 用户确认 → 再传 id」:
987
+
988
+ | 步骤 | 调用 | 说明 |
989
+ |---|---|---|
990
+ | ① 查 | `meeting.eb.crm.search {"keyword":"上海泛微网络科技股份有限公司"}` | 走 ESB 动作流 `esbFlowId=904205116264026112`,入参字段 **`custom_name`** |
991
+ | ② 确认 | —— | ⛔ 不许自动取第一条(同 SKILL 规则 0.5);`exact:false` 时必须把命中名念给用户 |
992
+ | ③ 传值 | `create.flow.prepare` 的 `crm_members` | 把 search 的 `items` 原样传(`[{customerId,name}]`)最省事;`[{id,name}]`、`客户名(客户id)`、逗号分隔都认。⛔ **必须带名称**,只给 id 抛 `crm_name_required` |
993
+
994
+ **请求体(动作流契约,2026-10-31 真机核对)**
995
+
996
+ ```json
997
+ { "customParams": { "mainTable": { "custom_name": "泛微网络" } }, "esbFlowId": "904205116264026112" }
998
+ ```
999
+
1000
+ 返回 `actionData.responseData.customData.mainTable = { mc, sjID }`:`sjID`=客户 id,`mc`=客户名称。
1001
+
1002
+ **三条真机事实(别再用猜的)**
1003
+
1004
+ 1. **入参字段名就是 `custom_name`**。之前试 `mc`/`sjmc`/`khmc`/`customerName` 全部无效、
1005
+ 误判成"模板空所以参数进不去"—— 真因是字段名不对。`esb.input-format`(copyCustomData)对这个流返回
1006
+ `customParams: null`,含义是「**没配自定义入参模板 = 透传**」,不是「模板是空对象 = 丢弃入参」。
1007
+ ⇒ CLI 现在:模板 `null` 时用默认字段名 `custom_name` 照常发;只有模板明确是 `mainTable: {}` 才判
1008
+ `blocked:"esb_template_empty"`。
1009
+ 2. **一次只回 1 条**(服务端是"包含匹配 + 取首个命中"):`当前`/`pageSize`/`rows` 都不改变结果,
1010
+ 所以"查 10 条给用户挑"做不到。实测:
1011
+ | 关键词 | 返回 |
1012
+ |---|---|
1013
+ | 深圳市腾讯斐泰科技有限公司 | 深圳市腾讯斐泰科技有限公司 / 1320482515670098010(`exact:true`)|
1014
+ | 腾讯 | 深圳市腾讯斐泰科技有限公司 / 1320482515670098010(`exact:false`)|
1015
+ | 泛微 | 泛微 / 1331361148057387759(库里真有叫「泛微」的客户,**不是**上海泛微)|
1016
+ | 泛微网络 | 泛微网络科技有限公司 / 1330932351389754061 |
1017
+ | 上海泛微网络科技股份有限公司 | 上海泛微网络科技股份有限公司 / 1315014081515634745 |
1018
+ | 不存在的客户XYZ | `{mc:"", sjID:""}` 空行 → `items: []` |
1019
+ ⇒ 给全称最稳;片段命中名跟用户说的不一致时**必须回问**。
1020
+ 3. **`hasData` 恒为 0**,命中时也是 0 ⇒ 判空只看 `mc`/`sjID`,不要看 `hasData`(CLI 已不再用它下结论)。
1021
+
1022
+ - 出参:`items:[{customerId,name}]`、`total`、`exact`(命中名==关键词)、`singleBestMatch`、
1023
+ `source`(命中 customData 哪条路径)、`keywordField`(实际传的入参字段)、`blocked`。
1024
+ - 解析兼容多种输出形态(动作流改结构不用改代码):`customData.mainTable` 单条、
1025
+ `.list/rows/items/data…`、`customData.detail1|detail2…`,行被 `{mainTable:{…}}` 包一层也能剥开;
1026
+ 字段别名兼容 `id/customerId`、`name/sjmc`。
1027
+ - 「应到客户数」(fieldId `1326141435517583564`)按 `crm_members` 条数**自动算**;
1028
+ 要覆盖就显式传 `crm_member_count`。
1029
+
1030
+ ## 参会客户明细(明细表,2.39.6 起;2.39.7 打通落库)
1031
+
1032
+ 宿主表单里另有一张**明细表**「参会客户明细」,列固定 5 个:姓名 / 性别 / 职位 / 手机号码 / 备注。
1033
+
1034
+ **联系人与地址来自 ESB 出参 `lxr` / `khdz`**(2026-10-31 用户加上后的实测形状):
1035
+
1036
+ | ESB 字段 | 含义 | 真机值示例 |
1037
+ |---|---|---|
1038
+ | `lxr` | 联系人明细(数组) | `{"field_…706":"利明","field_…708":"11111111111","field_…707":"信息部"}` |
1039
+ | ↳ `field_1173221220888062706` | 姓名 | 利明 / 胡老师 / 谷俊 |
1040
+ | ↳ `field_1173221220888062708` | 手机号 | 11111111111 |
1041
+ | ↳ `field_1173221220888062707` | 部门(部分行没有) | 信息部 |
1042
+ | `khdz` | 客户地址明细(数组) | ⛔ **只回明细行 id**,没有地址文本 |
1043
+
1044
+ `crm.search` 会把 `lxr` 归一化成 `items[].contacts = [{name,mobile,dept}]`(按姓名+手机号去重),
1045
+ `khdz` 归一化成 `items[].addresses`(当前恒为空,同时回 `addressHint` 说明"ESB 没输出地址文本")。
1046
+
1047
+ 用法:
1048
+ - **有 `contacts`** → 把「姓名(部门)手机号」列成选项让用户挑一位,⛔ 不许自己选;
1049
+ - **没有 `contacts`** → 问用户联系人姓名+手机号(有的话再要职位/性别);
1050
+ - 选定后与客户一起提交 `crm_member_details:[{"xm","sjhm","zw","xb"}]`(部门放 `zw`)。
1051
+ - `prepare` 发现「传了客户没带明细」会 warning 提醒,别忽略。
1052
+
1053
+ | 项 | 值(e-cology「会议申请流程」真机) |
1054
+ |---|---|
1055
+ | 宿主流程 | `1326190634427154474` 会议申请流程(eBuilder 表单 `1179906784309559297`,表 `uf_mt_work_chkhmx`)|
1056
+ | subFormId | `1332370499762806784`(= `data.details` 的键)|
1057
+ | 列字段 id | 姓名 `1332370499762806785`(xm) / 性别 `…786`(xb) / 职位 `…787`(zw) / 手机号码 `…788`(sjhm) / 备注 `1332370774666043392`(bz) |
1058
+
1059
+ **入参**:`create.flow.prepare` 的 `crm_member_details`
1060
+
1061
+ ```json
1062
+ [{"xm":"张三","xb":"男","zw":"采购经理","sjhm":"13800000000","bz":"主谈"}]
1063
+ ```
1064
+ 中文键(`姓名/性别/职位/手机号码/备注`)与 `name/mobile/title/remark` 等别名都认;
1065
+ 姓名与手机号都为空的行走丢弃;subFormId 与列字段 id **不用传**,CLI 从 `workflow.createForm` 的字段清单里按列名反查
1066
+ (`resolveCrmDetailTarget`:挑「有姓名列」且命中列数最多的那张表,不会误选会议议题/会议服务)。
1067
+
1068
+ **⛔ 三个必须知道的现实(2026-10-31 真机核实)**
1069
+
1070
+ 1. **明细字段只认「发起节点布局」**。表建好、表单字段管理里也有、节点字段权限(`viewRelateConfig`)也勾了 display,
1071
+ 但**没摆上发起节点布局**、或**摆在隐藏行**上时,`getFormLayout` 的 `pageLayouts[0].comps` 里虽然能看到这张
1072
+ DetailTable,它下面 5 个列字段却会被判「不可见」→ `workflow.createForm` 的 `fields` 里没有它们 →
1073
+ `data.details` 一提交就被 `bindInputFields` 判 `NOT_FOUND`。
1074
+ CLI 现在会返回 `layoutWarning`("明细表 N 的 k 个字段全部被判为不可见(该明细表所在的行/列在表单布局里是隐藏的)"),
1075
+ **看到它就去查布局,不要回"表单里没有这张明细表"**。查法:`pageLayouts[0].config.workbook.Sheet1.rows[<DetailTable 的 excel.row>].visible`
1076
+ 为 `false` ⇒ 那一行是隐藏行(真机实例:明细表在 row 8,`visible:false, attrs:{hide:true}`)。
1077
+ 修法:设计器里把明细表挪到可见行 / 取消隐藏该行,保存发布后重新载入表单。
1078
+ 2. **明细表和触发它的主表字段常配「显示联动」**(本租户:`参会客户` 为空 ⇒ 整表 `hideLine`;非空 ⇒ `show`)。
1079
+ 这是**正常配置,不是配错**。旧逻辑把它与"隐藏行"一视同仁 ⇒ 整表字段被丢,建会写不进明细。
1080
+ 现在 `buildCreateFormData` 会认这种 `detail` + `show` 规则:字段照常下发并标 `conditional: true`,
1081
+ `layoutWarning` 里点名触发字段(如「明细表 1332370499762806784 因显示联动隐藏,触发字段:参会客户」)。
1082
+ 主表字段自己也配了 `show` 的(`参会客户` 就是)同样处理 —— 否则 `crm_members` 根本映射不到字段。
1083
+ ⇒ 看到 `conditional: true` **照常填**,填上触发字段表单里就显示了。
1084
+ 3. **同一条流程上两者可能都齐全,也可能只占一半**:
1085
+ - 「会议申请流程」`1326190634427154474`:**同时有**「参会客户」(`1329100543558172681`)与「参会客户明细」;
1086
+ - 「会议申请流程(NEW)」`1325677244111462606`:有「参会客户」(`1326141435517583562`)/「应到客户数」,**没有**明细表。
1087
+ ⇒ 落到没有该字段的流程时,`prepare` 的 `unmapped` 会提示(`crm_member_count` 属自动派生,已静默忽略),
1088
+ 如实告知用户即可。
1089
+
1090
+ **真机落库证据(2026-10-31,requestId `1332389461976473600`)**:单据详情 `workflow.detail` 回读 —— 姓名「张三」/
1091
+ 性别「男」/ 职位「采购经理」/ 手机号码「13800000000」/ 备注「主谈」全部落库,`参会客户` = 「深圳市腾讯斐泰科技有限公司」。
1092
+
1093
+ **⛔ 参会客户只给 id 会被静默存空**:客户浏览按钮按**名称**落 `dataOptions.content`,`[{id:"…",name:""}]`
1094
+ 提交后单据里是空值、**不报错**。CLI 现在抛 `crm_name_required` 拦住,必须传 `[{id,name}]` 或 `客户名(客户id)`。
@@ -40,7 +40,29 @@ weaver-work-cli --json meeting run meeting.invitation.render --input-json \
40
40
 
41
41
  ## 出参
42
42
 
43
- `filePath` / `fileName` / `bytes` / `meetingId` / `meetingName` / `filledFields[]` / `pendingFields[]` / **`dataSource`**,以及 `warnings`(有待补充字段时会列出)。
43
+ `text` / `filePath` / `fileName` / `bytes` / `meetingId` / `meetingName` / `filledFields[]` / `pendingFields[]` / **`dataSource`**,以及 `warnings`(有待补充字段时会列出)。
44
+
45
+ ### `text`:对话内直接展示的正文(2.42.0 起)
46
+
47
+ **这是给"在对话里看"用的**,与 docx 同源同字段(走同一个占位符解析器和同一份议程行),
48
+ 只是换成 Markdown:标题 / 称呼 / 邀请语 / 会议要素 / 议程表 / 落款 / 备注。
49
+
50
+ ```
51
+ # 邀请函
52
+
53
+ **尊敬的 某某集团:**
54
+
55
+ 王丹丹 诚邀您参加「灰度测试对业务的好处沟通会」,现将会议安排通知如下:
56
+
57
+ - **会议名称**:…
58
+ - **会议时间**:2026-11-01 14:00~15:00
59
+ …
60
+ | 议程安排 | 议程内容 | 议程时间 |
61
+ ```
62
+
63
+ ⛔ 用户要的是**在对话里看到邀请函内容**(2026-10-31 明确纠正:"不是发文件,是直接在智能体对话中来展示的")。
64
+ 所以回复必须把 `text` 全文贴出来,`filePath` 只是附带的"可下载打印"说明。
65
+ ⛔ 别把 `text` 包进代码块(会变成一段代码,不像邀请函),也别只贴前几行。
44
66
 
45
67
  | `dataSource` | 含义 |
46
68
  | --- | --- |
@@ -54,6 +76,8 @@ weaver-work-cli --json meeting run meeting.invitation.render --input-json \
54
76
  | `agendaSource` | `meeting.topic`=按会议议题自动填 / `extra`=调用方传入 / `template`=**没有议题,保留模板示例行** |
55
77
  | `agendaRows` | 实际写入议程表的行数(`template` 时为 0) |
56
78
  | `agendaTableFilled` | 是否真的重建了议程表 |
79
+ | `detailSupplemented` | 用 `meeting.eb.meeting.detail` 补回来的字段名(list 单查会丢「参会人员」,见「注意事项」) |
80
+ | `callerSource` | `meeting.caller` / `meeting.mt_creator` / `session.user`(发起人本人兜底) / `none` |
57
81
 
58
82
  > ⚠️ `agendaSource=template` 时会同时给一条 `warnings`:议程表里还是模板的示例行
59
83
  > (“15分钟/泛微公司介绍”),提醒人工改成真实议程 —— 客户看到的邀请函不该印着别人的议程。
@@ -132,8 +156,16 @@ weaver-work-cli --json meeting run meeting.invitation.render --input-json '{"mtI
132
156
 
133
157
  ## 注意事项
134
158
 
135
- - **不要用 `meeting.eb.meeting.detail` 取数据**:该接口**在部分环境只返回 `{id}`**(部分环境),取不到字段;
136
- 邀请函统一走 `meeting.eb.meeting.list` 单查。⚠️ 但另一类环境(部分环境)detail 会返回完整 51 个字段 ——
137
- 所以**不能一概而论,跨环境稳妥做法仍是 list 单查**。
138
- - 生成后如需把文件发给对方,**本 operation 不提供发送能力**(IM/邮件都不走这里),由使用者自行处理。
159
+ - **数据源:list 单查为主,detail 只用来「补空」**(2.42.0 起):
160
+ `meeting.eb.meeting.list` 单查在真机上会丢字段(2026-10-31 实测同一会议
161
+ `hrm_members` 在 list 里是空串、在 detail 里是「王丹丹」),所以 CLI 会用
162
+ `meeting.eb.meeting.detail` 补 **list 里为空的**白名单字段(`hrm_members`/`mt_desc`/`caller`/
163
+ `contacter`/时间/`total_member` 等),补回来的字段名列在出参 `detailSupplemented` 里。
164
+ ⛔ **`address` 不从 detail 补** —— detail 的 `address` 是会议室 **id**,写进邀请函比空着更糟。
165
+ 白名单外的新字段仍走 `{dataKey}` 兜底,跨环境语义不变。
166
+ - **召集人兜底顺序**:`meeting.caller`(会议自己填的)→ `meeting.mt_creator`(创建人)→
167
+ `session.user`(**发起人本人**,2.42.0 起)。看 `callerSource` 判断用的哪一个;
168
+ 以前会议没填 caller 就直接【待补充】,邀请函开头那句「XXX 诚邀您参加」整句是空的。
169
+ - 生成后如需把文件发给对方,**本 operation 不提供发送能力**(IM/邮件都不走这里),由使用者自行处理;
170
+ 对话里展示走 `text` 字段(见「出参」)。
139
171
  - 模板出错时会在本地抛 `template_missing`,提示 CLI 包缺少 `templates/meeting/invitation.docx`;此时重装 CLI 即可,不要手工改模板路径。
Binary file
@@ -573,7 +573,7 @@
573
573
  }
574
574
  },
575
575
  "artifactBaseline": {
576
- "aggregateSha256": "85e2d5c138f4a2c399e9a6aece690be88c53801e269504c63236292e61ea51b1",
576
+ "aggregateSha256": "bae91aefcc30c01410c2288ae7b31fee438a77bdd50f5df894e7f10e249b6b5c",
577
577
  "files": [
578
578
  {
579
579
  "path": "src/shortcuts/okr/errors.ts",
@@ -587,8 +587,8 @@
587
587
  },
588
588
  {
589
589
  "path": "src/shortcuts/okr/host.ts",
590
- "size": 8002,
591
- "sha256": "b2d225d0061093e4a82c3e5bbcbf14f7994e605e55177d6914185f81b99d7c92"
590
+ "size": 8072,
591
+ "sha256": "dd2a4a5773cd440e5f6136b7c106cf19f2dc26251d03ffb1d17983b921f27ae7"
592
592
  },
593
593
  {
594
594
  "path": "src/shortcuts/okr/index.ts",
@@ -53,7 +53,7 @@ XiaoE 环境有两种识别入口:桌面客户端由 Agent 根据宿主或任
53
53
  - 工作目录名含 `xiaoeUserData`、使用 XiaoE 内置 Node.js,或已安装相关 CLI;
54
54
  - 过去在同一台机器上登录或安装过 XiaoE。
55
55
 
56
- 桌面客户端首次没有本地会话时,Agent 判定为 XiaoE 后显式执行 `weaver-work-cli auth xiaoe`;后续业务命令只有需要 XiaoE 专属业务行为时才在 `weaver-work-cli` 之后加 `--runtime-agent xiaoe`,例如 `weaver-work-cli --runtime-agent xiaoe workflow ...`。已保存的 XiaoE 会话过期恢复不依赖这个参数,也不依赖 Skill 或 Agent:CLI 会根据会话内的 `agentType` / `loginSource` 在公共请求层自行处理。`--runtime-agent` 不携带、不选择凭据。
56
+ 桌面客户端首次没有本地会话时,Agent 判定为 XiaoE 后可显式执行 `weaver-work-cli auth xiaoe`,或通过 `--runtime-agent xiaoe` 标识宿主,让业务命令在加载会话时自动获取登录信息,例如 `weaver-work-cli --runtime-agent xiaoe workflow ...`;网页端已有 `XIAOE_*` 标记时自动识别。已保存的 XiaoE 会话过期恢复不依赖这个参数,也不依赖 Skill 或 Agent:CLI 会根据会话内的 `agentType` / `loginSource` 在公共请求层自行处理。`--runtime-agent` 表示运行时身份,不携带凭据。
57
57
 
58
58
  WorkBuddy、Codex 及其他智能体一律使用 `weaver-work-cli auth login --base-url "<用户确认的登录域名>" --agent_type "<当前智能体名称>"` 走浏览器 OAuth。`auth login` / `auth oidc` 不会读取或消费 XiaoE 凭据。
59
59
 
@@ -67,9 +67,9 @@ Token、Cookie、ETEAMSID 和业务凭证**只能由 `weaver-work-cli` 内部读
67
67
 
68
68
  下述 `auth xiaoe` 流程仅适用于上述已确认的 XiaoE 智能体环境;其他智能体不执行宿主脚本检测,直接进入浏览器 OAuth 流程。`auth xiaoe` 命令本身就是认证方式的显式选择;`hasXiaoEEnv` 使用桌面的 `--runtime-agent xiaoe` 或任意 `XIAOE_*` 环境变量识别运行环境。
69
69
 
70
- 首次缺少本地会话时只运行 `weaver-work-cli auth xiaoe`。CLI 内部按「平台凭证 Node 换票 → CLI 自带 `xiaoe_env.py` 兼容换票 → 宿主 `tokens.py` → 桌面 XiaoE 客户端会话 → `WEAVER_XIAOE_*` 环境映射」顺序取凭据;其中 `XIAOE_DOMAIN` 是 XiaoE/erpa 换票服务地址,不是 E10 地址。`xiaoe_env.py` 属于 CLI npm 包,不放入 shared Skill,且只能由 CLI 内部执行和解析。已有 XiaoE 会话被接口明确拒绝为失效时,CLI 根据会话元数据在公共请求层静默恢复并重放一次;这个流程绕开 shared Skill,Agent 不参与,也不得再补跑登录或原业务命令。失败时 CLI 返回最终结构化错误。
70
+ 首次缺少本地会话时,已识别为 XiaoE 的业务命令会在 CLI 公共会话加载层自动获取登录信息;如需提前登录,只运行 `weaver-work-cli auth xiaoe`。CLI 内部按「平台凭证 Node 换票 → CLI 自带 `xiaoe_env.py` 兼容换票 → 宿主 `tokens.py` → 桌面 XiaoE 客户端会话 → `WEAVER_XIAOE_*` 环境映射」顺序取凭据;其中 `XIAOE_DOMAIN` 是 XiaoE/erpa 换票服务地址,不是 E10 地址。`xiaoe_env.py` 属于 CLI npm 包,不放入 shared Skill,且只能由 CLI 内部执行和解析。已有 XiaoE 会话被接口明确拒绝为失效时,CLI 根据会话元数据在公共请求层静默恢复并重放一次;这个流程绕开 shared Skill,Agent 不参与,也不得再补跑登录或原业务命令。失败时 CLI 返回最终结构化错误。
71
71
 
72
- 1. 首次无本地登录态、准备执行业务命令前需要建立 E10 会话,或 `auth status --no-check` 显示未登录时,运行:
72
+ 1. 首次无本地登录态、需要在业务命令之前显式建立 E10 会话时,可运行:
73
73
  ```text
74
74
  weaver-work-cli auth xiaoe
75
75
  ```
@@ -77,7 +77,7 @@ Token、Cookie、ETEAMSID 和业务凭证**只能由 `weaver-work-cli` 内部读
77
77
  3. XiaoE 统一登录由 CLI 按序取凭证:① 平台注入的 `XIAOE_USER_TOKEN` + `XIAOE_DOMAIN`,先走 Node 换票,再由 CLI npm 包自带的标准库 `xiaoe_env.py` 作兼容回退;② 宿主 `xiaoeUserData/tokens.py`(仅桌面宿主,CLI 在 macOS/Windows 都会先自动发现 XiaoE 客户端内置 Python,再回退到系统 Python);③ 内置原生实现读取桌面 XiaoE 客户端会话换取 `eteamId`,依次查找 `XIAOE_USER_SETTINGS_PATH`、`XIAOE_ROBOT_DATA_ROOT` / `XIAOE_ROBOT_ROOT` 和默认 `XiaoE/Robots/<id>/user_settings.json`,因此会话有效时不要求存在 `tokens.py`;④ `WEAVER_XIAOE_*` 环境映射。宿主只注入 `XIAOE_DOMAIN`、`XIAOE_USER_TOKEN` 等平台变量,不会注入 ETEAMSID 环境变量,CLI 也不读取 `XIAOE_ETEAMSID`。Agent 不要打印、转述、索取或要求用户手动设置这些凭证,也不要直接执行任一脚本或因为脚本报缺依赖就让用户安装 Python 包——凭据链内部的兼容回退由 CLI 完成。
78
78
  4. `auth xiaoe` 是 XiaoE 认证方式的显式入口:CLI 不再判断当前宿主,只检查并消费可用凭据源。E10 目标地址按「显式 `--base-url` → 专用 `WEAVER_XIAOE_*` E10 配置/映射 → 当前 profile → CLI 内置默认值」解析,绝不能把 `XIAOE_DOMAIN` 当作 E10 地址。Token、Cookie、ETEAMSID 仍属于凭证,禁止在回复中展示。
79
79
  5. XiaoE 统一登录走不通时,无论 macOS、Windows、Linux 或 Web,CLI 都返回 `authentication/xiaoe_credential_unavailable`,绝不自动打开浏览器或降级到 `auth login`;本任务必须停止,不得另行调用其他登录 Skill 或登录命令。
80
- 6. `auth status --no-check` 不会触发 XiaoE 统一登录;业务命令加载到 `agentType=XiaoE` 或 `loginSource=xiaoe-unified` 的会话并被 E10 明确拒绝为失效时,即使没有 `XIAOE_*` 或 `--runtime-agent xiaoe`,也会静默触发一次统一登录并重放该请求一次。首次无本地会话仍须显式执行 `auth xiaoe`;具体读取 [`e10-auth-and-session.md`](references/e10-auth-and-session.md)。
80
+ 6. `auth status --no-check` 不会触发 XiaoE 统一登录;业务命令加载到 `agentType=XiaoE` 或 `loginSource=xiaoe-unified` 的会话并被 E10 明确拒绝为失效时,即使没有 `XIAOE_*` 或 `--runtime-agent xiaoe`,也会静默触发一次统一登录并重放该请求一次。无可读取的本地会话时,则需要当前 `XIAOE_*` 或 `--runtime-agent xiaoe` 等宿主标记才能自动获取;显式 `--auth` 不触发自动替换。具体读取 [`e10-auth-and-session.md`](references/e10-auth-and-session.md)。
81
81
 
82
82
  ### 认证错误只报告状态,不指定登录命令
83
83
 
@@ -202,4 +202,4 @@ User-Agent: AgentType=<agentType>,IsAgent=true
202
202
 
203
203
  7. 附件、图片上传或文件解析属于敏感数据处理。即便 operation 风险等级不是高风险写入,也必须先取得用户对“文件内容可能进入大模型/外部解析服务”的明确确认;不能把用户仅提供文件路径或文件名视为同意解析或上传。
204
204
 
205
- 8. Agent 明确选择 `auth xiaoe` 后,CLI 按顺序从平台注入凭证(Node 换票后由 CLI npm 包自带 `xiaoe_env.py` 兼容回退)、宿主 `xiaoeUserData/tokens.py`、内置原生实现读取的桌面 XiaoE 客户端会话(宿主注入路径优先、默认 `XiaoE/Robots/<id>/user_settings.json` 回退)、`WEAVER_XIAOE_*` 环境映射读取支持统一登录的凭证。业务命令不会在首次无会话时自动登录,但已有会话被接口明确拒绝时会根据持久化会话的 `agentType` / `loginSource` 静默恢复 1 次,不要求 Agent 添加 `--runtime-agent xiaoe`;该参数仅用于其他 XiaoE 专属业务行为。不要要求用户提供、展示或手动设置这些凭证。任意系统失败时都反馈结构化错误,不自动降级浏览器。
205
+ 8. Agent 明确选择 `auth xiaoe` 后,或业务命令在已识别的 XiaoE 运行时发现本地会话缺失时,CLI 按顺序从平台注入凭证(Node 换票后由 CLI npm 包自带 `xiaoe_env.py` 兼容回退)、宿主 `xiaoeUserData/tokens.py`、内置原生实现读取的桌面 XiaoE 客户端会话(宿主注入路径优先、默认 `XiaoE/Robots/<id>/user_settings.json` 回退)、`WEAVER_XIAOE_*` 环境映射读取支持统一登录的凭证。已有会话被接口明确拒绝时会根据持久化会话的 `agentType` / `loginSource` 静默恢复 1 次,不要求 Agent 添加 `--runtime-agent xiaoe`。不要要求用户提供、展示或手动设置这些凭证。任意系统失败时都反馈结构化错误,不自动降级浏览器。
@@ -29,7 +29,7 @@ weaver-work-cli auth whoami
29
29
  - 业务命令失败,stderr JSON 中 `error.type === "authentication"`(如 `E10 auth not found`)
30
30
  - 业务命令返回 `error.subtype === "session_expired"`(E10 登录态 401/302 失效)
31
31
 
32
- CLI 的认证错误只是状态信号,不是登录命令。已有 XiaoE 会话过期时,公共请求层会根据持久化会话的 `agentType` / `loginSource` 自动恢复,不依赖 `XIAOE_*`、`--runtime-agent xiaoe`、shared Skill 或 Agent。仅首次无会话、`auth not found` 等认证缺失才进入下述显式登录流程。
32
+ CLI 的认证错误只是状态信号,不是登录命令。已有 XiaoE 会话过期时,公共请求层会根据持久化会话的 `agentType` / `loginSource` 自动恢复,不依赖 `XIAOE_*`、`--runtime-agent xiaoe`、shared Skill 或 Agent。业务命令无可读取的本地会话时,若当前 `XIAOE_*`、`--runtime-agent xiaoe` 等标记已识别为 XiaoE,公共会话加载层也会先静默获取登录信息。失败时返回 `xiaoe_credential_unavailable`,提示已尝试自动获取,Agent 只反馈并停止;不要再次登录或重跑。需要在业务命令之前主动建立会话时,可按下述流程显式登录。
33
33
 
34
34
  此时**禁止**:
35
35
 
@@ -40,12 +40,12 @@ CLI 的认证错误只是状态信号,不是登录命令。已有 XiaoE 会话
40
40
 
41
41
  **正确流程(按序执行,缺一不可):**
42
42
 
43
- 0. **仅首次无本地会话时,由 XiaoE 智能体环境主动选择统一登录**:桌面端宿主/任务上下文明确标识为 XiaoE,或网页端命中原有环境变量判断时,才运行:
43
+ 0. **首次无本地会话且需要提前登录时,由 XiaoE 智能体环境显式选择统一登录**:桌面端宿主/任务上下文明确标识为 XiaoE,或网页端命中原有环境变量判断时,才运行:
44
44
  ```text
45
45
  weaver-work-cli auth xiaoe
46
46
  ```
47
47
  本机存在 `xiaoeUserData/tokens.py`、XiaoE 客户端目录、工作目录或历史登录,都不能作为宿主身份依据。桌面客户端可由 `--runtime-agent xiaoe` 标识;命令进程中存在任意 `XIAOE_*` 变量时也直接标识为 XiaoE。未命中这两类判断的 WorkBuddy、Codex 及其他智能体必须跳过此步,进入下方浏览器 OAuth 流程。
48
- CLI 会按“显式 `--base-url` → 专用 `WEAVER_XIAOE_*` E10 配置/映射 → 当前 profile `config.baseUrl` → CLI 内置默认值”解析 E10 登录域名;`XIAOE_DOMAIN` 只作为 XiaoE/erpa 换票服务地址。业务命令不会在缺少本地会话时主动登录;已有会话被接口明确拒绝为失效时,公共请求层根据会话内 `agentType=XiaoE` 或 `loginSource=xiaoe-unified` 静默恢复并重放一次,不要求 Agent 添加 `--runtime-agent xiaoe`。恢复失败或重放后仍失效时,Agent 只反馈最终错误并停止,不再运行登录或业务命令。
48
+ CLI 会按“显式 `--base-url` → 专用 `WEAVER_XIAOE_*` E10 配置/映射 → 当前 profile `config.baseUrl` → CLI 内置默认值”解析 E10 登录域名;`XIAOE_DOMAIN` 只作为 XiaoE/erpa 换票服务地址。已识别为 XiaoE 的业务命令缺少本地会话时会静默尝试统一登录;已有会话被接口明确拒绝为失效时,公共请求层根据会话内 `agentType=XiaoE` 或 `loginSource=xiaoe-unified` 静默恢复并重放一次,不要求 Agent 添加 `--runtime-agent xiaoe`。恢复失败或重放后仍失效时,Agent 只反馈最终错误并停止,不再运行登录或业务命令。
49
49
 
50
50
  1. **仅非 XiaoE 环境进入本步**。禁止先执行 `auth xiaoe` 或调用其他登录 Skill。先调用宿主提供的提问 / 弹框能力询问用户,让用户二选一:
51
51
  - 输入本次要登录的 E10 登录域名(base URL),形如 `https://<企业域名>`;或
@@ -3,9 +3,9 @@ name: weaver-e10-wenshuding
3
3
  display_name: 泛微E10文书定档案管理
4
4
  display_name_en: Weaver E10 Wenshuding
5
5
  description: "泛微 E10 文书定档案管理:全宗与预归档库、全文检索、档案基本信息、借阅车、借阅单、原文下载、发起借阅/续借流程页与预归档上传确认链。"
6
- description_zh: "泛微 E10 文书定档案管理。支持查询全宗与预归档电子文件库、全文检索可借档案、查看档案基本信息、查看借阅车并直接加入档案(免确认写操作)、查看借阅单与详情、下载借阅单原文 zip,并通过 prepare/apply 确认链处理发起借阅、续借和预归档上传。全宗信息仅在预归档上传时需要查询;借阅相关流程页面默认用系统默认浏览器打开。全文检索结果的默认返回显示样式为三段式卡片视图(标题可点击、命中词高亮、全宗/分类/日期摘要行)。"
6
+ description_zh: "泛微 E10 文书定档案管理。支持查询全宗与预归档电子文件库、全文检索可借档案、查看档案基本信息、查看借阅车并直接加入档案(免确认写操作)、查看借阅单与详情、下载借阅单原文 zip,并通过 prepare/apply 确认链处理发起借阅、续借和预归档上传。全宗信息仅在预归档上传时需要查询;借阅/续借流程页只生成 Markdown 超链接(a 标签)返回,不自动打开浏览器,由客户端决定打开方式。全文检索结果的默认返回显示样式为三段式卡片视图(标题可点击、命中词高亮、全宗/分类/日期摘要行)。"
7
7
  description_en: "Weaver E10 Wenshuding archive skill for fonds and pre-archive libraries, full-text search, archive info, borrow car, borrow orders, original file packaging and download, borrow/renew workflow URL generation, and confirmed pre-archive upload."
8
- version: 1.0.4
8
+ version: 1.0.5
9
9
  author: 泛微网络科技股份有限公司
10
10
  agent_created: true
11
11
  requires:
@@ -24,7 +24,21 @@ cliHelp: "weaver-work-cli archive --help"
24
24
 
25
25
  本 Skill 是 CLI 型技能,不自行发起 HTTP 请求:认证与会话**统一由 `weaver-e10-shared` 共享规则和 `weaver-work-cli auth ...` 命令体系托管**,禁止自建或绕过登录流程。
26
26
 
27
- 请求头三件套(Cookie 完整原始串 / `eteamsid` / `User-Agent`)由 `weaver-work-cli` 统一注入,唯一权威声明见 [`../weaver-e10-shared/SKILL.md`](../weaver-e10-shared/SKILL.md) 的「请求头契约」章节。
27
+ 接口请求头(由 CLI 注入,Agent 不手写):
28
+
29
+ ```text
30
+ Cookie: <登录返回的完整原始 Cookie 串> # 禁止裁剪、去重或改写
31
+ eteamsid: <登录返回的 ETEAMSID>
32
+ User-Agent: AgentType=<agentType>,IsAgent=true
33
+ ```
34
+
35
+ | 凭证 | 取值与要求 |
36
+ | --- | --- |
37
+ | `Cookie` | 登录返回的**完整原始 Cookie 串**,禁止裁剪、去重或改写 |
38
+ | `eteamsid` | 登录返回的 `ETEAMSID` |
39
+ | `User-Agent` | `AgentType=<agentType>,IsAgent=true` |
40
+
41
+ 完整权威说明见 [`../weaver-e10-shared/SKILL.md`](../weaver-e10-shared/SKILL.md) 的「请求头契约」章节。
28
42
 
29
43
  Agent 不得自行拼接、改写或向用户索取上述凭证(禁止要求用户贴 Cookie / ETEAMSID / token),也不得直接 `curl` / `fetch` E10 接口。
30
44
  所有命令通过 `weaver-work-cli --json archive run <operation>` 执行:简单 JSON 优先传 `--input-json '<json>'`,复杂或多行 JSON 先写入 UTF-8 文件再传 `--input <path>`,只有确认当前 shell 能稳定传管道时才使用 `--input -`。调用前先按需读取 references 下对应的文件,查参数结构,不要猜字段;**references 是第一信息源**,`weaver-work-cli archive schema` 是 operation、字段和风险等级的合约来源。
@@ -41,7 +55,7 @@ Agent 不得自行拼接、改写或向用户索取上述凭证(禁止要求
41
55
 
42
56
  出现以下任一语义时,优先走本 Skill:
43
57
 
44
- - 文书定 / 档案 / 全宗 / 收集库 / 管理库 / 预归档库 / 电子文件库
58
+ - 文书定 / 档案 / 全宗 / 收集库 / 管理库 / 预归档库 / 电子文件库 / 我上传的档案 / 我上传的档案文件
45
59
  - 档案检索 / 全文检索 / 可借档案 / 档号 / 案卷 / 保管期限 / 密级 / 库位
46
60
  - 借阅车 / 加入借阅车 / 我的借阅车
47
61
  - 借阅单 / 我的借阅 / 借阅记录 / 续借 / 归还期限
@@ -57,6 +71,11 @@ Agent 不得自行拼接、改写或向用户索取上述凭证(禁止要求
57
71
  |---|---|---|
58
72
  | 查看可用 operation、字段和风险等级 | `archive schema` | [`archive-agent-entry.md`](references/archive-agent-entry.md) |
59
73
  | 查询全宗 / 预归档电子文件库节点 | `archive run archive.fonds.list` / `archive.prelib.tree` | [`archive-fonds.md`](references/archive-fonds.md) |
74
+ | 查看电子文件库列表(预归档库内的数据) | `archive run archive.prelib.list` | [`archive-prelib-list.md`](references/archive-prelib-list.md) |
75
+ | 查看我的档案 / 我上传的档案(默认我上传的电子文件库) | `archive run archive.prelib.list` | [`archive-prelib-list.md`](references/archive-prelib-list.md) |
76
+ | 对电子文件库数据做智能识别 | `archive run archive.prelib.intelligent.prepare` -> 用户确认 -> `.apply` | [`archive-prelib-list.md`](references/archive-prelib-list.md) |
77
+ | 提交整理(预归档数据整理提交) | `archive run archive.prelib.arrange.prepare` -> 用户确认 -> `.apply` | [`archive-prelib-arrange.md`](references/archive-prelib-arrange.md) |
78
+ | 打开某条预归档档案(生成链接) | `archive run archive.prelib.open` | [`archive-prelib-open.md`](references/archive-prelib-open.md) |
60
79
  | 全文检索可借档案(默认卡片视图展示) | `archive run archive.search.run` | [`archive-search.md`](references/archive-search.md) |
61
80
  | 查看档案基本信息 | `archive run archive.info.get` | [`archive-info.md`](references/archive-info.md) |
62
81
  | 查看借阅车 | `archive run archive.borrow-car.list` | [`archive-borrow-car.md`](references/archive-borrow-car.md) |
@@ -72,11 +91,15 @@ Agent 不得自行拼接、改写或向用户索取上述凭证(禁止要求
72
91
  处理链:
73
92
 
74
93
  - 检索并借阅:`archive.search.run` -> 用户选择条目 -> `archive.borrow-car.add`(免确认直接加入)-> 需要时 `archive.borrow-car.list` 复核
75
- - 从借阅车发起借阅:`archive.borrow-car.list` 取 `arcDangan` 与 `dataId` -> `archive.flow.borrow-car.prepare` -> 用户确认 -> `.apply` -> 用系统默认浏览器打开返回的流程创建页 URL(仅用户强调内置打开时用 IDE 内置视图)
94
+ - 从借阅车发起借阅:`archive.borrow-car.list` 取 `arcDangan` 与 `dataId` -> `archive.flow.borrow-car.prepare` -> 用户确认 -> `.apply` -> 把流程创建页 URL 以 Markdown 超链接(a 标签)返回,不自动打开浏览器,由客户端决定打开方式
76
95
  - 从检索结果直接发起借阅:`archive.search.run` 取 `id`+`formId` -> `archive.flow.search.prepare` -> 用户确认 -> `.apply` -> 同上默认系统浏览器打开 URL
77
96
  - 续借:`archive.borrow-list.list` 取 `dataId` -> `archive.flow.renew.prepare` -> 用户确认 -> `.apply` -> 同上默认系统浏览器打开 URL
78
97
  - 下载原文:`archive.borrow-list.list` 取 `dataId` -> `archive.borrow-list.download.prepare`(校验未超期且有可下载原文)-> 用户确认 -> `.apply`(轮询打包并落盘)
79
- - 预归档上传:`archive.fonds.list` 取全宗 `id` -> 需要时 `archive.prelib.tree` 取 `treeId` -> `archive.upload.prelib.prepare` -> 用户确认 -> `.apply`
98
+ - 查看我的档案 / 我上传的档案:`archive.prelib.list`(默认即"我上传的电子文件库"数据,不传 treeId 自动取电子文件库节点)
99
+ - 提交整理:`archive.prelib.list` 取行 id -> `archive.prelib.arrange.prepare` -> 用户确认 -> `.apply`(只处理识别成功的数据,必须原样转达服务端 message,见 [`archive-prelib-arrange.md`](references/archive-prelib-arrange.md))
100
+ - 打开档案链接:`archive.prelib.list` 取行 id -> `archive.prelib.open` 生成 `/sp/custom/archive/fileLibEdit?singleMetaId=行id&treeId=节点treeId`(见 [`archive-prelib-open.md`](references/archive-prelib-open.md))
101
+ - 预归档上传:`archive.fonds.list` 取全宗 `id`(**名称字段是 `fonds_name`,不是 `name`/`content`**)-> 需要时 `archive.prelib.tree` 取 `treeId` -> `archive.upload.prelib.prepare` -> `.apply`(用户已给出文件 + 明确全宗即视为已确认,直接上传;全宗未定、有歧义或多节点未指定时必须先问,详见 [`archive-upload.md`](references/archive-upload.md))
102
+ - 查看并识别电子文件库数据:`archive.prelib.list`(取列表与行 `id`)-> 用户勾选 -> `archive.prelib.intelligent.prepare` -> 用户确认 -> `.apply` -> 返回识别任务 `taskId`(异步,不要声称识别完成)
80
103
 
81
104
  ## 执行原则(减少误路由、误重试和无效消耗)
82
105
 
@@ -39,6 +39,20 @@ weaver-work-cli --json archive run archive.borrow-list.detail --input-json '{"da
39
39
  - 表格样式:所有列(表头与内容)居中显示。
40
40
  - 无值列留空或用 `-`;题名过长时截断。
41
41
 
42
+ ## 详情展示(档案题名必须可点击)
43
+
44
+ `archive.borrow-list.detail` 返回的 `details[].arcDangan[]` 每项都带 `name`、`viewPath`、`url`(已拼好环境域名)。
45
+
46
+ 展示借阅明细时,**"档案"列用题名做超链接**(Markdown `[题名](url)`,渲染即 `<a>`),点击在系统里打开该档案:
47
+
48
+ | 档案 | 档号 | 文件日期 | 借阅方式 |
49
+ | :---: | :---: | :---: | :---: |
50
+ | [发文](http://host/sp/custom/archive/archiveView?arcId=...&arcFormId=...) | GXDA-XZ·2025-30-8 | 2025-11-03 | 电子查看、下载 |
51
+
52
+ - 优先用 `url`(含域名,可直接点);`url` 为空时用 `viewPath` 自行拼当前环境域名。
53
+ - `id` 形如 `{档案ID}_{表单ID}`,是内部标识,**不要直接展示**,也不要让用户抄。
54
+ - 同一明细有多条档案时,每条都要带链接;无 `url` 时退回纯文本题名,不要拼半个链接。
55
+
42
56
  ## 字段复用
43
57
 
44
58
  - `dataId` 是借阅单主表 ID,用于查看详情、下载和续借。
@@ -43,6 +43,8 @@ weaver-work-cli --json archive run archive.borrow-list.download.apply --input-js
43
43
  ## 注意
44
44
 
45
45
  - 下载是异步任务,`.apply` 可能持续一段时间;进度只在终端以进度条形式反馈,Agent 不要因为等待就中断并重试。
46
+ - 文件下载接口可能返回 **302 重定向**(跳到文件服务/CDN)。CLI 已对下载请求开启跟随重定向,**不会再把这种 302 误判为登录失效**;若仍报 `session_expired`,才是真的需要重新登录。
47
+ - 提交打包任务与下载是两个阶段:`batchDownloadBorrowZip`(提交)→ 轮询进度 → `file/remotedownload`(取文件)。若提交和轮询都成功、只有最后一步失败,说明是下载环节问题,不要把整个任务重复提交。
46
48
  - 打包完成前中断会浪费一次服务端任务;中断后如需继续,重新执行 `.prepare` 再 `.apply`。
47
49
  - 涉及本地文件写入:下载到的 zip 可能包含敏感档案内容,**必须先提醒用户文件内容会落到本地磁盘并可能进入当前大模型上下文,等待用户明确确认后才执行 `.apply`**。
48
50
  - `exportType=0`(直接导出)时其余三个分组字段必须为空;`exportType=1` 时按结构补齐分组字段,字段取值只能取档案基础字段候选。
@@ -41,6 +41,6 @@ weaver-work-cli --json archive run archive.flow.renew.prepare --input-json '{"da
41
41
  ## 注意
42
42
 
43
43
  - `.prepare` 会检查是否绑定借阅流程;未绑定时返回 `validation/borrow_flow_unbound`,应提示联系管理员在档案设置中绑定借阅流程,不要重试。
44
- - `.apply` 返回的是**流程创建页 URL**,CLI 不自动打开浏览器。Agent 拿到 URL 后**默认用系统默认浏览器打开**供用户填写提交(macOS `open`,Windows `start`),除非用户明确要求“在 IDE 内置浏览器打开”;不要声称“已发起借阅申请”。
44
+ - `.apply` 返回的是**流程创建页 URL**,CLI 不自动打开浏览器,**Agent 也不要自动打开**(不要执行 `open` / `start`)。把 URL 作为 **Markdown 超链接**返回,例如 `[填写并提交](URL)`(渲染即 `<a>` 标签),由客户端/用户自行决定打开方式(内置浏览器、系统浏览器或复制链接)。不要声称“已发起借阅申请”。
45
45
  - 从借阅车发起会缓存档案与借阅车两组参数(两次缓存写入),从检索结果发起只缓存档案,续借不缓存。
46
46
  - URL 中的缓存参数由服务端生成,Agent 不要手工拼接或改写 URL。
@@ -0,0 +1,76 @@
1
+ # 提交整理(预归档电子文件库)
2
+
3
+ ## 什么时候读取
4
+
5
+ 用户要对电子文件库里的数据做「提交整理 / 整理 / 归档整理」时读取本文件。写操作前也读取共享高风险协议:`../../weaver-e10-shared/references/high-risk-write.md`。
6
+
7
+ ## 链路
8
+
9
+ `archive.prelib.list` 取列表 -> 用户给序号 -> 取 `rows[序号-1].id` -> 提交整理。
10
+
11
+ | 阶段 | Operation | 必填输入 |
12
+ | --- | --- | --- |
13
+ | 准备 | `archive.prelib.arrange.prepare` | `checkIds`;可选 `treeId`、`formId` |
14
+ | 提交 | `archive.prelib.arrange.apply` | `continuation`、`confirm=true` |
15
+
16
+ Windows PowerShell:
17
+
18
+ ```powershell
19
+ weaver-work-cli --json archive run archive.prelib.arrange.prepare --input-json '{"checkIds":["1313909785262178418"]}'
20
+
21
+ weaver-work-cli --json archive run archive.prelib.arrange.apply --input-json '{"continuation":"PREPARE_CONTINUATION","confirm":true}'
22
+ ```
23
+
24
+ macOS/Linux(bash/zsh):
25
+
26
+ ```bash
27
+ weaver-work-cli --json archive run archive.prelib.arrange.prepare --input-json '{"checkIds":["1313909785262178418"]}'
28
+
29
+ weaver-work-cli --json archive run archive.prelib.arrange.apply --input-json '{"continuation":"PREPARE_CONTINUATION","confirm":true}'
30
+ ```
31
+
32
+ ## 前置参数
33
+
34
+ - `checkIds` 取 `archive.prelib.list` 返回 `rows[n].id`(该列 `hide=true` 不展示),**按用户给的序号取,不要让用户抄 id**。
35
+ - `treeId` 取 `archive.prelib.tree` 的电子文件库节点 `id`;不传时自动取第一个节点。
36
+ - `formId` 不传时取 `getTreeDetail` 的 `extraParams.metaFormId`。
37
+
38
+ ## 接口
39
+
40
+ `POST /api/archive/core/prefileBatch/batchSave`(无 query 参数)
41
+
42
+ ```json
43
+ {
44
+ "treeId": "1229705529974292495_1229705529974292495",
45
+ "autoBatchProduct": true,
46
+ "formId": "1042286248190812199",
47
+ "checkIds": "1330598993225465906",
48
+ "logFlag": "preLib"
49
+ }
50
+ ```
51
+
52
+ 与智能识别 `intelligentCate` **完全同参**,只多一个 `autoBatchProduct: true`。
53
+
54
+ ## 提交前:只有「已识别」的数据会被处理
55
+
56
+ - 提交整理**只处理识别状态为「已识别」**的数据;**未识别、识别中、识别异常**的行会被服务端**自动过滤掉**。
57
+ - 所以提交前先看列表的 `read_state`:若不是"已识别",**先提示用户**——这些行提交了也不会被处理,建议先做智能识别并确认识别成功(可再查一次列表确认状态变为"已识别")。
58
+ - 用户仍要提交也可以提交:**后台会过滤,不会报错**,但必须如实转达服务端 `message`,并说明实际处理了 0 条。
59
+
60
+ ## 关键:不要声称"整理完成"
61
+
62
+ - 该接口**只处理识别成功的数据**;未识别、识别异常的行会被跳过。
63
+ - 响应**没有 `data`**,处理说明在顶层 `msg`,例如:
64
+
65
+ ```
66
+ 选中1条数据包含1条异常数据,系统仅处理0条识别成功的数据!
67
+ ```
68
+
69
+ - 必须把 `message` **原样转达**给用户,不要说"已整理完成"。
70
+ - 若处理条数为 0(全是未识别/异常),要提示用户先做**智能识别**,识别成功后再提交整理。
71
+
72
+ ## 注意
73
+
74
+ - 提交整理是**写操作**:必须先 `prepare`、用户明确确认后才 `apply`,不要自动补 `confirm=true`。
75
+ - 任一步失败直接报错,不要自动重放 `.apply`。
76
+ - 未拿到 `treeId`(预归档树返回空)时按 [`archive-prelib-list.md`](archive-prelib-list.md) 的"获取不到节点"规则处理:重新获取一次 -> 仍无则判无权限并停止,**不要猜测 treeId**。