weaver-work-cli 0.1.29 → 0.1.31

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 (185) hide show
  1. package/dist/chunks/archive-U766FTFH.js +2537 -0
  2. package/dist/chunks/archive-oa-DMWEKX3L.js +1317 -0
  3. package/dist/chunks/asset-TCR7VDEV.js +2109 -0
  4. package/dist/chunks/attachment-content-AQNX5N3S.js +23 -0
  5. package/dist/chunks/blog-EVZWGDVM.js +2157 -0
  6. package/dist/chunks/caizhilian-JOWS6SL5.js +10087 -0
  7. package/dist/chunks/calendar-5WNCV66Q.js +1195 -0
  8. package/dist/chunks/chunk-2DUV44UX.js +15606 -0
  9. package/dist/chunks/chunk-324YPTC2.js +1607 -0
  10. package/dist/chunks/chunk-65QMVWHS.js +231 -0
  11. package/dist/chunks/chunk-6V7ZLF34.js +387 -0
  12. package/dist/chunks/chunk-AC7KJWC5.js +358 -0
  13. package/dist/chunks/chunk-AJ62BGAW.js +29 -0
  14. package/dist/chunks/chunk-BUSC6UAE.js +43 -0
  15. package/dist/chunks/chunk-CVZ2JOSW.js +62 -0
  16. package/dist/chunks/chunk-D4LTJSJD.js +477 -0
  17. package/dist/chunks/chunk-EG6ZU444.js +654 -0
  18. package/dist/chunks/chunk-EZALDOQH.js +383 -0
  19. package/dist/chunks/chunk-FMPJJYYI.js +106 -0
  20. package/dist/chunks/chunk-G2JSIUWF.js +769 -0
  21. package/dist/chunks/chunk-GCG2NMWR.js +703 -0
  22. package/dist/chunks/chunk-GPMFD4RD.js +75 -0
  23. package/dist/chunks/chunk-H3WDBYJW.js +508 -0
  24. package/dist/chunks/chunk-H6XSTSLM.js +2357 -0
  25. package/dist/chunks/chunk-J7RJTZSV.js +5556 -0
  26. package/dist/chunks/chunk-LUSPKZKY.js +53 -0
  27. package/dist/chunks/chunk-NIAJ5ZCG.js +73 -0
  28. package/dist/chunks/chunk-NOODWMCL.js +584 -0
  29. package/dist/chunks/chunk-OOUTBLZ4.js +51 -0
  30. package/dist/chunks/chunk-P26ZWSKU.js +73 -0
  31. package/dist/chunks/chunk-QWY6PGL6.js +3472 -0
  32. package/dist/chunks/chunk-R2IJAK7T.js +464 -0
  33. package/dist/chunks/chunk-R7O5PUWO.js +205 -0
  34. package/dist/chunks/chunk-RCGYCOMG.js +6962 -0
  35. package/dist/chunks/chunk-VZTXRG6X.js +403 -0
  36. package/dist/chunks/chunk-WHD4XMRP.js +161 -0
  37. package/dist/chunks/chunk-YLCYX7LE.js +371 -0
  38. package/dist/chunks/chunk-ZEDWSH32.js +68 -0
  39. package/dist/chunks/continuation-2CKSBLA6.js +11 -0
  40. package/dist/chunks/continuation-HZIZRZBX.js +13 -0
  41. package/dist/chunks/continuation-NLECEJPX.js +11 -0
  42. package/dist/chunks/ebuilder-form-NJ4YK6CC.js +2276 -0
  43. package/dist/chunks/ehr-MMYN36VA.js +5241 -0
  44. package/dist/chunks/employee-SAK2QYXX.js +11 -0
  45. package/dist/chunks/esb-HIWHOU7Q.js +141 -0
  46. package/dist/chunks/fna-KBACQTA5.js +1444 -0
  47. package/dist/chunks/host-3OHS5QUX.js +21 -0
  48. package/dist/chunks/host-IG6KEH5Q.js +19 -0
  49. package/dist/chunks/host-KQL5N4HO.js +23 -0
  50. package/dist/chunks/host-LLSZQCWR.js +17 -0
  51. package/dist/chunks/hrm-LYEC67ZQ.js +244 -0
  52. package/dist/chunks/im-RN2UKAEU.js +252 -0
  53. package/dist/chunks/invoice-EEPHLAF6.js +5179 -0
  54. package/dist/chunks/jiuchuanhui-WVVZYSJE.js +1940 -0
  55. package/dist/chunks/lazy-dispatch-MDOFFL2S.js +28 -0
  56. package/dist/chunks/mail-LNQLTF6L.js +2695 -0
  57. package/dist/chunks/meeting-XSD3BDVQ.js +504 -0
  58. package/dist/chunks/msg-parse-4GSQ2WTO.js +41 -0
  59. package/dist/chunks/okr-TMWTIU2K.js +2482 -0
  60. package/dist/chunks/plan-A2FSFA7T.js +2025 -0
  61. package/dist/chunks/project-T26QLBQF.js +1361 -0
  62. package/dist/chunks/registry-2VLUAESA.js +14 -0
  63. package/dist/chunks/registry-JCFEYXOE.js +18 -0
  64. package/dist/chunks/registry-NYPYMZXG.js +16 -0
  65. package/dist/chunks/registry-Q7OQJ3SU.js +19 -0
  66. package/dist/chunks/registry-ZJMJVWFA.js +19 -0
  67. package/dist/chunks/room-recommend-UR4ZDZS6.js +20 -0
  68. package/dist/chunks/schedule-5L2PM4M6.js +24 -0
  69. package/dist/chunks/state-Y2XBP6YE.js +15 -0
  70. package/dist/chunks/workflow-TR6PG2SL.js +245 -0
  71. package/dist/cmd/argv.js +45 -0
  72. package/dist/cmd/docs/index.js +3 -3
  73. package/dist/cmd/lazy-dispatch.js +20 -0
  74. package/dist/cmd/root.js +2 -4
  75. package/dist/cmd/setup/index.js +2 -2
  76. package/dist/cmd/skills/index.js +2 -2
  77. package/dist/core/package-paths.js +47 -0
  78. package/dist/index.js +163 -7
  79. package/dist/internal/e10/auth/xiaoe.js +3 -3
  80. package/dist/internal/e10/request-runtime.js +18 -62
  81. package/dist/internal/skills/detector.js +2 -2
  82. package/dist/shortcuts/contract/data/performance-catalog.js +1306 -0
  83. package/dist/shortcuts/contract/host.js +91 -35
  84. package/dist/shortcuts/contract/index.js +213 -0
  85. package/dist/shortcuts/contract/manifest.js +928 -0
  86. package/dist/shortcuts/contract/ooxml/docx.js +295 -0
  87. package/dist/shortcuts/contract/ooxml/xlsx.js +221 -0
  88. package/dist/shortcuts/contract/ooxml/zip.js +158 -0
  89. package/dist/shortcuts/contract/operations/assistant.js +1156 -0
  90. package/dist/shortcuts/contract/operations/clause-library.js +522 -0
  91. package/dist/shortcuts/contract/operations/compare.js +193 -0
  92. package/dist/shortcuts/contract/operations/credit-page.js +34 -0
  93. package/dist/shortcuts/contract/operations/flow.js +98 -0
  94. package/dist/shortcuts/contract/operations/page.js +66 -0
  95. package/dist/shortcuts/contract/operations/performance.js +733 -0
  96. package/dist/shortcuts/contract/operations/quote.js +557 -0
  97. package/dist/shortcuts/contract/operations/recommend.js +78 -0
  98. package/dist/shortcuts/contract/operations/registry.js +18 -0
  99. package/dist/shortcuts/contract/operations/review.js +83 -0
  100. package/dist/shortcuts/contract/operations/shared.js +37 -0
  101. package/dist/shortcuts/contract/operations/upload.js +108 -0
  102. package/dist/shortcuts/contract/operations/write.js +3 -2
  103. package/dist/shortcuts/index.js +140 -40
  104. package/dist/shortcuts/invoice/manifest.js +34 -11
  105. package/dist/shortcuts/invoice/operations/reim-auto.js +9 -0
  106. package/dist/shortcuts/invoice/operations/reim.js +81 -5
  107. package/dist/shortcuts/invoice/operations/shared.js +12 -5
  108. package/dist/shortcuts/meeting/host.js +45 -3
  109. package/dist/shortcuts/meeting/invitation/docx.js +442 -0
  110. package/dist/shortcuts/meeting/operations/attachment-content.js +418 -0
  111. package/dist/shortcuts/meeting/operations/attachment.js +442 -0
  112. package/dist/shortcuts/meeting/operations/eb/cache.js +57 -0
  113. package/dist/shortcuts/meeting/operations/eb/catalog.js +343 -28
  114. package/dist/shortcuts/meeting/operations/eb/conflict.js +372 -11
  115. package/dist/shortcuts/meeting/operations/eb/create-flow.js +710 -0
  116. package/dist/shortcuts/meeting/operations/eb/decision.js +47 -1
  117. package/dist/shortcuts/meeting/operations/eb/factory.js +129 -11
  118. package/dist/shortcuts/meeting/operations/eb/index.js +122 -2
  119. package/dist/shortcuts/meeting/operations/eb/room-recommend.js +378 -0
  120. package/dist/shortcuts/meeting/operations/eb/room-summary.js +84 -0
  121. package/dist/shortcuts/meeting/operations/eb/schedule.js +450 -0
  122. package/dist/shortcuts/meeting/operations/from-group-chat.js +576 -0
  123. package/dist/shortcuts/meeting/operations/invitation.js +458 -0
  124. package/dist/shortcuts/meeting/operations/minute-content.js +266 -0
  125. package/dist/shortcuts/meeting/operations/pipeline.js +489 -0
  126. package/dist/shortcuts/meeting/operations/qrcode.js +131 -0
  127. package/dist/shortcuts/meeting/operations/receipts.js +1 -1
  128. package/dist/shortcuts/meeting/operations/registry.js +18 -0
  129. package/dist/shortcuts/meeting/operations/summary.js +276 -0
  130. package/dist/shortcuts/meeting/operations/task-notify.js +325 -0
  131. package/dist/shortcuts/meeting/operations.js +42 -1
  132. package/dist/shortcuts/meeting/qr/encoder.js +427 -0
  133. package/dist/shortcuts/meeting/qr/render.js +103 -0
  134. package/dist/shortcuts/workflow/operations/form.js +17 -5
  135. package/docs/contract.md +39 -4
  136. package/docs/invoice.md +5 -5
  137. package/package.json +3 -2
  138. package/scripts/bundle.mjs +63 -0
  139. package/skill-template/business-info.json +25 -4
  140. package/skill-template/domains/jinchengda.md +16 -3
  141. package/skill-template/domains/yepiaotong.md +1 -1
  142. package/skills/weaver-e10-jinchengda/SKILL.md +111 -31
  143. package/skills/weaver-e10-jinchengda/references/contract-agent-entry.md +7 -13
  144. package/skills/weaver-e10-jinchengda/references/contract-ai-assistant.md +150 -0
  145. package/skills/weaver-e10-jinchengda/references/contract-ai-review.md +87 -0
  146. package/skills/weaver-e10-jinchengda/references/contract-clause-library-crud.md +111 -0
  147. package/skills/weaver-e10-jinchengda/references/contract-clause-recommender.md +0 -15
  148. package/skills/weaver-e10-jinchengda/references/contract-clause-reference-save.md +0 -13
  149. package/skills/weaver-e10-jinchengda/references/contract-credit-page.md +50 -0
  150. package/skills/weaver-e10-jinchengda/references/contract-disabled-capabilities.md +4 -2
  151. package/skills/weaver-e10-jinchengda/references/contract-doc-compare.md +74 -0
  152. package/skills/weaver-e10-jinchengda/references/contract-flow-launch.md +84 -0
  153. package/skills/weaver-e10-jinchengda/references/contract-performance-query.md +29 -0
  154. package/skills/weaver-e10-jinchengda/references/contract-quote-to-contract.md +28 -0
  155. package/skills/weaver-e10-jinchengda/references/contract-request-status.md +2 -21
  156. package/skills/weaver-e10-jinchengda/references/contract-request-write.md +0 -24
  157. package/skills/weaver-e10-jinchengda/references/contract-signing-subjects.md +0 -15
  158. package/skills/weaver-e10-jinchengda/references/contract-subject-create.md +0 -17
  159. package/skills/weaver-e10-jinchengda/references/contract-template-recommend.md +70 -0
  160. package/skills/weaver-e10-jinchengda/references/contract-template-selector.md +0 -15
  161. package/skills/weaver-e10-jinchengda/references/contract-workflow-discovery.md +0 -15
  162. package/skills/weaver-e10-jinchengda/references/source-manifest.json +1168 -152
  163. package/skills/weaver-e10-meeting/SKILL.md +493 -17
  164. package/skills/weaver-e10-meeting/references/meeting-change.md +4 -4
  165. package/skills/weaver-e10-meeting/references/meeting-create.md +6 -6
  166. package/skills/weaver-e10-meeting/references/meeting-eb.md +503 -27
  167. package/skills/weaver-e10-meeting/references/meeting-invitation.md +113 -0
  168. package/skills/weaver-e10-meeting/references/meeting-lifecycle.md +6 -6
  169. package/skills/weaver-e10-meeting/references/meeting-minute-file.md +425 -0
  170. package/skills/weaver-e10-meeting/references/meeting-queries.md +4 -4
  171. package/skills/weaver-e10-meeting/references/meeting-receipts-signs.md +15 -15
  172. package/skills/weaver-e10-meeting/references/meeting-verification.md +19 -11
  173. package/skills/weaver-e10-meeting.zip +0 -0
  174. package/skills/weaver-e10-yepiaotong/SKILL.md +9 -5
  175. package/skills/weaver-e10-yepiaotong/references/invoice-enterprise-list.md +1 -1
  176. package/skills/weaver-e10-yepiaotong/references/invoice-personal-list.md +6 -5
  177. package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +14 -11
  178. package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +97 -56
  179. package/skills/weaver-e10-yepiaotong/references/reim-examples.md +84 -60
  180. package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +142 -105
  181. package/skills/weaver-e10-yepiaotong/references/reim-matching-rules.md +53 -194
  182. package/skills/weaver-e10-yepiaotong/references/reim-phone-subsidy-rules.md +7 -7
  183. package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +164 -72
  184. package/skills/weaver-e10-yepiaotong/references/source-manifest.json +6 -0
  185. package/templates/meeting/invitation.docx +0 -0
@@ -1,7 +1,8 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { basename } from 'node:path';
1
3
  import { E10_SESSION_EXPIRED_MESSAGE } from '../../internal/e10/auth/messages.js';
2
4
  import { requireE10Session } from '../../internal/e10/context.js';
3
5
  import { getActiveProfile } from '../../internal/e10/auth/session.js';
4
- import { E10ApiError, createE10RequestRuntime, } from '../../internal/e10/request-runtime.js';
5
6
  import { ContractCliError, contractAuthError, contractNetworkError, contractValidationError, } from './errors.js';
6
7
  const DEFAULT_TIMEOUT_MS = 30_000;
7
8
  function assertPath(requestPath) {
@@ -15,6 +16,38 @@ function assertPath(requestPath) {
15
16
  throw contractValidationError('path_not_allowed', '今承达合同管理只能调用 /api/ 路径');
16
17
  }
17
18
  }
19
+ function withQuery(baseUrl, requestPath, query = {}) {
20
+ const url = new URL(`${baseUrl}${requestPath}`);
21
+ for (const [key, value] of Object.entries(query)) {
22
+ if (value === undefined || value === null || value === '')
23
+ continue;
24
+ if (Array.isArray(value)) {
25
+ for (const item of value)
26
+ url.searchParams.append(key, String(item));
27
+ }
28
+ else {
29
+ url.searchParams.set(key, String(value));
30
+ }
31
+ }
32
+ return url;
33
+ }
34
+ async function fetchWithTimeout(url, options, timeoutMs) {
35
+ const controller = new AbortController();
36
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
37
+ try {
38
+ return await fetch(url, { ...options, signal: controller.signal, redirect: 'manual' });
39
+ }
40
+ catch (error) {
41
+ if (error instanceof Error && error.name === 'AbortError') {
42
+ throw contractNetworkError('timeout', `请求超时(${timeoutMs}ms)`, { retryable: false });
43
+ }
44
+ const message = error instanceof Error ? error.message : String(error);
45
+ throw contractNetworkError('transport', `请求失败:${message}`, { retryable: true });
46
+ }
47
+ finally {
48
+ clearTimeout(timer);
49
+ }
50
+ }
18
51
  function textOf(value, keys) {
19
52
  for (const key of keys) {
20
53
  const candidate = value?.[key];
@@ -44,6 +77,23 @@ export function contractBusinessStatus(path, value) {
44
77
  const ok = (code === 0 || code === '0' || code === 200 || code === '200') && root.status !== false && root.fail !== true;
45
78
  return { ok, code: code === undefined ? undefined : String(code), message: textOf(root, ['msg', 'message']) ?? textOf(messageNode, ['errmsg', 'msg']) };
46
79
  }
80
+ // 文件服务与文档检索接口没有 message.errcode,成功码只有 code=0/200 或 status=true,且以 data 是否落地为准。
81
+ if (path.startsWith('/api/file/') || path.startsWith('/api/doc/')) {
82
+ const code = root.code ?? messageNode.code ?? messageNode.errcode;
83
+ const flagOk = root.status !== false && root.fail !== true;
84
+ if (code === undefined) {
85
+ const ok = flagOk && (root.data !== undefined || root.status === true || Object.keys(root).length > 0);
86
+ return { ok, message: textOf(root, ['msg', 'message']) };
87
+ }
88
+ const ok = (code === 0 || code === '0' || code === 200 || code === '200') && flagOk;
89
+ return { ok, code: String(code), message: textOf(root, ['msg', 'message']) ?? textOf(messageNode, ['msg', 'errmsg']) };
90
+ }
91
+ // 助手列表 getListDatas:/api/ebuilder/form/list/**,成功码与 ebd 一致(code=0/200 且 status 非 false)。
92
+ if (path.startsWith('/api/ebuilder/form/list/')) {
93
+ const code = root.code ?? messageNode.errcode ?? messageNode.code;
94
+ const ok = (code === 0 || code === '0' || code === 200 || code === '200') && root.status !== false && root.fail !== true;
95
+ return { ok, code: code === undefined ? undefined : String(code), message: textOf(root, ['msg', 'message']) ?? textOf(messageNode, ['errmsg', 'msg']) };
96
+ }
47
97
  if (path === '/api/ebuilder/form/obj/getObjsByTag'
48
98
  || path === '/api/bs/ebuilder/app/tags/getAppIds'
49
99
  || path === '/api/ebuilder/common/ds/fields'
@@ -81,6 +131,15 @@ function inferProfile(ctx) {
81
131
  const options = ctx.getGlobalOptions();
82
132
  return options.profile || getActiveProfile();
83
133
  }
134
+ function requestHeaders(session) {
135
+ return {
136
+ Accept: 'application/json, text/plain, */*',
137
+ Cookie: session.cookieHeader(),
138
+ eteamsid: session.eteamsId,
139
+ 'User-Agent': session.uaHeader(),
140
+ Origin: session.getBaseUrl(),
141
+ };
142
+ }
84
143
  export function createContractHost(ctx, dependencies = {}) {
85
144
  let e10Session = null;
86
145
  let sessionContext = null;
@@ -101,13 +160,14 @@ export function createContractHost(ctx, dependencies = {}) {
101
160
  return sessionContext;
102
161
  }
103
162
  async function contractRequest(request) {
104
- const { method = 'POST', path, query = {}, body, form, userIdField, timeoutMs = DEFAULT_TIMEOUT_MS, } = request;
163
+ const { method = 'POST', path, query = {}, body, form, file, headers: extraHeaders, userIdField, timeoutMs = DEFAULT_TIMEOUT_MS, } = request;
105
164
  assertPath(path);
106
165
  const session = await ensureSession();
107
166
  const context = await getSession();
108
- const finalQuery = Object.fromEntries(Object.entries(query).filter(([, value]) => value !== undefined && value !== null && value !== ''));
167
+ const headers = { ...requestHeaders(session), ...(extraHeaders ?? {}) };
168
+ const finalQuery = { ...query };
109
169
  let finalBody = body;
110
- let formData;
170
+ const init = { method, headers };
111
171
  if (userIdField) {
112
172
  if (!context.userId) {
113
173
  throw contractAuthError('user_id_missing', '当前会话没有可用的用户 ID,请确认 E10 登录态');
@@ -117,42 +177,38 @@ export function createContractHost(ctx, dependencies = {}) {
117
177
  else
118
178
  finalBody = { ...finalBody, [userIdField]: context.userId };
119
179
  }
120
- if (form) {
121
- formData = new FormData();
122
- for (const [key, value] of Object.entries(form))
123
- formData.append(key, value);
124
- }
125
- const runtime = createE10RequestRuntime(ctx, session, {
126
- interceptors: dependencies.interceptors,
127
- fetch: dependencies.fetch,
128
- });
129
- let response;
130
- try {
131
- response = await runtime.requestJson({
132
- module: 'contract',
133
- method,
134
- path,
135
- query: finalQuery,
136
- body: formData ? undefined : finalBody,
137
- formData,
138
- timeoutMs,
139
- });
140
- }
141
- catch (error) {
142
- if (error instanceof E10ApiError && error.type === 'network') {
143
- throw contractNetworkError(error.subtype, error.message, {
144
- retryable: error.retryable,
145
- details: error.details,
146
- });
180
+ if (form || file) {
181
+ const data = new FormData();
182
+ for (const [key, value] of Object.entries(form ?? {}))
183
+ data.append(key, value);
184
+ if (file) {
185
+ let buffer;
186
+ try {
187
+ buffer = await readFile(file.path);
188
+ }
189
+ catch {
190
+ throw contractValidationError('file_unreadable', `无法读取文件:${file.path}`);
191
+ }
192
+ const filename = file.filename ?? basename(file.path);
193
+ data.append(file.field ?? 'file', new Blob([new Uint8Array(buffer)], { type: file.contentType ?? 'application/octet-stream' }), filename);
147
194
  }
148
- throw error;
195
+ init.body = data;
196
+ }
197
+ else if (finalBody !== undefined) {
198
+ headers['Content-Type'] = 'application/json;charset=UTF-8';
199
+ init.body = JSON.stringify(finalBody);
149
200
  }
201
+ const url = withQuery(context.baseUrl, path, finalQuery);
202
+ const response = await fetchWithTimeout(url, init, timeoutMs);
150
203
  if (response.status === 401 || response.status === 302) {
151
204
  throw contractAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status, path });
152
205
  }
153
- const text = response.text;
154
- const value = response.value;
155
- if (response.parseError) {
206
+ const text = await response.text();
207
+ let value = {};
208
+ try {
209
+ value = text ? JSON.parse(text) : {};
210
+ }
211
+ catch {
156
212
  throw contractNetworkError('protocol', `接口返回不是合法 JSON(HTTP ${response.status})`, {
157
213
  retryable: false,
158
214
  details: { path, status: response.status },
@@ -197,6 +197,38 @@ export const contractShortcut = {
197
197
  { flag: '--page-num <n>', description: 'page number', key: 'pageNum', kind: 'int' },
198
198
  { flag: '--page-size <n>', description: 'page size', key: 'pageSize', kind: 'int' },
199
199
  ]);
200
+ registerCommand(clause, 'permission', 'Check clause library permission (termComponent)', 'contract.clause.permission');
201
+ registerCommand(clause, 'types', 'List clause category types', 'contract.clause.types');
202
+ registerCommand(clause, 'check', 'Check whether a clause name already exists', 'contract.clause.check', [
203
+ { flag: '--clause-name <name>', description: 'clause name', key: 'clauseName' },
204
+ { flag: '--belong-id <id>', description: 'clause category id', key: 'belongId' },
205
+ ]);
206
+ registerCommand(clause, 'browser', 'Search clauses for their ids', 'contract.clause.browser', [
207
+ { flag: '--name <name>', description: 'clause name keyword', key: 'name' },
208
+ ]);
209
+ registerCommand(clause, 'subcompany', 'Search sub-companies for clause groups', 'contract.clause.subcompany', [
210
+ { flag: '--name <name>', description: 'sub-company name keyword', key: 'name' },
211
+ ]);
212
+ registerCommand(clause, 'create-prepare', 'Prepare clause creation', 'contract.clause.create.prepare');
213
+ registerCommand(clause, 'create-apply', 'Apply a prepared clause creation', 'contract.clause.create.apply', CONTINUATION_FLAGS);
214
+ registerCommand(clause, 'update-prepare', 'Prepare clause update', 'contract.clause.update.prepare');
215
+ registerCommand(clause, 'update-apply', 'Apply a prepared clause update', 'contract.clause.update.apply', CONTINUATION_FLAGS);
216
+ registerCommand(clause, 'delete-prepare', 'Prepare clause deletion', 'contract.clause.delete.prepare');
217
+ registerCommand(clause, 'delete-apply', 'Apply a prepared clause deletion', 'contract.clause.delete.apply', CONTINUATION_FLAGS);
218
+ const category = clause.command('category').description('Clause category write commands');
219
+ registerCommand(category, 'create-prepare', 'Prepare category creation', 'contract.clause.category.create.prepare');
220
+ registerCommand(category, 'create-apply', 'Apply a prepared category creation', 'contract.clause.category.create.apply', CONTINUATION_FLAGS);
221
+ registerCommand(category, 'update-prepare', 'Prepare category update', 'contract.clause.category.update.prepare');
222
+ registerCommand(category, 'update-apply', 'Apply a prepared category update', 'contract.clause.category.update.apply', CONTINUATION_FLAGS);
223
+ registerCommand(category, 'delete-prepare', 'Prepare category deletion (cascades clauses)', 'contract.clause.category.delete.prepare');
224
+ registerCommand(category, 'delete-apply', 'Apply a prepared category deletion', 'contract.clause.category.delete.apply', CONTINUATION_FLAGS);
225
+ const clauseGroup = clause.command('group').description('Clause group write commands');
226
+ registerCommand(clauseGroup, 'create-prepare', 'Prepare clause group creation', 'contract.clause.group.create.prepare');
227
+ registerCommand(clauseGroup, 'create-apply', 'Apply a prepared clause group creation', 'contract.clause.group.create.apply', CONTINUATION_FLAGS);
228
+ registerCommand(clauseGroup, 'update-prepare', 'Prepare clause group update', 'contract.clause.group.update.prepare');
229
+ registerCommand(clauseGroup, 'update-apply', 'Apply a prepared clause group update', 'contract.clause.group.update.apply', CONTINUATION_FLAGS);
230
+ registerCommand(clauseGroup, 'delete-prepare', 'Prepare clause group deletion', 'contract.clause.group.delete.prepare');
231
+ registerCommand(clauseGroup, 'delete-apply', 'Apply a prepared clause group deletion', 'contract.clause.group.delete.apply', CONTINUATION_FLAGS);
200
232
  const reference = clause.command('reference').description('Clause reference commands');
201
233
  registerCommand(reference, 'get', 'Query referenced clauses of a contract document', 'contract.clause.reference.get', [
202
234
  { flag: '--file-id <id>', description: 'contract file id', key: 'fileId' },
@@ -314,5 +346,186 @@ export const contractShortcut = {
314
346
  { flag: '--request-id <id>', description: 'request id', key: 'requestId' },
315
347
  { flag: '--other-params <json>', description: 'paging params JSON', key: 'otherParams' },
316
348
  ]);
349
+ const review = contract.command('review').description('Contract AI review commands');
350
+ // paths 是数组,子命令只提供 JSON 输入入口,避免把路径拆成多个位置参数。
351
+ registerCommand(review, 'upload', 'Upload contracts and get the AI review page url', 'contract.review.upload');
352
+ registerCommand(review, 'export', 'Export AI review records', 'contract.review.export', [
353
+ { flag: '--file-id <id>', description: 'contract file id', key: 'fileId' },
354
+ { flag: '--sclx <types>', description: '1 risk, 2 legal, 3 proofreading', key: 'sclx' },
355
+ ]);
356
+ const flow = contract.command('flow').description('Contract flow entry commands');
357
+ registerCommand(flow, 'page', 'Build the flow create page url', 'contract.flow.page', [
358
+ { flag: '--flow <name>', description: '契约锁 / 新客户 / 老客户增值 / 常规二次销售', key: 'flow' },
359
+ ]);
360
+ registerCommand(flow, 'launch', 'Upload a contract and build the flow url with auto fill', 'contract.flow.launch', [
361
+ { flag: '--flow <name>', description: '契约锁 / 新客户 / 老客户增值 / 常规二次销售', key: 'flow' },
362
+ { flag: '--path <file>', description: 'local doc/docx path', key: 'path' },
363
+ ]);
364
+ const recommend = contract.command('recommend').description('Contract template recommendation commands');
365
+ registerCommand(recommend, 'doc', 'Recommend templates from a plain description', 'contract.recommend.doc', [
366
+ { flag: '--content <text>', description: 'requirement description', key: 'content' },
367
+ ]);
368
+ const compare = contract.command('compare').description('Contract document comparison commands');
369
+ registerCommand(compare, 'upload', 'Upload files for comparison (module docCompared)', 'contract.compare.upload');
370
+ registerCommand(compare, 'search', 'Search documents by name', 'contract.compare.search', [
371
+ { flag: '--keyword <text>', description: 'file name keyword', key: 'keyword' },
372
+ { flag: '--page-no <n>', description: 'page number', key: 'pageNo', kind: 'int' },
373
+ { flag: '--page-size <n>', description: 'page size', key: 'pageSize', kind: 'int' },
374
+ ]);
375
+ registerCommand(compare, 'versions', 'List historical versions of a file', 'contract.compare.versions', [
376
+ { flag: '--file-id <id>', description: 'file id', key: 'fileId' },
377
+ { flag: '--doc-id <id>', description: 'document id', key: 'docId' },
378
+ { flag: '--page-no <n>', description: 'page number', key: 'pageNo', kind: 'int' },
379
+ ]);
380
+ registerCommand(compare, 'page', 'Build the document comparison page url', 'contract.compare.page', [
381
+ { flag: '--base-file-id <id>', description: 'base file id', key: 'baseFileId' },
382
+ { flag: '--base-file-name <name>', description: 'base file name', key: 'baseFileName' },
383
+ { flag: '--compare-file-id <id>', description: 'compare file id', key: 'compareFileId' },
384
+ { flag: '--compare-file-name <name>', description: 'compare file name', key: 'compareFileName' },
385
+ ]);
386
+ registerCommand(compare, 'diff', 'Fetch the comparison diff result', 'contract.compare.diff', [
387
+ { flag: '--base-file-id <id>', description: 'base file id', key: 'baseFileId' },
388
+ { flag: '--compare-file-id <id>', description: 'compare file id', key: 'compareFileId' },
389
+ ]);
390
+ const credit = contract.command('credit').description('Enterprise credit commands');
391
+ registerCommand(credit, 'page', 'Build the enterprise credit page url', 'contract.credit.page');
392
+ const performance = contract.command('performance').description('Performance ledger commands (local links + read-only list queries)');
393
+ registerCommand(performance, 'link', 'Build a filtered performance menu link (local)', 'contract.performance.link', [
394
+ { flag: '--menu <name>', description: 'menu name or alias', key: 'menu' },
395
+ { flag: '--origin <url>', description: 'business baseUrl', key: 'origin' },
396
+ { flag: '--period <yyyy[-mm]>', description: 'performance period', key: 'period' },
397
+ { flag: '--time-field <name>', description: 'override time field', key: 'time-field' },
398
+ { flag: '--conditions <json>', description: 'conditions JSON array', key: 'conditions' },
399
+ ]);
400
+ registerCommand(performance, 'fields', 'List filter fields of a performance menu (local)', 'contract.performance.fields', [
401
+ { flag: '--menu <name>', description: 'menu name or alias', key: 'menu' },
402
+ ]);
403
+ registerCommand(performance, 'source-entry', 'List contract source ledger entries (local)', 'contract.performance.source.entry', [
404
+ { flag: '--source <name>', description: 'source name or alias', key: 'source' },
405
+ { flag: '--origin <url>', description: 'business baseUrl', key: 'origin' },
406
+ ]);
407
+ registerCommand(performance, 'menu-search', 'Search permitted EB menus', 'contract.performance.menu.search', [
408
+ { flag: '--keywords <json>', description: 'keywords JSON array', key: 'keywords' },
409
+ ]);
410
+ registerCommand(performance, 'list-init', 'Initialize an EB list and verify objId', 'contract.performance.list.init', [
411
+ { flag: '--api-prefix <p>', description: 'api prefix', key: 'apiPrefix' },
412
+ { flag: '--list-id <id>', description: 'list id', key: 'listId' },
413
+ { flag: '--expected-obj-id <id>', description: 'expected objId', key: 'expectedObjId' },
414
+ ]);
415
+ registerCommand(performance, 'list-filters', 'Read saved search filters and column mapping', 'contract.performance.list.filters', [
416
+ { flag: '--api-prefix <p>', description: 'api prefix', key: 'apiPrefix' },
417
+ { flag: '--list-id <id>', description: 'list id', key: 'listId' },
418
+ { flag: '--app-id <id>', description: 'app id', key: 'appId' },
419
+ { flag: '--obj-id <id>', description: 'obj id', key: 'objId' },
420
+ { flag: '--include-fields', description: 'also read column mapping', key: 'includeFields', kind: 'bool' },
421
+ ]);
422
+ registerCommand(performance, 'list-query', 'Query a source ledger by exact condition (all pages)', 'contract.performance.list.query', [
423
+ { flag: '--api-prefix <p>', description: 'api prefix', key: 'apiPrefix' },
424
+ { flag: '--list-id <id>', description: 'list id', key: 'listId' },
425
+ { flag: '--app-id <id>', description: 'app id', key: 'appId' },
426
+ { flag: '--obj-id <id>', description: 'obj id', key: 'objId' },
427
+ { flag: '--search-field-id <id>', description: 'contract number field id', key: 'searchFieldId' },
428
+ { flag: '--search-operator <op>', description: 'eq/like/startWith', key: 'searchOperator' },
429
+ { flag: '--search-value <value>', description: 'full contract number', key: 'searchValue' },
430
+ { flag: '--search-param-json <json>', description: 'full searchParamData JSON string', key: 'searchParamJson' },
431
+ { flag: '--page-size <n>', description: 'page size', key: 'pageSize', kind: 'int' },
432
+ { flag: '--max-pages <n>', description: 'max pages', key: 'maxPages', kind: 'int' },
433
+ ]);
434
+ registerCommand(performance, 'receipt-query', 'Query the receipt ledger by contract numbers', 'contract.performance.receipt.query', [
435
+ { flag: '--origin <url>', description: 'business baseUrl', key: 'origin' },
436
+ { flag: '--list-id <id>', description: 'receipt list id', key: 'listId' },
437
+ { flag: '--api-prefix <p>', description: 'api prefix', key: 'apiPrefix' },
438
+ { flag: '--app-id <id>', description: 'app id', key: 'appId' },
439
+ { flag: '--obj-id <id>', description: 'obj id', key: 'objId' },
440
+ { flag: '--contract-numbers <json>', description: 'contract numbers JSON array', key: 'contractNumbers' },
441
+ { flag: '--page-size <n>', description: 'page size', key: 'pageSize', kind: 'int' },
442
+ ]);
443
+ const quote = contract.command('quote').description('Quote-to-contract commands (local xlsx/docx)');
444
+ registerCommand(quote, 'rmb', 'Convert a number to RMB uppercase (local)', 'contract.quote.rmb', [
445
+ { flag: '--num <value>', description: 'number', key: 'num' },
446
+ ]);
447
+ registerCommand(quote, 'sheets', 'List sheets of a quote xlsx', 'contract.quote.sheets', [
448
+ { flag: '--path <file>', description: 'quote xlsx path', key: 'path' },
449
+ ]);
450
+ registerCommand(quote, 'parse', 'Parse a quote xlsx into meta/totals/sections', 'contract.quote.parse', [
451
+ { flag: '--path <file>', description: 'quote xlsx path', key: 'path' },
452
+ { flag: '--sheet <name>', description: 'sheet name', key: 'sheet' },
453
+ { flag: '--keep-remark', description: 'keep remark column', key: 'keepRemark', kind: 'bool' },
454
+ { flag: '--include-zero', description: 'keep zero-qty/amount items', key: 'includeZero', kind: 'bool' },
455
+ ]);
456
+ registerCommand(quote, 'fill', 'Fill a real .docx contract template with data JSON', 'contract.quote.fill', [
457
+ { flag: '--template <file>', description: 'real contract template docx', key: 'template' },
458
+ { flag: '--data <file>', description: 'data JSON path', key: 'data' },
459
+ { flag: '--out <file>', description: 'output docx path', key: 'out' },
460
+ { flag: '--detail <mode>', description: 'append|none', key: 'detail' },
461
+ { flag: '--map-out <file>', description: 'mapping log path', key: 'mapOut' },
462
+ ]);
463
+ const assistant = contract.command('assistant').description('Contract AI assistant commands');
464
+ registerCommand(assistant, 'init', 'Initialize or refresh assistant configuration', 'contract.assistant.init');
465
+ registerCommand(assistant, 'meta', 'Read assistant list field metadata (ai_background_config)', 'contract.assistant.meta');
466
+ registerCommand(assistant, 'list', 'List AI assistants', 'contract.assistant.list', [
467
+ { flag: '--name <name>', description: 'assistant name filter', key: 'name' },
468
+ ]);
469
+ registerCommand(assistant, 'doc-query', 'Query storage dir and execute settings', 'contract.assistant.doc.query', [
470
+ { flag: '--ai-id <id>', description: 'assistant data id', key: 'ai_id' },
471
+ ]);
472
+ registerCommand(assistant, 'config-query', 'Query the 16 agents of an assistant', 'contract.assistant.config.query', [
473
+ { flag: '--ai-id <id>', description: 'assistant data id', key: 'ai_id' },
474
+ { flag: '--ai-mark <mark>', description: 'filter by ai_mark, e.g. Control', key: 'aiMark' },
475
+ ]);
476
+ registerCommand(assistant, 'tips-query', 'Query tips of an assistant', 'contract.assistant.tips.query', [
477
+ { flag: '--ai-id <id>', description: 'assistant data id', key: 'ai_id' },
478
+ ]);
479
+ registerCommand(assistant, 'doc-folder-search', 'Search doc folders for storage settings', 'contract.assistant.doc.folder.search', [
480
+ { flag: '--name <name>', description: 'folder name keyword', key: 'name' },
481
+ ]);
482
+ registerCommand(assistant, 'keygroup-search', 'Search keyword groups', 'contract.assistant.keygroup.search', [
483
+ { flag: '--name <name>', description: 'keyword group name', key: 'name' },
484
+ ]);
485
+ registerCommand(assistant, 'rule-classification-list', 'List control rule classifications', 'contract.assistant.rule.classification.list');
486
+ registerCommand(assistant, 'rule-list', 'List control rules', 'contract.assistant.rule.list', [
487
+ { flag: '--flid <id>', description: 'classification id', key: 'flid' },
488
+ { flag: '--page-no <n>', description: 'page number', key: 'pageNo', kind: 'int' },
489
+ { flag: '--page-size <n>', description: 'page size', key: 'pageSize', kind: 'int' },
490
+ ]);
491
+ registerCommand(assistant, 'rule-group-query', 'Query control rule groups of the Control agent', 'contract.assistant.rule.group.query', [
492
+ { flag: '--config-id <id>', description: 'Control agent id', key: 'config_id' },
493
+ ]);
494
+ registerCommand(assistant, 'element-query', 'Query element extraction sets of the Extract agent', 'contract.assistant.element.query', [
495
+ { flag: '--config-id <id>', description: 'Extract agent id', key: 'config_id' },
496
+ ]);
497
+ registerCommand(assistant, 'flow-list', 'List assistant flow bindings', 'contract.assistant.flow.list', [
498
+ { flag: '--ai-id <id>', description: 'assistant data id', key: 'ai_id' },
499
+ { flag: '--rule-config-id <id>', description: 'Control agent id', key: 'rule_config_id' },
500
+ { flag: '--page-index <n>', description: 'page index', key: 'pageIndex', kind: 'int' },
501
+ { flag: '--page-size <n>', description: 'page size', key: 'pageSize', kind: 'int' },
502
+ ]);
503
+ // 写操作输入含嵌套对象,统一走 --input / --input-json。
504
+ const assistantWrites = [
505
+ ['create', 'assistant creation', 'contract.assistant.create'],
506
+ ['delete', 'assistant deletion', 'contract.assistant.delete'],
507
+ ['doc-save', 'storage dir / execute mode write', 'contract.assistant.doc.save'],
508
+ ['agent-update', 'agent config update', 'contract.assistant.agent.update'],
509
+ ['tips-create', 'tip creation', 'contract.assistant.tips.create'],
510
+ ['tips-delete', 'tip deletion', 'contract.assistant.tips.delete'],
511
+ ['rule-classification-create', 'control rule classification creation', 'contract.assistant.rule.classification.create'],
512
+ ['rule-classification-update', 'control rule classification update', 'contract.assistant.rule.classification.update'],
513
+ ['rule-classification-delete', 'control rule classification deletion', 'contract.assistant.rule.classification.delete'],
514
+ ['rule-create', 'control rule creation', 'contract.assistant.rule.create'],
515
+ ['rule-update', 'control rule update', 'contract.assistant.rule.update'],
516
+ ['rule-delete', 'control rule deletion', 'contract.assistant.rule.delete'],
517
+ ['rule-group-create', 'control rule group creation', 'contract.assistant.rule.group.create'],
518
+ ['rule-group-update', 'control rule group update', 'contract.assistant.rule.group.update'],
519
+ ['rule-group-delete', 'control rule group deletion', 'contract.assistant.rule.group.delete'],
520
+ ['element-create', 'element extraction set creation', 'contract.assistant.element.create'],
521
+ ['element-delete', 'element extraction set deletion', 'contract.assistant.element.delete'],
522
+ ['flow-save', 'assistant flow binding creation', 'contract.assistant.flow.save'],
523
+ ['flow-update', 'assistant flow binding update', 'contract.assistant.flow.update'],
524
+ ['flow-delete', 'assistant flow binding deletion', 'contract.assistant.flow.delete'],
525
+ ];
526
+ for (const [name, description, operation] of assistantWrites) {
527
+ registerCommand(assistant, `${name}-prepare`, `Prepare ${description}`, `${operation}.prepare`);
528
+ registerCommand(assistant, `${name}-apply`, `Apply a prepared ${description}`, `${operation}.apply`, CONTINUATION_FLAGS);
529
+ }
317
530
  },
318
531
  };