weaver-work-cli 0.1.39 → 0.1.40

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 (103) hide show
  1. package/README.md +4 -2
  2. package/dist/chunks/{archive-ENZYBBME.js → archive-JHTONRST.js} +2 -2
  3. package/dist/chunks/{archive-oa-YWLEC5V4.js → archive-oa-FCHLCPHC.js} +2 -2
  4. package/dist/chunks/{asset-OOV6DWPA.js → asset-RLIHC7DB.js} +2 -2
  5. package/dist/chunks/{asset-idle-RE632MY5.js → asset-idle-KVOFTLCP.js} +2 -2
  6. package/dist/chunks/{attachment-content-RWN2FCLL.js → attachment-content-RZYDB3MB.js} +3 -3
  7. package/dist/chunks/{blog-PEPOJAL7.js → blog-42OZTJNP.js} +2 -2
  8. package/dist/chunks/{caizhilian-WYIQDVPJ.js → caizhilian-KRK547K5.js} +2 -2
  9. package/dist/chunks/{calendar-CIARBAOX.js → calendar-RTWAMKHD.js} +2 -2
  10. package/dist/chunks/{chunk-L4N7B7ZD.js → chunk-4CTESSKI.js} +4 -4
  11. package/dist/chunks/{chunk-XXJOSZTQ.js → chunk-4TEDNCON.js} +43 -5
  12. package/dist/chunks/chunk-57IECMWX.js +487 -0
  13. package/dist/chunks/{chunk-CQHGNCK2.js → chunk-7BRU4EFH.js} +13 -7
  14. package/dist/chunks/{chunk-KTCB5R5H.js → chunk-7E6MUOEK.js} +2 -2
  15. package/dist/chunks/{chunk-I2HB737U.js → chunk-7U577Q7U.js} +2 -2
  16. package/dist/chunks/{chunk-BJGXMFGD.js → chunk-CAQNBBQA.js} +2 -2
  17. package/dist/chunks/{chunk-MUQUHKPG.js → chunk-CXRQWOZ5.js} +2 -2
  18. package/dist/chunks/{chunk-T7JDJJ7H.js → chunk-FLS4DPGP.js} +110 -16
  19. package/dist/chunks/{chunk-P2DAISYW.js → chunk-I566ZYNF.js} +1 -1
  20. package/dist/chunks/{chunk-36DIFZAH.js → chunk-IZSSVYAG.js} +2 -2
  21. package/dist/chunks/{chunk-EINRJHQ3.js → chunk-JWRZM2H2.js} +3 -3
  22. package/dist/chunks/{chunk-F2EQXUEE.js → chunk-LFMSDBZN.js} +97 -14
  23. package/dist/chunks/{chunk-GVPJZXJ2.js → chunk-LN447PY2.js} +91 -50
  24. package/dist/chunks/{chunk-K3RUEEOL.js → chunk-NETCCARD.js} +2 -2
  25. package/dist/chunks/{chunk-YS5DPN4T.js → chunk-NJKREDA3.js} +1 -1
  26. package/dist/chunks/{chunk-ZXRNHZTE.js → chunk-SPRHHSVC.js} +2 -2
  27. package/dist/chunks/{chunk-HJYVHXUQ.js → chunk-T6EGVBKU.js} +1 -1
  28. package/dist/chunks/{chunk-NLK2RZKG.js → chunk-VNBU55SL.js} +428 -145
  29. package/dist/chunks/{chunk-EZGFHJFW.js → chunk-WFFNM65B.js} +26 -7
  30. package/dist/chunks/{conflict-DRMDOL56.js → conflict-VR55AOOO.js} +2 -2
  31. package/dist/chunks/{contract-73MERZWN.js → contract-HI4FNPYE.js} +2 -2
  32. package/dist/chunks/{cowork-HNGBPD7A.js → cowork-HJLI353D.js} +12 -5
  33. package/dist/chunks/{ebuilder-form-OY6DVNRK.js → ebuilder-form-HTGI63UU.js} +3 -3
  34. package/dist/chunks/{ehr-RAQNEQO7.js → ehr-GYXIYH3A.js} +2 -2
  35. package/dist/chunks/env-DW3G4HUO.js +19 -0
  36. package/dist/chunks/{esb-6XV7C7YV.js → esb-I5INCEFE.js} +4 -4
  37. package/dist/chunks/factory-TKXGXS6L.js +30 -0
  38. package/dist/chunks/{fna-XTSRB7G7.js → fna-K2MHTQ24.js} +2 -2
  39. package/dist/chunks/group-chat-VYBNMJLG.js +18 -0
  40. package/dist/chunks/{host-VGPVP7YF.js → host-256GVCAH.js} +3 -3
  41. package/dist/chunks/{host-A7J6GDUP.js → host-D5SERMAJ.js} +3 -3
  42. package/dist/chunks/{host-3F5UM5GN.js → host-JM4YVHFM.js} +3 -3
  43. package/dist/chunks/{host-YAQAPYNP.js → host-L3VLITMT.js} +3 -3
  44. package/dist/chunks/{host-YMBXWFWX.js → host-ZUQTJYYK.js} +3 -3
  45. package/dist/chunks/{hrm-TLHKC545.js → hrm-VLRBKTZB.js} +3 -3
  46. package/dist/chunks/{im-YOUCFMUK.js → im-QK3VTLXK.js} +8 -8
  47. package/dist/chunks/{invoice-WNBS2B4C.js → invoice-T5JTA32H.js} +3 -3
  48. package/dist/chunks/{jiuchuanhui-XABWS5RN.js → jiuchuanhui-P2FNEQVZ.js} +2 -2
  49. package/dist/chunks/{lazy-dispatch-NLZ5UQQI.js → lazy-dispatch-XRRI46M6.js} +4 -4
  50. package/dist/chunks/{mail-LRYMBFNL.js → mail-3Y7MJ6PS.js} +9 -4
  51. package/dist/chunks/{meeting-ESXL6MFI.js → meeting-M7LTXGJE.js} +11 -10
  52. package/dist/chunks/{okr-EOV65SSF.js → okr-OBC6S67L.js} +2 -2
  53. package/dist/chunks/{plan-YFPVKW6Y.js → plan-5H6I53SK.js} +2 -2
  54. package/dist/chunks/{project-MDVZUYQW.js → project-L75QZV4S.js} +2 -2
  55. package/dist/chunks/{registry-QCLZEDAP.js → registry-KMHCPAAD.js} +9 -8
  56. package/dist/chunks/{registry-OZSMDVPP.js → registry-QGHFNUWS.js} +2 -2
  57. package/dist/chunks/{registry-VT5Y2HLA.js → registry-RXPN6BBT.js} +4 -4
  58. package/dist/chunks/{registry-YX4CSEMD.js → registry-UGRBCBHO.js} +2 -2
  59. package/dist/chunks/{room-recommend-L3MWH4JW.js → room-recommend-A3UDC3CA.js} +4 -4
  60. package/dist/chunks/{schedule-UASAVDVD.js → schedule-5GCACCK7.js} +4 -4
  61. package/dist/chunks/{workflow-KDGIUCNW.js → workflow-M5ZJ7DWF.js} +6 -6
  62. package/dist/index.js +28 -28
  63. package/dist/internal/e10/auth/commands.js +109 -56
  64. package/dist/internal/e10/auth/session.js +11 -1
  65. package/dist/internal/e10/auth/xiaoe.js +29 -4
  66. package/dist/internal/e10/client.js +13 -0
  67. package/dist/internal/e10/context.js +14 -6
  68. package/dist/internal/e10/request-runtime.js +9 -0
  69. package/dist/shortcuts/cowork/operations/item-write.js +10 -2
  70. package/dist/shortcuts/mail/operations/mail-send.js +8 -2
  71. package/dist/shortcuts/meeting/operations/eb/catalog.js +5 -1
  72. package/dist/shortcuts/meeting/operations/eb/create-flow.js +381 -104
  73. package/dist/shortcuts/meeting/operations/eb/crm-search.js +87 -5
  74. package/dist/shortcuts/meeting/operations/eb/flow-memory.js +49 -0
  75. package/dist/shortcuts/meeting/operations/eb/group-chat.js +583 -0
  76. package/dist/shortcuts/meeting/operations/eb/index.js +2 -0
  77. package/dist/shortcuts/meeting/operations/eb/room-recommend.js +19 -3
  78. package/dist/shortcuts/meeting/operations/eb/room-summary.js +2 -0
  79. package/dist/shortcuts/meeting/operations/eb/usage-cache.js +99 -0
  80. package/dist/shortcuts/meeting/operations/from-group-chat.js +35 -12
  81. package/dist/shortcuts/workflow/operations/form.js +21 -2
  82. package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupRules.js +52 -1
  83. package/dist/shortcuts/workflow/operations/todoSmartConvert/summaryCache.js +10 -9
  84. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.collect.js +28 -2
  85. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.core.js +1 -0
  86. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.group.js +17 -9
  87. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.js +1 -0
  88. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.summary.js +14 -2
  89. package/docs/e10-auth.md +15 -0
  90. package/package.json +1 -1
  91. package/scripts/mcp-meeting.mjs +234 -0
  92. package/skills/weaver-e10-cowork/references/cowork-write.md +1 -1
  93. package/skills/weaver-e10-mail/references/mail-send.md +2 -0
  94. package/skills/weaver-e10-meeting/SKILL.md +88 -25
  95. package/skills/weaver-e10-meeting/references/meeting-minute-file.md +25 -11
  96. package/skills/weaver-e10-meeting.zip +0 -0
  97. package/skills/weaver-e10-shared/SKILL.md +1 -1
  98. package/skills/weaver-e10-shared/references/e10-auth-and-session.md +1 -1
  99. package/skills/weaver-e10-workflow/SKILL.md +4 -0
  100. package/skills/weaver-e10-workflow/aigroup/default.json +12 -0
  101. package/skills/weaver-e10-workflow/references/todo-smart-convert.md +17 -11
  102. package/skills/weaver-e10-workflow/tools/todo-summary.cjs +73 -23
  103. package/dist/chunks/{chunk-2LV74IWP.js → chunk-E7OK5WD5.js} +5 -5
@@ -79,6 +79,11 @@ collect
79
79
  ### 取数
80
80
 
81
81
  - 默认 `category=todo`,只调用对应分类的列表接口;待办接口为 `getTodoListData`。collect 不调用总数、分组统计或详情接口。
82
+ - **小分类 / tabid(2026-11-02)**:用户明确提到小分类词(待处理 / 待阅 / 超时 / 未读 / 被退回 / 草稿 / 抄送 / 转发 / 传阅 / 关注 / 被督办 / 被转办 / 新反馈 / 已查阅)时,`prep`/`run` 传 `--sub-category <词>` 或 `--tabid <tabid>`(等价入口,**显式 tabid 优先**)。todo 词表:全部=0、待处理=7、未读=1、新反馈=2、已查阅=3、待阅=5、超时=6、被退回=8、转发=4、传阅=11、抄送=9、关注=10、被督办=12、被转办=13、草稿=14。用户未表达小分类时**不要传**(默认 tabid=0 = 全部待办,保住「汇总下待办 = 全量」的历史语义)。小分类与时间范围(`--days`/`--from`/`--to`)可叠加:接口先按 tab 圈定、再按时间过滤。**此参数只影响汇总取数**,`workflow.search` 等链路不受影响。
83
+ - **isremarks(2026-11-02,词表已按 wfc_operate.isremark 补齐)**:待办**参与身份**筛选,多个 code 用英文逗号拼接(如 `0,2,20`),放 `getTodoListData` 的 **`params` 层**;`prep`/`run` 传 `--isremarks`,多值取**并集**。**仅汇总链路生效**——注入点在 todoSmartConvert 的 collect 内部,`workflow.search` 的代码路径与 schema 均未改动。词表:`0`=节点操作者、`1`=节点操作者(代理)、`2`=节点协办人、`5`=超时指定干预人、`6`=超时指定干预人(代理)、`7`=异常处理指定干预人、`8`=异常处理指定干预人(代理)、`10`=意见征询接收人、`11`=意见征询接收人(代理)、`20`=传阅接收人、`21`=传阅接收人(代理)、`30`=抄送需反馈、`31`=抄送需反馈(代理)、`33`=抄送协办人、`40`=转发接收人、`41`=转发接收人(代理)、`50`=协办人、`60`=传阅接收人无需反馈、`61`=传阅接收人无需反馈(代理)、`70`=抄送无需反馈、`71`=抄送无需反馈(代理)、`80`=转发接收人无需反馈、`81`=转发接收人无需反馈(代理)。实测(近一年):`0`→54 条(节点操作者,当前待办的绝对主体),传阅/协办/抄送类身份→0 条;**不传 = 不过滤**(tabid 圈定的全部)。典型用法:「汇总下需要我反馈的抄送」→ `--isremarks 30,31`(抄送需反馈)。
84
+ - **标题摘要模式(2026-11-03 用户定稿)**:内部留言、公司重要通知、安全问题处理工单、产品开发计划制定及任务跟踪(e-todo)、E10项目版本发布申请流程 五类 `needSummary:false`(摘要=流程标题,**不取详情、不进模型**);安全问题/内部留言的 `aiContext` 改为「流程标题」(分组仍按标题分桶,模型 1 轮);e-todo 与安全工单的 `summaryRequiredFields` 已删除(标题模式下要素校验会误拦)。收益:单条摘要 282→0 条进模型、素材 194KB→~10KB、详情取数 -93%,冷缓存全量 35 分钟 → **2 轮模型往返(约 1 分钟)**。备份:`/tmp/aigroup-default-backup-20261103.json`(改前快照,含 generalRules)。
85
+ - **通用规则区 `generalRules`(2026-11-03)**:default.json 顶层可选区块(与具体工作流无关的全局行为;schemaVersion 仍为 3,旧版本 CLI 忽略)。当前仅启用 **`priorityGroup`**——第一分组标题与入选规则(`overdue` 已超时 / `levelFallback` 紧急程度降级链;预留 `expiringToday` 未启用)。`identityFilter`(默认排除抄送类身份)已于 11-03 下午移除:汇总默认**包含**抄送数据,需要排除时由调用方显式传 `--isremarks`(非抄送 18 码白名单见 git 历史/本文件 §2 词表)。后续新的通用规则以新键扩展(预留)。
86
+ - **空结果文案(2026-11-03 用户定稿)**:collect 取到 0 条(或排除条件滤光)时,`prep`/`run` **不进 build**(CLI 会抛 `items_empty`),直接以 `exit 0` 输出用户文案并结束——①无任何显式限制条件 ⇒ 「您当前没有待办。」;②带显式限制条件(时间范围/小分类/tabid/参与身份/排除清单/侧重点)⇒ 「您当前没有符合条件的待办,可以尝试调整限制数据的范围后重试。(当前条件:…)」并回显命中的条件。执行方原样转述即可,**不要自动放宽范围重查**。
82
87
  - 时间范围一次传入,通过 `current` 递增翻页。默认 `limit=200`,最大 `limit=500`;单页最多 100 条,最多 5 页。`pageSize` 是兼容参数,实际大小由 `limit` 推导。
83
88
  - 达到 limit、页内没有新增数据或返回空页时停止;跨页按 `requestId` 去重。超过上限会在 warnings 中说明。
84
89
  - 只使用响应中的 `displayData`,不把技术行当作回退数据。长 ID 始终按字符串处理。
@@ -105,10 +110,8 @@ collect
105
110
  - 详情缓存(条目格式 v3):过滤后的 formData 字段 / basicInfo(已剔除标题类字段)/ 阈值指标 / `excludeTag`,
106
111
  **详情为空也写**;旧版本条目(v2 及更早,basicInfo 里还带标题)读取时视为无效,自动重拉;
107
112
  `excludeOriginFormDataFields` 变了 ⇒ `excludeTag` 对不上 ⇒ 旧条目自动失效重拉(与摘要缓存的 pk 机制同思路);
108
- - 摘要缓存:单条摘要文本。条目除 `maxChars`/`pk`(口径)外还带 **`dv`(详情素材特征值,
109
- 2026-11-01 根治)**:写入时对当前详情素材(basicInfo+fields 内容哈希)取特征值,
110
- 读取时与当前素材比对——素材升级/排除清单调整/详情缓存被清(无法核验)⇒ 旧摘要失效重写;
111
- 无 `dv` 的旧条目按旧规则兼容命中(7 天 TTL 内自然消化)。
113
+ - 摘要缓存:单条摘要文本。条目除 `maxChars`/`pk`(口径)外还带 **`dv`(详情素材特征值,2026-11-01 根治)**:写入时对当前详情素材(basicInfo+fields 内容哈希)取特征值,读取时与当前素材比对——素材升级/排除清单调整/详情缓存被清(无法核验)⇒ 旧摘要失效重写;无 `dv` 的旧条目按旧规则兼容命中。
114
+ **失效条件(2026-11-02 用户定稿):只由 `requestSummaryPrompt`(default.json / 用户意图)调整触发**——①条目缺 `pk` = 旧口径条目,**兼容命中**(无法证明口径变过就不作废);②`maxChars` 仅在用户显式传 `--summary-chars` 时参与比对,规则/默认字数变化(如 50→150)**不作废**历史摘要;③`dv` 仍比对素材变化。对照实测:修复前 285 条旧口径条目全 miss(冷缓存 35 分钟级),修复后同数据集 `prefilled=312|待写 0`。
112
115
  记录里带 `lastFeedBackDateTime` 就是为了这个 key:**流程有新反馈 ⇒ key 变 ⇒ 缓存自然失效**。
113
116
  - 详情取数时机:`collect` 只为「用户给了 `groupFocus` 且意图适用于本组」的组预取字段;`smartGroup` 对全部条目走一次「缓存优先」的取数(命中零请求)。因此**冷缓存下详情请求集中在 `smartGroup`,`summary` 阶段通常 0 请求**。
114
117
  - 摘要缓存**只省 AI、不省详情**:阈值指标只认流程详情数据,所以命中摘要的条目仍会查一次详情缓存;摘要为空的条目用标题兜底。
@@ -119,24 +122,24 @@ collect
119
122
  - 优先组固定为 `id=priority`、标题“建议优先处理的流程”,排在第一位。超时条目必入;没有级别 2 时才使用级别 1,级别 0 不因等级入选。
120
123
  - 优先组是**叠加视图**,不是筛选:入选条目**仍保留在各自的工作流分组里**(优先组只是置顶入口)。因此 `Σcount` 会大于 `totalCount`,**`totalCount` 一律按去重条数计(= collect 取到的全部条数),不做分组求和**。
121
124
  - 普通组保持接口返回的首次出现顺序。只有调用方明确给出排序意图时才传 `groupOrder`;`topN` 只影响中间 Markdown,不裁剪最终数组。
122
- - `groupingBrief` 用组内 1-based `idx` 标识条目。AI 生成 `aiGroups` 时优先用 `seq`,不要手抄长 `requestId`。
125
+ - `groupingBrief` 用组内 1-based `idx` 标识条目;`idx` 与 `prep` 输出目录 `state.json` 里 `planGroups[].rows[].requestId` 一一对应。生成 `aiGroups` 时一律用 `requestId`:需要映射就从 `state.json` 一次性提取,不要手抄,更不要用 `seq`(已废弃)。
123
126
 
124
127
  ## 4. `smartGroup` 和 `aiGroups`
125
128
 
126
- `aiGroups` 是扁平数组,每项只允许 `groupId`、`title`、`requestIds` 或 `seq`:
129
+ `aiGroups` 是扁平数组,每项只允许 `groupId`、`title`、`requestIds` 三个键(**`seq` 已废弃**:传入即报 `aiGroups 元素必须是 {groupId,title,requestIds:[...]}(seq 已废弃)`,2026-11-02 起文档统一只给 `requestIds` 写法):
127
130
 
128
131
  ```json
129
132
  [
130
- { "groupId": "workflow-id", "title": "安全通知", "seq": [1, 3] },
131
- { "groupId": "workflow-id", "title": "制度通知", "seq": [2, 4] }
133
+ { "groupId": "workflow-id", "title": "安全通知", "requestIds": ["101", "103"] },
134
+ { "groupId": "workflow-id", "title": "制度通知", "requestIds": ["102", "104"] }
132
135
  ]
133
136
  ```
134
137
 
135
- - `requestIds` 与 `seq` 二选一,不能同时出现,也不能都为空。
138
+ - `requestIds` 必填且非空,成员必须属于本组;未知 `groupId`、未知 `requestId`、重复分配直接失败。
136
139
  - 优先组不可二次分组。
137
140
  - 组内少于 3 条时**一律平铺单条**,不产生任何汇总项——阈值组(1天以内 / 100元以内)、问题支持过期组、内部留言整组都不例外;**即使给了 `aiGroups` 也忽略**(CLI 写 warning)。这条是硬门槛,没有例外。
138
141
  - **计划子组不足 2 条会被解散平铺**(CLI 写 warning「N 个子组不足 2 条,已解散」)——这是机制行为,与上一条相互独立:若 `groupingPrompt` 的自然粒度每组只有 1 条(如 安全问题处理工单 按 git 文件,11 条对应 11 个文件),按它给的计划会全部解散、整组平铺,**这是该计划的必然结果,不是错误**;要真正成组,就得按能凑够每组 ≥2 条的粒度给计划(如按文件族),且组名仍必须来自 `groupingPrompt` 口径、**不得为凑组虚构更粗粒度的新组名**(如"XML/Java 文件类型")。
139
- - 组内至少 3 条时,完全省略 `aiGroups` 走 CLI 确定性分组;显式传入后,未知 `groupId`、未知 `requestId`、重复分配和越界序号直接失败(**仅在本组计划会被采纳时校验**:意图适用于本类型,或本组是内部留言)。
142
+ - 组内至少 3 条时,完全省略 `aiGroups` 走 CLI 确定性分组;显式传入后,未知 `groupId`、未知 `requestId`、重复分配直接失败(**仅在本组计划会被采纳时校验**:意图适用于本类型,或本组是内部留言)。
140
143
  - `aiGroups` 何时该给——**三种情形**(`prep` 输出会给组标 `[必须给 plan]`,照标注执行即可):
141
144
  - ① 用户给了侧重点(`groupFocus`),且侧重点**按意图表适用于本组类型**;
142
145
  - ② 本组是**内部留言** —— 而且**≥3 条时是必须给**:没有侧重点(或侧重点不适用)就按**流程标题**分组,缺计划直接报 `ai_groups_required`;
@@ -279,6 +282,7 @@ collect
279
282
  - `app` 的值按原始字符写 **`@weapp/workflow`**(`@` 后面**没有**斜杠,共 15 个字符):**不要写成 `@//weapp/workflow`、不要转义成 `@\/\/weapp\/workflow`、也不要加前导空格**——带前导空格会导致 app 解析失败(用户 2026-10-27 以截图校正)。
280
283
  - 脚本 `exportFinal` 已在 stdout 的 `[JSON_BEGIN]`/`[JSON_END]` 之间直接输出**带标签的整块载荷**,原样粘贴即可;交付 JSON 文件(`~/Downloads/<用户名>_<时间戳>.json`)由脚本自动落盘并打印路径,**默认不 `present_files`(见 §6.1 顶部)**。旧 `--file` 分支(写 `待办汇总-*.json` 外框归档)已于 2026-11-01 **删除**——传了也会被忽略,不要再依赖它。
281
284
  - **交付硬闸门(2026-11-01)**:`finish`/`build` 导出前强制校验——①空单条摘要 >0、②空组摘要 >0、③待写摘要未全部回填(列出缺失 requestId)、④详情取数失败(`failed>0`,防"静默降级+标题编内容")、⑤**降级话术黑名单**(摘要含「未在标题体现 / 标题未体现 / 标题里没有 / 详见流程 / 详见详情 / 待确认」即拦截——把取数失败写成业务信息缺失)、⑥**要素级校验**(规则 `summaryRequiredFields` 声明的关键字,本组每条摘要必须逐项包含,缺任一即拦截并列出缺失项)——任一命中即 `exit 1` 拒绝导出。显式豁免:`--allow-empty-summary`(豁免①②③⑤⑥)、`--allow-detail-fail`(豁免④)。**豁免是给"确认要带瑕疵出文件"用的,不要拿它当常规手段绕过校验。**
285
+ - **组摘要未回填 ≠ 失败(2026-11-02 P2 定稿)**:`finish`/`build` 遇到组摘要待回填时,把**完整素材**(含每个成员的 `requestId`、标题、发起人、单条摘要、`prompt`)写 `<out>/need-group-summaries.json`,以 **`exit 0` + `NEEDS_GROUP_SUMMARIES`** 返回、**不导出**(控制台只给紧凑清单,此前每批 400 字符的截断预览已废除);在该文件每个元素里补 `summary` 后用 `--group-summaries` **指回同一个文件**重跑即可(脚本自动只取 `groupId`/`summary`,`items` 等多余字段不外传)。`--allow-empty-summary` 豁免后才按空组摘要继续导出。上方①②④⑤⑥等真失败仍 `exit 1`。
282
286
  - 体积见 §6.2:**不能按组拆成多个 `<browsertool>` 块**(拆开就不是合法载荷);超限时先在正文说明条数与预计体积,建议缩小范围,用户坚持再照做。
283
287
 
284
288
 
@@ -308,6 +312,8 @@ collect
308
312
 
309
313
  ⇒ 端到端提速最有效的不是优化 CLI,而是**减少往返次数**:
310
314
 
315
+ - **第一原则(2026-11-02 用户定稿,先看这条)**:**不截断脚本输出、不探查中间产物**。`todo-summary.cjs` 打的是纯文本素材,`| head -c` 不会报错、只会让「待写摘要」悄悄缺条(实测 17.6 KB / 9 条被截成 5 条,缓存随后已写、重跑也补不回,只能整套重跑);`<out>/` 下的 `items.json` / `state.json` / `smartgroup.json` / `*.log` 更不能为"确认一下"去翻。遵守这两条,同一次汇总可从 12 轮压到 1 轮(脚本口径 71.9s → 3.0s);违反其中任一条,必然多 2~3 轮、约 25~60s。细则见 SKILL.md「5) 命令输出读取纪律」。
316
+ - **素材落盘(2026-11-02 P3-B)**:`build`/`run` 停在待写摘要时,完整素材(batches 数组,含 `items[].requestId/context` 等,**无损**)写 `<out>/need-summaries.json`,控制台只留批次索引(`NEEDS_SUMMARIES`);模型用 Read 按需读该文件写 `aiSummaries.json` 后 `finish --summaries` 回填,**不再解析控制台长日志**(冷缓存 268 条时旧输出达 850KB)。
311
317
  - 用 `run --days N --limit N --out DIR --timing-report` 一次跑完 `prep + build`(无待写摘要时连 `finish` 一起),别一步步手动跑。
312
318
  - **时间段默认(2026-11-01 用户定稿)**:用户**没有说明数据的时间段**时,**不加任何时间条件**——不传 `--days` / `--from` / `--to`,取数范围就是全部待办,默认取**前 500 条**(`--limit` 不传即为 500);只有用户明确说了时段("近一年""近 30 天""某区间")才传 `--days` 或 `--from/--to`。不要替用户默认加时间范围。
313
319
  - **有侧重点(`--focus`)时的最短路径是 4 轮**,多一轮就多 5~7s:
@@ -356,7 +362,7 @@ weaver-work-cli --json workflow run workflow.todoSmartConvert --input-json '{"st
356
362
  | --- | --- |
357
363
  | `stage_invalid` / `input_unknown_key` | 按错误中的允许字段修正 |
358
364
  | `items_required` / `items_invalid` / `items_too_many` | 先执行 `collect`,再回灌原始 `items` |
359
- | `ai_groups_invalid` / `ai_group_*` | 检查 `groupId`、`title`、`seq`/`requestIds` 和覆盖范围 |
365
+ | `ai_groups_invalid` / `ai_group_*` | 检查 `groupId`、`title`、`requestIds`(`seq` 已废弃,改用 `requestIds`)和覆盖范围 |
360
366
  | `final_groups_required` / `wfidgroup_invalid` | 原样回灌上一步 `wfIdGroup` |
361
367
  | `ai_summaries_required` / `ai_summary_*` | 只提交本轮有效 `requestId`,不能重复 |
362
368
  | `ai_group_summaries_required` / `ai_group_summary_*` | 使用汇总项 id,不使用父组 id |
@@ -746,6 +746,17 @@ function cmdPrep(args) {
746
746
  if (args['sub-category'] && args['sub-category'] !== true) {
747
747
  input.subCategory = String(args['sub-category']);
748
748
  }
749
+ // 2026-11-02:小分类的等价直传入口。显式 tabid 优先级高于 subCategory/tabName
750
+ // (CLI buildSearchQuery:先解析 subCategory/tabName,再用显式 tabid 覆盖)。
751
+ // 仅影响本次汇总取数范围,不触碰 workflow.search 的默认行为。
752
+ if (args.tabid && args.tabid !== true) {
753
+ input.tabid = String(args.tabid);
754
+ }
755
+ // 2026-11-02:备注筛选(getTodoListData params.isremarks),多个数字英文逗号拼接。
756
+ // 仅汇总链路生效(CLI collect 内部注入 params),workflow.search 不受影响。
757
+ if (args.isremarks && args.isremarks !== true) {
758
+ input.isremarks = String(args.isremarks);
759
+ }
749
760
  // 摘要字数口径要带进 collect:否则缓存命中按默认 50 字判定,
750
761
  // 用户要求「10 字以内」时仍会回填旧的长摘要(2026-10-22 实测踩到)。
751
762
  if (args['summary-chars'] && args['summary-chars'] !== true) {
@@ -775,6 +786,29 @@ function cmdPrep(args) {
775
786
  const kept = exclude.length ? all.filter((row) => !exclude.includes(String(row.workflowName || ''))) : all;
776
787
  const dropped = all.length - kept.length;
777
788
 
789
+ // 2026-11-03 用户定稿:collect 空结果按「是否带显式限制条件」给不同文案,直接结束(exit 0),
790
+ // 不进 build(CLI 会抛 items_empty 校验错误)。
791
+ // - 无限制条件(如「汇总我的待办」)⇒ 「您当前没有待办。」
792
+ // - 带限制条件(时间范围 / 小分类 / tabid / 参与身份 / 排除清单 / 侧重点)⇒
793
+ // 「您当前没有符合条件的待办,可以尝试调整限制数据的范围后重试。」并回显条件。
794
+ if (all.length === 0 || kept.length === 0) {
795
+ const constraints = [];
796
+ if (days > 0) constraints.push(`近 ${days} 天`);
797
+ if (args.from && args.to) constraints.push(`${args.from} 至 ${args.to}`);
798
+ if (input.subCategory) constraints.push(`小分类「${input.subCategory}」`);
799
+ if (input.tabid) constraints.push(`tabid=${input.tabid}`);
800
+ if (input.isremarks) constraints.push(`参与身份 ${input.isremarks}`);
801
+ if (exclude.length) constraints.push(`排除流程「${exclude.join('、')}」`);
802
+ if (input.groupFocus) constraints.push(`侧重点「${input.groupFocus}」`);
803
+ if (all.length === 0 && constraints.length === 0) {
804
+ console.log('您当前没有待办。');
805
+ } else {
806
+ console.log('您当前没有符合条件的待办,可以尝试调整限制数据的范围后重试。%s',
807
+ constraints.length ? `(当前条件:${constraints.join('、')})` : '');
808
+ }
809
+ return 'EMPTY';
810
+ }
811
+
778
812
  // 组结构直接用 CLI 返回的 wfIdGroup(已做 priority 抽取,不能再自己按 workflowName 复算,
779
813
  // 否则会把被抽进「建议优先处理」的条目重复计入原流程)。
780
814
  // 注意:wfIdGroup[].requestDatas 里**没有 workflowName**,要按 requestId 从 items 回查,
@@ -959,22 +993,19 @@ function cmdBuild(args) {
959
993
  cmdFinish({ ...args, dir });
960
994
  return;
961
995
  }
962
- console.log(`\n待写摘要(把结果写成 aiSummaries.json,元素 {requestId,summary};每批的「口径」必须遵守):`);
996
+ // 2026-11-02 P3-B:素材无损落盘(此前整段吐控制台,268 条时 build 输出达 850KB,
997
+ // 模型要多轮读长文本还易被截断);控制台只留批次索引,模型用 Read 按需读 need-summaries.json。
998
+ const needFile = path.join(dir, 'need-summaries.json');
999
+ fs.writeFileSync(needFile, JSON.stringify(batches, null, 2));
1000
+ console.log(`\n⚠ NEEDS_SUMMARIES:%d 条单条摘要待写(完整素材已写入 %s):`, pending.length, needFile);
963
1001
  for (const b of batches) {
964
1002
  const items = b.items || [];
965
1003
  if (items.length === 0) continue;
966
- console.log(`## 批次 ${b.batchId}|${b.groupTitle}${b.subGroupTitle && b.subGroupTitle !== b.groupTitle ? ` → ${b.subGroupTitle}` : ''}|目标字数 ${b.suggestedMaxChars}`);
967
- if (b.prompt) console.log(`口径:${b.prompt}`);
968
- if (b.hint) console.log(`提示:${b.hint}`);
969
- for (const item of items) {
970
- console.log(`### ${item.requestId}`);
971
- console.log(`T: ${String(item.requestNameTitle || '').slice(0, 160)}`);
972
- // 素材**几乎不截断**(4000 字符保险丝):2026-11-01 实测 240 字截断把 e-todo 模板的
973
- // 「预估开发总人天/需求概述」等尾部要素裁掉,模型只能靠标题凑数(要素缺失复盘定稿)。
974
- console.log(`C: ${String(item.context || '').replace(/\s+/g, ' ').slice(0, 4000)}`);
975
- }
1004
+ console.log(` - ${b.batchId}|${b.groupTitle}${b.subGroupTitle && b.subGroupTitle !== b.groupTitle ? ` → ${b.subGroupTitle}` : ''}|${items.length} 条|目标字数 ${b.suggestedMaxChars}${b.prompt ? `|口径:${b.prompt}` : ''}`);
1005
+ if (b.hint) console.log(` 提示:${b.hint}`);
976
1006
  }
977
- console.log('\n下一步:node %s finish --dir %s --summaries <aiSummaries.json>', path.basename(__filename), dir);
1007
+ console.log(' → 读 need-summaries.json(items[].requestId + context),摘要写成 aiSummaries.json(元素 {requestId,summary})后重跑:');
1008
+ console.log(' node %s finish --dir %s --summaries <aiSummaries.json> --timing-report', path.basename(__filename), dir);
978
1009
  // 组摘要(aiGroup.groupSummary.needAI=true 的汇总项):口径随批次下发,模型按它写 aiGroupSummaries
979
1010
  const gsBatches = sg.data.groupSummaryBatches || [];
980
1011
  if (gsBatches.length > 0) {
@@ -1033,7 +1064,10 @@ function cmdFinish(args) {
1033
1064
  : null;
1034
1065
  if (groupSummariesFile) {
1035
1066
  // 组摘要必须由模型写、且每轮重算;这里只是把「回填」并进同一次命令,省掉一次模型往返。
1036
- const aiGroupSummaries = readJson(groupSummariesFile);
1067
+ // need-group-summaries.json 可直接指回:这里投影成 CLI 需要的 {groupId,summary},
1068
+ // 多余字段(title/items/stats 等)不外传,避免 CLI 白名单校验拒绝。
1069
+ const aiGroupSummaries = readJson(groupSummariesFile)
1070
+ .map((x) => ({ groupId: x.groupId || x.id, summary: x.summary }));
1037
1071
  const t2 = Date.now();
1038
1072
  const gs = runStage({
1039
1073
  smartSummaryTitle: result.data.smartSummaryTitle,
@@ -1053,12 +1087,21 @@ function cmdFinish(args) {
1053
1087
  for (const text of gsWarnings) console.log(' ⚠ %s', text);
1054
1088
  finalResult = gs;
1055
1089
  } else {
1056
- console.log('\n⚠ 还有 %d 个组摘要素材待模型生成(groupSummary 阶段):', groupBatches.length);
1057
- for (const batch of groupBatches) console.log(JSON.stringify(batch).slice(0, 400));
1058
- console.log(' → 写成 [{groupId,summary}] 后加 `--group-summaries <file>` 重跑本命令,可在同一次调用里回填');
1059
- if (args['allow-empty-summary'] !== true) {
1060
- console.error('✖ 交付拦截:%d 个组摘要未回填,导出会是空组摘要。补齐 --group-summaries 后重跑,或加 --allow-empty-summary 显式豁免。', groupBatches.length);
1061
- process.exit(1);
1090
+ // 2026-11-02 P2 定稿:组摘要未回填 ≠ 校验失败。完整素材落盘(此前控制台每批只打
1091
+ // JSON.stringify(batch).slice(0, 400) 的预览,等于没有素材),以 exit 0 + NEEDS_GROUP_SUMMARIES
1092
+ // 返回、不导出;真失败(空单条摘要/降级话术/要素缺失/详情失败)仍由 exportFinal 以 exit 1 拦截。
1093
+ const needFile = path.join(dir, 'need-group-summaries.json');
1094
+ fs.writeFileSync(needFile, JSON.stringify(groupBatches, null, 2));
1095
+ console.log('\n⚠ NEEDS_GROUP_SUMMARIES:%d 个组摘要待回填(完整素材已写入 %s):', groupBatches.length, needFile);
1096
+ for (const batch of groupBatches) {
1097
+ console.log(' - %s|%s → %s|%d 条', batch.groupId, batch.parentTitle, batch.title, batch.count);
1098
+ }
1099
+ if (args['allow-empty-summary'] === true) {
1100
+ console.log(' --allow-empty-summary 已指定:跳过回填、按空组摘要继续导出。');
1101
+ } else {
1102
+ console.log(' → 在该文件的每个元素里补 "summary" 字段(脚本会自动只取 groupId/summary),重跑:');
1103
+ console.log(' node %s finish --dir %s --group-summaries %s --timing-report', path.basename(__filename), dir, needFile);
1104
+ return; // 不导出、退出码 0:素材已备齐、等回填,不是失败
1062
1105
  }
1063
1106
  }
1064
1107
  }
@@ -1093,14 +1136,18 @@ function cmdRun(args) {
1093
1136
  const dir = args.out && args.out !== true
1094
1137
  ? String(args.out)
1095
1138
  : `/tmp/todo-summary-${new Date().toISOString().replace(/[-:T]/g, '').slice(0, 14)}`;
1096
- cmdPrep({ ...args, out: dir });
1139
+ // collect 空结果已在 prep 里给出用户文案并结束(EMPTY),不再进 build/finish
1140
+ if (cmdPrep({ ...args, out: dir }) === 'EMPTY') return;
1097
1141
  cmdBuild({ ...args, dir });
1098
1142
  // 无待写摘要时 cmdBuild 已经内部走完 cmdFinish(含满意度标题填充与交付闸门),这里直接收工
1099
1143
  if (fs.existsSync(path.join(dir, 'final.data.json'))) return;
1144
+ // build→finish 已把组摘要素材落盘并停下(NEEDS_GROUP_SUMMARIES,exit 0)⇒ 不再重复跑 finish,
1145
+ // 也不再重复打印(cmdFinish 刚打过完整指引),静默收工(2026-11-02 P2)。
1146
+ if (fs.existsSync(path.join(dir, 'need-group-summaries.json'))) return;
1100
1147
  const sg = readJson(path.join(dir, 'smartgroup.json'));
1101
1148
  const pending = ((sg.data.summaryBatches || []).flatMap((batch) => batch.items || []));
1102
1149
  if (pending.length > 0) {
1103
- console.log('\n⚠ 有 %d 条待写摘要:写成 aiSummaries.json 后跑 finish(**不用重跑** collect/smartGroup)', pending.length);
1150
+ console.log('\n⚠ 有 %d 条待写摘要:素材见 %s;写成 aiSummaries.json 后跑 finish(**不用重跑** collect/smartGroup)', pending.length, path.join(dir, 'need-summaries.json'));
1104
1151
  console.log(' node %s finish --dir %s --summaries <aiSummaries.json> --timing-report', path.basename(__filename), dir);
1105
1152
  return;
1106
1153
  }
@@ -1125,10 +1172,13 @@ else if (cmd === 'run') cmdRun(args);
1125
1172
  else {
1126
1173
  console.log('用法:node ' + path.basename(__filename) + ' <run|prep|build|finish> [options]');
1127
1174
  console.log(' run [--days N | --from A --to B] [--limit 500] [--out DIR] [--timing-report] # 一次跑完 prep+build;用户没说时间段就都不传 = 不限时间取前 500 条');
1128
- console.log(' prep --limit 100 [--exclude 内部留言] [--days 1460] [--sub-category 待处理] [--out DIR]');
1175
+ console.log(' prep --limit 100 [--exclude 内部留言] [--days 1460] [--sub-category 待处理] [--tabid 7] [--isremarks 1,2] [--out DIR] # 小分类:--sub-category/--tabid(显式 tabid 优先);isremarks=备注筛选(数字逗号拼接)');
1129
1176
  console.log(' build --dir DIR [--plan aiGroups.json] # prep 标注 [必须给 plan] 的组必须传;其余不传走确定性分组');
1130
1177
  console.log(' finish --dir DIR [--summaries aiSummaries.json] [--group-summaries aiGroupSummaries.json] [--timing-report]');
1131
- console.log(' 交付闸门:空摘要 / 组摘要缺失 / 详情取数失败都会 exit 1 拒绝导出;显式豁免:--allow-empty-summary / --allow-detail-fail');
1178
+ console.log(' 待写摘要素材:build/ run 停下时写 <out>/need-summaries.json(无损),控制台只留批次索引;写 aiSummaries.json 后 finish --summaries 回填');
1179
+ console.log(' 组摘要未回填:以 exit 0 + NEEDS_GROUP_SUMMARIES 返回(不导出),完整素材在 <out>/need-group-summaries.json;');
1180
+ console.log(' 在该文件补 summary 后用 --group-summaries 指回它重跑。真失败(空摘要/降级话术/要素缺失/详情失败)仍 exit 1;');
1181
+ console.log(' 豁免:--allow-empty-summary / --allow-detail-fail');
1132
1182
  console.log(' 默认:载荷只带 params.dataSource(现起本地服务,空闲 30 分钟自动退出);--no-serve 退回内联 data');
1133
1183
  console.log(' 提示:`--timing-report` 会在控制台打一段耗时摘要(阶段墙钟 / CLI 内部),**不产出 md**');
1134
1184
  process.exit(2);
@@ -1,10 +1,5 @@
1
1
  import { createRequire as __esbuildCreateRequire } from 'node:module';
2
2
  const require = __esbuildCreateRequire(import.meta.url);
3
- import {
4
- imBusinessError,
5
- imConfirmationError,
6
- imValidationError
7
- } from "./chunk-ZEDWSH32.js";
8
3
  import {
9
4
  collapseNewlines,
10
5
  collectI18nIds,
@@ -17,6 +12,11 @@ import {
17
12
  parseMsg,
18
13
  senderName
19
14
  } from "./chunk-YLCYX7LE.js";
15
+ import {
16
+ imBusinessError,
17
+ imConfirmationError,
18
+ imValidationError
19
+ } from "./chunk-ZEDWSH32.js";
20
20
 
21
21
  // src/shortcuts/im/operations/types.ts
22
22
  var READ = "read";