weaver-work-cli 0.1.22 → 0.1.24

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 (57) hide show
  1. package/README.md +23 -2
  2. package/dist/internal/e10/auth/commands.js +194 -16
  3. package/dist/internal/e10/auth/xiaoe.js +15 -6
  4. package/dist/internal/e10/context.js +3 -3
  5. package/dist/internal/e10/request-runtime.js +46 -4
  6. package/dist/shortcuts/caizhilian/file-upload/metadata.js +124 -0
  7. package/dist/shortcuts/caizhilian/file-upload/multipart.js +47 -0
  8. package/dist/shortcuts/caizhilian/file-upload/protocol.js +116 -0
  9. package/dist/shortcuts/caizhilian/file-upload/receipt.js +37 -0
  10. package/dist/shortcuts/caizhilian/host.js +13 -5
  11. package/dist/shortcuts/caizhilian/operations/handlers/file-upload.js +72 -179
  12. package/dist/shortcuts/caizhilian/operations/handlers/folder.js +701 -4
  13. package/dist/shortcuts/caizhilian/operations/registry.js +5 -1
  14. package/dist/shortcuts/caizhilian/operations/specs.js +52 -0
  15. package/dist/shortcuts/meeting/operations/change.js +7 -4
  16. package/dist/shortcuts/meeting/operations/create.js +5 -3
  17. package/dist/shortcuts/meeting/operations/eb/decision.js +22 -2
  18. package/dist/shortcuts/meeting/operations/lifecycle.js +8 -6
  19. package/dist/shortcuts/meeting/operations/receipts.js +54 -21
  20. package/dist/shortcuts/meeting/operations/shared.js +28 -0
  21. package/dist/shortcuts/meeting/operations/signs.js +14 -4
  22. package/dist/shortcuts/project/operations/read.js +7 -6
  23. package/dist/shortcuts/workflow/continuation.js +14 -9
  24. package/dist/shortcuts/workflow/endpoints.js +11 -1
  25. package/dist/shortcuts/workflow/operations/flow-status.js +63 -0
  26. package/dist/shortcuts/workflow/operations/form.js +650 -518
  27. package/dist/shortcuts/workflow/operations/read.js +374 -13
  28. package/dist/shortcuts/workflow/operations/shared.js +3 -0
  29. package/dist/shortcuts/workflow/operations/write.js +5 -5
  30. package/dist/shortcuts/workflow/operations.js +8 -6
  31. package/docs/caizhilian.md +8 -2
  32. package/docs/e10-auth.md +18 -3
  33. package/package.json +1 -1
  34. package/skills/weaver-e10-caizhilian/SKILL.md +8 -3
  35. package/skills/weaver-e10-caizhilian/references/file-upload.md +100 -295
  36. package/skills/weaver-e10-caizhilian/references/folder.md +31 -3
  37. package/skills/weaver-e10-caizhilian/references/source-manifest.json +536 -25
  38. package/skills/weaver-e10-jiuchuanhui/SKILL.md +9 -1
  39. package/skills/weaver-e10-meeting/SKILL.md +3 -2
  40. package/skills/weaver-e10-meeting/references/meeting-eb.md +10 -0
  41. package/skills/weaver-e10-meeting/references/meeting-receipts-signs.md +7 -2
  42. package/skills/weaver-e10-meeting/references/meeting-verification.md +1 -1
  43. package/skills/weaver-e10-meeting.zip +0 -0
  44. package/skills/weaver-e10-shared/SKILL.md +12 -2
  45. package/skills/weaver-e10-shared/references/e10-auth-and-session.md +21 -3
  46. package/skills/weaver-e10-shijingran/SKILL.md +68 -3
  47. package/skills/weaver-e10-shijingran/references/disabled-capabilities.md +22 -0
  48. package/skills/weaver-e10-shijingran/references/source-manifest.json +12 -4
  49. package/skills/weaver-e10-workflow/SKILL.md +10 -8
  50. package/skills/weaver-e10-workflow/references/source-manifest.json +36 -31
  51. package/skills/weaver-e10-workflow/references/workflow-batch.md +2 -4
  52. package/skills/weaver-e10-workflow/references/workflow-create.md +58 -36
  53. package/skills/weaver-e10-workflow/references/workflow-edit.md +2 -1
  54. package/skills/weaver-e10-workflow/references/workflow-memory.md +2 -2
  55. package/skills/weaver-e10-workflow/references/workflow-operate.md +2 -1
  56. package/skills/weaver-e10-workflow/references/workflow-query.md +9 -7
  57. package/skills/weaver-e10-workflow/references/workflow-share.md +2 -0
@@ -888,7 +888,7 @@
888
888
  }
889
889
  },
890
890
  "artifactBaseline": {
891
- "aggregateSha256": "3ca81d7b85aa07fd196cea5d127f8a68b5bfa38d7b9050644783264feeed4345",
891
+ "aggregateSha256": "a70b78d1893cf024dd80372667f58775830d310d20c38d8778ca21bbdf7f1e2f",
892
892
  "files": [
893
893
  {
894
894
  "path": "skills/weaver-e10-workflow/references/workflow-agent-entry.md",
@@ -897,38 +897,38 @@
897
897
  },
898
898
  {
899
899
  "path": "skills/weaver-e10-workflow/references/workflow-batch.md",
900
- "size": 28997,
901
- "sha256": "5748b933b2be30f8bbebc51eb0ae70c6d4eed1f2a14d7c601e9c97ed8e02e808"
900
+ "size": 28467,
901
+ "sha256": "4467ec07e3b5dddd67098d0aec6818e33ac420d5408733f97708a7eadbac905a"
902
902
  },
903
903
  {
904
904
  "path": "skills/weaver-e10-workflow/references/workflow-create.md",
905
- "size": 30764,
906
- "sha256": "2b0fb5a3d1b53f7586279f4a51f8a390d02ce6c2dbc3de902602d784508741ce"
905
+ "size": 42157,
906
+ "sha256": "0c2d103baed11bd10254ef61f72ca31d3410e1de0d3ce515eafe855c823924d6"
907
907
  },
908
908
  {
909
909
  "path": "skills/weaver-e10-workflow/references/workflow-edit.md",
910
- "size": 6304,
911
- "sha256": "bab0bf3b7af9cf1b71525ed79904af1477a698be7d6c45560394246cce97a560"
910
+ "size": 6585,
911
+ "sha256": "17c233c2c6edd175f7bbc059dc1878b2a6c17154047d47ec6e88e4c38e1fee66"
912
912
  },
913
913
  {
914
914
  "path": "skills/weaver-e10-workflow/references/workflow-memory.md",
915
- "size": 13714,
916
- "sha256": "e28b9a1a4f10feb0257f7f1848fab69caef43b1713a359f235503150612c44dc"
915
+ "size": 13929,
916
+ "sha256": "70758e63429a6cbfaf7a821ad93889b384bb42c895d2082680ed0006a19d4793"
917
917
  },
918
918
  {
919
919
  "path": "skills/weaver-e10-workflow/references/workflow-operate.md",
920
- "size": 9523,
921
- "sha256": "6b7c2cc03ed3d94a0a04c74c48a394e4bd31c8f3a58143c0682b8683a5eef3fe"
920
+ "size": 9727,
921
+ "sha256": "64a87b8e70c767b6e230e910ee0668dc426124667ccb424705008ecc422710ef"
922
922
  },
923
923
  {
924
924
  "path": "skills/weaver-e10-workflow/references/workflow-query.md",
925
- "size": 108319,
926
- "sha256": "902e3cb5e24114963ad41dac652a0d46d7bc7d1d5a49eda3d9bd3ec861e9527a"
925
+ "size": 108743,
926
+ "sha256": "c5bb7942ee840b9934a08475d6d6827dc8f7801c24bab85d859c8d75cc4234f8"
927
927
  },
928
928
  {
929
929
  "path": "skills/weaver-e10-workflow/references/workflow-share.md",
930
- "size": 6507,
931
- "sha256": "3691ee1e43b1be18d41c1a6ea2a6c6a322d2dd927a8169db475590376af0b83b"
930
+ "size": 6750,
931
+ "sha256": "5a1ce6977a36a7f4aa55c8d7cae7763088b9061ecd17954e04dc769ffe300d99"
932
932
  },
933
933
  {
934
934
  "path": "skills/weaver-e10-workflow/references/workflow-view.md",
@@ -937,18 +937,18 @@
937
937
  },
938
938
  {
939
939
  "path": "skills/weaver-e10-workflow/SKILL.md",
940
- "size": 39786,
941
- "sha256": "3d7b2c84ad5827c5ab5dd9d85ae53b70adb669082b45b0dc023de69290c95927"
940
+ "size": 40794,
941
+ "sha256": "d33da96aec46a20a7824dd2e8c6702765bfc06d40e268c79bbe9eebbc5b1e25f"
942
942
  },
943
943
  {
944
944
  "path": "src/shortcuts/workflow/continuation.ts",
945
- "size": 30337,
946
- "sha256": "5e0f18be2f792dfc551ad496c787d2de68024b560e7157487a494bb080623684"
945
+ "size": 30700,
946
+ "sha256": "e5fa7d8fbf0ae334977d18c388f829b29f2bb69b6250081d2d21f68a8bac2cec"
947
947
  },
948
948
  {
949
949
  "path": "src/shortcuts/workflow/endpoints.ts",
950
- "size": 8879,
951
- "sha256": "1570e01906dd76b63107f8c2027ef8a8ea2a3cd8a4b75598aa4c61d4de4a8e30"
950
+ "size": 9589,
951
+ "sha256": "2ef1ea72023bb4b7941aaa258159151999983ebac3c91c1034e5ca40e1c18e89"
952
952
  },
953
953
  {
954
954
  "path": "src/shortcuts/workflow/errors.ts",
@@ -972,18 +972,23 @@
972
972
  },
973
973
  {
974
974
  "path": "src/shortcuts/workflow/operations.ts",
975
- "size": 9238,
976
- "sha256": "6f272f7e5828dfb7bacb557230744aec884f12299e3a5a6b1fc925ca7aaaa677"
975
+ "size": 9461,
976
+ "sha256": "50f028b494fc572637c90afeade84c0f0cc36de92a5fa355b4813125a3c6eff0"
977
+ },
978
+ {
979
+ "path": "src/shortcuts/workflow/operations/flow-status.ts",
980
+ "size": 3774,
981
+ "sha256": "7a7a892c1385d0d065c3ad2fdb7c8c2ba451d9ccb77f198e86edc0cc6c6f6e98"
977
982
  },
978
983
  {
979
984
  "path": "src/shortcuts/workflow/operations/form.ts",
980
- "size": 225404,
981
- "sha256": "4938e30cecf9d6da790325d1162f834bf85c21e8b18f1e5d5c77d9483216f947"
985
+ "size": 235099,
986
+ "sha256": "db612187d35df210c3caeaccdfd9618f20ea870c361b5a45aeec5f2434568043"
982
987
  },
983
988
  {
984
989
  "path": "src/shortcuts/workflow/operations/read.ts",
985
- "size": 251625,
986
- "sha256": "374e4d600dfa9b0754755c051ebfd2f4a6549a52d4cb7e78ec2b6c46c838e9e8"
990
+ "size": 272728,
991
+ "sha256": "55a8baf6cd4feef9508a13f8acc5bf3a018b31616368df90fbfc33ab93d92927"
987
992
  },
988
993
  {
989
994
  "path": "src/shortcuts/workflow/operations/registry.ts",
@@ -992,8 +997,8 @@
992
997
  },
993
998
  {
994
999
  "path": "src/shortcuts/workflow/operations/shared.ts",
995
- "size": 9076,
996
- "sha256": "89c1784879fb269f91de1a3fa0fb836c73ba7b0da31fe57c5781521cb4b4e663"
1000
+ "size": 9323,
1001
+ "sha256": "496c414e40cca8a96cb05800961e03baf6657e61ac36ea0025cd3960f1cc2c05"
997
1002
  },
998
1003
  {
999
1004
  "path": "src/shortcuts/workflow/operations/types.ts",
@@ -1002,8 +1007,8 @@
1002
1007
  },
1003
1008
  {
1004
1009
  "path": "src/shortcuts/workflow/operations/write.ts",
1005
- "size": 141423,
1006
- "sha256": "17dd749ca23872888127b1576c2507dbded16284ed69d8114964ac36f75e5f97"
1010
+ "size": 141978,
1011
+ "sha256": "f8ca00a7096aef887bd4ed84391988589b128b8cdde2cbb043d78f0460342414"
1007
1012
  },
1008
1013
  {
1009
1014
  "path": "src/shortcuts/workflow/state.ts",
@@ -112,8 +112,6 @@ CLI 内部的循环口径(了解即可,**不要自己复刻**):
112
112
 
113
113
  适用:"批量提交 / 全部提交 / 一起提交"多条待办。入参 = `confirm: true` + `requestIds`(+ `remark` / `batchSize` / `async`)。
114
114
 
115
- 写端点= **`POST /api/workflow/core/flow/batchSubmit`**(前端同款;2026-09-20 由 `/api/workflow/core/paService/v1/batchSubmit` 换过来)。请求体形态(CLI 内部拼好,**模型不需要自己构造**):`{isMobile, isAsync, isSelectAll, conditionId, batchSubmitListParams, requestIds, operateUserIds, remark, handWrittenSign}`,其中 `batchSubmitListParams` 是一段 **JSON 字符串**(内含 `params` 查询上下文与 `searchParams.formDatas` 的空壳条件),`requestIds`/`operateUserIds` 为逗号分隔串。响应是**统一的逐条结果结构**(`data.submitResult[]` 含 `status`/`requestId`/`requestName`/`resultMessage`/`data.requestNameTitle`,另有 `data.failMsg` 映射与 `data.operateId`)——CLI 已按它算成功/失败条数与 `failures`。
116
-
117
115
  返回 `readCount`、`submittedCount`、`skippedRequestIds`(**CLI 本地判定**:`isRemark=100` 不可批量提交、被跳过的条目;接口本身不返回该属性)、`batchRead`、`submitResponse`;原样转述返回的结果与提示文案。
118
116
 
119
117
  ### 批量置已读 batchRead
@@ -152,7 +150,7 @@ CLI 内部的循环口径(了解即可,**不要自己复刻**):
152
150
  | `position` | 岗位 |
153
151
  | `all` | 所有人(无 name) |
154
152
 
155
- 名称自动转 ID;`name` 支持 `"名称(ID)"`(此时直接采用括号里的 ID、不再搜名称)。多命中返回候选列表让用户确认,禁止静默全选;0 命中报错提示核对。可选 `minSeclevel` / `maxSeclevel`(用户明确要求限制时传)。返回按每批 `addRequestShare2` 的**逐条结果**计价:`sharedCount` 只数 `data[]` 里 `result === "true"` 的条目,`result === "false"` 的进 `failures`(原因取 `msg`)。
153
+ 名称自动转 ID;`name` 支持 `"名称(ID)"`(此时直接采用括号里的 ID、不再搜名称)。多命中返回候选列表让用户确认(**只问用户完整名称或其它可用于检索的关键词,ID 由你按 `candidates` 拼好,不要向用户索取 ID**),禁止静默全选;0 命中报错提示核对。可选 `minSeclevel` / `maxSeclevel`(用户明确要求限制时传)。返回按每批 `addRequestShare2` 的**逐条结果**计价:`sharedCount` 只数 `data[]` 里 `result === "true"` 的条目,`result === "false"` 的进 `failures`(原因取 `msg`)。
156
154
 
157
155
  ### 批量转发 batchForward
158
156
 
@@ -165,7 +163,7 @@ CLI 内部的循环口径(了解即可,**不要自己复刻**):
165
163
  | `group` | 群组 |
166
164
  | `all` | 所有人(无 name) |
167
165
 
168
- `name` 支持 `"名称(ID)"`(此时直接采用括号里的 ID、不再搜名称)。接收人含 `all` 时会检查系统是否允许转发给所有人;不允许则停止并提示联系系统管理员,不得去掉 all 后静默继续。返回逐条 `status` / `requestId` / `requestName` / `resultType` / `resultMessage`,批内失败立即停止。
166
+ `name` 支持 `"名称(ID)"`(此时直接采用括号里的 ID、不再搜名称);多命中同上——**只问用户完整姓名或其它可用于检索的关键词,ID 由你按候选拼好,不要向用户索取 ID**。接收人含 `all` 时会检查系统是否允许转发给所有人;不允许则停止并提示联系系统管理员,不得去掉 all 后静默继续。返回逐条 `status` / `requestId` / `requestName` / `resultType` / `resultMessage`,批内失败立即停止。
169
167
 
170
168
  ### 批量退回 batchReject
171
169
 
@@ -13,11 +13,11 @@
13
13
 
14
14
  ## 发起链路(两条命令,模型不需要自己判断必填)
15
15
 
16
- 1. `workflow.createForm`:按用户说法解析可发起的工作流并载入表单,拿回 `continuation`(表单会话短句柄,载荷由 CLI 托管在本机)。
17
- - 返回 `NEEDS_CLARIFICATION` 时按 `candidates` 向用户确认,确认后用 `名称(ID)` 重发**同一条命令**。
18
- 2. 按用户意图把字段值填进 `data`(键用字段 id)。
16
+ 1. `workflow.createForm`:按用户说法解析可发起的工作流并载入表单,拿回 `continuation`(表单会话短句柄,载荷由 CLI 托管在本机)与必填/可写字段清单;**同时返回 `historyRequestData`**——本表单必填字段在历史流程里的取值参考(`null` = 没有可参考的)。
17
+ - 返回 `NEEDS_CLARIFICATION` 时按 `candidates` 向用户确认(只问完整名称或其它可用于检索的关键词,**不要向用户索取 ID**),确认后由你按 `名称(ID)` 拼好、重发**同一条命令**。
18
+ 2. 按用户意图把字段值填进 `data`(键用字段 id):**用户说了的照用户说的填;用户没提到的必填字段,先看第 1 步的 `historyRequestData`**——能直接照用的就填上(不必再问用户),其余留空。
19
19
  3. `workflow.createRequest`:`context` 传第 1 步返回的 `continuation`,`action` 按用户意图取 `draft`/`submit`。
20
- - `action: "submit"` 且仍有必填缺失 → **命令不会创建流程**,返回 `NEEDS_INPUT` + `missingFields`;把缺失项**一次问齐**后带同一 `context` 重发 `action: "submit"`。
20
+ - `action: "submit"` 且仍有必填缺失 → **命令不会创建流程**,返回 `NEEDS_INPUT` + `missingFields` + `historyRequestData`(**只含本次新出现的必填字段**的历史参考值,可能为 `null`);**先按 `historyRequestData` 判断这些字段能不能参考**,能参考的直接填入重发,不能的再把缺失项**一次问齐**后带同一 `context` 重发 `action: "submit"`。
21
21
  - `action: "draft"` 且仍有必填缺失 → 照常建草稿,`missingFields` 只作提醒(必须原样转述给用户)。
22
22
  - **不要(也无法)自己判断"必填是否齐"**:缺失与否由命令按**实际所填数据**(含联动带出值)实时算出,照 `missingFields` 走即可。
23
23
  4. 成功时命令**直接返回 `requestId` / `requestName` / `url`**(`status` 为 `CREATED` = 已建草稿、`CREATED_SUBMITTED` = 已提交审批)——**按返回值汇报即可,不需要再去查询反查**。
@@ -29,7 +29,9 @@
29
29
  - `validation/continuation_busy`:该 `context` 正被另一次执行占用、上一次还没发出写入——**稍后原样重试同一条命令**即可(不要重跑 createForm、不要换句柄);
30
30
  - `validation/continuation_consumed`:占用该句柄的执行停在无法判定的旧状态——先只读回查确认是否已发起,确认没发起才重跑。
31
31
 
32
- **省时纪律(这几件事一次都别做,每违反一条就多烧一轮工具往返)**:① 拿字段清单**不要**写脚本解析 `resultFile`(`fields` 被移出时用同伴的 `writableFields`);② `data` 的键**不要**写 `"字段名(字段ID)"`(只认字段 id);③ 只读字段**不要**传(看 `editableFields`);④ 浏览 / 人员 / 发票类必填项**不要**先猜一个值试试;⑤ 读命令输出**不要**用 `head`/`tail` 截断;⑥ 输出被宿主截断时**不要**去找宿主的工具结果目录(`~/.workbuddy/projects/**/tool-results/**`:读不了,去了必白跑一轮),按输出最前面的 `resultFile` 取。
32
+ **省时纪律(这几件事一次都别做,每违反一条就多烧一轮工具往返)**:① 拿字段清单**不要**写脚本解析 `resultFile`——输出里给了 `largeOutputNotice` 时直接照抄它给的那条读命令(路径与 `limit` 都写好了)把文件一次读完;② `data` 的键**不要**写 `"字段名(字段ID)"`(只认字段 id);③ 只读字段**不要**传(看 `editableFields`);④ 读命令输出**不要**用 `head`/`tail` 截断;⑤ 输出被宿主截断时**不要**去找宿主的工具结果目录(`~/.workbuddy/projects/**/tool-results/**`:读不了,去了必白跑一轮),按输出最前面的 `resultFile` 取。
33
+
34
+ **输出纪律(与上面的省时纪律同理:多写的每一句都在拖长回复,并让用户看不懂)**:① 面向用户**只给三样**——"这次做了什么、结果如何" + "**已填内容预览**"(展示口径见下文「主表(已填内容)展示规则」)+ "需要用户提供什么",其余不说——**尤其不要交代"用了哪个流程 / 编号是多少 / 我是怎么判断的"这类内部依据**(**唯一例外**:**本次决策若依据了历史记忆,必须按 `SKILL.md`「总原则」里的全局规则向用户说明依据了记忆**);② **不要复述自己的判断过程、取舍与推演**,也不要写自我批评或事后反省——用户要的是结果,不是你怎么想的;③ **不要把澄清分支的区别讲给用户**(如"不是有多个候选要挑,而是一条都没命中"):该报"系统里没有「XX」"就按下文浏览按钮口径直接说结论,**不要解释你是怎么判定出来的**;④ 需要用户给值时**只说清"要什么值"**,不要顺带解释"我为什么判断不出来"。
33
35
 
34
36
  ## 输入
35
37
 
@@ -37,30 +39,30 @@
37
39
 
38
40
  - `workflow`(string[],必填):工作流条件——`"名称(ID)"` / 纯名称 / 纯数字 ID。
39
41
  - **自带显式 ID(`"名称(ID)"` 或纯数字)时不查可发起列表**:流程名与"你能不能发起"都由表单载入接口直接给出,因此比"按名称解析"少一整次往返。该 ID 不可用时仍回澄清,但会带 `clarificationReason` 说明是**哪一种**(见下)。
40
- - **纯名称**按当前用户**可发起**的工作流做模糊匹配,**可一次给多个说法**:数组多个元素(`["报销","报销流程"]`)与一个元素内用英文逗号分隔(`["报销,报销流程"]`)**完全等价**,CLI 会把各说法拆成关键词、命中取并集去重。
42
+ - **纯名称**按当前用户**可发起**的工作流做模糊匹配,**可一次给多个说法**:数组多个元素(`["<说法1>","<说法2>"]`)与一个元素内用英文逗号分隔(`["<说法1>,<说法2>"]`)**完全等价**,CLI 会把各说法拆成关键词、命中取并集去重。
41
43
  - **直接选定并载入表单**时,`selectionSource` 标明是如何选定的:`workflowId`(按 ID 命中)/ `single`(唯一命中)/ `exactName`(全名精确匹配)。`exactName` 表示 CLI 已替用户选定,**不要再反问“您指的是哪一个”**。
42
44
  - **0 命中**,或**多命中且没有与所写完全一致的** → **澄清**:返回 `status: "NEEDS_CLARIFICATION"` + `candidates`(每项含 `id`/`name`/`display`,`display` 是 `名称(ID)`),此时**不返回任何表单数据**。把候选**原样**列给用户(不加 "(Recommended)"/"推荐" 等后缀,由用户明确选择),选定后用 `display` 的 `名称(ID)` 重发同一条命令。
43
45
  - **自带显式 ID 但该 ID 不可用** → 同样回澄清(`candidates` 为空),并带 `clarificationReason` 标明是**哪一种**——这两句话**必须分开说、不许混**:
44
- - `clarificationReason = "workflow_not_exist"`:该 ID 不存在(可能已删除或被停用)。如实告知"这个 ID 不存在",让用户核对 ID 或改用流程名称重发;**不要**说成"没有可发起的工作流"这类模糊说法。
46
+ - `clarificationReason = "workflow_not_exist"`:该目标不存在(可能已删除或被停用)。如实告知"这个目标不存在",请用户改用该流程的**完整名称**(或其它可用于检索的关键词)重发——**不要向用户索取 ID**;**不要**说成"没有可发起的工作流"这类模糊说法。
45
47
  - `clarificationReason = "no_create_right"`:流程**存在**,但当前账号**没有发起权限**。**必须明确说出「存在但没有发起权限」**,绝不能转述成"流程不存在";并给出下一步:改用其他可发起的流程,或联系管理员为该流程授予发起权限。
46
48
  - `relatesTo`(string,可选):关联对象 id,仅透传不影响表单初始化。
47
- - 返回 `continuation`(表单会话短句柄 `wc-…`,形如 `wc-1a2b3c4d5e6f7a8b`;载荷由 CLI 托管在本机,**它就是第 3 步 `createRequest` 的 `context` 入参**)、`runtime`/`frame`、字段清单、`initialValues`、`systemFields`、`fileUploadParams`、`workflow`、`launchPreferences`。
48
- - **字段多的表单有"大输出"形态**(字段少时无此字段):结果最前面多出 `resultFile` / `persistedResult` / `outputBytes` / `largeOutputNotice`,且 `fields` 二选一——① 紧凑编码(`columns` 是列名,`rows` 每行一个字段、各列用 `|` 分隔、顺序同 `columns`,非列信息按字段 id 放 `extra`,**不在 `extra` 里就是默认值**);② `fieldsOmitted: true` + `fieldCount`,`fields` 整体移出 stdout,**同一份输出里给 `writableFields` 补偿索引**(`columns` = `id|name|subFormId|componentKey|flags`,`flags` 含义见 `flagLegend`,带选项字段的选项名见 `optionIndex`,**日期/时间字段的格式见 `formatIndex`,附件字段的上传限制见 `uploadLimits`**)。
49
- - **填值前要核对的属性都已在 `writableFields` 里,不要再为它们读 `resultFile`**:`formatIndex`(字段 id → `format`,如 `yyyy-MM-dd HH:mm`)与 `uploadLimits`(字段 id → `大小上限|格式限制|数量上限`,如 `100MB|白名单:jpg,pdf|100个`;`不限格式` 表示不限制后缀,`-` 表示该项未配置)。这两份只在 `fields` 被移出的档位出现,**没有对应条目就是该字段没有这类要求**。
50
- - **`fields` 是「布局级字段全集」,不等于"页面上肉眼可见的字段数"**:它含联动隐藏、以及未在当前页展示的字段(真机实例:某表单 `fields` 278 个,其中 178 个是明细列,而真正能填的只有 60 个)。**判断"哪些字段能填"只看 `requiredFields` + `subFormRequired` + `editableFields`(大输出时用 `writableFields`)**,不要拿 `fields` 的条数当可填字段数,也不要因为"表单上看着没这么多"就怀疑字段清单不对。
51
- - **有 `writableFields` 就直接用**:全部可写字段的「字段名 ↔ 字段 id」都在里面,**直接用它的字段 id 构造 `data` 的键**。
52
- - **不要为了拿字段清单去写脚本解析 `resultFile`**:只有需要某字段更细的元数据(`browserModule` / `browserType` / 完整 `options` 结构)时才按该字段 id 去取。读任何输出都**不要用 `head`/`tail` 截断**(截断会破坏 JSON,还会诱发重复执行同一条命令)。**输出被宿主截断时**(只看到 2048 字节预览、或提示"已保存到文件"),**不要去读宿主的工具结果目录**(`~/.workbuddy/projects/**/tool-results/**`:没有读权限,去了必白跑一轮),直接按同一份输出最前面的 `resultFile` 取完整结果。
49
+ - 返回 `continuation`(表单会话短句柄 `wc-…`,形如 `wc-1a2b3c4d5e6f7a8b`;载荷由 CLI 托管在本机,**它就是第 3 步 `createRequest` 的 `context` 入参**)、`runtime`/`frame`、字段清单、`initialValues`、`historyRequestData`(本表单**必填字段**的历史参考值,`null` = 无可参考)、`systemFields`、`fileUploadParams`、`workflow`、`launchPreferences`。
50
+ - **字段多的表单只回一条提示**(字段少时无此形态、就是原样全量):此时结果里**只有** `resultFile` / `persistedResult` / `outputBytes` / `largeOutputNotice` 四个键,**不带任何表单属性**。
51
+ - **看到 `largeOutputNotice` 就照抄它给的那条读命令、把文件一次读完——这是继续下一步的前置动作**:那条命令里文件路径与 `limit` 都已经算好(`limit` = 该文件总行数,一次就能读完),直接执行即可。**字段清单、必填、`initialValues`、`historyRequestData`,以及第 3 步 `createRequest` 要用的 `contextId` 全都在那个文件里**,不读它手里就没有任何字段信息。**不要重跑 `createForm`、不要分段读、不要用 `head`/`tail` 截断、也不要用脚本去挖文件。**
52
+ - 文件里是**完整结果**(未裁剪的 pretty JSON):`fields` 是**完整结构**(每个字段带 `id` / `name` / `subFormId` / `componentKey`,另有 `options` / `format` / `fileUploadParams` 等按需出现的键),并带 `requiredFields` / `subFormRequired` / `editableFields` / `initialValues` / `systemFields` / `continuation`。**`fields` 里不标必填**——哪些是必填只看 `requiredFields` / `subFormRequired`。
53
+ - **`fields` 是「布局级字段全集」,不等于"页面上肉眼可见的字段数"**:它含联动隐藏、以及未在当前页展示的字段(真机实例:某表单 `fields` 278 个,其中 178 个是明细列,而真正能填的只有 60 个)。**判断"哪些字段能填"只看 `requiredFields` + `subFormRequired` + `editableFields`**,不要拿 `fields` 的条数当可填字段数,也不要因为"表单上看着没这么多"就怀疑字段清单不对。
54
+ - **输出被宿主截断时**(只看到 2048 字节预览、或提示"已保存到文件"):**不要去读宿主的工具结果目录**(`~/.workbuddy/projects/**/tool-results/**`:没有读权限,去了必白跑一轮),按同一份输出最前面的 `resultFile` 取完整结果。
53
55
  - **不要为了"看清字段"重跑 `createForm`**:返回什么就按什么拼 `data`。
54
56
 
55
57
  **查询词策略**:
56
58
 
57
59
  - **优先用记忆别名改写后再传**:用户给出的表达命中记忆别名(如"手机话费报销"含别名"费用报销")→ **直接传记忆别名**(可与原词并列成一次多关键词,见下条),**不要分两次命令试探**(先只传原词、没命中再换一个词)。
58
- - **一次给多个说法**:`workflow` 同一批次可并列多个说法(数组多元素 或 英文逗号分隔,见输入节);**不确定完整名称时,把①用户说法 ②可能的全名/同义说法 ③一个更宽的「上位词」都并列进这一批**——用户说"会议室预定",批次里就一并带上"会议"(如 `["会议室预定","会议室预订","会议室申请","会议"]`)。**同一批次加词不额外花往返**:命中取并集去重,某个词命不中只是白给,命中了就多一条线索。
60
+ - **一次给多个说法**:`workflow` 同一批次可并列多个说法(数组多元素 或 英文逗号分隔,见输入节);**不确定完整名称时,把①用户说法 ②可能的全名/同义说法 ③一个更宽的「上位词」都并列进这一批**(如 `["原说法","同义说法","上位词"]`)。**同一批次加词不额外花往返**:命中取并集去重,某个词命不中只是白给,命中了就多一条线索。
59
61
  - **上位词可以放进批次,但命中后必须核对**:`"话费"` / `"会议"` 这类宽词可能命中**语义无关**的工作流(如“话费”→“话费补贴标准审批流程”)。载入表单后**先核对 `workflow` 里的名称/类型与用户意图是否一致**(报销类意图 → 名称应含“报销/费用”,不应是“补贴标准/行政事务”类);**不一致就绝不要往下填字段**,改用记忆别名或更准的说法重发 createForm。**`selectionSource: "single"`(唯一命中即选定、不澄清)是最该核对的一档**。
60
62
  - **真正被禁的是"分多次命令逐词去撞"**:禁止先甲、再乙、再丙地反复试(把"换词"当检索策略,每试一次多烧一轮往返);**同一条命令里并列多个词、其中包括一个上位词,都不属于被禁的情形**——那是**补充召回**,不是拿宽泛词当主力检索。
61
63
  - **不要再继续换词试探**(一次多关键词后仍未定,就反问用户确认)。
62
64
 
63
- **拿到 form 返回后直接按用户已给信息拼 `data` 并立即调用 `createRequest`**——不分析字段、不猜映射、不比对选项,**也不要用空 `data` 先探测必填清单**(用户说了什么字段就填什么、用用户原词;必填缺失由 `createRequest` 的 `missingFields` 告知)。
65
+ **拿到 form 返回后直接按用户已给信息拼 `data` 并立即调用 `createRequest`**——不分析字段、不猜映射、不比对选项,**也不要用空 `data` 先探测必填清单**(用户说了什么字段就填什么、值用用户说过的说法;必填缺失由 `createRequest` 的 `missingFields` 告知)。
64
66
 
65
67
  **`initialValues`**:OA 初始化表单时预填的字段值(含 onLoadForm 联动带出值),`data` 应包含这些值(用户明确填写的以用户为准);**带 `subFormId` 的是明细表字段**(放进 `details` 对应行对象),**不带的是主表字段**(放 `main`)。这些默认值 **CLI 会自动并入**(主表进 `main`,明细按你建的行补),**漏带不会因此被报成缺必填**——不要为了"怕丢默认值"多跑一轮。反过来:**`missingFields` 里出现的字段就是真的没值**(OA 对浏览按钮类默认值可能只下发类型标记、不下发值),此时必须问用户,不要猜值。
66
68
 
@@ -86,13 +88,13 @@
86
88
  Windows PowerShell:
87
89
 
88
90
  ```powershell
89
- weaver-work-cli --json workflow run workflow.createForm --input-json '{"workflow":["请假"]}'
91
+ weaver-work-cli --json workflow run workflow.createForm --input-json '{"workflow":["<工作流名称>"]}'
90
92
  ```
91
93
 
92
94
  macOS/Linux(bash/zsh):
93
95
 
94
96
  ```bash
95
- weaver-work-cli --json workflow run workflow.createForm --input-json '{"workflow":["请假"]}'
97
+ weaver-work-cli --json workflow run workflow.createForm --input-json '{"workflow":["<工作流名称>"]}'
96
98
  ```
97
99
 
98
100
  ### ② 填好字段后一次完成发起(action 必填)
@@ -100,37 +102,54 @@ weaver-work-cli --json workflow run workflow.createForm --input-json '{"workflow
100
102
  Windows PowerShell:
101
103
 
102
104
  ```powershell
103
- weaver-work-cli --json workflow run workflow.createRequest --input-json '{"context":"<createForm返回的continuation>","data":{"main":{"报销事由":"客户约谈"}},"action":"submit"}'
105
+ weaver-work-cli --json workflow run workflow.createRequest --input-json '{"context":"<createForm返回的continuation>","data":{"main":{"<字段id>":"<字段值>"}},"action":"submit"}'
104
106
  ```
105
107
 
106
108
  macOS/Linux(bash/zsh):
107
109
 
108
110
  ```bash
109
- weaver-work-cli --json workflow run workflow.createRequest --input-json '{"context":"<createForm返回的continuation>","data":{"main":{"报销事由":"客户约谈"}},"action":"submit"}'
111
+ weaver-work-cli --json workflow run workflow.createRequest --input-json '{"context":"<createForm返回的continuation>","data":{"main":{"<字段id>":"<字段值>"}},"action":"submit"}'
110
112
  ```
111
113
 
112
114
  ## 返回
113
115
 
114
- - createForm:`status` 为 `FORM_READY` 时给 `continuation`、`workflow`、`runtime`、`frame`、`requiredFields`(字段 id 数组)、`subFormRequired`(subFormId → 字段 id 数组)、`editableFields`(**可写字段 id 白名单**)、`fields`(**布局级字段全集**,含联动隐藏/未在当前页展示的字段,**不等于"页面上肉眼可见的字段数"**;大表单时可能换成紧凑编码、或被整体移出 stdout —— 移出时同伴有 `writableFields`)、`initialValues`、`systemFields`、`fileUploadParams`、`launchPreferences`、`requiredInfoWarning`。**不返回 OA 的联动(显示属性)规则**——必填一律以 `createRequest` 的 `missingFields` 为准(见「注意」)。`status` 为 `NEEDS_CLARIFICATION` 时只给 `candidates` / `clarificationKeyword` / `clarificationReason`(存在时,见「输入」里的 `workflow_not_exist` / `no_create_right`)/ `candidateCount` / `clarificationQuestion` / `note`,**不含任何表单数据**——它不是失败(`ok:true`),也不代表查询已执行。
115
- - createRequest:`status`(`CREATED` / `CREATED_SUBMITTED` / `CREATED_SUBMIT_FAILED` / `NEEDS_INPUT` / `NEEDS_CONFIRMATION` / `ALREADY_APPLIED`)、`requestId`、`requestMark`、`requestName`、`url`、`contextId`、`fields`(确认预览:本次所填字段的落库结果,"我填的值到底存成了什么"就看这里)、`previewDetails`(明细表按列组织:`columns` 表头 + `rows` 每行明细;明细表按它排 Excel 列表格)、`missingFields`(**恒有值**:submit 成功时是空数组,draft 时是"提交前还需补齐"的提醒)、`missingFieldsNotice`(draft 且有缺失时的一段可直接转述的提醒文本)、`linkageResult`(联动带出/清空,原样转述)、`verification`(节点字段校验结果)、`attachmentFolderIds`、`submitResult`(提交结果,`success` / `failed`;**只在本命令真正发起过提交(`action:submit`)时出现**,`action:draft` 不带)、`submitFailReason`(**提交失败原因**:接口返回的可执行文案,仅 `submitResult: "failed"` 时出现)、`createRejectedReason`(创建这一步就被服务端拒绝、且未走提交路径时接口给出的原因)。
116
+ - createForm:`status` 为 `FORM_READY` 时给 `continuation`、`workflow`、`runtime`、`frame`、`requiredFields`(字段 id 数组)、`subFormRequired`(subFormId → 字段 id 数组)、`editableFields`(**可写字段 id 白名单**,已并入 `requiredFields` 的字段)、`fields`(**布局级字段全集**,含联动隐藏/未在当前页展示的字段,**不等于"页面上肉眼可见的字段数"**)。**字段多的表单只回一条提示**:此时只有 `resultFile` / `persistedResult` / `outputBytes` / `largeOutputNotice` 四个键,照抄提示里的读命令把文件一次读完即可拿到这里列出的全部内容(含 `contextId`)、`initialValues`、`systemFields`、`fileUploadParams`、`launchPreferences`、`requiredInfoWarning`。**不返回 OA 的联动(显示属性)规则**——必填一律以 `createRequest` 的 `missingFields` 为准(见「注意」)。`status` 为 `NEEDS_CLARIFICATION` 时只给 `candidates` / `clarificationKeyword` / `clarificationReason`(存在时,见「输入」里的 `workflow_not_exist` / `no_create_right`)/ `candidateCount` / `clarificationQuestion` / `note`,**不含任何表单数据**——它不是失败(`ok:true`),也不代表查询已执行。
117
+ - createRequest:`status`(`CREATED` / `CREATED_SUBMITTED` / `CREATED_SUBMIT_FAILED` / `NEEDS_INPUT` / `NEEDS_CONFIRMATION` / `ALREADY_APPLIED`)、`requestId`、`requestMark`、`requestName`、`url`、`contextId`、`fields`(确认预览:本次所填字段的落库结果,"我填的值到底存成了什么"就看这里)、`previewDetails`(明细表按列组织:`columns` 表头 + `rows` 每行明细;明细表按它排 Excel 列表格)、`missingFields`(**恒有值**:submit 成功时是空数组,draft 时是"提交前还需补齐"的提醒)、`missingFieldsNotice`(draft 且有缺失时的一段可直接转述的提醒文本)、`linkageResult`(联动带出/清空,原样转述)、`verification`(节点字段校验结果)、`attachmentFolderIds`、`submitResult`(提交结果,`success` / `failed`;**只在本命令真正发起过提交(`action:submit`)时出现**,`action:draft` 不带)、`submitFailReason`(**提交失败原因**:接口返回的可执行文案,仅 `submitResult: "failed"` 时出现)。
116
118
  - `NEEDS_CONFIRMATION`(`ambiguities` 非空)时同时给 `resolvedValues`("我传的值 → 服务端最终值"的回显)与 `missingFields`——先把 `ambiguities` 解决掉,再用同一 `context` 重发。
117
- - `needVerificationConfirm: true` 时流程**已创建但未提交**:向用户确认后用同一 `context`、带 `"verificationConfirmed": true` 重发 `action: "submit"`。
119
+ - `needVerificationConfirm: true` 时流程**已创建但未提交**:向用户确认后,用本次返回的 `requestId` 走提交(`workflow operateApply action=submit`);**不要用同一个 `context` 重发**——该句柄已消费,重发只会拿到 `ALREADY_APPLIED`。
118
120
  - **`CREATED_SUBMIT_FAILED`(提交结果=失败)**:流程**已创建为草稿**,但提交被服务端拒绝、**未进入审批**——表单数据已经落库,`requestId` / `requestName` / `url` 与成功时一样都给了(可直接打开查看或编辑),差别只在提交结果。此时 `submitResult: "failed"`、`submitFailReason` 是接口给出的失败原因。**处置:把失败原因原样转述给用户,并给出 `url`**;**不要**读成"什么都没做成",也**不要**原样重发同一次提交(会再堆一份草稿)。
119
121
  - `submitResult`:`CREATED_SUBMITTED` 时为 `"success"`(不带 `submitFailReason`);`CREATED_SUBMIT_FAILED` 时为 `"failed"`;**被节点字段校验拦下或未确认校验(`needVerificationConfirm`)时本就未提交,不返回该字段**。
122
+ - **`historyRequestData`(历史参考值,两条命令都会给)**:范围是**本工作流**、**近一年、非草稿、按发起时间倒序的前 5 条**「我发起的」流程——不是"所有流程混在一起",所以里面每条都是同一张表单的单据,字段可直接对照;形如 `[{requestId, requestName, createTime, fieldValues: [{fieldId, fieldName, value}]}]`;`value` 已按字段类型给出**可直接复用**的写法——浏览按钮 / 选项类为 `名称(id)`(多值以 `、` 分隔);**附件类为对象**(形如 `{"formField":{"id":"<字段id>"},"dataOptions":[{"optionId":"<附件ID>","content":"<文件名>","type":"<文件类型>"}]}`,可整块放进 `data`,见「历史流程数据参考规则」第三条);其余为普通字符串。**`null` 表示没有可参考的历史数据**(不返回空数组);某条历史流程在这批字段上一个值都没命中时会被整条剔除(所以条数可能少于 5)。**你不需要自己再去查历史流程。** 两条命令给的覆盖范围不同:
123
+ - `createForm` 返回的那份:**本表单必填字段**(`requiredFields` / `subFormRequired`)的取值——填 `data` 时就用它把能补的必填字段补上。
124
+ - `createRequest` 返回的那份(`NEEDS_INPUT` / `NEEDS_CONFIRMATION` 且 `missingFields` 非空时附带,其余情形不出现):**只含本次新出现的必填字段**(`createForm` 时还不是必填、联动命中后才变成必填的那些;`createForm` 已给过值的字段**不重复返回**)。
125
+ - **处置顺序(必守)**:`missingFields` 非空时**先看 `historyRequestData`**——这些字段的历史值能直接照用时,**直接填进 `data` 重发,不要拿去问用户**(这正是它存在的意义;`createForm` 已经给过的字段这里不会再给,那些值在第 2 步就该用上);**历史值缺失、或与本次情形明显不适用**时,才把这些字段一次问齐后带同一 `context` 重发 `action: "submit"`。**不要**把 `historyRequestData` 原样抛给用户当"参考列表"。
126
+
127
+ ## 历史流程数据参考规则
128
+
129
+ 历史流程数据有两个来源:命令随 `createForm` / `createRequest` 直接给的 `historyRequestData`,以及你自己按它的范围说明核对过的同类历史流程。**历史流程里的字段值只能按下面四条使用**——四条之外一律不推算、不拼接、不凭印象补值:
130
+
131
+ 1. **取值一致、且能推断与本次业务同类 → 可直接采用**:某个字段在**命中的历史流程里取值完全一致**(**一条也算**),并且对照这些历史流程的**其他字段值**,能推断它们和本次要填写的表单属于同一类业务时,直接把这个值填进 `data`,不必再问用户;**取值不一致**时,才需要**三条及以上**取值相同(同样要满足"能推断与本次同类业务"),否则按规则 2 处理或问用户。
132
+ 2. **看得出规律 → 按规律生成新值**:历史取值呈现可推断的规律(如编号递增、日期递推、金额分档)时,按该规律生成本次的新值;**规律推不出来就不要用**,照常问用户。
133
+ 3. **附件对象 → 直接复用,不要重新上传**:`historyRequestData` 里附件字段的 `value` **就是可直接使用的完整对象**(形如 `{"formField":{"id":"<字段id>"},"dataOptions":[{"optionId":"<附件ID>","content":"<文件名>","type":"<文件类型>"}]}`)——**把它整块放进 `data` 里该字段的位置**(主表字段进 `main`,明细字段进对应行的对象)即可,**不要自己拆解或改造**。两条硬要求:① `optionId` 只能用历史值里给的这个 ID,**不要拿文件名或其它字符串去拼**——拼出来的 ID 指向不存在的文件,命令不会报错、但附件是坏的;② `type` 照抄历史值(图片是 `image`、普通文件是 `file`),**不要改成别的**。这样复用就**不需要重新上传本地文件**(因此也不触发附件上传前的那句提醒);只有用户本次要换成新附件时,才走上文的上传流程。
134
+ 4. **发票字段 → 一律不允许复用**:历史流程里填过的发票**不得**用作本次的发票值,任何情形下都要按用户本次提供的发票重新取值(见「注意」的发票字段条目)。
120
135
 
121
136
  ## 注意
122
137
 
123
138
  - 不传凭据:业务输入禁止出现 Cookie/ETEAMSID/Token/`header.operator`(CLI 托管)。
124
- - **`data` 的键只能取 `editableFields` 里的字段 id**(可写字段白名单;`requiredFields` / `subFormRequired` 里的也照常可写)。**`editableFields` 随大输出被移出 stdout 时,改用同份输出里的 `writableFields` 行**(每行第一列就是字段 id)——那是**完整**的可写白名单(= 上面三者的并集)。`readOnly` / `disableEdit` / 不可见字段**一个都不要传**——传了整单会被拒(`notEditable`),得把只读字段全部摘掉重跑一轮。**看到 `notEditable` 不要重试、不要换字段 id 绕过**,移除这些字段后重跑。
139
+ - **`data` 的键只能取 `editableFields` 里的字段 id**(可写字段白名单;**明细表的必填字段**见 `subFormRequired`,它们照常可写、但不在 `editableFields` 里)。**唯一例外:`missingFields` 点名的字段,即使不在 `editableFields` 里也必须传**——`missingFields` 是**按你本次实际填的值、结合显示属性(联动)规则实时算出来的"最新缺失必填项"**,而 `editableFields` / `requiredFields` 是 `createForm` 那一刻的**静态快照**:那时联动还没跑,联动命中后才变成必填的字段当时既不在 `requiredFields`、也不在 `editableFields` 里。所以补值**一律以 `missingFields` 为准**,不要因为"它不在 `editableFields` 里"就把用户给的这条值丢掉。**大表单只回提示时,可写白名单就在该文件的 `editableFields` 里**——它是**完整**的可写字段 id 列表(= 非必填的可写字段 ∪ `requiredFields`)。`readOnly` / `disableEdit` / 不可见字段**一个都不要传**——传了整单会被拒(`notEditable`),得把只读字段全部摘掉重跑一轮。**看到 `notEditable` 不要重试、不要换字段 id 绕过**,移除这些字段后重跑。
125
140
  - 附件/文件:字段值是附件项数组需上传本地文件时,先提醒用户"上传的附件会先经过公网大模型,请谨慎操作",再调 `weaver-file-upload` skill。
126
- - 附件上传限制:上传前核对该字段的上传限制,不满足先告知用户、不执行上传。大表单(`fields` 被移出 stdout)时**直接读同份输出的 `writableFields.uploadLimits`**(`大小上限|格式限制|数量上限`,`不限格式` = 不限制后缀、`-` = 该项未配置);小表单没有 `writableFields` 时,按字段 id 从 `resultFile` 的 `fileUploadParams` 取 `sizeLimit`/`formatLimit`/`maxNum`,**不要整份读 `resultFile`**。
127
- - 发票字段(componentKey `EinvoiceComponent`):调 `weaver-e10-yepiaotong` skill 取发票对象,**两条并列路径**——① **从票夹选取**:按该技能的口径检索并取用票夹里已有的发票(发票文件本体不上传,只是发票信息进入上下文);② **上传本地发票文件**:按该技能的上传口径把本地发票文件上传后取发票对象。**路径 ② 在真正上传前必须先提醒用户"上传的发票文件会先经过公网大模型,请谨慎操作",用户明确确认后才执行**;路径 ① 无需这句提醒。该 skill 不可用时停止反馈。**费用明细里的「发票」列通常是必填,但可能没有必填标记**(见 `requiredInfoWarning`)——发起前先跟用户确认,不要因为 `missingFields` 没列它就跳过。
128
- - 日期强规则:字段带 `format`(如 `yyyy-MM-dd HH:mm`)时必须严格按 `format` 传完整值,只传日期会报 `DATETIME_FORMAT`,按提示补时间重传,不要靠命令自动补时间。`format` 从哪看:大表单一律看同份输出的 `writableFields.formatIndex`(**没有该字段的条目就是没有格式要求**);只有小表单(无 `writableFields`)或该档没给索引时,才按字段 id 去 `resultFile` 取。**不要为了拿 `format` 再读一次 `resultFile`**。
141
+ - 附件上传限制:上传前核对该字段的上传限制,不满足先告知用户、不执行上传。看该字段的 `fileUploadParams` 三项——`sizeLimit`(MB)、`formatLimit`(`mode` + `formats`;`formats` 为 `*.*` / `*` 表示不限制后缀)、`maxNum`(数量上限):小表单看 stdout 的 `fields`,大表单看你已经读到的 `resultFile` 里的 `fields`。
142
+ - 发票字段(componentKey `EinvoiceComponent`):支持两种赋值方式:① 从票夹选取:使用 `weaver-e10-yepiaotong` 技能查询票夹里已有的发票对象;② 使用 `weaver-e10-yepiaotong` 技能上传本地发票文件,并取上传后的发票对象。方式 ② 在真正上传前必须先提醒用户"上传的发票文件会先经过公网大模型,请谨慎操作",用户明确确认后才执行;方式 ① 无需这句提醒。用户未明确发票字段如何赋值时,先反问用户,不需要提前检测 `weaver-e10-yepiaotong` 技能是否可用,真正需要使用上述两种方式给发票赋值时,workbuddy环境下可直接到技能市场搜索【泛微E10业票通发票管理】并自动安装,搜索不到时反馈给用户,其余环境遇到技能缺失时直接反馈给用户。
143
+ - 发票类字段的历史值不可照抄。
144
+ - 发票值拿不到时直接问用户。
145
+ - 日期强规则:字段带 `format`(如 `yyyy-MM-dd HH:mm`)时必须严格按 `format` 传完整值,只传日期会报 `DATETIME_FORMAT`,按提示补时间重传,不要靠命令自动补时间。`format` 就在 `fields[].format` 上(**没有该键就是没有格式要求**):小表单看 stdout 的 `fields`,大表单看你已经读到的 `resultFile` 里的 `fields`,**不要为了拿 `format` 再读一次文件**。
129
146
  - **富文本字段(componentKey `RichText`)**:支持 HTML 内容、不受 maxLength 限制。**内容来自本地文档(docx/pptx/md 等)或结构化材料时,必须先把源内容转成 HTML(保留 h1-h3 层级、table 表格、ul/ol 列表结构)再填入,禁止直接填纯文本**;用户明确只要纯文本时除外。文本 / 富文本字段直接传字符串即可(CLI 按字段元数据落库),不需要也不允许把它包装成 `{id,name}` 之类的浏览按钮结构。
130
- - **字段键**:`main` 的键、`details[subFormId]` 行对象的键**都必须是字段 id**(`fields[].id`,或 `writableFields` 的 `id` 列)。`"字段名(字段ID)"` 这种写法**表单 data 不支持**(那是查询条件 `filterFields` 的写法),混用会报「存在重名或无法识别的表单字段,请改用字段 id」并白跑一轮。
131
- - 字段**值**格式:选项传 `name`;浏览按钮/人员/部门传名称自动转 ID;人员范围(EmployeeScope)传对象数组 `{"name":名称,"type":类型}`,类型取 user/dept/subcompany/group/role/position/external/all/allExternal。
147
+ - **字段键**:`main` 的键、`details[subFormId]` 行对象的键**都必须是字段 id**(`fields[].id`)。`"字段名(字段ID)"` 这种写法**表单 data 不支持**(那是查询条件 `filterFields` 的写法),混用会报「存在重名或无法识别的表单字段,请改用字段 id」并白跑一轮。
148
+ - 字段**值**格式:选项传 `name`;人员范围(EmployeeScope)传对象数组 `{"name":名称,"type":类型}`,类型取 user/dept/subcompany/group/role/position/external/all/allExternal。
149
+ - **浏览按钮 / 人员 / 部门类字段**(值传字符串,CLI 自动转 ID):可写 `名称`,也可写 `名称(ID)`(括号内是纯数字时按 ID 用、不再查名);纯名称**首轮就该一次给多个说法**(与上面 `workflow` 同口径:**同一字符串内用英文逗号分隔**,如 `"全称写法,简称写法"`;说不出完整名称时的展开口径见下文「必填的浏览 / 人员 / 发票类字段」那条),CLI 会把这些说法拆开、连同整串一起拿候选:**只有命中唯一、或某个候选与整串/某个说法完全同名时才会自动采用**,否则会把所有候选列出来让你向用户确认(不会拿一个“最接近”的结果蒙过去)。**该字段允许多选时,多值用数组**(每个元素各自可以带多个说法)。**不支持裸 ID**——只写数字会被当名称去查,查不到就是 `NOT_FOUND`。
150
+ - **澄清时一律不向用户索取 ID**:任何"名称没对上 / 候选要确认"的场合,只问该对象的**完整名称**,或**其它可用于检索的关键词**;确认候选后的回传值(`{"id":…,"name":…}`)由你按候选自行拼好,**不要让用户提供 ID**。
132
151
  - **人员范围(EmployeeScope)解析失败**:`createRequest` 返回 `NEEDS_CONFIRMATION`,`ambiguities` 里 `kind = "EMPLOYEE_SCOPE"`:
133
- - `reason = "NOT_FOUND"` → 系统里没有该名称,**一次明确告知用户**“没找到「XX(类型)」,请给出系统里的准确名称或 `{"optionId":"候选id","content":"候选名称","type":"类型"}`”,最多重试 1 次;
152
+ - `reason = "NOT_FOUND"` → 系统里没有该名称,**一次明确告知用户**“没找到「XX(类型)」,请给出该对象的完整名称,或其它可用于检索的关键词”,最多重试 1 次;
134
153
  - `reason = "MULTIPLE_MATCHES"` → 列出候选(`candidates`)让用户选,选定后按 `{"optionId","content","type"}` 回传;
135
154
  - `reason = "NOT_RESOLVED"` → 名称/类型齐了但没拿到 ID,通常上一次解析没成功,按上面两种口径让用户确认;
136
155
  - **禁止**因为"命令返回 ok"就当作字段已填好——出现 `ambiguities` 时必须先解决,否则该字段不会进入保存体。
@@ -139,18 +158,21 @@ weaver-work-cli --json workflow run workflow.createRequest --input-json '{"conte
139
158
  - **`missingFields` 可信**:条件命中与否由 `createRequest` 按**实际所填数据**(含联动带出值)实时计算,`missingFields` 就是当前真实缺失的必填项——照常调用,按它的返回补齐。**禁止**对用户说"系统不会校验必填项",也**禁止**用 `requiredInfoWarning` 非空当作"无法校验必填"的理由跳过校验。
140
159
  - 只有需要向用户交代"OA 页面上带红色星号的字段"时,才提示用户对照表单红星核对(含明细表里的列,如费用明细的「发票」)。
141
160
  - **必填缺失一次问齐**:`createRequest` 返回 `NEEDS_INPUT`(`missingFields`)时,**把主表 + 明细表全部缺失字段一次性列给用户**(每项注明需要的值类型/建议默认值),**禁止逐字段推演或逐个追问**;联动/默认值/记忆已覆盖的字段不会出现在 missing 里,直接采用即可。**`action: draft` 时缺失不阻断、状态是 `CREATED`,但 `missingFields` 同样会返回——必须原样转述(提交前需补齐),不要把 `CREATED` 读成"没有缺失"**(此时命令还会附一段 `missingFieldsNotice`,可直接用它)。
142
- - **必填的浏览 / 人员 / 发票类字段不要"先猜一个值试试"**:这类值要么来自用户(准确名称或 `{id,name}`),要么来自外部技能(发票走 `weaver-e10-yepiaotong`)。**第一次调用就在 `data` 里留空**,让 `missingFields` 把它们列出来,再连同其它缺失项**一次性问用户**;用猜测值去调用只会白跑一轮——就算被接受,你也不知道它解析成了**哪个**对象,仍然要回头问用户。
143
- - **`resolvedValues` / `fields` 用来自查解析结果**:`NEEDS_INPUT` / `NEEDS_CONFIRMATION` 时看 `resolvedValues`,成功时看 `fields`——都是"我传的值 → 服务端最终值"的回显(选项给名称,浏览/人员/部门给 `{id,name}` 数组)。**解析结果与预期不符就不要往下走**(例如传「泛微」被解析成了另一个主体),按上面的口径向用户确认后续用准确名称/ID。
144
- - **浏览按钮值匹配不上(BROWSER NOT FOUND)**:`createRequest` 返回 `NEEDS_CONFIRMATION`(`ambiguities` 里 `kind = "BROWSER"`)时按 `reason` 分别处理:
145
- - `reason = "NOT_FOUND"` 且 `candidatesAvailable = true` → CLI 已把该浏览控件首页的合法取值放进 `candidates`,**逐条列给用户挑**,选定后按 `{"id":"候选id","name":"候选名称"}` 重新提交;
146
- - `reason = "NOT_FOUND"` 且 `candidatesAvailable = false` → **一次明确告知用户"系统里没有「XX」,请提供系统里准确的名称或 `{id,name}`"**,用户给出后最多重试 1 次;
161
+ - **必填的浏览 / 人员 / 发票类字段:值来自用户的话 + 服务端解析(这里不存在"猜")**:从用户本轮说过的话里**取线索**——**含指路性的模糊线索**(楼层 / 楼栋 / 区域 / 简称等只有部分信息的说法)——**第一次调用就传进 `data`**。**线索不是完整名称时,首轮就把它的多种写法一次并列传完**(同 `workflow` 名的「一次给多个说法」口径,同一字符串内用英文逗号分隔):写法展开=**保留用户原话作锚点**,再补**全称 / 简称、去掉或补上单位词、数字写法变体**(如 `"全称写法,简称写法,去掉单位词的写法"`)——**只做同一个对象的写法变体,不要换另一个对象去试**。服务端只会有三种结果,按结果处置:**唯一命中**(直接可用,并按「主表(已填内容)展示规则」说明它命中成了什么)/**`MULTIPLE_MATCHES`**(列出 `candidates` 让用户点选,选定后按 `{"id":"候选id","name":"候选名称"}` 回传)/**`NOT_FOUND`**(明确告知"系统里没有「XX」,请提供该对象的完整名称,或其它可用于检索的关键词",最多重试 1 次)。**只有用户本轮完全没提到该字段时才留空**——留空是为了让 `missingFields` 把它列出来、连同其它缺失项**一次问齐**,这是**省往返手段,不是"不许传"**。真正**禁止**的只有两条:① **编造用户没说过的值**,或**凭空构造 `{id,name}` 绕过澄清**(就算被服务端接受,你也不知道它解析成了哪个对象)——**对用户原话做写法展开不算编造**(展开里始终留着用户原话作锚点);② 把多个说法拆成**一轮一轮重发**(同一条命令里并列多个说法属"补充召回",不额外花往返)。发票类走外部技能(`weaver-e10-yepiaotong`)。
162
+ - **特例 · 会议室字段(`browserType = mt_room`)**:房间名里**没有楼层 / 区域这类描述**,所以用户口里的楼层线索**本身不是房间名的子串**——只传带描述后缀的说法会 0 命中(`NOT_FOUND`、`candidates` 为空)。该字段首轮必须把线索的**最小可检索片段**(去掉描述性后缀后剩下的那部分)与**用户原话**一起**并列**传;命中多个候选时照常把 `candidates` 原样列给用户选。
163
+ - 这个字段**不做值推演**:最小可检索片段按上一条口径取定即可,**一次并列传完就下发命令**,不要在下发前反复比较"哪种写法更可能命中";**拿到候选就停**——照常把 `candidates` 原样列给用户选,不为"再试一次能否唯一命中"改写或收窄写法重发。
164
+ - 其它浏览按钮字段出现同类问题时,在本条下按同一格式**追加同级「特例 · <字段>(<browserType>)」小条**:只写该字段特有的匹配口径,**不写示例**。
165
+ - **`resolvedValues` / `fields` 既用来自查解析结果、也是「已填内容预览」的数据源**:`NEEDS_INPUT` / `NEEDS_CONFIRMATION` 时看 `resolvedValues`,成功时看 `fields`——都是"我传的值 → 服务端最终值"的回显(选项给名称,浏览/人员/部门给 `{id,name}` 数组)。**解析结果与预期不符就不要往下走**(例如传「泛微」被解析成了另一个主体),按上面的口径向用户确认,后续用完整名称。**这些回显同时要按下文「主表(已填内容)展示规则」转成给用户看的表格,不要只留在心里自查。**
166
+ - **浏览按钮值匹配不上(BROWSER NOT FOUND)**:`createRequest` 返回 `NEEDS_CONFIRMATION`(`ambiguities` 里 `kind = "BROWSER"`)时按 `reason` 分别处理。`candidates` 里**只会出现按你写的说法真实命中的值**,不会混进与该说法无关的系统默认清单:
147
167
  - `reason = "MULTIPLE_MATCHES"` → 列出 `candidates` 让用户选,选定后按 `{"id":"候选id","name":"候选名称"}` 回传;
148
- - **禁止自行换相近词反复提交**(如「差旅费」查不到就试「差旅」),也**禁止凭猜测直接构造 `{id,name}` 绕过澄清**。
168
+ - `reason = "NOT_FOUND"`(`candidatesAvailable = false`、`candidates` 为空)→ **一次明确告知用户"系统里没有「XX」,请提供该对象的完整名称,或其它可用于检索的关键词"**,用户给出后最多重试 1 次;
169
+ - 一个值有多种叫法时,**首轮就把这些写法一次用英文逗号串起来传**(展开口径见上文「必填的浏览 / 人员 / 发票类字段」那条)——同一条命令里并列多个说法属"补充召回",不额外花往返。**禁止的是拿一个说法试一次、失败后再换一个说法重发**(那是多轮逐词去撞),也**禁止凭空构造 `{id,name}` 绕过澄清**。
149
170
  - 明细表:`details` 的 key 是 subFormId,value 是行对象数组。
150
171
  - **明细表(子表单)展示规则(Excel 列展示)**:以 `previewDetails`(明细表按列组织:`columns` 表头 + `rows` 每行明细)为准——明细表**必须用 Excel 列展示**(表头 + 每行一条明细,形如 `| 序号 | 费用日期 | 费用类型 | 费用说明 | 申请金额 |`,每行一行),**禁止把明细字段按"字段\|内容"平铺**;`previewDetails` 为空时才用 `fields` 平铺兜底。多条明细时逐行展示(序号递增)。
172
+ - **主表(已填内容)展示规则(字段 / 值两列,单独成表)**:面向用户回显"这次填了什么"时,用**「字段 / 值」两列表格**展示,**只列本次实际填写的字段**——成功时取 `fields`、`NEEDS_INPUT` / `NEEDS_CONFIRMATION` 时取 `resolvedValues`;`requestName`(流程标题)已确定时在表内一并列出。**主表表格与明细表表格必须分开列**(先主表、后明细表),**禁止**把两表合成一张、也**禁止**用 bullet 列表代替表格;`missingFields` / `ambiguities` 里等用户确定的字段列为"未确定",并照常向用户询问。
151
173
  - 目录联动:附件字段 `folderDependsOnOption=true` 时,按最近一次返回的 `attachmentFolderIds` 取 `folderId`(null=不指定目录)再上传。
152
174
  - 初始化值:`createForm` 返回 `initialValues`(OA 预填值,含 onLoadForm 联动带出),`data` 应包含这些初始化字段值(用户明确填写的以用户为准);含 subFormId 的放 details 对应行,主表字段放 main。**漏带不会导致缺必填**(默认值由 CLI 自动并入主表与明细行);`missingFields` 里出现它就是真的没值,按上面口径问用户。
153
175
  - 不重试:saveFormData/flow/create 失败、超时或结果不确定(`SAVE_UNCERTAIN`/`PARTIAL_SAVED`/`CONTEXT_ALREADY_WRITTEN`/`WRITE_UNCERTAIN`)禁止重试,返回恢复信息并让用户人工检查。
154
176
  - 写操作遇登录失效:禁止自动重登重放,返回 `WRITE_UNCERTAIN` 停止,先只读回查。
155
177
  - `context` 与工作流强绑定:只用最终选定工作流那次 `createForm` 返回的 `continuation`;澄清后换了工作流就要重新 `createForm` 拿新句柄。
156
- - 本次发起的工作流本身、业务别名、以及字段口径偏好等**语义记忆**,按 memory 规则在任务结束时主动调用 `workflow.memoryExtract` 保存(见 workflow-memory.md)。
178
+ - **记忆保存(发起流程口径)**:本轮发起过程中,**只有用户有新的明确澄清**——① 工作流名称;② 字段名称;③ 浏览按钮字段值;④ 选项字段的选项值——才做记忆保存。**这四类之外一律不保存**:用户只是给出普通文本 / 日期 / 金额等字段的本次取值,或只是正常走完一次填单,都不构成记忆。满足条件时按 memory 规则在任务结束时**实际调用** `workflow.memoryExtract` 保存(见 workflow-memory.md)。
@@ -89,7 +89,7 @@ weaver-work-cli --json workflow run workflow.editApply --input-json '{"context":
89
89
  ## 返回
90
90
 
91
91
  - editLoad:`context`、`EDIT_READY`、`editableFields`(可编辑且可见字段 id)、`currentValues`(当前字段值)、`fields`(id→name/subFormId/componentKey/options)、`requestInfo`(标题/紧急程度/密级当前值,本次不改)。
92
- - editLoad 的**大表单形态**(字段多时才有,与 `createForm` 同一套):结果最前面多出 `resultFile` / `persistedResult` / `outputBytes` / `largeOutputNotice`,`fields` 要么换成紧凑编码(`columns` + `rows` 每行一字段、`|` 分隔;非列信息按字段 id 放 `extra`),要么带 `fieldsOmitted: true` + `fieldCount` 整体移出 stdout。两种形态都照常 `editPrepare`;要字段全文时从 `resultFile` **按需**提取,**不要重跑 `editLoad`**。
92
+ - editLoad 的**大表单形态**(字段多时才有,与 `createForm` 同一套):结果里**只有** `resultFile` / `persistedResult` / `outputBytes` / `largeOutputNotice` 四个键,**不带任何表单属性**——**先照抄 `largeOutputNotice` 里的读命令把该文件一次读完**(字段清单、`editableFields`、`currentValues`,以及第 2 步 `editPrepare` 要用的 `contextId` 全在里面),再照常做下一步;**不要重跑 `editLoad`、不要分段读**。
93
93
  - editPrepare:`READY`(changedFields + linkageResult)/ `NEEDS_CONFIRMATION`(重名用字段 id、明细表用 details 结构、不可编辑字段报 notEditable)。
94
94
  - editApply:`EDIT_SAVED`(仅 saveFormData,保存前自动触发 EVENT_SAVE_DATA 联动)。
95
95
 
@@ -103,4 +103,5 @@ weaver-work-cli --json workflow run workflow.editApply --input-json '{"context":
103
103
  - `linkageResult`(联动带出)原样转述给用户查看。
104
104
  - 流程已流转到非编辑节点时 editApply 返回"失去操作权限",如实转述。
105
105
  - 不重试:写操作失败、超时或结果不确定(`WRITE_UNCERTAIN`/`partial`)禁止重试,返回恢复信息并让用户人工检查。
106
+ - 接口异常一律原样反馈给用户,禁止自行尝试解决方案:把接口提示原文转述给用户、说明本次修改**没有保存成功**;不得替接口解释原因,不得自行改用别的做法(如重新发起一条)去绕。见 `SKILL.md`「总原则」。
106
107
  - 写操作遇登录失效:禁止自动重登重放,结果未知时不得自动重放。
@@ -111,7 +111,7 @@ weaver-work-cli --json workflow run workflow.memoryExtract --input ./mem-extract
111
111
 
112
112
  ## 记忆规则(保存时机与处理)
113
113
 
114
- 每轮完整实质任务结束后(输出最终回复前),必须自行判断本轮是否出现**新的、有价值的语义记忆**(例如用户新澄清/确认了具体工作流、字段名、字段选项;与已有记忆重复的不算,必填字段的填值偏好不算):
114
+ 每轮完整实质任务结束后(输出最终回复前),必须自行判断本轮是否出现**新的、有价值的语义记忆**(例如用户新澄清/确认了具体工作流、**字段名 / 浏览按钮字段值 / 选项字段的选项值**;与已有记忆重复的不算):
115
115
 
116
116
  - **有** → 组装本轮"用户原始意图 + 澄清过程 + 确认结果"的消息列表并调用 `workflow.memoryExtract`(同步,`async` 语义为返回真实结果):
117
117
  - `saved:true` → 用自然语言告知用户会记住什么(如"后续发起请假流程会默认按本次偏好填写"),不展示接口原文;
@@ -121,7 +121,7 @@ weaver-work-cli --json workflow run workflow.memoryExtract --input ./mem-extract
121
121
  **硬禁令(必须遵守)**:
122
122
 
123
123
  - **不允许只在思考中写"保存记忆"**:判断"有"后必须**实际调用** `workflow.memoryExtract` 命令,命令完成(拿到真实 `saved`)后再输出最终回复。只在思考/内心说"应该保存"而不执行命令 = 没保存,属于违规。
124
- - 本次发起的工作流本身、业务别名、以及本次新确认的字段口径偏好(**「字段口径」指字段名、选项含义这类语义澄清,不含单据里填了什么值;必填字段的填值偏好不算**),只要符合开头「新的、有价值的」判据,就属于要保存的情形,不要漏。
124
+ - **发起流程(`workflow.createForm` / `workflow.createRequest`)按更窄的口径**:本轮发起过程中,只有**用户有新的明确澄清**——① 工作流名称;② 字段名称;③ 浏览按钮字段值;④ 选项字段的选项值——才属于要保存的情形(口径见 [`workflow-create.md`](workflow-create.md));**这四类之外一律不保存**(用户只是给出普通文本 / 日期 / 金额字段的本次取值、或只是正常走完一次填单,都不算记忆),不要漏也不要多存。
125
125
  - **别名条目的 `workflowId` 是「(待确认)」时,它是一张待办不是终态**:本轮只要把该别名唯一解析出了 `workflowId`(**`cards[].workflowId`** 或 `countDetails[].workflowId` 里就有),任务结束时**必须再保存一次把 ID 补上**,不要放着不管——否则下一轮读到的还是「(待确认)」,只能拿纯名称去试探,多命中还要再澄清一次。
126
126
 
127
127
  消息列表由模型在本地组装并作为入参传入(`msgList` 或 `userMessage`+`assistantMessage`);可含多轮原始消息(尤其澄清链路),可精简无用消息(命令执行日志、大段接口原始返回、调试输出),不需要模型提前总结。
@@ -142,7 +142,8 @@ weaver-work-cli --json workflow run workflow.operatePrepare --input-json '{"requ
142
142
  ## 注意
143
143
 
144
144
  - `deleteRequest`(删除流程)不可恢复,执行前必须明确告知用户不可逆影响并征得确认。
145
- - 接收人名称由 CLI 调人员浏览器解析:**多命中**报 `receiver_ambiguous`(`error.message` 说明需回传 `"名称(ID)"`)、**0 命中**报 `receiver_not_found`——CLI **不会静默取第一个**。用户确认后按 `"名称(ID)"` 回传,其余已确认的接收人按同样格式一并带上(逗号分隔)。
145
+ - 接收人名称由 CLI 调人员浏览器解析:**多命中**报 `receiver_ambiguous`(`error.message` 附 `candidates`)、**0 命中**报 `receiver_not_found`——CLI **不会静默取第一个**。
146
+ - **澄清时一律不向用户索取 ID**:只问该接收人的**完整姓名**,或**其它可用于检索的关键词**;用户确认后由你按 `"姓名(ID)"`(ID 取 `candidates` 里的那一项)把值拼好回传,其余已确认的接收人按同样格式一并带上(逗号分隔)。**不要让用户提供 ID**。
146
147
  - 失败一律看 **stderr** 的 `{ok:false, error:{type, subtype, message, retryable}}`(**没有** `success`/`stopReason`/`userMessage` 字段);`error.message` 原样转述,不自行改写或补造结果。
147
148
  - `continuation` 是 CLI 托管的短句柄(形如 `wc-1a2b3c4d5e6f7a8b`),Agent 只原样回传,禁止解析、手工构造、修改或复用;`confirm` 必须且只能为 `true`。
148
149
  - Apply 被重复执行、且上一次已经成功时,返回 `ok:true` + `data.status = "ALREADY_APPLIED"`(含 `previousResult`;若上一次是"服务端已成功回执、只是没来得及写回结果",还会给出 `requestId`)——**这不是失败**,本次没有重复写入,按上一次结果汇报即可,不要重跑 Prepare。
@@ -1,6 +1,6 @@
1
1
  # 流程查询(workflow.search / workflow.todoStat)
2
2
 
3
- > **分段索引 —— 本文件约 108 KB / 833 行,必须按段读:整读会超单次读取上限被明确拒绝**(Read 单次上限约 **20,000 tokens ≈ 100 KB / 800 行**);**开头的契约段(1-244 行,约 30 KB)一次就能读完**,其余段落按本索引的行区间分次读。**
3
+ > **分段索引 —— 本文件约 108 KB / 835 行,必须按段读:整读会超单次读取上限被明确拒绝**(Read 单次上限约 **20,000 tokens ≈ 100 KB / 800 行**);**开头的契约段(1-244 行,约 30 KB)一次就能读完**,其余段落按本索引的行区间分次读。**
4
4
  > 被拒时按报错提示改用 `offset`/`limit`、**回到本文件按行段重读**即可;**不要**去找宿主的落盘文件(`~/.workbuddy/projects/**/tool-results/**` 无读取权限,去读只会拿到 `Permission … has been denied`、白费一轮——"落盘 + 只回 2048 字节预览"那是**命令输出**超线时的行为,本文件的读取不走那条路)。
5
5
  >
6
6
  > | 段落 | 行区间 | 读取方式 |
@@ -9,10 +9,10 @@
9
9
  > | `planJson` 批量编排 | 245-324 | 泛化待办 / 一次取多组数时读:`offset 245 limit 80` |
10
10
  > | 汇报式分组骨架 + 七个维度 + 参与身份说明与分组去向 + 常见业务重点字段 + 汇总渲染规则 + 渲染红线 | 325-524 | 需要输出分组结果前读(分两次):`offset 325 limit 100`、`offset 425 limit 100` |
11
11
  > | 智能分组示例(各业务域样例,**仅供格式参照,不要照抄内容**) | 525-639 | 一般**不用读** |
12
- > | **异常返回处理 + 澄清后回传**(澄清信封、修正指令、认证失效) | 640-700 | 拿到 `ok:false` 或 `NEEDS_CLARIFICATION` 时读:`offset 640 limit 61` |
13
- > | 调用示例 | 701-779 | 需要时读:`offset 701 limit 79` |
14
- > | 返回(返回结构 / 错误码 / 幂等口径) | 780-819 | 处理 `ok` / `error` 时读:`offset 780 limit 40` |
15
- > | 注意 | 820-833 | 需要时读:`offset 820 limit 14` |
12
+ > | **异常返回处理 + 澄清后回传**(澄清信封、修正指令、认证失效) | 640-702 | 拿到 `ok:false` 或 `NEEDS_CLARIFICATION` 时读:`offset 640 limit 63` |
13
+ > | 调用示例 | 703-781 | 需要时读:`offset 703 limit 79` |
14
+ > | 返回(返回结构 / 错误码 / 幂等口径) | 782-821 | 处理 `ok` / `error` 时读:`offset 782 limit 40` |
15
+ > | 注意 | 822-835 | 需要时读:`offset 822 limit 14` |
16
16
  >
17
17
  > 行号以本索引为准;**改本文件时同步更新本索引**。按 `##` 标题定位同样有效。
18
18
 
@@ -94,7 +94,7 @@
94
94
  | 发起人 | `creator`、`creatorDept`、`creatorSubcom` | 姓名/部门/分部;「我/我的」= 当前用户 |
95
95
  | 工作流类型 | `workflowType` | 类型名;**多命中/0 命中时 CLI 返回澄清信封并列出候选**,改用 `名称(ID)` 重发 |
96
96
  | 当前节点 ID | `nodeId`、`nodeIdTerm`(`in`/`notin`) | 节点 ID |
97
- | 流程状态 | `flowStatus`、`flowStatusTerm`(`in`/`notin`) | 状态值;`已结束` = 强制+正常结束 |
97
+ | 流程状态 | `flowStatus`、`flowStatusTerm`(`in`/`notin`) | `finish`(已结束)/ `normalFinish`(正常结束)/ `forceFinish`(强制结束)/ `notFinish`(未结束·审批中)——**传英文 key**,不接受中文;可逗号分隔多值 |
98
98
  | 精确过滤/排除 | `requestId`、`exRequestId` | 逗号分隔多个 requestId |
99
99
  | 排序 | `sort` | `"排序方式:asc\|desc"`,多组逗号分隔 |
100
100
  | 条件关系 | `conditionType` | `and`(默认)/`or` |
@@ -657,6 +657,8 @@ CLI 按 OA 版本自动路由,**两种模式的返回形态不同,按实际
657
657
 
658
658
  名称类条件**解析不出唯一对象**时不会静默放行:返回澄清信封(`ok:true` + `status:NEEDS_CLARIFICATION` + `data.candidates`),**不返回任何业务数据**。收到澄清就按下面的流程把候选原样交给用户;**不要**自行挑一个候选继续,也**不要**换词重发试探。
659
659
 
660
+ **澄清时一律不向用户索取 ID**:只问该对象的**完整名称**,或**其它可用于检索的关键词**——候选确认后的回传格式(`名称(ID)`)由你按 `candidates[].display` 自行拼好,**不要让用户提供 ID**。
661
+
660
662
  返回形态分两类(澄清信封 / 硬失败),**不要混为一谈**:
661
663
 
662
664
  | 情形 | 返回 | 处理 |
@@ -668,7 +670,7 @@ CLI 按 OA 版本自动路由,**两种模式的返回形态不同,按实际
668
670
  | 表单字段元数据读不到 / 空清单 | **澄清信封**(`clarificationType=field_meta`,**无候选**) | 按 `clarificationQuestion` 如实告知用户或改不带 `filterFields` 查询 |
669
671
  | 工作流类型 / 发起人 / 发起人部门 / 发起人分部 / 紧急程度 **0 命中** | **`ok:false` + `error.subtype=<字段>_not_found`**(V11.3 是硬失败) | 按上表「异常返回处理」的 `*_not_found` 行处理,**不是**澄清 |
670
672
 
671
- **候选就用服务端返回的这一批(最多 10 条),不要指望 CLI 帮你扩召回**:CLI 按用户原词直接问服务端,返回几条就是几条——这是刻意的,名称类模糊匹配在大租户下可能命中成千上万条,取全既慢又没意义。所以:① 把这批候选**原样**给用户看;② **这批里都不匹配时,请用户给出准确的完整名称(或用 `名称(ID)`)**,不要自行换相近词反复试探、也不要要求 CLI 取更多候选;③ 用户给了更准的词就重发一次,仍不匹配就如实告知。
673
+ **候选就用服务端返回的这一批(最多 10 条),不要指望 CLI 帮你扩召回**:CLI 按用户原词直接问服务端,返回几条就是几条——这是刻意的,名称类模糊匹配在大租户下可能命中成千上万条,取全既慢又没意义。所以:① 把这批候选**原样**给用户看;② **这批里都不匹配时,请用户给出该对象的完整名称(或其它可用于检索的关键词)**,不要自行换相近词反复试探、也不要要求 CLI 取更多候选;③ 用户给了更准的词就重发一次,仍不匹配就如实告知。
672
674
 
673
675
  `data.candidates` 为空(`candidateCount=0`)说明该名称在当前环境**根本没有对应对象**(多半是错别字/漏字),请用户给准确全名后重发,**不要**当作"没有匹配的流程"答复。
674
676
 
@@ -41,6 +41,8 @@
41
41
 
42
42
  名称自动转 ID;`name` 也支持 `"名称(ID)"`(如 `"张三(1001)"`):此时**直接采用括号里的 ID、不再搜名称**,多命中澄清后按该形式回传即可。多命中返回候选列表让用户确认,禁止静默全选(不允许把同名多人全部设为共享对象);0 命中报错提示核对名称。
43
43
 
44
+ **澄清时一律不向用户索取 ID**:只问该对象的**完整名称**,或**其它可用于检索的关键词**;候选确认后的 `"名称(ID)"` 由你按 `candidates` 里的那一项自行拼好,**不要让用户提供 ID**。
45
+
44
46
  ## 示例
45
47
 
46
48
  ### 共享给一个人 + 一个部门 + 所有人