weaver-work-cli 0.1.36 → 0.1.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/dist/chunks/{archive-XBVH7JU7.js → archive-ENZYBBME.js} +559 -68
- package/dist/chunks/{archive-oa-MZM3EKFQ.js → archive-oa-YWLEC5V4.js} +4 -3
- package/dist/chunks/{asset-4XO7UOUW.js → asset-OOV6DWPA.js} +8 -7
- package/dist/chunks/asset-idle-RE632MY5.js +670 -0
- package/dist/chunks/{attachment-content-VXSWANAC.js → attachment-content-RWN2FCLL.js} +3 -3
- package/dist/chunks/{blog-PGZKOPSC.js → blog-PEPOJAL7.js} +5 -4
- package/dist/chunks/{caizhilian-BH4ZVGUN.js → caizhilian-WYIQDVPJ.js} +5 -4
- package/dist/chunks/{calendar-MXEMTIO4.js → calendar-CIARBAOX.js} +4 -3
- package/dist/chunks/{chunk-NCOVUAZK.js → chunk-36DIFZAH.js} +4 -3
- package/dist/chunks/{chunk-I6QGIBDM.js → chunk-BJGXMFGD.js} +4 -3
- package/dist/chunks/{chunk-TC6MZAO3.js → chunk-CQHGNCK2.js} +52 -2
- package/dist/chunks/{chunk-WXFPWCXG.js → chunk-EINRJHQ3.js} +3 -3
- package/dist/chunks/{chunk-JUXVYKII.js → chunk-EZGFHJFW.js} +201 -19
- package/dist/chunks/{chunk-VPUTVEMC.js → chunk-F2EQXUEE.js} +436 -290
- package/dist/chunks/{chunk-JYKABYCV.js → chunk-GVPJZXJ2.js} +3 -3
- package/dist/chunks/{chunk-6LLJFKJE.js → chunk-HJYVHXUQ.js} +1 -1
- package/dist/chunks/{chunk-T72N74ZT.js → chunk-I2HB737U.js} +5 -4
- package/dist/chunks/{chunk-VPXOPQJI.js → chunk-K3RUEEOL.js} +4 -2
- package/dist/chunks/{chunk-HXJQI5NM.js → chunk-KTCB5R5H.js} +3 -2
- package/dist/chunks/{chunk-XMGSYD6S.js → chunk-L4N7B7ZD.js} +4 -4
- package/dist/chunks/{chunk-QYGO5EE2.js → chunk-MUQUHKPG.js} +4 -3
- package/dist/chunks/{chunk-QHFANTX7.js → chunk-NLK2RZKG.js} +1348 -90
- package/dist/chunks/{chunk-F746NKNF.js → chunk-P2DAISYW.js} +1 -1
- package/dist/chunks/{chunk-BPE37FPB.js → chunk-T7JDJJ7H.js} +3 -3
- package/dist/chunks/{chunk-JNG42JKG.js → chunk-XXJOSZTQ.js} +6 -6
- package/dist/chunks/{chunk-5DQEEGCC.js → chunk-YS5DPN4T.js} +1 -1
- package/dist/chunks/{chunk-EG6ZU444.js → chunk-ZUX3P6BQ.js} +10 -5
- package/dist/chunks/{chunk-JCSN3JGM.js → chunk-ZXRNHZTE.js} +7 -6
- package/dist/chunks/{conflict-JAB2LJEZ.js → conflict-DRMDOL56.js} +2 -2
- package/dist/chunks/{contract-XI2EEIZU.js → contract-73MERZWN.js} +4 -3
- package/dist/chunks/{cowork-SCPGLBA4.js → cowork-HNGBPD7A.js} +4 -3
- package/dist/chunks/{ebuilder-form-EYLHNOTA.js → ebuilder-form-OY6DVNRK.js} +3 -3
- package/dist/chunks/{ehr-EAP77IMT.js → ehr-RAQNEQO7.js} +4 -3
- package/dist/chunks/{esb-2TGGXEE7.js → esb-6XV7C7YV.js} +4 -4
- package/dist/chunks/{fna-2X7ZE7BU.js → fna-XTSRB7G7.js} +4 -3
- package/dist/chunks/{host-Q4LZGCRU.js → host-3F5UM5GN.js} +3 -3
- package/dist/chunks/{host-XCLDDXKQ.js → host-A7J6GDUP.js} +3 -3
- package/dist/chunks/{host-I4NRK4MX.js → host-VGPVP7YF.js} +3 -3
- package/dist/chunks/{host-C6EL2RKL.js → host-YAQAPYNP.js} +3 -3
- package/dist/chunks/{host-UEI5FGDM.js → host-YMBXWFWX.js} +3 -3
- package/dist/chunks/{hrm-YXERJM76.js → hrm-TLHKC545.js} +3 -3
- package/dist/chunks/{im-A4VZN2TQ.js → im-YOUCFMUK.js} +3 -3
- package/dist/chunks/{invoice-2Z6YPMIS.js → invoice-WNBS2B4C.js} +3 -3
- package/dist/chunks/{jiuchuanhui-AR5GMKZB.js → jiuchuanhui-XABWS5RN.js} +4 -3
- package/dist/chunks/{lazy-dispatch-QXW7P4X3.js → lazy-dispatch-NLZ5UQQI.js} +5 -5
- package/dist/chunks/{mail-7GZ6CPBJ.js → mail-LRYMBFNL.js} +4 -3
- package/dist/chunks/{meeting-3NMGA3MB.js → meeting-ESXL6MFI.js} +13 -12
- package/dist/chunks/{okr-BZ6XUOAG.js → okr-EOV65SSF.js} +4 -3
- package/dist/chunks/{plan-DR5CMUYP.js → plan-YFPVKW6Y.js} +4 -3
- package/dist/chunks/{project-6J63MK33.js → project-MDVZUYQW.js} +4 -3
- package/dist/chunks/{registry-VRTNC6UR.js → registry-QCLZEDAP.js} +8 -8
- package/dist/chunks/{registry-KDD7DHNK.js → registry-VT5Y2HLA.js} +4 -4
- package/dist/chunks/{registry-TKX2E7C7.js → registry-YX4CSEMD.js} +3 -3
- package/dist/chunks/{room-recommend-XCWRMB5P.js → room-recommend-L3MWH4JW.js} +4 -4
- package/dist/chunks/{schedule-IVBICP32.js → schedule-UASAVDVD.js} +4 -4
- package/dist/chunks/{workflow-D74NFK3C.js → workflow-KDGIUCNW.js} +9 -6
- package/dist/core/output.js +16 -6
- package/dist/index.js +33 -28
- package/dist/internal/e10/auth/messages.js +1 -0
- package/dist/internal/e10/auth-recovery.js +127 -7
- package/dist/internal/e10/client.js +16 -2
- package/dist/internal/e10/context.js +16 -3
- package/dist/internal/e10/request-runtime.js +106 -8
- package/dist/shortcuts/archive/host.js +5 -2
- package/dist/shortcuts/archive/manifest.js +1 -1
- package/dist/shortcuts/archive/operations/borrow-list.js +13 -1
- package/dist/shortcuts/archive/operations/flow-url.js +1 -1
- package/dist/shortcuts/archive/operations/prelib.js +472 -0
- package/dist/shortcuts/archive/operations/registry.js +2 -0
- package/dist/shortcuts/archive/operations/upload.js +1 -1
- package/dist/shortcuts/archive-oa/host.js +2 -1
- package/dist/shortcuts/asset/host.js +6 -5
- package/dist/shortcuts/asset-idle/errors.js +44 -0
- package/dist/shortcuts/asset-idle/host.js +161 -0
- package/dist/shortcuts/asset-idle/index.js +114 -0
- package/dist/shortcuts/asset-idle/manifest.js +159 -0
- package/dist/shortcuts/asset-idle/operations/idle.js +47 -0
- package/dist/shortcuts/asset-idle/operations/registry.js +33 -0
- package/dist/shortcuts/asset-idle/operations/shared.js +142 -0
- package/dist/shortcuts/asset-idle/operations/types.js +9 -0
- package/dist/shortcuts/asset-idle/operations.js +15 -0
- package/dist/shortcuts/blog/host.js +3 -2
- package/dist/shortcuts/caizhilian/host.js +3 -2
- package/dist/shortcuts/calendar/host.js +2 -1
- package/dist/shortcuts/contract/host.js +2 -1
- package/dist/shortcuts/cowork/host.js +2 -1
- package/dist/shortcuts/ebuilder-form/host.js +3 -1
- package/dist/shortcuts/ehr/host.js +2 -1
- package/dist/shortcuts/esb/host.js +2 -1
- package/dist/shortcuts/fna/host.js +2 -1
- package/dist/shortcuts/hrm/host.js +2 -1
- package/dist/shortcuts/im/host.js +3 -2
- package/dist/shortcuts/index.js +5 -0
- package/dist/shortcuts/invoice/host.js +5 -4
- package/dist/shortcuts/jiuchuanhui/host.js +2 -1
- package/dist/shortcuts/mail/host.js +2 -1
- package/dist/shortcuts/meeting/host.js +3 -2
- package/dist/shortcuts/meeting/invitation/text.js +71 -0
- package/dist/shortcuts/meeting/operations/eb/create-flow.js +1073 -50
- package/dist/shortcuts/meeting/operations/eb/crm-search.js +478 -0
- package/dist/shortcuts/meeting/operations/eb/factory.js +60 -1
- package/dist/shortcuts/meeting/operations/eb/index.js +2 -0
- package/dist/shortcuts/meeting/operations/invitation.js +122 -9
- package/dist/shortcuts/okr/host.js +2 -1
- package/dist/shortcuts/plan/host.js +2 -1
- package/dist/shortcuts/project/host.js +2 -1
- package/dist/shortcuts/workflow/host.js +3 -0
- package/dist/shortcuts/workflow/index.js +1 -1
- package/dist/shortcuts/workflow/operations/form.js +44 -11
- package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupRules.js +77 -26
- package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupStore.js +6 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/summaryCache.js +59 -117
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailCache.js +44 -7
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailFetcher.js +37 -29
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.collect.js +20 -6
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.detail.js +22 -18
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.groupSummary.js +34 -10
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.js +4 -2
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.smartGroup.js +9 -2
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.summary.js +110 -20
- package/docs/_catalog.md +3 -0
- package/docs/asset-idle.md +45 -0
- package/docs/e10-auth.md +1 -1
- package/docs/todo-smart-convert/subgroup-rules.md +1 -1
- package/package.json +1 -1
- package/scripts/package-skill.mjs +2 -0
- package/skill-template/business-info.json +14 -1
- package/skill-template/domains/asset-idle.md +13 -0
- package/skill-template/domains/wenshuding.md +3 -0
- package/skills/weaver-e10-archive-oa/SKILL.md +1 -0
- package/skills/weaver-e10-archive-oa/references/my-borrow.md +49 -0
- package/skills/weaver-e10-asset-idle/SKILL.md +73 -0
- package/skills/weaver-e10-asset-idle/references/idle-list.md +62 -0
- package/skills/weaver-e10-asset-idle/references/idle-stats-and-charts.md +65 -0
- package/skills/weaver-e10-asset-idle/references/source-manifest.json +193 -0
- package/skills/weaver-e10-asset-idle/references/widget-style.md +205 -0
- package/skills/weaver-e10-caizhilian/SKILL.md +29 -11
- package/skills/weaver-e10-caizhilian/references/auth-and-install.md +12 -0
- package/skills/weaver-e10-caizhilian/references/files.md +1 -1
- package/skills/weaver-e10-caizhilian/references/setting-encrypt.md +1 -1
- package/skills/weaver-e10-caizhilian/references/source-manifest.json +45 -45
- package/skills/weaver-e10-cowork/SKILL.md +2 -0
- package/skills/weaver-e10-jucailin/SKILL.md +2 -0
- package/skills/weaver-e10-jucailin/references/recruit-read.md +2 -0
- package/skills/weaver-e10-jucailin/references/recruit-write.md +1 -1
- package/skills/weaver-e10-mail/SKILL.md +3 -0
- package/skills/weaver-e10-meeting/SKILL.md +250 -301
- package/skills/weaver-e10-meeting/references/meeting-eb.md +203 -0
- package/skills/weaver-e10-meeting/references/meeting-invitation.md +37 -5
- package/skills/weaver-e10-meeting.zip +0 -0
- package/skills/weaver-e10-okr/references/source-manifest.json +3 -3
- package/skills/weaver-e10-shared/SKILL.md +5 -5
- package/skills/weaver-e10-shared/references/e10-auth-and-session.md +3 -3
- package/skills/weaver-e10-wenshuding/SKILL.md +29 -6
- package/skills/weaver-e10-wenshuding/references/archive-borrow-list.md +14 -0
- package/skills/weaver-e10-wenshuding/references/archive-download.md +2 -0
- package/skills/weaver-e10-wenshuding/references/archive-flow.md +1 -1
- package/skills/weaver-e10-wenshuding/references/archive-prelib-arrange.md +76 -0
- package/skills/weaver-e10-wenshuding/references/archive-prelib-list.md +107 -0
- package/skills/weaver-e10-wenshuding/references/archive-prelib-open.md +59 -0
- package/skills/weaver-e10-wenshuding/references/archive-upload.md +4 -1
- package/skills/weaver-e10-wenshuding/references/source-manifest.json +108 -65
- package/skills/weaver-e10-workflow/SKILL.md +5 -2
- package/skills/weaver-e10-workflow/aigroup/default.json +154 -19
- package/skills/weaver-e10-workflow/references/todo-smart-convert.md +59 -27
- package/skills/weaver-e10-workflow/tools/todo-serve.cjs +113 -25
- package/skills/weaver-e10-workflow/tools/todo-summary.cjs +292 -42
- package/skills/weaver-e10-yimiaoban/references/source-manifest.json +3 -3
|
@@ -3,12 +3,13 @@ const require = __esbuildCreateRequire(import.meta.url);
|
|
|
3
3
|
import {
|
|
4
4
|
E10ApiError,
|
|
5
5
|
createE10RequestRuntime,
|
|
6
|
+
isE10SessionExpiredResponse,
|
|
6
7
|
requireE10Session
|
|
7
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-EZGFHJFW.js";
|
|
8
9
|
import {
|
|
9
10
|
E10_SESSION_EXPIRED_MESSAGE,
|
|
10
11
|
getActiveProfile
|
|
11
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-XXJOSZTQ.js";
|
|
12
13
|
import {
|
|
13
14
|
CliError,
|
|
14
15
|
isCliError,
|
|
@@ -266,7 +267,7 @@ function createProjectHost(ctx, dependencies = {}) {
|
|
|
266
267
|
} catch (error) {
|
|
267
268
|
mapRuntimeNetworkError(error);
|
|
268
269
|
}
|
|
269
|
-
if (response
|
|
270
|
+
if (isE10SessionExpiredResponse(response)) {
|
|
270
271
|
throw projectAuthError("session_expired", E10_SESSION_EXPIRED_MESSAGE, {
|
|
271
272
|
httpStatus: response.status
|
|
272
273
|
});
|
|
@@ -4,14 +4,14 @@ import {
|
|
|
4
4
|
getMeetingOperation,
|
|
5
5
|
hasMeetingOperation,
|
|
6
6
|
meetingOperationDefinitions
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-NLK2RZKG.js";
|
|
8
|
+
import "./chunk-T7JDJJ7H.js";
|
|
9
|
+
import "./chunk-L4N7B7ZD.js";
|
|
10
|
+
import "./chunk-P2DAISYW.js";
|
|
11
|
+
import "./chunk-EINRJHQ3.js";
|
|
12
|
+
import "./chunk-KTCB5R5H.js";
|
|
13
|
+
import "./chunk-YS5DPN4T.js";
|
|
14
|
+
import "./chunk-CQHGNCK2.js";
|
|
15
15
|
import "./chunk-LUSPKZKY.js";
|
|
16
16
|
import "./chunk-BUSC6UAE.js";
|
|
17
17
|
export {
|
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
esbOperationDefinitions,
|
|
5
5
|
getEsbOperation,
|
|
6
6
|
hasEsbOperation
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
} from "./chunk-HJYVHXUQ.js";
|
|
8
|
+
import "./chunk-BJGXMFGD.js";
|
|
9
9
|
import "./chunk-GPMFD4RD.js";
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-EZGFHJFW.js";
|
|
11
|
+
import "./chunk-XXJOSZTQ.js";
|
|
12
12
|
import "./chunk-LUSPKZKY.js";
|
|
13
13
|
import "./chunk-BUSC6UAE.js";
|
|
14
14
|
export {
|
|
@@ -4,12 +4,12 @@ import {
|
|
|
4
4
|
getWorkflowOperation,
|
|
5
5
|
hasWorkflowOperation,
|
|
6
6
|
workflowOperationDefinitions
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-F2EQXUEE.js";
|
|
8
8
|
import "./chunk-EZALDOQH.js";
|
|
9
9
|
import "./chunk-FMPJJYYI.js";
|
|
10
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-ZUX3P6BQ.js";
|
|
11
11
|
import "./chunk-AJ62BGAW.js";
|
|
12
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-XXJOSZTQ.js";
|
|
13
13
|
import "./chunk-LUSPKZKY.js";
|
|
14
14
|
import "./chunk-BUSC6UAE.js";
|
|
15
15
|
export {
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
loadRooms,
|
|
7
7
|
recommendRooms,
|
|
8
8
|
rememberFrequentRoom
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-T7JDJJ7H.js";
|
|
10
|
+
import "./chunk-P2DAISYW.js";
|
|
11
|
+
import "./chunk-YS5DPN4T.js";
|
|
12
|
+
import "./chunk-CQHGNCK2.js";
|
|
13
13
|
import "./chunk-LUSPKZKY.js";
|
|
14
14
|
import "./chunk-BUSC6UAE.js";
|
|
15
15
|
export {
|
|
@@ -8,10 +8,10 @@ import {
|
|
|
8
8
|
resolveMeetingScheduleTypeIds,
|
|
9
9
|
resolveMemberIdsByName,
|
|
10
10
|
runScheduleConflictFlow
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-L4N7B7ZD.js";
|
|
12
|
+
import "./chunk-P2DAISYW.js";
|
|
13
|
+
import "./chunk-YS5DPN4T.js";
|
|
14
|
+
import "./chunk-CQHGNCK2.js";
|
|
15
15
|
import "./chunk-LUSPKZKY.js";
|
|
16
16
|
import "./chunk-BUSC6UAE.js";
|
|
17
17
|
export {
|
|
@@ -2,7 +2,7 @@ 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-K3RUEEOL.js";
|
|
6
6
|
import {
|
|
7
7
|
USER_INTENT_RULE_FILE,
|
|
8
8
|
aigroupUserDir,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
validateRuleFile,
|
|
18
18
|
workflowOperationDefinitions,
|
|
19
19
|
workflowSuccess
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-F2EQXUEE.js";
|
|
21
21
|
import {
|
|
22
22
|
createWorkflowContinuationSigner
|
|
23
23
|
} from "./chunk-EZALDOQH.js";
|
|
@@ -26,10 +26,10 @@ import {
|
|
|
26
26
|
WorkflowCliError,
|
|
27
27
|
workflowValidationError
|
|
28
28
|
} from "./chunk-FMPJJYYI.js";
|
|
29
|
-
import "./chunk-
|
|
29
|
+
import "./chunk-ZUX3P6BQ.js";
|
|
30
30
|
import "./chunk-AJ62BGAW.js";
|
|
31
|
-
import "./chunk-
|
|
32
|
-
import "./chunk-
|
|
31
|
+
import "./chunk-EZGFHJFW.js";
|
|
32
|
+
import "./chunk-XXJOSZTQ.js";
|
|
33
33
|
import {
|
|
34
34
|
isCliError,
|
|
35
35
|
toErrorEnvelope
|
|
@@ -166,6 +166,7 @@ function namesOf(rule) {
|
|
|
166
166
|
}
|
|
167
167
|
function saveUserIntents(payload, options = {}) {
|
|
168
168
|
const dir = options.dir ?? aigroupUserDir(options.ctx);
|
|
169
|
+
if (!dir) throw workflowValidationError("aigroup_no_skill_context", "\u65E0\u5F53\u524D skill \u4E0A\u4E0B\u6587\uFF08WEAVER_WORK_CLI_SKILL_DIR \u672A\u8BBE\u7F6E\uFF09\uFF1A\u7528\u6237\u610F\u56FE\u4E0D\u53EF\u8BFB\u5199");
|
|
169
170
|
const warnings = [];
|
|
170
171
|
const entries = normalizeIntentPayload(payload);
|
|
171
172
|
if (entries.length === 0) throw workflowValidationError("aigroup_invalid", "\u5165\u53C2\u91CC\u6CA1\u6709\u89C4\u5219\u6761\u76EE");
|
|
@@ -206,6 +207,7 @@ function saveUserIntents(payload, options = {}) {
|
|
|
206
207
|
}
|
|
207
208
|
function readUserIntents(options = {}) {
|
|
208
209
|
const dir = options.dir ?? aigroupUserDir(options.ctx);
|
|
210
|
+
if (!dir) return { dir: null, file: "", exists: false, error: "\u65E0\u5F53\u524D skill \u4E0A\u4E0B\u6587\uFF08WEAVER_WORK_CLI_SKILL_DIR \u672A\u8BBE\u7F6E\uFF09", rules: [] };
|
|
209
211
|
const file = join(dir, USER_INTENT_RULE_FILE);
|
|
210
212
|
if (!existsSync(file)) return { dir, file, exists: false, error: null, rules: [] };
|
|
211
213
|
const loaded = loadRuleFile(file);
|
|
@@ -213,6 +215,7 @@ function readUserIntents(options = {}) {
|
|
|
213
215
|
}
|
|
214
216
|
function clearUserIntents(options = {}) {
|
|
215
217
|
const dir = options.dir ?? aigroupUserDir(options.ctx);
|
|
218
|
+
if (!dir) throw workflowValidationError("aigroup_no_skill_context", "\u65E0\u5F53\u524D skill \u4E0A\u4E0B\u6587\uFF08WEAVER_WORK_CLI_SKILL_DIR \u672A\u8BBE\u7F6E\uFF09\uFF1A\u7528\u6237\u610F\u56FE\u4E0D\u53EF\u8BFB\u5199");
|
|
216
219
|
const file = join(dir, USER_INTENT_RULE_FILE);
|
|
217
220
|
mkdirSync(dir, { recursive: true, mode: 448 });
|
|
218
221
|
writeFileSync(file, `${JSON.stringify({ schemaVersion: 2, rules: [] }, null, 2)}
|
|
@@ -382,7 +385,7 @@ var workflowShortcut = {
|
|
|
382
385
|
const user = readUserIntents({ ctx });
|
|
383
386
|
ctx.output.write({
|
|
384
387
|
dir: loaded.dir,
|
|
385
|
-
defaultFile: join2(loaded.dir, "default.json"),
|
|
388
|
+
defaultFile: loaded.dir ? join2(loaded.dir, "default.json") : null,
|
|
386
389
|
userIntentFile: user.file,
|
|
387
390
|
userIntentExists: user.exists,
|
|
388
391
|
userIntentError: user.error,
|
package/dist/core/output.js
CHANGED
|
@@ -63,21 +63,31 @@ export function refMaxBytes(ctx) {
|
|
|
63
63
|
export function bytesOf(value) {
|
|
64
64
|
return Buffer.byteLength(JSON.stringify(value ?? null, null, 2), 'utf8');
|
|
65
65
|
}
|
|
66
|
-
|
|
66
|
+
/** 链接类字段不参与截断:被截断的 URL 无法点击或调用。 */
|
|
67
|
+
function isLinkField(key) {
|
|
68
|
+
if (!key)
|
|
69
|
+
return false;
|
|
70
|
+
return /(?:^|[a-z0-9])(?:url|urls|uri|href|link|links)$/i.test(key);
|
|
71
|
+
}
|
|
72
|
+
function compactValue(value, arrayLimit, stringLimit, depth = 0, key) {
|
|
67
73
|
if (depth > 6)
|
|
68
74
|
return '<omitted: too deep>';
|
|
75
|
+
// 链接字段整体豁免;数组元素继承父字段名,因此 openUrls / links 里的每条 URL 也完整保留
|
|
76
|
+
const limit = isLinkField(key) ? Number.MAX_SAFE_INTEGER : stringLimit;
|
|
69
77
|
if (typeof value === 'string') {
|
|
70
|
-
return value.length >
|
|
71
|
-
? `${value.slice(0,
|
|
78
|
+
return value.length > limit
|
|
79
|
+
? `${value.slice(0, limit)}…(truncated ${value.length - limit} chars)`
|
|
72
80
|
: value;
|
|
73
81
|
}
|
|
74
82
|
if (Array.isArray(value)) {
|
|
75
|
-
return value
|
|
83
|
+
return value
|
|
84
|
+
.slice(0, arrayLimit)
|
|
85
|
+
.map((item) => compactValue(item, arrayLimit, limit, depth + 1, key));
|
|
76
86
|
}
|
|
77
87
|
if (value && typeof value === 'object') {
|
|
78
88
|
const out = {};
|
|
79
|
-
for (const [
|
|
80
|
-
out[
|
|
89
|
+
for (const [name, inner] of Object.entries(value)) {
|
|
90
|
+
out[name] = compactValue(inner, arrayLimit, stringLimit, depth + 1, name);
|
|
81
91
|
}
|
|
82
92
|
return out;
|
|
83
93
|
}
|
package/dist/index.js
CHANGED
|
@@ -7,12 +7,12 @@ import {
|
|
|
7
7
|
firstPositionalToken,
|
|
8
8
|
registerCommands,
|
|
9
9
|
toCommandMetadata
|
|
10
|
-
} from "./chunks/chunk-
|
|
11
|
-
import "./chunks/chunk-
|
|
10
|
+
} from "./chunks/chunk-GVPJZXJ2.js";
|
|
11
|
+
import "./chunks/chunk-ZUX3P6BQ.js";
|
|
12
12
|
import "./chunks/chunk-AJ62BGAW.js";
|
|
13
|
-
import "./chunks/chunk-
|
|
14
|
-
import "./chunks/chunk-
|
|
15
|
-
import "./chunks/chunk-
|
|
13
|
+
import "./chunks/chunk-ZXRNHZTE.js";
|
|
14
|
+
import "./chunks/chunk-EZGFHJFW.js";
|
|
15
|
+
import "./chunks/chunk-XXJOSZTQ.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-NLZ5UQQI.js");
|
|
33
33
|
await dispatchLazyShortcut(definition, shortcutMetadata());
|
|
34
34
|
});
|
|
35
35
|
}
|
|
@@ -39,112 +39,117 @@ 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-WNBS2B4C.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-RAQNEQO7.js")).ehrShortcut
|
|
48
48
|
}),
|
|
49
49
|
lazyShortcut({
|
|
50
50
|
name: "cowork",
|
|
51
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-
|
|
52
|
+
load: async () => (await import("./chunks/cowork-HNGBPD7A.js")).coworkShortcut
|
|
53
53
|
}),
|
|
54
54
|
lazyShortcut({
|
|
55
55
|
name: "archive",
|
|
56
56
|
description: "E10 \u6587\u4E66\u5B9A\u6863\u6848\u7BA1\u7406 CLI",
|
|
57
|
-
load: async () => (await import("./chunks/archive-
|
|
57
|
+
load: async () => (await import("./chunks/archive-ENZYBBME.js")).archiveShortcut
|
|
58
58
|
}),
|
|
59
59
|
lazyShortcut({
|
|
60
60
|
name: "archive-oa",
|
|
61
61
|
description: "E10 \u6863\u6848\u5B9A\u4F4D\u4E0E OA \u5546\u52A1\u5408\u540C\u501F\u9605 CLI",
|
|
62
|
-
load: async () => (await import("./chunks/archive-oa-
|
|
62
|
+
load: async () => (await import("./chunks/archive-oa-YWLEC5V4.js")).archiveOaShortcut
|
|
63
63
|
}),
|
|
64
64
|
lazyShortcut({
|
|
65
65
|
name: "calendar",
|
|
66
66
|
description: "\u6CDB\u5FAEE10\u65E5\u7A0B\u7BA1\u7406 CLI\uFF08\u521B\u5EFA/\u67E5\u8BE2/\u66F4\u65B0/\u5220\u9664/\u5B57\u5178\uFF09",
|
|
67
|
-
load: async () => (await import("./chunks/calendar-
|
|
67
|
+
load: async () => (await import("./chunks/calendar-CIARBAOX.js")).calendarShortcut
|
|
68
68
|
}),
|
|
69
69
|
lazyShortcut({
|
|
70
70
|
name: "fna",
|
|
71
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",
|
|
72
|
-
load: async () => (await import("./chunks/fna-
|
|
72
|
+
load: async () => (await import("./chunks/fna-XTSRB7G7.js")).fnaShortcut
|
|
73
73
|
}),
|
|
74
74
|
lazyShortcut({
|
|
75
75
|
name: "hrm",
|
|
76
76
|
description: "\u6CDB\u5FAEE10\u7EC4\u7EC7\u7BA1\u7406\uFF08\u5458\u5DE5/\u7EC4\u7EC7/\u5C97\u4F4D\u67E5\u8BE2\uFF09CLI",
|
|
77
|
-
load: async () => (await import("./chunks/hrm-
|
|
77
|
+
load: async () => (await import("./chunks/hrm-TLHKC545.js")).hrmShortcut
|
|
78
78
|
}),
|
|
79
79
|
lazyShortcut({
|
|
80
80
|
name: "mail",
|
|
81
81
|
description: "\u6CDB\u5FAEE10\u90AE\u4EF6\u7BA1\u7406 CLI",
|
|
82
|
-
load: async () => (await import("./chunks/mail-
|
|
82
|
+
load: async () => (await import("./chunks/mail-LRYMBFNL.js")).mailShortcut
|
|
83
83
|
}),
|
|
84
84
|
lazyShortcut({
|
|
85
85
|
name: "meeting",
|
|
86
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",
|
|
87
|
-
load: async () => (await import("./chunks/meeting-
|
|
87
|
+
load: async () => (await import("./chunks/meeting-ESXL6MFI.js")).meetingShortcut
|
|
88
88
|
}),
|
|
89
89
|
lazyShortcut({
|
|
90
90
|
name: "okr",
|
|
91
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",
|
|
92
|
-
load: async () => (await import("./chunks/okr-
|
|
92
|
+
load: async () => (await import("./chunks/okr-EOV65SSF.js")).okrShortcut
|
|
93
93
|
}),
|
|
94
94
|
lazyShortcut({
|
|
95
95
|
name: "plan",
|
|
96
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",
|
|
97
|
-
load: async () => (await import("./chunks/plan-
|
|
97
|
+
load: async () => (await import("./chunks/plan-YFPVKW6Y.js")).planShortcut
|
|
98
98
|
}),
|
|
99
99
|
lazyShortcut({
|
|
100
100
|
name: "esb",
|
|
101
101
|
description: "\u6CDB\u5FAEE10 ESB \u4E2D\u5FC3\u81EA\u5B9A\u4E49\u89E6\u53D1\u52A8\u4F5C\u6D41 CLI",
|
|
102
|
-
load: async () => (await import("./chunks/esb-
|
|
102
|
+
load: async () => (await import("./chunks/esb-6XV7C7YV.js")).esbShortcut
|
|
103
103
|
}),
|
|
104
104
|
lazyShortcut({
|
|
105
105
|
name: "ebuilder-form",
|
|
106
106
|
description: "\u6CDB\u5FAEE10 eBuilder \u8868\u5355\u83DC\u5355\u3001\u5217\u8868\u548C\u8868\u5355\u6570\u636E CLI",
|
|
107
|
-
load: async () => (await import("./chunks/ebuilder-form-
|
|
107
|
+
load: async () => (await import("./chunks/ebuilder-form-OY6DVNRK.js")).ebuilderFormShortcut
|
|
108
108
|
}),
|
|
109
109
|
lazyShortcut({
|
|
110
110
|
name: "jiuchuanhui",
|
|
111
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",
|
|
112
|
-
load: async () => (await import("./chunks/jiuchuanhui-
|
|
112
|
+
load: async () => (await import("./chunks/jiuchuanhui-XABWS5RN.js")).jiuchuanhuiShortcut
|
|
113
113
|
}),
|
|
114
114
|
lazyShortcut({
|
|
115
115
|
name: "asset",
|
|
116
116
|
description: "E10 \u8D44\u4EA7\u7BA1\u7406\uFF08\u8D44\u7BA1\u5BB6\uFF09CLI",
|
|
117
|
-
load: async () => (await import("./chunks/asset-
|
|
117
|
+
load: async () => (await import("./chunks/asset-OOV6DWPA.js")).assetShortcut
|
|
118
|
+
}),
|
|
119
|
+
lazyShortcut({
|
|
120
|
+
name: "asset-idle",
|
|
121
|
+
description: "E10 \u95F2\u7F6E\u8D44\u4EA7\u5224\u5B9A\u7ED3\u679C\u67E5\u8BE2 CLI\uFF08\u5206\u9875\u83B7\u53D6/\u805A\u5408\u7EDF\u8BA1\uFF09",
|
|
122
|
+
load: async () => (await import("./chunks/asset-idle-RE632MY5.js")).assetIdleShortcut
|
|
118
123
|
}),
|
|
119
124
|
lazyShortcut({
|
|
120
125
|
name: "im",
|
|
121
126
|
description: "\u6CDB\u5FAEE10\u6613\u79D2\u529E\uFF08\u5373\u65F6\u901A\u8BAF\uFF09CLI",
|
|
122
|
-
load: async () => (await import("./chunks/im-
|
|
127
|
+
load: async () => (await import("./chunks/im-YOUCFMUK.js")).imShortcut
|
|
123
128
|
}),
|
|
124
129
|
lazyShortcut({
|
|
125
130
|
name: "project",
|
|
126
131
|
description: "\u6CDB\u5FAEE10\u4E8B\u4E95\u7136\u9879\u76EE\u7BA1\u7406 CLI\uFF08\u9879\u76EE/\u4EFB\u52A1\u67E5\u8BE2\u4E0E\u786E\u8BA4\u5199\u5165\uFF09",
|
|
127
|
-
load: async () => (await import("./chunks/project-
|
|
132
|
+
load: async () => (await import("./chunks/project-MDVZUYQW.js")).projectShortcut
|
|
128
133
|
}),
|
|
129
134
|
lazyShortcut({
|
|
130
135
|
name: "workflow",
|
|
131
136
|
description: "\u6CDB\u5FAEE10\u6D41\u7A0B\u667A\u80FD\u52A9\u624B CLI\uFF08\u67E5\u8BE2/\u67E5\u770B/\u64CD\u4F5C/\u6279\u91CF/\u53D1\u8D77/\u4FEE\u6539\uFF09",
|
|
132
|
-
load: async () => (await import("./chunks/workflow-
|
|
137
|
+
load: async () => (await import("./chunks/workflow-KDGIUCNW.js")).workflowShortcut
|
|
133
138
|
}),
|
|
134
139
|
lazyShortcut({
|
|
135
140
|
name: "blog",
|
|
136
141
|
description: "\u6CDB\u5FAEE10\u5DE5\u4F5C\u65E5\u62A5 CLI\uFF08\u67E5\u8BE2/\u53D1\u5E03/\u7F16\u8F91/\u8BC4\u8BBA/\u70B9\u8D5E/\u63D0\u9192/\u5BFC\u51FA\uFF09",
|
|
137
|
-
load: async () => (await import("./chunks/blog-
|
|
142
|
+
load: async () => (await import("./chunks/blog-PEPOJAL7.js")).blogShortcut
|
|
138
143
|
}),
|
|
139
144
|
lazyShortcut({
|
|
140
145
|
name: "caizhilian",
|
|
141
146
|
description: "\u6CDB\u5FAEE10\u91C7\u77E5\u8FDE\uFF08\u6587\u6863\u4E2D\u5FC3\uFF09CLI",
|
|
142
|
-
load: async () => (await import("./chunks/caizhilian-
|
|
147
|
+
load: async () => (await import("./chunks/caizhilian-WYIQDVPJ.js")).caizhilianShortcut
|
|
143
148
|
}),
|
|
144
149
|
lazyShortcut({
|
|
145
150
|
name: "contract",
|
|
146
151
|
description: "\u6CDB\u5FAEE10\u4ECA\u627F\u8FBE\u5408\u540C\u7BA1\u7406 CLI",
|
|
147
|
-
load: async () => (await import("./chunks/contract-
|
|
152
|
+
load: async () => (await import("./chunks/contract-73MERZWN.js")).contractShortcut
|
|
148
153
|
})
|
|
149
154
|
];
|
|
150
155
|
function shortcutMetadata() {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export const E10_REAUTH_GUIDANCE = '请结合当前宿主环境选择合适的登录方式,恢复登录后重试原请求。';
|
|
2
2
|
export const E10_AUTH_REQUIRED_MESSAGE = `E10 登录态不可用。${E10_REAUTH_GUIDANCE}`;
|
|
3
|
+
export const E10_XIAOE_RECOVERY_FAILED_MESSAGE = 'E10 登录态不可用。已尝试小 e 自动重新获取登录信息,但未取得可用登录态。请在小 e 中恢复登录后重试。';
|
|
3
4
|
export const E10_SESSION_EXPIRED_MESSAGE = `E10 登录态已失效,本次操作已停止。${E10_REAUTH_GUIDANCE}`;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isXiaoERuntimeAgent } from '../../core/runtime-agent.js';
|
|
2
|
-
import { getActiveProfile } from './auth/session.js';
|
|
3
|
-
import { hasXiaoEEnv, tryXiaoEUnifiedLogin } from './auth/xiaoe.js';
|
|
2
|
+
import { getActiveProfile, readProfileConfig } from './auth/session.js';
|
|
3
|
+
import { hasXiaoEEnv, resolveXiaoEPreferredBaseUrl, tryXiaoEUnifiedLogin } from './auth/xiaoe.js';
|
|
4
4
|
const AUTH_REQUIRED_CODES = new Set(['-2', '401']);
|
|
5
5
|
const AUTH_REQUIRED_MARKERS = [
|
|
6
6
|
'未登录',
|
|
@@ -23,6 +23,116 @@ const AUTH_REQUIRED_MARKERS = [
|
|
|
23
23
|
'not logged in',
|
|
24
24
|
'not login',
|
|
25
25
|
];
|
|
26
|
+
const REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]);
|
|
27
|
+
/** Location 命中这些特征即为登录类跳转。 */
|
|
28
|
+
const LOGIN_REDIRECT_MARKERS = [
|
|
29
|
+
'login',
|
|
30
|
+
'passport',
|
|
31
|
+
'sso',
|
|
32
|
+
'oauth',
|
|
33
|
+
'signin',
|
|
34
|
+
'sign-in',
|
|
35
|
+
'authorize',
|
|
36
|
+
'authn',
|
|
37
|
+
'atrust',
|
|
38
|
+
'checkticket',
|
|
39
|
+
];
|
|
40
|
+
/** Location 命中这些特征即为文件服务/对象存储交接。 */
|
|
41
|
+
const FILE_REDIRECT_MARKERS = [
|
|
42
|
+
'fileservice',
|
|
43
|
+
'/file/download',
|
|
44
|
+
'/file/remotedownload',
|
|
45
|
+
'/remotedownload/',
|
|
46
|
+
'/api/file/',
|
|
47
|
+
'/download/',
|
|
48
|
+
'aliyuncs.com',
|
|
49
|
+
'myqcloud.com',
|
|
50
|
+
'qiniucdn.com',
|
|
51
|
+
'qbox.me',
|
|
52
|
+
'jdcloud.com',
|
|
53
|
+
'amazonaws.com',
|
|
54
|
+
'blob.core.windows.net',
|
|
55
|
+
'ctyunapi.cn',
|
|
56
|
+
'hiclouds.com',
|
|
57
|
+
'minio',
|
|
58
|
+
's3.',
|
|
59
|
+
'obs.',
|
|
60
|
+
'ks3',
|
|
61
|
+
];
|
|
62
|
+
/** 这些请求路径本身就是取文件:其 3xx 只要不是登录页,就是文件服务交接。 */
|
|
63
|
+
const FILE_REQUEST_PATH_MARKERS = [
|
|
64
|
+
'/api/file/',
|
|
65
|
+
'/file/download',
|
|
66
|
+
'/remotedownload/',
|
|
67
|
+
'/fileservice',
|
|
68
|
+
'/download',
|
|
69
|
+
];
|
|
70
|
+
/** 跳转目标是前端页面骨架(如 wui/index.html#/main),不是文件直链。 */
|
|
71
|
+
const APP_SHELL_REDIRECT = /(?:\.html?(?:[?#]|$)|#\/|wui\/)/u;
|
|
72
|
+
export function isE10RedirectStatus(status) {
|
|
73
|
+
return REDIRECT_STATUSES.has(status);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* 取跳转目标里「有语义」的部分:主机名 + 路径 + hash,**丢掉 query**。
|
|
77
|
+
* 对象存储的签名 query 是长随机串,拿去匹配关键词容易误伤(例如签名里恰好
|
|
78
|
+
* 出现 `sso`),所以只在主机与路径上判定。
|
|
79
|
+
*/
|
|
80
|
+
function redirectTarget(location) {
|
|
81
|
+
const raw = location.trim().toLowerCase();
|
|
82
|
+
if (!raw)
|
|
83
|
+
return '';
|
|
84
|
+
try {
|
|
85
|
+
const url = new URL(raw, 'https://e10.invalid');
|
|
86
|
+
return `${url.hostname}${url.pathname}${url.hash}`.toLowerCase();
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return raw.split('?')[0];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* 识别 3xx 的真实语义。登录跳转优先判定,避免对象存储地址里的参数误伤;
|
|
94
|
+
* 若是下载类请求且目标不像登录页,则认为是文件服务交接(对象存储的签名地址
|
|
95
|
+
* 不一定带 `fileservice` 之类的特征,只能靠请求路径反推)。
|
|
96
|
+
*/
|
|
97
|
+
export function classifyE10Redirect(response) {
|
|
98
|
+
if (!isE10RedirectStatus(response.status))
|
|
99
|
+
return 'other';
|
|
100
|
+
const target = redirectTarget(response.headers?.get('location') || '');
|
|
101
|
+
if (!target)
|
|
102
|
+
return 'other';
|
|
103
|
+
if (LOGIN_REDIRECT_MARKERS.some((marker) => target.includes(marker)))
|
|
104
|
+
return 'login';
|
|
105
|
+
if (FILE_REDIRECT_MARKERS.some((marker) => target.includes(marker)))
|
|
106
|
+
return 'file';
|
|
107
|
+
const requestPath = (response.requestPath || '').toLowerCase();
|
|
108
|
+
if (requestPath
|
|
109
|
+
&& FILE_REQUEST_PATH_MARKERS.some((marker) => requestPath.includes(marker))
|
|
110
|
+
// 跳到前端页面骨架说明不是文件直链,继续按「无法判定」保守处理。
|
|
111
|
+
&& !APP_SHELL_REDIRECT.test(target)) {
|
|
112
|
+
return 'file';
|
|
113
|
+
}
|
|
114
|
+
return 'other';
|
|
115
|
+
}
|
|
116
|
+
/** 3xx 指向文件服务:属于下载直传,登录态有效,不得触发重新登录。 */
|
|
117
|
+
export function isE10FileRedirect(response) {
|
|
118
|
+
return classifyE10Redirect(response) === 'file';
|
|
119
|
+
}
|
|
120
|
+
/** 3xx 指向登录页:登录态确实失效。 */
|
|
121
|
+
export function isE10LoginRedirect(response) {
|
|
122
|
+
return classifyE10Redirect(response) === 'login';
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* 业务层统一的「HTTP 层登录态失效」判定:401,或 3xx 且不是文件服务交接。
|
|
126
|
+
* 各 shortcut 用它替代原来的 `status === 401 || status === 302`,避免把下载
|
|
127
|
+
* 直传的 302 误报成登录失效。
|
|
128
|
+
*/
|
|
129
|
+
export function isE10SessionExpiredResponse(response) {
|
|
130
|
+
if (response.status === 401)
|
|
131
|
+
return true;
|
|
132
|
+
if (isE10RedirectStatus(response.status))
|
|
133
|
+
return !isE10FileRedirect(response);
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
26
136
|
const recoveryInFlight = new Map();
|
|
27
137
|
function asRecord(value) {
|
|
28
138
|
return value && typeof value === 'object' && !Array.isArray(value)
|
|
@@ -77,9 +187,12 @@ function responseText(response) {
|
|
|
77
187
|
* Detect only explicit authentication rejection signals. A bare HTTP 403 is
|
|
78
188
|
* deliberately excluded because E10 also uses it for ordinary permission
|
|
79
189
|
* denials, which must never trigger a credential refresh.
|
|
190
|
+
*
|
|
191
|
+
* 3xx 只在「跳到登录页」或「无法判定」时才算认证失败:下载接口把文件交接给
|
|
192
|
+
* 文件服务时同样返回 302,那不是登录失效,重新登录既无用也会白白换一次票据。
|
|
80
193
|
*/
|
|
81
194
|
export function isE10AuthenticationRequired(response) {
|
|
82
|
-
if (response
|
|
195
|
+
if (isE10SessionExpiredResponse(response))
|
|
83
196
|
return true;
|
|
84
197
|
if (responseCodes(response.value).some((code) => AUTH_REQUIRED_CODES.has(code)))
|
|
85
198
|
return true;
|
|
@@ -112,8 +225,10 @@ export function canAutomaticallyRecoverXiaoE(ctx, currentSession) {
|
|
|
112
225
|
|| isXiaoERuntimeAgent(currentSession?.agentType);
|
|
113
226
|
}
|
|
114
227
|
/**
|
|
115
|
-
* Silently
|
|
116
|
-
*
|
|
228
|
+
* Silently recover a stale or missing XiaoE session. Without a local session,
|
|
229
|
+
* current runtime evidence is required before obtaining credentials.
|
|
230
|
+
* Concurrent requests for the same profile/base URL share one credential
|
|
231
|
+
* exchange, so a burst of 401 responses
|
|
117
232
|
* does not start a burst of login attempts.
|
|
118
233
|
*/
|
|
119
234
|
export async function recoverXiaoEAuthSession(ctx, currentSession) {
|
|
@@ -121,7 +236,12 @@ export async function recoverXiaoEAuthSession(ctx, currentSession) {
|
|
|
121
236
|
return null;
|
|
122
237
|
const options = globalOptions(ctx);
|
|
123
238
|
const profile = options.profile || getActiveProfile();
|
|
124
|
-
const
|
|
239
|
+
const config = readProfileConfig(profile);
|
|
240
|
+
const baseUrl = resolveXiaoEPreferredBaseUrl({
|
|
241
|
+
explicitBaseUrl: currentSession?.getBaseUrl() || options.baseUrl,
|
|
242
|
+
profileBaseUrl: config.baseUrl,
|
|
243
|
+
env: ctx.env,
|
|
244
|
+
});
|
|
125
245
|
const key = `${profile}\n${baseUrl}`;
|
|
126
246
|
const existing = recoveryInFlight.get(key);
|
|
127
247
|
if (existing)
|
|
@@ -133,7 +253,7 @@ export async function recoverXiaoEAuthSession(ctx, currentSession) {
|
|
|
133
253
|
profileBaseUrl: baseUrl,
|
|
134
254
|
allowBundledEnvScript: true,
|
|
135
255
|
allowTokenScript: true,
|
|
136
|
-
tenantKeyFallback: currentSession.tenantKey,
|
|
256
|
+
tenantKeyFallback: currentSession?.tenantKey || config.tenantKey,
|
|
137
257
|
profileHint: profile,
|
|
138
258
|
// Intentionally no logger: transparent recovery must not leak an
|
|
139
259
|
// intermediate "login" step into agent stdout/stderr or JSON output.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isE10AuthenticationRequired, sameE10SessionIdentity, } from './auth-recovery.js';
|
|
1
|
+
import { isE10AuthenticationRequired, isE10LoginRedirect, isE10RedirectStatus, sameE10SessionIdentity, } from './auth-recovery.js';
|
|
2
2
|
class E10AuthenticationContextChangedError extends Error {
|
|
3
3
|
}
|
|
4
4
|
export class E10ApiClient {
|
|
@@ -78,6 +78,7 @@ export class E10ApiClient {
|
|
|
78
78
|
if (!authenticationRecoveryAttempted && isE10AuthenticationRequired({
|
|
79
79
|
status: resp.status,
|
|
80
80
|
headers: resp.headers,
|
|
81
|
+
requestPath: safePathname(url),
|
|
81
82
|
text,
|
|
82
83
|
value,
|
|
83
84
|
})) {
|
|
@@ -94,7 +95,12 @@ export class E10ApiClient {
|
|
|
94
95
|
}
|
|
95
96
|
}
|
|
96
97
|
// Preserve the legacy password-based refresh for non-XiaoE callers.
|
|
97
|
-
|
|
98
|
+
// 只有真的跳到登录页才刷新;3xx 交给文件服务(下载直传)时登录态仍有效。
|
|
99
|
+
if (isE10LoginRedirect({
|
|
100
|
+
status: resp.status,
|
|
101
|
+
headers: resp.headers,
|
|
102
|
+
requestPath: safePathname(url),
|
|
103
|
+
}) || (isE10RedirectStatus(resp.status) && !resp.headers.get('location'))) {
|
|
98
104
|
const ok = await this.auth.ensureValid();
|
|
99
105
|
if (!ok)
|
|
100
106
|
throw new Error('E10 session expired; please login again');
|
|
@@ -134,3 +140,11 @@ function refreshAuthenticationHeaders(init, session) {
|
|
|
134
140
|
headers['user-agent'] = session.uaHeader();
|
|
135
141
|
init.headers = headers;
|
|
136
142
|
}
|
|
143
|
+
function safePathname(rawUrl) {
|
|
144
|
+
try {
|
|
145
|
+
return new URL(rawUrl).pathname;
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return rawUrl.startsWith('/') ? rawUrl.split('?')[0] : '';
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -1,14 +1,27 @@
|
|
|
1
1
|
import { CliError, ExitCode } from '../../core/errors.js';
|
|
2
|
-
import { E10_AUTH_REQUIRED_MESSAGE } from './auth/messages.js';
|
|
2
|
+
import { E10_AUTH_REQUIRED_MESSAGE, E10_XIAOE_RECOVERY_FAILED_MESSAGE } from './auth/messages.js';
|
|
3
3
|
import { E10AuthSession } from './auth/session.js';
|
|
4
4
|
import { E10ApiClient } from './client.js';
|
|
5
|
-
import { recoverXiaoEAuthSession } from './auth-recovery.js';
|
|
5
|
+
import { canAutomaticallyRecoverXiaoE, recoverXiaoEAuthSession } from './auth-recovery.js';
|
|
6
6
|
export async function getE10Session(ctx, load = {}) {
|
|
7
7
|
const options = ctx.getGlobalOptions();
|
|
8
8
|
return E10AuthSession.fromOptions(options, ctx.cwd, load);
|
|
9
9
|
}
|
|
10
10
|
export async function requireE10Session(ctx, load = {}) {
|
|
11
|
-
|
|
11
|
+
let session = await getE10Session(ctx, load);
|
|
12
|
+
if (!session && canAutomaticallyRecoverXiaoE(ctx)) {
|
|
13
|
+
// Read-only probes use getE10Session; only a command requiring a session
|
|
14
|
+
// may establish one from the current XiaoE host's credentials.
|
|
15
|
+
session = await recoverXiaoEAuthSession(ctx).catch(() => null);
|
|
16
|
+
if (!session) {
|
|
17
|
+
throw Object.assign(new CliError(E10_XIAOE_RECOVERY_FAILED_MESSAGE, ExitCode.AuthError), {
|
|
18
|
+
type: 'authentication',
|
|
19
|
+
subtype: 'xiaoe_credential_unavailable',
|
|
20
|
+
retryable: false,
|
|
21
|
+
stage: 'xiaoe_unified_login',
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
12
25
|
if (!session) {
|
|
13
26
|
throw new CliError(E10_AUTH_REQUIRED_MESSAGE, ExitCode.AuthError);
|
|
14
27
|
}
|