weaver-work-cli 0.1.32 → 0.1.36
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.
- package/README.md +2 -2
- package/dist/chunks/{archive-UMGX72K6.js → archive-XBVH7JU7.js} +2 -2
- package/dist/chunks/{archive-oa-N2IYBLF3.js → archive-oa-MZM3EKFQ.js} +2 -2
- package/dist/chunks/{asset-GLEGKFG5.js → asset-4XO7UOUW.js} +2 -2
- package/dist/chunks/{attachment-content-AQNX5N3S.js → attachment-content-VXSWANAC.js} +3 -2
- package/dist/chunks/{blog-E44OTVDA.js → blog-PGZKOPSC.js} +2 -2
- package/dist/chunks/{caizhilian-DQUFZXZL.js → caizhilian-BH4ZVGUN.js} +2 -2
- package/dist/chunks/{calendar-JKPIRKFD.js → calendar-MXEMTIO4.js} +2 -2
- package/dist/chunks/{chunk-QWY6PGL6.js → chunk-2LV74IWP.js} +361 -56
- package/dist/chunks/chunk-3SO6QL6U.js +73 -0
- package/dist/chunks/chunk-5DQEEGCC.js +229 -0
- package/dist/chunks/{chunk-G3QJULO2.js → chunk-6LLJFKJE.js} +1 -1
- package/dist/chunks/{chunk-C6R3B2ML.js → chunk-BPE37FPB.js} +35 -7
- package/dist/chunks/chunk-BYATLLEF.js +68 -0
- package/dist/chunks/chunk-BYBSCN4X.js +932 -0
- package/dist/chunks/{chunk-CVZ2JOSW.js → chunk-F746NKNF.js} +1 -1
- package/dist/chunks/{chunk-GCG2NMWR.js → chunk-HXJQI5NM.js} +4 -2
- package/dist/chunks/{chunk-YRVDW4WN.js → chunk-I6QGIBDM.js} +2 -2
- package/dist/chunks/{chunk-H7J4DC5R.js → chunk-JCSN3JGM.js} +2 -2
- package/dist/chunks/{chunk-2GA5ZIQL.js → chunk-JNG42JKG.js} +30 -1
- package/dist/chunks/{chunk-DW6AUUKS.js → chunk-JUXVYKII.js} +9 -4
- package/dist/chunks/{chunk-6RKD4DRZ.js → chunk-JYKABYCV.js} +2 -2
- package/dist/chunks/{chunk-6EFWDL7Y.js → chunk-NCOVUAZK.js} +2 -2
- package/dist/chunks/{chunk-E4Z23GHM.js → chunk-QHFANTX7.js} +1114 -904
- package/dist/chunks/{ebuilder-form-V5FG2EHC.js → chunk-QYGO5EE2.js} +22 -1148
- package/dist/chunks/{chunk-IURUFGZK.js → chunk-T72N74ZT.js} +50 -33
- package/dist/chunks/{chunk-H6XSTSLM.js → chunk-TC6MZAO3.js} +137 -204
- package/dist/chunks/{chunk-WKI2FBIQ.js → chunk-VPUTVEMC.js} +737 -341
- package/dist/chunks/{chunk-WSKBSQ2U.js → chunk-VPXOPQJI.js} +2 -2
- package/dist/chunks/chunk-WXFPWCXG.js +774 -0
- package/dist/chunks/{chunk-4YC43QQ4.js → chunk-XMGSYD6S.js} +4 -4
- package/dist/chunks/conflict-JAB2LJEZ.js +21 -0
- package/dist/chunks/continuation-RN6PZN2M.js +11 -0
- package/dist/chunks/contract-XI2EEIZU.js +9110 -0
- package/dist/chunks/cowork-SCPGLBA4.js +2527 -0
- package/dist/chunks/ebuilder-form-EYLHNOTA.js +121 -0
- package/dist/chunks/{ehr-HMFY6VIL.js → ehr-EAP77IMT.js} +1344 -27
- package/dist/chunks/{esb-ZYSVB7SG.js → esb-2TGGXEE7.js} +4 -4
- package/dist/chunks/{fna-B7RKPAZD.js → fna-2X7ZE7BU.js} +13 -8
- package/dist/chunks/{host-OCH2BCCV.js → host-C6EL2RKL.js} +3 -3
- package/dist/chunks/{host-45WED2KK.js → host-I4NRK4MX.js} +3 -3
- package/dist/chunks/{host-I4Z6BFYX.js → host-Q4LZGCRU.js} +3 -3
- package/dist/chunks/host-UEI5FGDM.js +23 -0
- package/dist/chunks/{host-KNZ52LJZ.js → host-XCLDDXKQ.js} +3 -3
- package/dist/chunks/{hrm-2KAZGUHI.js → hrm-YXERJM76.js} +3 -3
- package/dist/chunks/{im-ACJJWH4U.js → im-A4VZN2TQ.js} +88 -12
- package/dist/chunks/{invoice-ZK3WCX2U.js → invoice-2Z6YPMIS.js} +3 -3
- package/dist/chunks/{jiuchuanhui-5PQD3IL2.js → jiuchuanhui-AR5GMKZB.js} +2 -2
- package/dist/chunks/{lazy-dispatch-JQXBW3GM.js → lazy-dispatch-QXW7P4X3.js} +4 -4
- package/dist/chunks/{mail-S2HDDXO2.js → mail-7GZ6CPBJ.js} +45 -24
- package/dist/chunks/{meeting-QVN3I37L.js → meeting-3NMGA3MB.js} +278 -43
- package/dist/chunks/{okr-QNG4VC2Q.js → okr-BZ6XUOAG.js} +2 -2
- package/dist/chunks/operations-5QL3AECO.js +11 -0
- package/dist/chunks/{plan-A25EMW6U.js → plan-DR5CMUYP.js} +2 -2
- package/dist/chunks/{project-G6XV66DZ.js → project-6J63MK33.js} +2 -2
- package/dist/chunks/{registry-DC6KR3NH.js → registry-KDD7DHNK.js} +4 -4
- package/dist/chunks/{registry-2VLUAESA.js → registry-OZSMDVPP.js} +2 -2
- package/dist/chunks/{registry-7C5UMIPL.js → registry-TKX2E7C7.js} +2 -2
- package/dist/chunks/{registry-TI3CIUXF.js → registry-VRTNC6UR.js} +8 -6
- package/dist/chunks/{room-recommend-WRTHO6Y2.js → room-recommend-XCWRMB5P.js} +4 -3
- package/dist/chunks/{schedule-KFIITGSK.js → schedule-IVBICP32.js} +4 -3
- package/dist/chunks/{workflow-DJ7SYWAF.js → workflow-D74NFK3C.js} +179 -6
- package/dist/index.js +35 -25
- package/dist/internal/e10/auth-recovery.js +14 -4
- package/dist/internal/e10/fetch-timing.js +31 -0
- package/dist/internal/e10/request-runtime.js +5 -0
- package/dist/shortcuts/contract/host.js +34 -59
- package/dist/shortcuts/cowork/continuation.js +70 -0
- package/dist/shortcuts/cowork/errors.js +59 -0
- package/dist/shortcuts/cowork/host.js +180 -0
- package/dist/shortcuts/cowork/index.js +166 -0
- package/dist/shortcuts/cowork/manifest.js +65 -0
- package/dist/shortcuts/cowork/operations/discuss-write.js +277 -0
- package/dist/shortcuts/cowork/operations/item-write.js +380 -0
- package/dist/shortcuts/cowork/operations/member-write.js +283 -0
- package/dist/shortcuts/cowork/operations/permission-write.js +286 -0
- package/dist/shortcuts/cowork/operations/read.js +423 -0
- package/dist/shortcuts/cowork/operations/registry.js +39 -0
- package/dist/shortcuts/cowork/operations/review-write.js +157 -0
- package/dist/shortcuts/cowork/operations/shared.js +215 -0
- package/dist/shortcuts/cowork/operations/types.js +39 -0
- package/dist/shortcuts/cowork/operations.js +19 -0
- package/dist/shortcuts/ehr/host.js +4 -1
- package/dist/shortcuts/ehr/operations/recruit-candidate-import.js +757 -0
- package/dist/shortcuts/ehr/operations/recruit-position.js +367 -0
- package/dist/shortcuts/ehr/operations/recruit-stats.js +133 -0
- package/dist/shortcuts/ehr/operations/recruit-write.js +43 -16
- package/dist/shortcuts/ehr/operations/recruit.js +182 -10
- package/dist/shortcuts/ehr/operations/registry.js +6 -0
- package/dist/shortcuts/fna/operations/expense-chart.js +19 -7
- package/dist/shortcuts/im/diagnostics.js +97 -0
- package/dist/shortcuts/im/host.js +58 -31
- package/dist/shortcuts/im/index.js +7 -2
- package/dist/shortcuts/im/operations/at-mention.js +127 -0
- package/dist/shortcuts/im/operations/file-user.js +10 -2
- package/dist/shortcuts/im/operations/group-read.js +26 -5
- package/dist/shortcuts/im/operations/group-write.js +35 -28
- package/dist/shortcuts/im/operations/msg-sync.js +7 -2
- package/dist/shortcuts/im/operations/msg-write.js +76 -10
- package/dist/shortcuts/im/operations/quote-mention.js +119 -0
- package/dist/shortcuts/im/operations/session.js +1 -1
- package/dist/shortcuts/im/operations/shared.js +10 -0
- package/dist/shortcuts/im/operations/types.js +13 -0
- package/dist/shortcuts/index.js +10 -0
- package/dist/shortcuts/mail/host.js +12 -1
- package/dist/shortcuts/mail/operations/types.js +17 -2
- package/dist/shortcuts/meeting/host.js +27 -34
- package/dist/shortcuts/meeting/index.js +79 -1
- package/dist/shortcuts/meeting/manifest.js +10 -0
- package/dist/shortcuts/meeting/operations/create.js +4 -1
- package/dist/shortcuts/meeting/operations/eb/catalog.js +10 -0
- package/dist/shortcuts/meeting/operations/eb/conflict.js +84 -8
- package/dist/shortcuts/meeting/operations/eb/create-flow.js +1195 -140
- package/dist/shortcuts/meeting/operations/eb/factory.js +170 -8
- package/dist/shortcuts/meeting/operations/eb/index.js +16 -3
- package/dist/shortcuts/meeting/operations/eb/room-recommend.js +50 -5
- package/dist/shortcuts/meeting/operations/eb-fallback.js +163 -0
- package/dist/shortcuts/meeting/operations/env.js +99 -46
- package/dist/shortcuts/meeting/operations/form-fields.js +110 -0
- package/dist/shortcuts/meeting/operations/invitation.js +79 -20
- package/dist/shortcuts/meeting/operations/registry.js +2 -0
- package/dist/shortcuts/meeting/operations/standard-guard.js +71 -0
- package/dist/shortcuts/meeting/operations.js +16 -0
- package/dist/shortcuts/workflow/endpoints.js +8 -3
- package/dist/shortcuts/workflow/index.js +110 -1
- package/dist/shortcuts/workflow/operations/form.js +204 -36
- package/dist/shortcuts/workflow/operations/read.js +104 -23
- package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupRules.js +448 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupStore.js +106 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/businessRules.js +47 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.collect.js +30 -23
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.core.js +1 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.group.js +1 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.groupSummary.js +2 -1
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.js +2 -4
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.smartGroup.js +138 -181
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.summary.js +12 -7
- package/dist/shortcuts/workflow/operations.js +23 -1
- package/docs/e10-auth.md +1 -1
- package/docs/ehr.md +1 -1
- package/docs/fna.md +2 -1
- package/docs/im.md +8 -1
- package/docs/todo-smart-convert/README.md +1 -1
- package/docs/todo-smart-convert/data-contract.md +2 -2
- package/docs/todo-smart-convert/subgroup-rules.md +6 -0
- package/package.json +1 -1
- package/skill-template/business-info.json +18 -0
- package/skill-template/domains/cowork.md +14 -0
- package/skill-template/domains/yimiaoban.md +3 -3
- package/skill-template/skill-template.md +1 -1
- package/skills/weaver-e10-blog/SKILL.md +5 -5
- package/skills/weaver-e10-caizhilian/SKILL.md +5 -5
- package/skills/weaver-e10-calendar/SKILL.md +5 -5
- package/skills/weaver-e10-cowork/SKILL.md +101 -0
- package/skills/weaver-e10-cowork/references/cowork-read.md +90 -0
- package/skills/weaver-e10-cowork/references/cowork-write.md +131 -0
- package/skills/weaver-e10-cowork/references/safety-boundaries.md +45 -0
- package/skills/weaver-e10-esb/SKILL.md +5 -5
- package/skills/weaver-e10-hrm/SKILL.md +5 -5
- package/skills/weaver-e10-jinchengda/SKILL.md +2 -2
- package/skills/weaver-e10-jiuchuanhui/SKILL.md +5 -5
- package/skills/weaver-e10-jucailin/SKILL.md +38 -14
- package/skills/weaver-e10-jucailin/references/recruit-create.md +104 -0
- package/skills/weaver-e10-jucailin/references/recruit-read.md +25 -0
- package/skills/weaver-e10-jucailin/references/recruit-write.md +13 -0
- package/skills/weaver-e10-jucailin/references/salary.md +15 -11
- package/skills/weaver-e10-mail/SKILL.md +17 -14
- package/skills/weaver-e10-meeting/SKILL.md +442 -46
- package/skills/weaver-e10-meeting/references/meeting-eb.md +135 -3
- package/skills/weaver-e10-meeting/references/meeting-invitation.md +28 -2
- package/skills/weaver-e10-meeting/references/meeting-queries.md +9 -6
- package/skills/weaver-e10-meeting/references/meeting-verification.md +8 -6
- package/skills/weaver-e10-meeting.zip +0 -0
- package/skills/weaver-e10-okr/SKILL.md +5 -5
- package/skills/weaver-e10-okr/references/source-manifest.json +3 -3
- package/skills/weaver-e10-plan/SKILL.md +5 -5
- package/skills/weaver-e10-qiyecheng/SKILL.md +5 -2
- package/skills/weaver-e10-qiyecheng/references/catalog.md +2 -2
- package/skills/weaver-e10-qiyecheng/references/expense-chart.md +15 -1
- package/skills/weaver-e10-qiyecheng/references/source-manifest.json +22 -21
- package/skills/weaver-e10-shared/SKILL.md +12 -12
- package/skills/weaver-e10-shared/references/e10-auth-and-session.md +4 -4
- package/skills/weaver-e10-wenshuding/SKILL.md +5 -5
- package/skills/weaver-e10-workflow/SKILL.md +29 -5
- package/skills/weaver-e10-workflow/aigroup/default.json +88 -0
- package/skills/weaver-e10-workflow/references/todo-smart-convert.md +66 -14
- package/skills/weaver-e10-workflow/references/workflow-agent-entry.md +1 -1
- package/skills/weaver-e10-workflow/references/workflow-memory.md +1 -1
- package/skills/weaver-e10-workflow/references/workflow-query.md +12 -10
- package/skills/weaver-e10-workflow/references/workflow-view.md +2 -2
- package/skills/weaver-e10-workflow/tools/todo-serve.cjs +239 -0
- package/skills/weaver-e10-workflow/{scripts → tools}/todo-summary.cjs +218 -28
- package/skills/weaver-e10-yepiaotong/SKILL.md +10 -8
- package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +7 -7
- package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +10 -10
- package/skills/weaver-e10-yepiaotong/references/reim-examples.md +40 -37
- package/skills/weaver-e10-yepiaotong/references/reim-expense-subject-rules.md +4 -4
- package/skills/weaver-e10-yepiaotong/references/reim-form-fill-rules.md +27 -38
- package/skills/weaver-e10-yepiaotong/references/reim-phone-subsidy-rules.md +4 -4
- package/skills/weaver-e10-yepiaotong/references/reim-workflow.md +37 -29
- package/skills/weaver-e10-yimiaoban/SKILL.md +156 -33
- package/skills/weaver-e10-yimiaoban/references/ding-write.md +1 -1
- package/skills/weaver-e10-yimiaoban/references/error-codes.md +5 -1
- package/skills/weaver-e10-yimiaoban/references/group-read.md +5 -1
- package/skills/weaver-e10-yimiaoban/references/group-write.md +6 -4
- package/skills/weaver-e10-yimiaoban/references/msg-read.md +1 -0
- package/skills/weaver-e10-yimiaoban/references/msg-write.md +34 -2
- package/skills/weaver-e10-yimiaoban/references/safety-boundaries.md +5 -2
- package/skills/weaver-e10-yimiaoban/references/source-manifest.json +79 -58
- package/skills/weaver-e10-yimiaoban/references/user-remind.md +2 -2
- package/skills/weaver-e10-ziguanjia/SKILL.md +5 -5
|
@@ -2,15 +2,22 @@ import { createRequire as __esbuildCreateRequire } from 'node:module';
|
|
|
2
2
|
const require = __esbuildCreateRequire(import.meta.url);
|
|
3
3
|
import {
|
|
4
4
|
createWorkflowHost
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-VPXOPQJI.js";
|
|
6
6
|
import {
|
|
7
|
+
USER_INTENT_RULE_FILE,
|
|
8
|
+
aigroupUserDir,
|
|
7
9
|
asObject,
|
|
8
10
|
assertNoForbiddenKeys,
|
|
9
11
|
compactStdoutPaths,
|
|
12
|
+
emptyRuleFile,
|
|
10
13
|
getWorkflowOperation,
|
|
14
|
+
loadRuleFile,
|
|
15
|
+
loadRules,
|
|
16
|
+
resetActiveRules,
|
|
17
|
+
validateRuleFile,
|
|
11
18
|
workflowOperationDefinitions,
|
|
12
19
|
workflowSuccess
|
|
13
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-VPUTVEMC.js";
|
|
14
21
|
import {
|
|
15
22
|
createWorkflowContinuationSigner
|
|
16
23
|
} from "./chunk-EZALDOQH.js";
|
|
@@ -21,8 +28,8 @@ import {
|
|
|
21
28
|
} from "./chunk-FMPJJYYI.js";
|
|
22
29
|
import "./chunk-EG6ZU444.js";
|
|
23
30
|
import "./chunk-AJ62BGAW.js";
|
|
24
|
-
import "./chunk-
|
|
25
|
-
import "./chunk-
|
|
31
|
+
import "./chunk-JUXVYKII.js";
|
|
32
|
+
import "./chunk-JNG42JKG.js";
|
|
26
33
|
import {
|
|
27
34
|
isCliError,
|
|
28
35
|
toErrorEnvelope
|
|
@@ -82,6 +89,8 @@ function clarificationEnvelope(error, operation) {
|
|
|
82
89
|
const candidates = Array.isArray(details.candidates) ? details.candidates : [];
|
|
83
90
|
const question = typeof details.clarificationQuestion === "string" && details.clarificationQuestion ? details.clarificationQuestion : error.message;
|
|
84
91
|
const reason = typeof details.clarificationReason === "string" ? details.clarificationReason : "";
|
|
92
|
+
const missingInput = Array.isArray(details.missingInput) ? details.missingInput.map(String) : [];
|
|
93
|
+
const requiredInput = details.requiredInput && typeof details.requiredInput === "object" ? details.requiredInput : null;
|
|
85
94
|
return workflowSuccess(operation, {
|
|
86
95
|
type: "workflowClarification",
|
|
87
96
|
status: "NEEDS_CLARIFICATION",
|
|
@@ -89,6 +98,8 @@ function clarificationEnvelope(error, operation) {
|
|
|
89
98
|
clarificationKeyword: details.clarificationKeyword ?? null,
|
|
90
99
|
clarificationQuestion: question,
|
|
91
100
|
...reason ? { clarificationReason: reason } : {},
|
|
101
|
+
...missingInput.length ? { missingInput } : {},
|
|
102
|
+
...missingInput.length && requiredInput ? { requiredInput } : {},
|
|
92
103
|
candidates,
|
|
93
104
|
candidateCount: candidates.length,
|
|
94
105
|
note: clarificationNote(reason, candidates.length)
|
|
@@ -96,6 +107,9 @@ function clarificationEnvelope(error, operation) {
|
|
|
96
107
|
}
|
|
97
108
|
function clarificationNote(reason, candidateCount) {
|
|
98
109
|
const base = "\u8FD9\u4E0D\u662F\u5931\u8D25\uFF0C\u4E5F**\u4E0D\u4EE3\u8868\u67E5\u8BE2\u5DF2\u6267\u884C**\uFF1A\u672C\u6B21\u67E5\u8BE2\u5DF2\u505C\u6B62\uFF0C\u6CA1\u6709\u8FD4\u56DE\u4EFB\u4F55\u6D41\u7A0B\u6570\u636E\u3002";
|
|
110
|
+
if (reason === "workflow_required") {
|
|
111
|
+
return "\u672C\u6B21\u547D\u4EE4**\u6CA1\u6709\u62FF\u5230\u5FC5\u586B\u5165\u53C2 `workflow`**\uFF08\u6CA1\u5199\u8FD9\u4E2A\u952E\u3001\u7A7A\u6570\u7EC4\u3001\u7A7A\u5B57\u7B26\u4E32\u90FD\u7B97\u6CA1\u7ED9\uFF09\u2014\u2014\u547D\u4EE4\u505C\u5728\u4E86\u67E5\u8BE2\u4E4B\u524D\uFF1A**\u6CA1\u6709\u53D1\u8D77\u4EFB\u4F55\u6D41\u7A0B**\uFF0C\u4E5F\u6CA1\u6709\u53BB\u67E5\u53EF\u53D1\u8D77\u5217\u8868\uFF0C\u8FD9\u65E2\u4E0D\u662F\u6267\u884C\u5931\u8D25\uFF0C\u4E5F\u4E0D\u4EE3\u8868\u300C\u6CA1\u6709\u5339\u914D\u7684\u6D41\u7A0B\u300D\u3002\u8BF7\u5148\u5411\u7528\u6237\u786E\u8BA4\u8981\u53D1\u8D77\u54EA\u4E2A\u6D41\u7A0B\uFF08**\u5FC5\u987B\u95EE\uFF0C\u4E0D\u8981\u81EA\u5DF1\u731C\uFF0C\u4E5F\u4E0D\u8981\u62FF\u76F8\u4F3C\u7684\u540D\u5B57\u4EE3\u66FF**\uFF09\uFF0C\u518D\u6309 `requiredInput.workflow` \u7ED9\u51FA\u7684\u5F62\u6001\u628A\u5165\u53C2\u8865\u4E0A\u3001\u91CD\u53D1\u540C\u4E00\u6761\u547D\u4EE4\u3002\u6CE8\u610F `--input` \u63A5\u6536\u7684\u662F**\u6587\u4EF6\u8DEF\u5F84**\uFF08`-` \u8868\u793A\u6807\u51C6\u8F93\u5165\uFF09\uFF0C\u5185\u8054 JSON \u8981\u7528 `--input-json`\u3002";
|
|
112
|
+
}
|
|
99
113
|
if (reason === "workflow_not_exist") {
|
|
100
114
|
return base + '\u8BF7\u5982\u5B9E\u544A\u77E5\u7528\u6237\uFF1A\u8BE5\u5DE5\u4F5C\u6D41\u4E0D\u5B58\u5728\uFF08\u53EF\u80FD\u5DF2\u5220\u9664\u6216\u88AB\u505C\u7528\uFF09\uFF0C\u8BF7\u7528\u6237\u6539\u7528\u8BE5\u6D41\u7A0B\u7684\u5B8C\u6574\u540D\u79F0\uFF08\u6216\u5176\u5B83\u53EF\u7528\u4E8E\u68C0\u7D22\u7684\u5173\u952E\u8BCD\uFF09\u91CD\u65B0\u6307\u5B9A\u2014\u2014**\u4E0D\u8981\u5411\u7528\u6237\u7D22\u53D6 ID**\u3002**\u4E0D\u8981**\u8BF4\u6210"\u6CA1\u6709\u53EF\u53D1\u8D77\u7684\u5DE5\u4F5C\u6D41"\u8FD9\u7C7B\u6A21\u7CCA\u8BF4\u6CD5\u2014\u2014\u95EE\u9898\u5C31\u51FA\u5728\u8FD9\u4E2A\u76EE\u6807\u4E0A\u3002';
|
|
101
115
|
}
|
|
@@ -129,6 +143,86 @@ async function executeWorkflowOperation(operation, rawInput, context) {
|
|
|
129
143
|
return result;
|
|
130
144
|
}
|
|
131
145
|
|
|
146
|
+
// src/shortcuts/workflow/index.ts
|
|
147
|
+
import { join as join2 } from "node:path";
|
|
148
|
+
|
|
149
|
+
// src/shortcuts/workflow/operations/todoSmartConvert/aigroupStore.ts
|
|
150
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
151
|
+
import { join } from "node:path";
|
|
152
|
+
function normalizeIntentPayload(payload) {
|
|
153
|
+
if (Array.isArray(payload)) return payload;
|
|
154
|
+
if (payload && typeof payload === "object") {
|
|
155
|
+
const record = payload;
|
|
156
|
+
if (Array.isArray(record.rules)) return record.rules;
|
|
157
|
+
if (record.workflowName !== void 0) return [record];
|
|
158
|
+
}
|
|
159
|
+
throw workflowValidationError("aigroup_invalid", "\u5165\u53C2\u5FC5\u987B\u662F\u89C4\u5219\u5BF9\u8C61\u3001\u89C4\u5219\u6570\u7EC4\uFF0C\u6216 { rules: [...] }");
|
|
160
|
+
}
|
|
161
|
+
function namesOf(rule) {
|
|
162
|
+
const raw = rule?.workflowName;
|
|
163
|
+
if (typeof raw === "string") return [raw.trim()].filter(Boolean);
|
|
164
|
+
if (Array.isArray(raw)) return raw.map((item) => String(item ?? "").trim()).filter(Boolean);
|
|
165
|
+
return [];
|
|
166
|
+
}
|
|
167
|
+
function saveUserIntents(payload, options = {}) {
|
|
168
|
+
const dir = options.dir ?? aigroupUserDir(options.ctx);
|
|
169
|
+
const warnings = [];
|
|
170
|
+
const entries = normalizeIntentPayload(payload);
|
|
171
|
+
if (entries.length === 0) throw workflowValidationError("aigroup_invalid", "\u5165\u53C2\u91CC\u6CA1\u6709\u89C4\u5219\u6761\u76EE");
|
|
172
|
+
const starred = entries.filter((rule) => namesOf(rule).includes("*"));
|
|
173
|
+
if (starred.length > 0) {
|
|
174
|
+
throw workflowValidationError(
|
|
175
|
+
"aigroup_wildcard_unsupported",
|
|
176
|
+
"\u7528\u6237\u610F\u56FE\u4E0D\u80FD\u4F7F\u7528\u901A\u914D workflowName\u300C*\u300D\uFF1A\u515C\u5E95\u89C4\u5219\u7531 aigroup/default.json \u51B3\u5B9A"
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
const check = validateRuleFile({ schemaVersion: 2, defaults: {}, rules: entries });
|
|
180
|
+
if (check.length > 0) {
|
|
181
|
+
throw workflowValidationError("aigroup_invalid", `\u89C4\u5219\u6821\u9A8C\u5931\u8D25\uFF1A${check.join("\uFF1B")}`);
|
|
182
|
+
}
|
|
183
|
+
const file = join(dir, USER_INTENT_RULE_FILE);
|
|
184
|
+
const existing = existsSync(file) ? loadRuleFile(file) : emptyRuleFile();
|
|
185
|
+
if (existing.error) {
|
|
186
|
+
warnings.push(`${existing.error}\uFF1B\u672C\u6B21\u5C06\u91CD\u5EFA\u8BE5\u6587\u4EF6`);
|
|
187
|
+
}
|
|
188
|
+
const byName = /* @__PURE__ */ new Map();
|
|
189
|
+
const replaced = [];
|
|
190
|
+
for (const rule of existing.file.rules) {
|
|
191
|
+
for (const name of namesOf(rule)) byName.set(name, rule);
|
|
192
|
+
}
|
|
193
|
+
for (const rule of entries) {
|
|
194
|
+
const names = namesOf(rule);
|
|
195
|
+
for (const name of names) {
|
|
196
|
+
if (byName.has(name)) replaced.push(name);
|
|
197
|
+
byName.set(name, rule);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
const merged = [...new Set(byName.values())];
|
|
201
|
+
const text = `${JSON.stringify({ schemaVersion: 2, rules: merged }, null, 2)}
|
|
202
|
+
`;
|
|
203
|
+
mkdirSync(dir, { recursive: true, mode: 448 });
|
|
204
|
+
writeFileSync(file, text, { mode: 384 });
|
|
205
|
+
return { file, saved: entries.length, total: merged.length, replaced: [...new Set(replaced)], warnings };
|
|
206
|
+
}
|
|
207
|
+
function readUserIntents(options = {}) {
|
|
208
|
+
const dir = options.dir ?? aigroupUserDir(options.ctx);
|
|
209
|
+
const file = join(dir, USER_INTENT_RULE_FILE);
|
|
210
|
+
if (!existsSync(file)) return { dir, file, exists: false, error: null, rules: [] };
|
|
211
|
+
const loaded = loadRuleFile(file);
|
|
212
|
+
return { dir, file, exists: true, error: loaded.error, rules: loaded.file.rules };
|
|
213
|
+
}
|
|
214
|
+
function clearUserIntents(options = {}) {
|
|
215
|
+
const dir = options.dir ?? aigroupUserDir(options.ctx);
|
|
216
|
+
const file = join(dir, USER_INTENT_RULE_FILE);
|
|
217
|
+
mkdirSync(dir, { recursive: true, mode: 448 });
|
|
218
|
+
writeFileSync(file, `${JSON.stringify({ schemaVersion: 2, rules: [] }, null, 2)}
|
|
219
|
+
`, { mode: 384 });
|
|
220
|
+
return file;
|
|
221
|
+
}
|
|
222
|
+
function readRawUserIntents(file) {
|
|
223
|
+
return readFileSync(file, "utf8");
|
|
224
|
+
}
|
|
225
|
+
|
|
132
226
|
// src/shortcuts/workflow/index.ts
|
|
133
227
|
function asOptions(value) {
|
|
134
228
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
@@ -218,6 +312,43 @@ async function executeAndPrint(ctx, operation, input) {
|
|
|
218
312
|
process.exitCode = isCliError(error) ? error.exitCode : 1 /* GeneralError */;
|
|
219
313
|
}
|
|
220
314
|
}
|
|
315
|
+
function fieldNamesOf(inputSchema) {
|
|
316
|
+
const properties = inputSchema.properties;
|
|
317
|
+
if (!properties || typeof properties !== "object" || Array.isArray(properties)) return [];
|
|
318
|
+
return Object.keys(properties);
|
|
319
|
+
}
|
|
320
|
+
function manifestIndex() {
|
|
321
|
+
return {
|
|
322
|
+
schemaVersion: workflowManifest.schemaVersion,
|
|
323
|
+
name: workflowManifest.name,
|
|
324
|
+
title: workflowManifest.title,
|
|
325
|
+
version: workflowManifest.version,
|
|
326
|
+
host: workflowManifest.host,
|
|
327
|
+
status: workflowManifest.status,
|
|
328
|
+
sourceSkill: workflowManifest.sourceSkill,
|
|
329
|
+
capabilities: workflowManifest.capabilities,
|
|
330
|
+
operationCount: workflowManifest.operations.length,
|
|
331
|
+
operations: workflowManifest.operations.map((definition) => ({
|
|
332
|
+
name: definition.name,
|
|
333
|
+
resource: definition.resource,
|
|
334
|
+
summary: definition.summary,
|
|
335
|
+
...definition.capability ? { capability: definition.capability } : {},
|
|
336
|
+
risk: definition.risk,
|
|
337
|
+
...definition.requiresConfirmation ? { requiresConfirmation: true } : {},
|
|
338
|
+
fields: fieldNamesOf(definition.inputSchema)
|
|
339
|
+
})),
|
|
340
|
+
withheldOperations: workflowManifest.withheldOperations,
|
|
341
|
+
operationsHint: "\u9ED8\u8BA4\u53EA\u5217 operation \u4E0E\u5B57\u6BB5\u540D\uFF1B\u5B57\u6BB5\u7C7B\u578B\u3001\u679A\u4E3E\u548C\u586B\u5199\u53E3\u5F84\u7528 `workflow schema --operation <name>` \u5355\u53D6\uFF0C\u6574\u4EFD\u5B8C\u6574 manifest \u7528 `workflow schema --full`\u3002"
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
function findOperationContract(name) {
|
|
345
|
+
const full = name.startsWith("workflow.") ? name : `workflow.${name}`;
|
|
346
|
+
const matched = workflowManifest.operations.find((definition) => definition.name === full);
|
|
347
|
+
if (!matched) {
|
|
348
|
+
throw workflowValidationError("operation_unknown", `\u6D41\u7A0B\u6A21\u5757\u4E0D\u652F\u6301\u64CD\u4F5C\uFF1A${name}`);
|
|
349
|
+
}
|
|
350
|
+
return matched;
|
|
351
|
+
}
|
|
221
352
|
function withJsonInputOptions(command) {
|
|
222
353
|
command.option("--input <path>", "JSON input file, or - for stdin").option("--input-json <json>", "inline JSON input object");
|
|
223
354
|
return command;
|
|
@@ -228,8 +359,50 @@ var workflowShortcut = {
|
|
|
228
359
|
category: "shortcut",
|
|
229
360
|
register({ program, action }) {
|
|
230
361
|
const workflow = program.command("workflow").description("\u6CDB\u5FAEE10\u6D41\u7A0B\u667A\u80FD\u52A9\u624B\uFF08\u5F85\u529E/\u5DF2\u529E/\u6211\u53D1\u8D77/\u5168\u90E8\u3001\u8BE6\u60C5\u3001\u64CD\u4F5C\u3001\u6279\u91CF\u3001\u53D1\u8D77\u3001\u4FEE\u6539\uFF09");
|
|
231
|
-
workflow.command("schema").description("Print workflow operation manifest for agents").action(action((ctx) => {
|
|
232
|
-
|
|
362
|
+
workflow.command("schema").description("Print workflow operation manifest for agents").option("--operation <name>", "print one operation with its full inputSchema").option("--full", "print the whole manifest (about 65 KB; stdout may be trimmed)").action(action((ctx, options) => {
|
|
363
|
+
const opts = asOptions(options);
|
|
364
|
+
const requested = String(opts.operation ?? "").trim();
|
|
365
|
+
if (requested && opts.full === true) {
|
|
366
|
+
throw workflowValidationError("option_conflict", "\u4E0D\u80FD\u540C\u65F6\u4F20 --operation \u548C --full");
|
|
367
|
+
}
|
|
368
|
+
if (opts.full === true) {
|
|
369
|
+
ctx.output.write(workflowManifest, { json: true });
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
if (requested) {
|
|
373
|
+
ctx.output.write(findOperationContract(requested), { json: true });
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
ctx.output.write(manifestIndex(), { json: true });
|
|
377
|
+
}));
|
|
378
|
+
const aigroup = workflow.command("aigroup").description("ai\u4E8C\u6B21\u5206\u7EC4\u89C4\u5219\u5E93\uFF08\u9ED8\u8BA4\u89C4\u5219 + \u7528\u6237\u610F\u56FE\uFF09");
|
|
379
|
+
aigroup.command("show").description("Print effective ai-group rules (default merged with user intents)").option("--raw", "also print user-intents.json as stored on disk").action(action((ctx, options) => {
|
|
380
|
+
const opts = asOptions(options);
|
|
381
|
+
const loaded = loadRules({ ctx });
|
|
382
|
+
const user = readUserIntents({ ctx });
|
|
383
|
+
ctx.output.write({
|
|
384
|
+
dir: loaded.dir,
|
|
385
|
+
defaultFile: join2(loaded.dir, "default.json"),
|
|
386
|
+
userIntentFile: user.file,
|
|
387
|
+
userIntentExists: user.exists,
|
|
388
|
+
userIntentError: user.error,
|
|
389
|
+
defaults: loaded.file.defaults,
|
|
390
|
+
rules: loaded.file.rules,
|
|
391
|
+
userRules: user.rules,
|
|
392
|
+
warnings: loaded.warnings,
|
|
393
|
+
...opts.raw === true && user.exists ? { rawUserIntents: readRawUserIntents(user.file) } : {}
|
|
394
|
+
}, { json: true });
|
|
395
|
+
}));
|
|
396
|
+
withJsonInputOptions(aigroup.command("set").description("Save user-intent rules: validated, whole-entry replace by workflowName").action(action(async (ctx, options) => {
|
|
397
|
+
const payload = await inputFrom(options);
|
|
398
|
+
const result = saveUserIntents(payload, { ctx });
|
|
399
|
+
resetActiveRules();
|
|
400
|
+
ctx.output.write(result, { json: true });
|
|
401
|
+
})));
|
|
402
|
+
aigroup.command("clear").description("Empty user-intent rules (default.json is never touched)").action(action((ctx) => {
|
|
403
|
+
const file = clearUserIntents({ ctx });
|
|
404
|
+
resetActiveRules();
|
|
405
|
+
ctx.output.write({ cleared: true, file }, { json: true });
|
|
233
406
|
}));
|
|
234
407
|
withJsonInputOptions(workflow.command("run").description("Run a workflow operation with JSON input").argument("<operation>", "operation name, e.g. workflow.search")).action(action(async (ctx, operation, options) => {
|
|
235
408
|
await executeAndPrint(ctx, String(operation), await inputFrom(options));
|
package/dist/index.js
CHANGED
|
@@ -7,12 +7,12 @@ import {
|
|
|
7
7
|
firstPositionalToken,
|
|
8
8
|
registerCommands,
|
|
9
9
|
toCommandMetadata
|
|
10
|
-
} from "./chunks/chunk-
|
|
10
|
+
} from "./chunks/chunk-JYKABYCV.js";
|
|
11
11
|
import "./chunks/chunk-EG6ZU444.js";
|
|
12
12
|
import "./chunks/chunk-AJ62BGAW.js";
|
|
13
|
-
import "./chunks/chunk-
|
|
14
|
-
import "./chunks/chunk-
|
|
15
|
-
import "./chunks/chunk-
|
|
13
|
+
import "./chunks/chunk-JCSN3JGM.js";
|
|
14
|
+
import "./chunks/chunk-JUXVYKII.js";
|
|
15
|
+
import "./chunks/chunk-JNG42JKG.js";
|
|
16
16
|
import "./chunks/chunk-LUSPKZKY.js";
|
|
17
17
|
import "./chunks/chunk-BUSC6UAE.js";
|
|
18
18
|
|
|
@@ -29,7 +29,7 @@ function lazyShortcut(definition) {
|
|
|
29
29
|
placeholder.allowExcessArguments(true);
|
|
30
30
|
placeholder.helpOption(false);
|
|
31
31
|
placeholder.action(async () => {
|
|
32
|
-
const { dispatchLazyShortcut } = await import("./chunks/lazy-dispatch-
|
|
32
|
+
const { dispatchLazyShortcut } = await import("./chunks/lazy-dispatch-QXW7P4X3.js");
|
|
33
33
|
await dispatchLazyShortcut(definition, shortcutMetadata());
|
|
34
34
|
});
|
|
35
35
|
}
|
|
@@ -39,102 +39,112 @@ var builtinShortcuts = [
|
|
|
39
39
|
lazyShortcut({
|
|
40
40
|
name: "invoice",
|
|
41
41
|
description: "E10 \u4E1A\u7968\u901A\u53D1\u7968\u7BA1\u7406 CLI",
|
|
42
|
-
load: async () => (await import("./chunks/invoice-
|
|
42
|
+
load: async () => (await import("./chunks/invoice-2Z6YPMIS.js")).invoiceShortcut
|
|
43
43
|
}),
|
|
44
44
|
lazyShortcut({
|
|
45
45
|
name: "ehr",
|
|
46
46
|
description: "\u6CDB\u5FAEE10\u805A\u624D\u6797\uFF08\u4EBA\u4E8B/\u51FA\u52E4/\u85AA\u916C\uFF09CLI",
|
|
47
|
-
load: async () => (await import("./chunks/ehr-
|
|
47
|
+
load: async () => (await import("./chunks/ehr-EAP77IMT.js")).ehrShortcut
|
|
48
|
+
}),
|
|
49
|
+
lazyShortcut({
|
|
50
|
+
name: "cowork",
|
|
51
|
+
description: "\u6CDB\u5FAEE10\u534F\u4F5C\u533A\uFF08\u534F\u4F5C\u4E8B\u9879/\u8BA8\u8BBA/\u5BA1\u6279/\u5171\u4EAB\u6743\u9650\uFF09CLI",
|
|
52
|
+
load: async () => (await import("./chunks/cowork-SCPGLBA4.js")).coworkShortcut
|
|
48
53
|
}),
|
|
49
54
|
lazyShortcut({
|
|
50
55
|
name: "archive",
|
|
51
56
|
description: "E10 \u6587\u4E66\u5B9A\u6863\u6848\u7BA1\u7406 CLI",
|
|
52
|
-
load: async () => (await import("./chunks/archive-
|
|
57
|
+
load: async () => (await import("./chunks/archive-XBVH7JU7.js")).archiveShortcut
|
|
53
58
|
}),
|
|
54
59
|
lazyShortcut({
|
|
55
60
|
name: "archive-oa",
|
|
56
61
|
description: "E10 \u6863\u6848\u5B9A\u4F4D\u4E0E OA \u5546\u52A1\u5408\u540C\u501F\u9605 CLI",
|
|
57
|
-
load: async () => (await import("./chunks/archive-oa-
|
|
62
|
+
load: async () => (await import("./chunks/archive-oa-MZM3EKFQ.js")).archiveOaShortcut
|
|
58
63
|
}),
|
|
59
64
|
lazyShortcut({
|
|
60
65
|
name: "calendar",
|
|
61
66
|
description: "\u6CDB\u5FAEE10\u65E5\u7A0B\u7BA1\u7406 CLI\uFF08\u521B\u5EFA/\u67E5\u8BE2/\u66F4\u65B0/\u5220\u9664/\u5B57\u5178\uFF09",
|
|
62
|
-
load: async () => (await import("./chunks/calendar-
|
|
67
|
+
load: async () => (await import("./chunks/calendar-MXEMTIO4.js")).calendarShortcut
|
|
63
68
|
}),
|
|
64
69
|
lazyShortcut({
|
|
65
70
|
name: "fna",
|
|
66
71
|
description: "\u6CDB\u5FAEE10\u9F50\u4E1A\u6210\u8D39\u63A7\u4E2D\u5FC3\uFF08\u9884\u7B97/\u8D39\u7528\u4E2D\u5FC3/\u501F\u6B3E\u7BA1\u7406/\u53D1\u7968\u6838\u9500\uFF09CLI",
|
|
67
|
-
load: async () => (await import("./chunks/fna-
|
|
72
|
+
load: async () => (await import("./chunks/fna-2X7ZE7BU.js")).fnaShortcut
|
|
68
73
|
}),
|
|
69
74
|
lazyShortcut({
|
|
70
75
|
name: "hrm",
|
|
71
76
|
description: "\u6CDB\u5FAEE10\u7EC4\u7EC7\u7BA1\u7406\uFF08\u5458\u5DE5/\u7EC4\u7EC7/\u5C97\u4F4D\u67E5\u8BE2\uFF09CLI",
|
|
72
|
-
load: async () => (await import("./chunks/hrm-
|
|
77
|
+
load: async () => (await import("./chunks/hrm-YXERJM76.js")).hrmShortcut
|
|
73
78
|
}),
|
|
74
79
|
lazyShortcut({
|
|
75
80
|
name: "mail",
|
|
76
81
|
description: "\u6CDB\u5FAEE10\u90AE\u4EF6\u7BA1\u7406 CLI",
|
|
77
|
-
load: async () => (await import("./chunks/mail-
|
|
82
|
+
load: async () => (await import("./chunks/mail-7GZ6CPBJ.js")).mailShortcut
|
|
78
83
|
}),
|
|
79
84
|
lazyShortcut({
|
|
80
85
|
name: "meeting",
|
|
81
86
|
description: "\u6CDB\u5FAEE10\u4F1A\u8BAE\u7BA1\u7406 CLI\uFF08\u6807\u51C6\u7248\uFF1A\u67E5\u8BE2/\u51B2\u7A81/\u9884\u7EA6/\u56DE\u6267/\u7B7E\u5230\uFF09",
|
|
82
|
-
load: async () => (await import("./chunks/meeting-
|
|
87
|
+
load: async () => (await import("./chunks/meeting-3NMGA3MB.js")).meetingShortcut
|
|
83
88
|
}),
|
|
84
89
|
lazyShortcut({
|
|
85
90
|
name: "okr",
|
|
86
91
|
description: "\u6CDB\u5FAEE10 OKR \u76EE\u6807\u7BA1\u7406 CLI\uFF08\u76EE\u6807\u67E5\u8BE2/\u65B0\u5EFA/\u7F16\u8F91\u3001\u5173\u952E\u6210\u679C\u3001\u76EE\u6807\u5BF9\u9F50\u3001\u8BC4\u8BBA\uFF09",
|
|
87
|
-
load: async () => (await import("./chunks/okr-
|
|
92
|
+
load: async () => (await import("./chunks/okr-BZ6XUOAG.js")).okrShortcut
|
|
88
93
|
}),
|
|
89
94
|
lazyShortcut({
|
|
90
95
|
name: "plan",
|
|
91
96
|
description: "\u6CDB\u5FAEE10\u8BA1\u5212\u62A5\u544A CLI\uFF08\u67E5\u8BE2/\u65B0\u5EFA/\u4FEE\u6539/\u53D1\u5E03/\u64A4\u56DE/\u63D0\u4EA4\u63D0\u9192/\u8BC4\u8BBA\uFF09",
|
|
92
|
-
load: async () => (await import("./chunks/plan-
|
|
97
|
+
load: async () => (await import("./chunks/plan-DR5CMUYP.js")).planShortcut
|
|
93
98
|
}),
|
|
94
99
|
lazyShortcut({
|
|
95
100
|
name: "esb",
|
|
96
101
|
description: "\u6CDB\u5FAEE10 ESB \u4E2D\u5FC3\u81EA\u5B9A\u4E49\u89E6\u53D1\u52A8\u4F5C\u6D41 CLI",
|
|
97
|
-
load: async () => (await import("./chunks/esb-
|
|
102
|
+
load: async () => (await import("./chunks/esb-2TGGXEE7.js")).esbShortcut
|
|
98
103
|
}),
|
|
99
104
|
lazyShortcut({
|
|
100
105
|
name: "ebuilder-form",
|
|
101
106
|
description: "\u6CDB\u5FAEE10 eBuilder \u8868\u5355\u83DC\u5355\u3001\u5217\u8868\u548C\u8868\u5355\u6570\u636E CLI",
|
|
102
|
-
load: async () => (await import("./chunks/ebuilder-form-
|
|
107
|
+
load: async () => (await import("./chunks/ebuilder-form-EYLHNOTA.js")).ebuilderFormShortcut
|
|
103
108
|
}),
|
|
104
109
|
lazyShortcut({
|
|
105
110
|
name: "jiuchuanhui",
|
|
106
111
|
description: "\u6CDB\u5FAEE10\u4E5D\u6C1A\u6C47\u8425\u9500\u7BA1\u7406 CLI\uFF08\u5BA2\u6237/\u8054\u7CFB\u4EBA/\u5546\u673A/\u7EBF\u7D22/\u8054\u7CFB\u8BA1\u5212/\u516C\u6D77\uFF09",
|
|
107
|
-
load: async () => (await import("./chunks/jiuchuanhui-
|
|
112
|
+
load: async () => (await import("./chunks/jiuchuanhui-AR5GMKZB.js")).jiuchuanhuiShortcut
|
|
108
113
|
}),
|
|
109
114
|
lazyShortcut({
|
|
110
115
|
name: "asset",
|
|
111
116
|
description: "E10 \u8D44\u4EA7\u7BA1\u7406\uFF08\u8D44\u7BA1\u5BB6\uFF09CLI",
|
|
112
|
-
load: async () => (await import("./chunks/asset-
|
|
117
|
+
load: async () => (await import("./chunks/asset-4XO7UOUW.js")).assetShortcut
|
|
113
118
|
}),
|
|
114
119
|
lazyShortcut({
|
|
115
120
|
name: "im",
|
|
116
121
|
description: "\u6CDB\u5FAEE10\u6613\u79D2\u529E\uFF08\u5373\u65F6\u901A\u8BAF\uFF09CLI",
|
|
117
|
-
load: async () => (await import("./chunks/im-
|
|
122
|
+
load: async () => (await import("./chunks/im-A4VZN2TQ.js")).imShortcut
|
|
118
123
|
}),
|
|
119
124
|
lazyShortcut({
|
|
120
125
|
name: "project",
|
|
121
126
|
description: "\u6CDB\u5FAEE10\u4E8B\u4E95\u7136\u9879\u76EE\u7BA1\u7406 CLI\uFF08\u9879\u76EE/\u4EFB\u52A1\u67E5\u8BE2\u4E0E\u786E\u8BA4\u5199\u5165\uFF09",
|
|
122
|
-
load: async () => (await import("./chunks/project-
|
|
127
|
+
load: async () => (await import("./chunks/project-6J63MK33.js")).projectShortcut
|
|
123
128
|
}),
|
|
124
129
|
lazyShortcut({
|
|
125
130
|
name: "workflow",
|
|
126
131
|
description: "\u6CDB\u5FAEE10\u6D41\u7A0B\u667A\u80FD\u52A9\u624B CLI\uFF08\u67E5\u8BE2/\u67E5\u770B/\u64CD\u4F5C/\u6279\u91CF/\u53D1\u8D77/\u4FEE\u6539\uFF09",
|
|
127
|
-
load: async () => (await import("./chunks/workflow-
|
|
132
|
+
load: async () => (await import("./chunks/workflow-D74NFK3C.js")).workflowShortcut
|
|
128
133
|
}),
|
|
129
134
|
lazyShortcut({
|
|
130
135
|
name: "blog",
|
|
131
136
|
description: "\u6CDB\u5FAEE10\u5DE5\u4F5C\u65E5\u62A5 CLI\uFF08\u67E5\u8BE2/\u53D1\u5E03/\u7F16\u8F91/\u8BC4\u8BBA/\u70B9\u8D5E/\u63D0\u9192/\u5BFC\u51FA\uFF09",
|
|
132
|
-
load: async () => (await import("./chunks/blog-
|
|
137
|
+
load: async () => (await import("./chunks/blog-PGZKOPSC.js")).blogShortcut
|
|
133
138
|
}),
|
|
134
139
|
lazyShortcut({
|
|
135
140
|
name: "caizhilian",
|
|
136
141
|
description: "\u6CDB\u5FAEE10\u91C7\u77E5\u8FDE\uFF08\u6587\u6863\u4E2D\u5FC3\uFF09CLI",
|
|
137
|
-
load: async () => (await import("./chunks/caizhilian-
|
|
142
|
+
load: async () => (await import("./chunks/caizhilian-BH4ZVGUN.js")).caizhilianShortcut
|
|
143
|
+
}),
|
|
144
|
+
lazyShortcut({
|
|
145
|
+
name: "contract",
|
|
146
|
+
description: "\u6CDB\u5FAEE10\u4ECA\u627F\u8FBE\u5408\u540C\u7BA1\u7406 CLI",
|
|
147
|
+
load: async () => (await import("./chunks/contract-XI2EEIZU.js")).contractShortcut
|
|
138
148
|
})
|
|
139
149
|
];
|
|
140
150
|
function shortcutMetadata() {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isXiaoERuntimeAgent } from '../../core/runtime-agent.js';
|
|
1
2
|
import { getActiveProfile } from './auth/session.js';
|
|
2
3
|
import { hasXiaoEEnv, tryXiaoEUnifiedLogin } from './auth/xiaoe.js';
|
|
3
4
|
const AUTH_REQUIRED_CODES = new Set(['-2', '401']);
|
|
@@ -94,12 +95,21 @@ export function isE10AuthenticationRequired(response) {
|
|
|
94
95
|
function globalOptions(ctx) {
|
|
95
96
|
return typeof ctx.getGlobalOptions === 'function' ? ctx.getGlobalOptions() : {};
|
|
96
97
|
}
|
|
97
|
-
/**
|
|
98
|
-
|
|
98
|
+
/**
|
|
99
|
+
* Decide whether an expired session can be recovered through XiaoE without
|
|
100
|
+
* involving the caller/Agent. Runtime evidence is preferred, but a persisted
|
|
101
|
+
* XiaoE login is also authoritative: business commands often run in a fresh
|
|
102
|
+
* process where the host no longer injects its original XIAOE_* markers.
|
|
103
|
+
*/
|
|
104
|
+
export function canAutomaticallyRecoverXiaoE(ctx, currentSession) {
|
|
99
105
|
const options = globalOptions(ctx);
|
|
100
106
|
// An explicitly supplied auth file is caller-owned and must not be replaced
|
|
101
107
|
// by a profile-backed XiaoE session behind the caller's back.
|
|
102
|
-
|
|
108
|
+
if (options.auth)
|
|
109
|
+
return false;
|
|
110
|
+
return hasXiaoEEnv(ctx.env || process.env, options)
|
|
111
|
+
|| currentSession?.loginSource === 'xiaoe-unified'
|
|
112
|
+
|| isXiaoERuntimeAgent(currentSession?.agentType);
|
|
103
113
|
}
|
|
104
114
|
/**
|
|
105
115
|
* Silently refresh a stale XiaoE session. Concurrent requests for the same
|
|
@@ -107,7 +117,7 @@ export function canAutomaticallyRecoverXiaoE(ctx) {
|
|
|
107
117
|
* does not start a burst of login attempts.
|
|
108
118
|
*/
|
|
109
119
|
export async function recoverXiaoEAuthSession(ctx, currentSession) {
|
|
110
|
-
if (!canAutomaticallyRecoverXiaoE(ctx))
|
|
120
|
+
if (!canAutomaticallyRecoverXiaoE(ctx, currentSession))
|
|
111
121
|
return null;
|
|
112
122
|
const options = globalOptions(ctx);
|
|
113
123
|
const profile = options.profile || getActiveProfile();
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
const storage = new AsyncLocalStorage();
|
|
3
|
+
export function createFetchTimingSink() {
|
|
4
|
+
return { fetchMs: 0, fetchCount: 0, fetchStart: null, fetchEnd: null };
|
|
5
|
+
}
|
|
6
|
+
/** 在 `sink` 的上下文里执行 `fn`:期间发生的 fetch 都会记到它上面。 */
|
|
7
|
+
export function runWithFetchTiming(sink, fn) {
|
|
8
|
+
return storage.run(sink, fn);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* fetch 前调一次,拿到的结束函数在 fetch 落定(成功或失败)时调一次。
|
|
12
|
+
* 返回 `null` 表示当前没有 sink(非计时路径)⇒ 调用方跳过全部计时动作。
|
|
13
|
+
*/
|
|
14
|
+
export function startFetchTiming() {
|
|
15
|
+
const sink = storage.getStore();
|
|
16
|
+
if (!sink)
|
|
17
|
+
return null;
|
|
18
|
+
const startedAt = Date.now();
|
|
19
|
+
let finished = false;
|
|
20
|
+
return () => {
|
|
21
|
+
if (finished)
|
|
22
|
+
return;
|
|
23
|
+
finished = true;
|
|
24
|
+
const endedAt = Date.now();
|
|
25
|
+
sink.fetchMs += Math.max(0, endedAt - startedAt);
|
|
26
|
+
sink.fetchCount += 1;
|
|
27
|
+
// 重试会有多次 fetch:起点取最早、终点取最晚,中间的空档(如换票据)不计入 fetchCost。
|
|
28
|
+
sink.fetchStart = sink.fetchStart === null ? startedAt : Math.min(sink.fetchStart, startedAt);
|
|
29
|
+
sink.fetchEnd = sink.fetchEnd === null ? endedAt : Math.max(sink.fetchEnd, endedAt);
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CliError, ExitCode } from '../../core/errors.js';
|
|
2
2
|
import { isE10AuthenticationRequired, recoverXiaoEAuthSession, sameE10SessionIdentity, } from './auth-recovery.js';
|
|
3
|
+
import { startFetchTiming } from './fetch-timing.js';
|
|
3
4
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
4
5
|
const DEFAULT_BIG_INT_STRINGS = true;
|
|
5
6
|
const RESERVED_HEADERS = [
|
|
@@ -220,6 +221,9 @@ export class E10RequestRuntime {
|
|
|
220
221
|
async fetchWithTimeout(url, init, timeoutMs) {
|
|
221
222
|
const controller = new AbortController();
|
|
222
223
|
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
224
|
+
// 「纯 fetch」= 发出请求 → 收到响应头(`fetch` 落定那一刻,不含读响应体/解析)。没有计时上下文
|
|
225
|
+
// (`startFetchTiming()` 返回 `null`)时它什么都不做,非计时路径零开销。
|
|
226
|
+
const stopFetchTiming = startFetchTiming();
|
|
223
227
|
try {
|
|
224
228
|
return await this.fetchFn(url, { ...init, signal: controller.signal });
|
|
225
229
|
}
|
|
@@ -238,6 +242,7 @@ export class E10RequestRuntime {
|
|
|
238
242
|
}
|
|
239
243
|
finally {
|
|
240
244
|
clearTimeout(timer);
|
|
245
|
+
stopFetchTiming?.();
|
|
241
246
|
}
|
|
242
247
|
}
|
|
243
248
|
async readResponse(response, responseType, bigIntStrings = DEFAULT_BIG_INT_STRINGS, maxResponseBytes, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
@@ -3,6 +3,7 @@ import { basename } from 'node:path';
|
|
|
3
3
|
import { E10_SESSION_EXPIRED_MESSAGE } from '../../internal/e10/auth/messages.js';
|
|
4
4
|
import { requireE10Session } from '../../internal/e10/context.js';
|
|
5
5
|
import { getActiveProfile } from '../../internal/e10/auth/session.js';
|
|
6
|
+
import { E10ApiError, createE10RequestRuntime, } from '../../internal/e10/request-runtime.js';
|
|
6
7
|
import { ContractCliError, contractAuthError, contractNetworkError, contractValidationError, } from './errors.js';
|
|
7
8
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
8
9
|
function assertPath(requestPath) {
|
|
@@ -16,38 +17,6 @@ function assertPath(requestPath) {
|
|
|
16
17
|
throw contractValidationError('path_not_allowed', '今承达合同管理只能调用 /api/ 路径');
|
|
17
18
|
}
|
|
18
19
|
}
|
|
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
|
-
}
|
|
51
20
|
function textOf(value, keys) {
|
|
52
21
|
for (const key of keys) {
|
|
53
22
|
const candidate = value?.[key];
|
|
@@ -131,15 +100,6 @@ function inferProfile(ctx) {
|
|
|
131
100
|
const options = ctx.getGlobalOptions();
|
|
132
101
|
return options.profile || getActiveProfile();
|
|
133
102
|
}
|
|
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
|
-
}
|
|
143
103
|
export function createContractHost(ctx, dependencies = {}) {
|
|
144
104
|
let e10Session = null;
|
|
145
105
|
let sessionContext = null;
|
|
@@ -164,10 +124,9 @@ export function createContractHost(ctx, dependencies = {}) {
|
|
|
164
124
|
assertPath(path);
|
|
165
125
|
const session = await ensureSession();
|
|
166
126
|
const context = await getSession();
|
|
167
|
-
const
|
|
168
|
-
const finalQuery = { ...query };
|
|
127
|
+
const finalQuery = Object.fromEntries(Object.entries(query).filter(([, value]) => value !== undefined && value !== null && value !== ''));
|
|
169
128
|
let finalBody = body;
|
|
170
|
-
|
|
129
|
+
let formData;
|
|
171
130
|
if (userIdField) {
|
|
172
131
|
if (!context.userId) {
|
|
173
132
|
throw contractAuthError('user_id_missing', '当前会话没有可用的用户 ID,请确认 E10 登录态');
|
|
@@ -178,9 +137,9 @@ export function createContractHost(ctx, dependencies = {}) {
|
|
|
178
137
|
finalBody = { ...finalBody, [userIdField]: context.userId };
|
|
179
138
|
}
|
|
180
139
|
if (form || file) {
|
|
181
|
-
|
|
140
|
+
formData = new FormData();
|
|
182
141
|
for (const [key, value] of Object.entries(form ?? {}))
|
|
183
|
-
|
|
142
|
+
formData.append(key, value);
|
|
184
143
|
if (file) {
|
|
185
144
|
let buffer;
|
|
186
145
|
try {
|
|
@@ -190,25 +149,41 @@ export function createContractHost(ctx, dependencies = {}) {
|
|
|
190
149
|
throw contractValidationError('file_unreadable', `无法读取文件:${file.path}`);
|
|
191
150
|
}
|
|
192
151
|
const filename = file.filename ?? basename(file.path);
|
|
193
|
-
|
|
152
|
+
formData.append(file.field ?? 'file', new Blob([new Uint8Array(buffer)], { type: file.contentType ?? 'application/octet-stream' }), filename);
|
|
194
153
|
}
|
|
195
|
-
init.body = data;
|
|
196
154
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
155
|
+
const runtime = createE10RequestRuntime(ctx, session, {
|
|
156
|
+
interceptors: dependencies.interceptors,
|
|
157
|
+
fetch: dependencies.fetch,
|
|
158
|
+
recoverAuthentication: dependencies.recoverAuthentication,
|
|
159
|
+
});
|
|
160
|
+
let response;
|
|
161
|
+
try {
|
|
162
|
+
response = await runtime.requestJson({
|
|
163
|
+
module: 'contract',
|
|
164
|
+
method,
|
|
165
|
+
path,
|
|
166
|
+
query: finalQuery,
|
|
167
|
+
body: formData ? undefined : finalBody,
|
|
168
|
+
formData,
|
|
169
|
+
headers: extraHeaders,
|
|
170
|
+
timeoutMs,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
if (error instanceof E10ApiError && error.type === 'network') {
|
|
175
|
+
throw contractNetworkError(error.subtype, error.message, {
|
|
176
|
+
retryable: error.retryable,
|
|
177
|
+
details: error.details,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
throw error;
|
|
200
181
|
}
|
|
201
|
-
const url = withQuery(context.baseUrl, path, finalQuery);
|
|
202
|
-
const response = await fetchWithTimeout(url, init, timeoutMs);
|
|
203
182
|
if (response.status === 401 || response.status === 302) {
|
|
204
183
|
throw contractAuthError('session_expired', E10_SESSION_EXPIRED_MESSAGE, { httpStatus: response.status, path });
|
|
205
184
|
}
|
|
206
|
-
const text =
|
|
207
|
-
|
|
208
|
-
try {
|
|
209
|
-
value = text ? JSON.parse(text) : {};
|
|
210
|
-
}
|
|
211
|
-
catch {
|
|
185
|
+
const { text, value } = response;
|
|
186
|
+
if (response.parseError) {
|
|
212
187
|
throw contractNetworkError('protocol', `接口返回不是合法 JSON(HTTP ${response.status})`, {
|
|
213
188
|
retryable: false,
|
|
214
189
|
details: { path, status: response.status },
|