weaver-work-cli 0.1.39 → 0.1.42
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-ENZYBBME.js → archive-J4I6MCKF.js} +2 -2
- package/dist/chunks/{archive-oa-YWLEC5V4.js → archive-oa-BRZKKTO4.js} +2 -2
- package/dist/chunks/{asset-OOV6DWPA.js → asset-L7D4FAOZ.js} +2 -2
- package/dist/chunks/{asset-idle-RE632MY5.js → asset-idle-DADLLV75.js} +2 -2
- package/dist/chunks/{attachment-content-RWN2FCLL.js → attachment-content-K4C7VLWQ.js} +3 -3
- package/dist/chunks/{blog-PEPOJAL7.js → blog-BVGQ7NZL.js} +2 -2
- package/dist/chunks/{caizhilian-WYIQDVPJ.js → caizhilian-SAADNFD6.js} +2 -2
- package/dist/chunks/{calendar-CIARBAOX.js → calendar-Q7NQY5Z2.js} +61 -23
- package/dist/chunks/{chunk-F2EQXUEE.js → chunk-3KTFS4IA.js} +397 -159
- package/dist/chunks/{chunk-G2JSIUWF.js → chunk-4PD5NWAX.js} +89 -0
- package/dist/chunks/{chunk-HJYVHXUQ.js → chunk-4RAE6JXP.js} +1 -1
- package/dist/chunks/{chunk-CQHGNCK2.js → chunk-72CKAUAG.js} +41 -8
- package/dist/chunks/{chunk-K3RUEEOL.js → chunk-APVFJUQH.js} +2 -2
- package/dist/chunks/{chunk-BJGXMFGD.js → chunk-BBKDXQEC.js} +2 -2
- package/dist/chunks/chunk-BIPYLLVS.js +501 -0
- package/dist/chunks/{chunk-GVPJZXJ2.js → chunk-EKWAQSLU.js} +92 -50
- package/dist/chunks/{chunk-XXJOSZTQ.js → chunk-FOAA27U5.js} +381 -57
- package/dist/chunks/{chunk-I2HB737U.js → chunk-G4UR6NXN.js} +2 -2
- package/dist/chunks/{chunk-YS5DPN4T.js → chunk-GEWYMQME.js} +1 -1
- package/dist/chunks/{chunk-P2DAISYW.js → chunk-GHXCDPTM.js} +1 -1
- package/dist/chunks/{chunk-L4N7B7ZD.js → chunk-IZ7S7QUS.js} +4 -4
- package/dist/chunks/{chunk-NLK2RZKG.js → chunk-JPRO6ER2.js} +122 -2214
- package/dist/chunks/{chunk-36DIFZAH.js → chunk-LADPYOWC.js} +2 -2
- package/dist/chunks/chunk-LDZQPUIA.js +1238 -0
- package/dist/chunks/chunk-NKZRQXST.js +2546 -0
- package/dist/chunks/{chunk-EINRJHQ3.js → chunk-QKNKR4RH.js} +3 -3
- package/dist/chunks/{chunk-T7JDJJ7H.js → chunk-R4CHUSKC.js} +126 -19
- package/dist/chunks/{chunk-EZGFHJFW.js → chunk-SA6VBIHY.js} +88 -15
- package/dist/chunks/{chunk-ZXRNHZTE.js → chunk-TTPJJJC4.js} +2 -2
- package/dist/chunks/{chunk-KTCB5R5H.js → chunk-W7BEHOSR.js} +2 -2
- package/dist/chunks/{chunk-MUQUHKPG.js → chunk-YRSZQUD2.js} +2 -2
- package/dist/chunks/{conflict-DRMDOL56.js → conflict-F2OMZRTO.js} +2 -2
- package/dist/chunks/{contract-73MERZWN.js → contract-5BETHRSG.js} +2 -2
- package/dist/chunks/{cowork-HNGBPD7A.js → cowork-3MN6EQQO.js} +27 -10
- package/dist/chunks/create-flow-5FQNNMVO.js +55 -0
- package/dist/chunks/{ebuilder-form-OY6DVNRK.js → ebuilder-form-SBHOYBUD.js} +3 -3
- package/dist/chunks/{ehr-RAQNEQO7.js → ehr-KMOJULKG.js} +432 -1234
- package/dist/chunks/env-LB7NBL2O.js +19 -0
- package/dist/chunks/{esb-6XV7C7YV.js → esb-W2PJCFCX.js} +4 -4
- package/dist/chunks/factory-6ZFQXQ46.js +30 -0
- package/dist/chunks/{fna-XTSRB7G7.js → fna-ZQPCUV4R.js} +2 -2
- package/dist/chunks/group-chat-2HHAJN46.js +20 -0
- package/dist/chunks/{host-YMBXWFWX.js → host-4CBHGOHT.js} +3 -3
- package/dist/chunks/{host-A7J6GDUP.js → host-ATKVNZAT.js} +3 -3
- package/dist/chunks/{host-3F5UM5GN.js → host-BQH22NTQ.js} +3 -3
- package/dist/chunks/{host-YAQAPYNP.js → host-X2CSLFM6.js} +3 -3
- package/dist/chunks/{host-VGPVP7YF.js → host-YTODKMSL.js} +3 -3
- package/dist/chunks/{hrm-TLHKC545.js → hrm-FFM4UJFS.js} +4 -4
- package/dist/chunks/{im-YOUCFMUK.js → im-VEHKDQPB.js} +8 -8
- package/dist/chunks/{invoice-WNBS2B4C.js → invoice-LVIKSIIF.js} +3 -3
- package/dist/chunks/{jiuchuanhui-XABWS5RN.js → jiuchuanhui-X6DINO5P.js} +2 -2
- package/dist/chunks/{lazy-dispatch-NLZ5UQQI.js → lazy-dispatch-KSWTN5L6.js} +4 -4
- package/dist/chunks/{mail-LRYMBFNL.js → mail-VDKRGUD3.js} +9 -4
- package/dist/chunks/{meeting-ESXL6MFI.js → meeting-CLC6HP3Z.js} +12 -10
- package/dist/chunks/{okr-EOV65SSF.js → okr-CHG4OO3U.js} +2 -2
- package/dist/chunks/{plan-YFPVKW6Y.js → plan-XWR75667.js} +2 -2
- package/dist/chunks/{project-MDVZUYQW.js → project-5BXOOKMG.js} +40 -23
- package/dist/chunks/recruit-stage-DGMFNNDE.js +4507 -0
- package/dist/chunks/{registry-VT5Y2HLA.js → registry-7FFOXIAW.js} +4 -4
- package/dist/chunks/{registry-QCLZEDAP.js → registry-BKBZPBAJ.js} +10 -8
- package/dist/chunks/{registry-YX4CSEMD.js → registry-RHMW6ANW.js} +2 -2
- package/dist/chunks/{registry-NYPYMZXG.js → registry-Z43434VG.js} +1 -1
- package/dist/chunks/{room-recommend-L3MWH4JW.js → room-recommend-62H7ZQQ6.js} +4 -4
- package/dist/chunks/{schedule-UASAVDVD.js → schedule-FNXKH3DQ.js} +4 -4
- package/dist/chunks/{workflow-KDGIUCNW.js → workflow-ADHKCAJK.js} +4 -4
- package/dist/index.js +33 -28
- package/dist/internal/e10/auth/commands.js +110 -56
- package/dist/internal/e10/auth/messages.js +6 -0
- package/dist/internal/e10/auth/session.js +28 -1
- package/dist/internal/e10/auth/xiaoe.js +315 -48
- package/dist/internal/e10/auth-recovery.js +36 -5
- package/dist/internal/e10/client.js +13 -0
- package/dist/internal/e10/context.js +61 -9
- package/dist/internal/e10/index.js +1 -1
- package/dist/internal/e10/network-error.js +93 -0
- package/dist/internal/e10/request-runtime.js +15 -0
- package/dist/shortcuts/calendar/operations/read.js +31 -22
- package/dist/shortcuts/calendar/operations/write.js +45 -1
- package/dist/shortcuts/cowork/operations/discuss-write.js +5 -1
- package/dist/shortcuts/cowork/operations/item-write.js +5 -3
- package/dist/shortcuts/cowork/operations/member-write.js +3 -1
- package/dist/shortcuts/cowork/operations/permission-write.js +5 -1
- package/dist/shortcuts/cowork/operations/shared.js +7 -0
- package/dist/shortcuts/ehr/operations/attend-write.js +43 -1
- package/dist/shortcuts/ehr/operations/hr-contact.js +7 -4
- package/dist/shortcuts/ehr/operations/hr-report.js +13 -7
- package/dist/shortcuts/ehr/operations/recruit-candidate-import.js +134 -59
- package/dist/shortcuts/ehr/operations/recruit-write.js +262 -17
- package/dist/shortcuts/ehr/operations/recruit.js +10 -4
- package/dist/shortcuts/ehr/operations/shared.js +47 -0
- package/dist/shortcuts/hrm/operations/org.js +118 -0
- package/dist/shortcuts/index.js +5 -0
- package/dist/shortcuts/mail/operations/mail-send.js +8 -2
- package/dist/shortcuts/meeting/operations/eb/catalog.js +9 -2
- package/dist/shortcuts/meeting/operations/eb/create-flow.js +461 -127
- package/dist/shortcuts/meeting/operations/eb/crm-search.js +87 -5
- package/dist/shortcuts/meeting/operations/eb/factory.js +33 -0
- package/dist/shortcuts/meeting/operations/eb/flow-memory.js +49 -0
- package/dist/shortcuts/meeting/operations/eb/group-chat.js +605 -0
- package/dist/shortcuts/meeting/operations/eb/index.js +2 -0
- package/dist/shortcuts/meeting/operations/eb/person-cache.js +96 -0
- package/dist/shortcuts/meeting/operations/eb/room-recommend.js +44 -6
- package/dist/shortcuts/meeting/operations/eb/room-summary.js +2 -0
- package/dist/shortcuts/meeting/operations/eb/usage-cache.js +99 -0
- package/dist/shortcuts/meeting/operations/from-group-chat.js +35 -12
- package/dist/shortcuts/project/operations/read.js +6 -25
- package/dist/shortcuts/project/operations/shared.js +22 -0
- package/dist/shortcuts/project/operations/write.js +28 -2
- package/dist/shortcuts/recruit-stage/context.js +119 -0
- package/dist/shortcuts/recruit-stage/continuation.js +73 -0
- package/dist/shortcuts/recruit-stage/errors.js +65 -0
- package/dist/shortcuts/recruit-stage/host.js +109 -0
- package/dist/shortcuts/recruit-stage/index.js +115 -0
- package/dist/shortcuts/recruit-stage/manifest.js +29 -0
- package/dist/shortcuts/recruit-stage/operations/interview-arrange.js +722 -0
- package/dist/shortcuts/recruit-stage/operations/interview-feedback.js +269 -0
- package/dist/shortcuts/recruit-stage/operations/jd-create.js +630 -0
- package/dist/shortcuts/recruit-stage/operations/list.js +431 -0
- package/dist/shortcuts/recruit-stage/operations/registry.js +38 -0
- package/dist/shortcuts/recruit-stage/operations/resume-import.js +1198 -0
- package/dist/shortcuts/recruit-stage/operations/search.js +158 -0
- package/dist/shortcuts/recruit-stage/operations/types.js +25 -0
- package/dist/shortcuts/recruit-stage/school-tiers.json +318 -0
- package/dist/shortcuts/recruit-stage/shared.js +608 -0
- package/dist/shortcuts/workflow/operations/form.js +21 -2
- package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupRules.js +52 -1
- package/dist/shortcuts/workflow/operations/todoSmartConvert/detailFieldRules.js +4 -2
- package/dist/shortcuts/workflow/operations/todoSmartConvert/summaryCache.js +19 -11
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailCache.js +17 -24
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailFetcher.js +14 -9
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.collect.js +78 -10
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.core.js +3 -1
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.detail.js +17 -11
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.group.js +16 -40
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.groupSummary.js +3 -2
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.js +52 -15
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.pipeline.js +16 -1
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.smartGroup.js +151 -63
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.subGroup.js +56 -0
- package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.summary.js +53 -16
- package/docs/e10-auth.md +22 -1
- package/docs/operation-manual.md +8 -0
- package/package.json +1 -1
- package/scripts/install-skill-to-xiaoe.mjs +105 -0
- package/scripts/mcp-meeting.mjs +234 -0
- package/scripts/package-skill.mjs +4 -2
- package/skill-template/business-info.json +24 -0
- package/skill-template/domains/recruit-stage.md +29 -0
- package/skills/weaver-e10-calendar/SKILL.md +2 -1
- package/skills/weaver-e10-calendar/references/calendar-write.md +54 -0
- package/skills/weaver-e10-cowork/SKILL.md +1 -1
- package/skills/weaver-e10-cowork/references/cowork-write.md +3 -1
- package/skills/weaver-e10-jucailin/SKILL.md +1 -1
- package/skills/weaver-e10-jucailin/references/attend-write.md +8 -0
- package/skills/weaver-e10-jucailin/references/hr-contact.md +8 -0
- package/skills/weaver-e10-jucailin/references/hr-report.md +8 -0
- package/skills/weaver-e10-jucailin/references/recruit-create.md +2 -2
- package/skills/weaver-e10-jucailin/references/recruit-read.md +1 -1
- package/skills/weaver-e10-jucailin/references/recruit-write.md +4 -3
- package/skills/weaver-e10-mail/SKILL.md +1 -1
- package/skills/weaver-e10-mail/references/mail-send.md +2 -0
- package/skills/weaver-e10-meeting/SKILL.md +119 -26
- package/skills/weaver-e10-meeting/references/meeting-minute-file.md +25 -11
- package/skills/weaver-e10-meeting.zip +0 -0
- package/skills/weaver-e10-recruit-stage/SKILL.md +226 -0
- package/skills/weaver-e10-recruit-stage/agents/openai.yaml +119 -0
- package/skills/weaver-e10-recruit-stage/lib/recruit-xiaoe-file.mjs +188 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-arrange-interview.md +322 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-capability-check.md +127 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-check-install.md +65 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-detail-process.md +63 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-edit-interview-feedback.md +142 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-jd-create.md +73 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-jd-template.md +56 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-list-candidate.md +101 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-list-interview.md +148 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-match-candidates.md +77 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-output-links.md +59 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-resolve-creator.md +69 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-resolve-metadata.md +241 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-resume-import.md +438 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-resume-parse.md +128 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-search-candidate.md +146 -0
- package/skills/weaver-e10-recruit-stage/references/recruit-urge-feedback.md +69 -0
- package/skills/weaver-e10-shared/SKILL.md +2 -2
- package/skills/weaver-e10-shared/references/e10-auth-and-session.md +4 -2
- package/skills/weaver-e10-shijingran/SKILL.md +3 -2
- package/skills/weaver-e10-shijingran/references/operations.md +3 -1
- package/skills/weaver-e10-shijingran/references/source-manifest.json +41 -40
- package/skills/weaver-e10-shijingran/references/write-operations.md +2 -0
- package/skills/weaver-e10-workflow/SKILL.md +7 -1
- package/skills/weaver-e10-workflow/aigroup/default.json +23 -9
- package/skills/weaver-e10-workflow/references/todo-smart-convert.md +37 -21
- package/skills/weaver-e10-workflow/tools/todo-summary.cjs +135 -43
- package/skills/weaver-e10-yepiaotong/SKILL.md +9 -10
- package/skills/weaver-e10-yepiaotong/references/invoice-agent-entry.md +6 -3
|
@@ -52,6 +52,75 @@ function writeWithRetry(path, data, options) {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
// src/internal/e10/network-error.ts
|
|
56
|
+
var NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
57
|
+
"ECONNREFUSED",
|
|
58
|
+
"ECONNRESET",
|
|
59
|
+
"ECONNABORTED",
|
|
60
|
+
"EHOSTUNREACH",
|
|
61
|
+
"EHOSTDOWN",
|
|
62
|
+
"ENETUNREACH",
|
|
63
|
+
"ENETDOWN",
|
|
64
|
+
"ENETRESET",
|
|
65
|
+
"ENOTFOUND",
|
|
66
|
+
"EAI_AGAIN",
|
|
67
|
+
"EPIPE",
|
|
68
|
+
"ETIMEDOUT",
|
|
69
|
+
"ESOCKETTIMEDOUT",
|
|
70
|
+
"ERR_SOCKET_CONNECTION_TIMEOUT",
|
|
71
|
+
"UND_ERR_CONNECT_TIMEOUT",
|
|
72
|
+
"UND_ERR_HEADERS_TIMEOUT",
|
|
73
|
+
"UND_ERR_BODY_TIMEOUT",
|
|
74
|
+
"UND_ERR_SOCKET",
|
|
75
|
+
"UND_ERR_CLOSED",
|
|
76
|
+
"UND_ERR_ABORTED",
|
|
77
|
+
"CERT_HAS_EXPIRED",
|
|
78
|
+
"DEPTH_ZERO_SELF_SIGNED_CERT",
|
|
79
|
+
"SELF_SIGNED_CERT_IN_CHAIN",
|
|
80
|
+
"UNABLE_TO_VERIFY_LEAF_SIGNATURE",
|
|
81
|
+
"ERR_TLS_CERT_ALTNAME_INVALID",
|
|
82
|
+
"ERR_SSL_WRONG_VERSION_NUMBER"
|
|
83
|
+
]);
|
|
84
|
+
var ABORT_ERROR_CODE = "ABORT_ERR";
|
|
85
|
+
function asRecord(value) {
|
|
86
|
+
return value && typeof value === "object" ? value : null;
|
|
87
|
+
}
|
|
88
|
+
function readErrorCauseCode(error, maxDepth = 5) {
|
|
89
|
+
let current = error;
|
|
90
|
+
const seen = /* @__PURE__ */ new Set();
|
|
91
|
+
for (let depth = 0; depth < maxDepth; depth += 1) {
|
|
92
|
+
if (current === void 0 || current === null || seen.has(current)) return void 0;
|
|
93
|
+
seen.add(current);
|
|
94
|
+
if (current instanceof Error && current.name === "AbortError") return ABORT_ERROR_CODE;
|
|
95
|
+
const record = asRecord(current);
|
|
96
|
+
if (!record) return void 0;
|
|
97
|
+
if (record.name === "AbortError") return ABORT_ERROR_CODE;
|
|
98
|
+
const code = record.code;
|
|
99
|
+
if (typeof code === "string" && code) return code;
|
|
100
|
+
const errno = record.errno;
|
|
101
|
+
if (typeof errno === "string" && errno) return errno;
|
|
102
|
+
if (typeof errno === "number") return String(errno);
|
|
103
|
+
current = record.cause;
|
|
104
|
+
}
|
|
105
|
+
return void 0;
|
|
106
|
+
}
|
|
107
|
+
function isAbortError(error) {
|
|
108
|
+
if (error instanceof Error && error.name === "AbortError") return true;
|
|
109
|
+
return asRecord(error)?.name === "AbortError";
|
|
110
|
+
}
|
|
111
|
+
function isNetworkErrorCode(code) {
|
|
112
|
+
return typeof code === "string" && NETWORK_ERROR_CODES.has(code.toUpperCase());
|
|
113
|
+
}
|
|
114
|
+
var TRANSPORT_MESSAGE_PATTERN = /fetch failed|socket hang up|other side closed|network|connection (?:refused|reset|closed)|timed? ?out|timeout|certificate|getaddrinfo|dns lookup/i;
|
|
115
|
+
function looksLikeTransportMessage(message) {
|
|
116
|
+
return TRANSPORT_MESSAGE_PATTERN.test(message);
|
|
117
|
+
}
|
|
118
|
+
function createTimeoutSignal(timeoutMs) {
|
|
119
|
+
const controller = new AbortController();
|
|
120
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
121
|
+
return { signal: controller.signal, clear: () => clearTimeout(timer) };
|
|
122
|
+
}
|
|
123
|
+
|
|
55
124
|
// src/internal/e10/auth/crypto.ts
|
|
56
125
|
import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
|
|
57
126
|
import { existsSync, mkdirSync, readFileSync } from "node:fs";
|
|
@@ -189,6 +258,7 @@ function parseAuthFile(raw) {
|
|
|
189
258
|
}
|
|
190
259
|
|
|
191
260
|
// src/internal/e10/auth/session.ts
|
|
261
|
+
var E10_TEAMS_CHECK_TIMEOUT_MS = 15e3;
|
|
192
262
|
var RSA_PUBLIC_KEY_PEM = `-----BEGIN PUBLIC KEY-----
|
|
193
263
|
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCEOk/WyyJKdAHIfMODFnKg7MBoraFBnL3F18hhLx5n01J5g4hCkmpc5+KQFKIQIA/QWk9m7QBzI/OV9ZDFk54LaWm3xP8C+P1TPp7UVGz3iNDLdvgSxuGEYPmML3NaqkbVlvW7/NlNA3ED4Kao7rR5GUYSdFfbaBoxBFae638hzQIDAQAB
|
|
194
264
|
-----END PUBLIC KEY-----`;
|
|
@@ -359,16 +429,16 @@ function findAuthFile(startDir = process.cwd(), options = {}) {
|
|
|
359
429
|
if (existsSync2(activeProfileAuth)) return activeProfileAuth;
|
|
360
430
|
return null;
|
|
361
431
|
}
|
|
362
|
-
function
|
|
432
|
+
function asRecord2(value) {
|
|
363
433
|
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
364
434
|
}
|
|
365
435
|
function readTeamsCheckUserInfo(resp, data) {
|
|
366
|
-
const root =
|
|
367
|
-
const nested =
|
|
368
|
-
const currentUser =
|
|
369
|
-
const currentTenant =
|
|
370
|
-
const department =
|
|
371
|
-
const position =
|
|
436
|
+
const root = asRecord2(data);
|
|
437
|
+
const nested = asRecord2(root.data);
|
|
438
|
+
const currentUser = asRecord2(root.currentUser || nested.currentUser);
|
|
439
|
+
const currentTenant = asRecord2(root.currentTenant || nested.currentTenant);
|
|
440
|
+
const department = asRecord2(currentUser.department);
|
|
441
|
+
const position = asRecord2(currentUser.position);
|
|
372
442
|
const userId = resp.headers.get("employeeId") || currentUser.employeeId || currentUser.id || nested.employeeId || root.employeeId || "";
|
|
373
443
|
const tenantKey = currentUser.tenantKey || currentTenant.tenantKey || nested.tenantKey || nested.tenantkey || root.tenantKey || root.tenantkey || "";
|
|
374
444
|
return {
|
|
@@ -488,6 +558,15 @@ var E10AuthSession = class _E10AuthSession {
|
|
|
488
558
|
get credentialSourceLabel() {
|
|
489
559
|
return this.data.credentialSourceLabel || "";
|
|
490
560
|
}
|
|
561
|
+
get expiryTimes() {
|
|
562
|
+
const value = Number(this.data.expiryTimes);
|
|
563
|
+
return Number.isFinite(value) && value > 0 ? value : void 0;
|
|
564
|
+
}
|
|
565
|
+
/** XiaoE 换取的 ETEAMSID 是否已经超过其明确的失效时间。 */
|
|
566
|
+
isExpired(now = Date.now()) {
|
|
567
|
+
const expiryTimes = this.expiryTimes;
|
|
568
|
+
return expiryTimes !== void 0 && now >= expiryTimes;
|
|
569
|
+
}
|
|
491
570
|
getBaseUrl() {
|
|
492
571
|
return (this.data.baseUrl || "").replace(/\/$/, "");
|
|
493
572
|
}
|
|
@@ -540,6 +619,7 @@ var E10AuthSession = class _E10AuthSession {
|
|
|
540
619
|
stTicket: this.data.stTicket,
|
|
541
620
|
redirectUrl: this.data.redirectUrl,
|
|
542
621
|
cookieSavedAt: this.data.cookieSavedAt,
|
|
622
|
+
expiryTimes: this.expiryTimes,
|
|
543
623
|
mainUrl: this.data.mainUrl,
|
|
544
624
|
...sourceInfo,
|
|
545
625
|
hasEteamsId: Boolean(this.eteamsId)
|
|
@@ -566,12 +646,13 @@ var E10AuthSession = class _E10AuthSession {
|
|
|
566
646
|
const authPath = findAuthFile(startDir, options);
|
|
567
647
|
if (!authPath) return null;
|
|
568
648
|
const session = _E10AuthSession.fromFile(authPath, baseUrl, passportUrl);
|
|
569
|
-
if (session && !(load.skipProfileEnrichment && hasUsableUserId(session))) {
|
|
649
|
+
if (session && !session.isExpired() && !(load.skipProfileEnrichment && hasUsableUserId(session))) {
|
|
570
650
|
await session.fetchEmployeeId();
|
|
571
651
|
}
|
|
572
652
|
return session;
|
|
573
653
|
}
|
|
574
654
|
async fetchEmployeeId() {
|
|
655
|
+
const { signal, clear } = createTimeoutSignal(E10_TEAMS_CHECK_TIMEOUT_MS);
|
|
575
656
|
try {
|
|
576
657
|
const resp = await fetch(
|
|
577
658
|
`${this.getBaseUrl()}/api/baseserver/layout/teamsCheck?clientType=not_xinchuang&client=WEB&domainName=${encodeURIComponent(this.getBaseUrl())}`,
|
|
@@ -584,7 +665,8 @@ var E10AuthSession = class _E10AuthSession {
|
|
|
584
665
|
cookie: this.cookieHeader(),
|
|
585
666
|
"user-agent": this.uaHeader(),
|
|
586
667
|
origin: this.getBaseUrl()
|
|
587
|
-
}
|
|
668
|
+
},
|
|
669
|
+
signal
|
|
588
670
|
}
|
|
589
671
|
);
|
|
590
672
|
const data = await resp.json().catch(() => ({}));
|
|
@@ -596,9 +678,12 @@ var E10AuthSession = class _E10AuthSession {
|
|
|
596
678
|
if (userInfo.subcompany) this.data.subcompany = userInfo.subcompany;
|
|
597
679
|
if (userInfo.position) this.data.position = userInfo.position;
|
|
598
680
|
} catch {
|
|
681
|
+
} finally {
|
|
682
|
+
clear();
|
|
599
683
|
}
|
|
600
684
|
}
|
|
601
685
|
async checkValid() {
|
|
686
|
+
const { signal, clear } = createTimeoutSignal(E10_TEAMS_CHECK_TIMEOUT_MS);
|
|
602
687
|
try {
|
|
603
688
|
const resp = await fetch(`${this.getBaseUrl()}/api/ecode/tree/list?parentId=0`, {
|
|
604
689
|
headers: {
|
|
@@ -607,11 +692,14 @@ var E10AuthSession = class _E10AuthSession {
|
|
|
607
692
|
cookie: this.cookieHeader(),
|
|
608
693
|
"user-agent": this.uaHeader()
|
|
609
694
|
},
|
|
610
|
-
redirect: "manual"
|
|
695
|
+
redirect: "manual",
|
|
696
|
+
signal
|
|
611
697
|
});
|
|
612
698
|
return resp.status === 200;
|
|
613
699
|
} catch {
|
|
614
700
|
return false;
|
|
701
|
+
} finally {
|
|
702
|
+
clear();
|
|
615
703
|
}
|
|
616
704
|
}
|
|
617
705
|
async ensureValid() {
|
|
@@ -712,6 +800,8 @@ var E10AuthSession = class _E10AuthSession {
|
|
|
712
800
|
var E10_REAUTH_GUIDANCE = "\u8BF7\u7ED3\u5408\u5F53\u524D\u5BBF\u4E3B\u73AF\u5883\u9009\u62E9\u5408\u9002\u7684\u767B\u5F55\u65B9\u5F0F\uFF0C\u6062\u590D\u767B\u5F55\u540E\u91CD\u8BD5\u539F\u8BF7\u6C42\u3002";
|
|
713
801
|
var E10_AUTH_REQUIRED_MESSAGE = `E10 \u767B\u5F55\u6001\u4E0D\u53EF\u7528\u3002${E10_REAUTH_GUIDANCE}`;
|
|
714
802
|
var E10_XIAOE_RECOVERY_FAILED_MESSAGE = "E10 \u767B\u5F55\u6001\u4E0D\u53EF\u7528\u3002\u5DF2\u5C1D\u8BD5\u5C0F e \u81EA\u52A8\u91CD\u65B0\u83B7\u53D6\u767B\u5F55\u4FE1\u606F\uFF0C\u4F46\u672A\u53D6\u5F97\u53EF\u7528\u767B\u5F55\u6001\u3002\u8BF7\u5728\u5C0F e \u4E2D\u6062\u590D\u767B\u5F55\u540E\u91CD\u8BD5\u3002";
|
|
803
|
+
var E10_XIAOE_HOST_CREDENTIAL_MISSING_MESSAGE = "E10 \u767B\u5F55\u6001\u4E0D\u53EF\u7528\u3002\u5C0F e \u7F51\u9875\u7AEF\u672A\u5411\u5F53\u524D\u8FD0\u884C\u73AF\u5883\u6CE8\u5165\u7EDF\u4E00\u767B\u5F55\u51ED\u636E\uFF0C\u81EA\u52A8\u83B7\u53D6\u5DF2\u505C\u6B62\u3002\u8BF7\u68C0\u67E5\u7F51\u9875\u6280\u80FD\u6C99\u7BB1\u7684\u5BBF\u4E3B\u51ED\u636E\u900F\u4F20\u540E\u91CD\u8BD5\u3002";
|
|
804
|
+
var E10_XIAOE_NETWORK_UNAVAILABLE_MESSAGE = "\u6682\u65F6\u65E0\u6CD5\u8FDE\u63A5 E10\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5";
|
|
715
805
|
var E10_SESSION_EXPIRED_MESSAGE = `E10 \u767B\u5F55\u6001\u5DF2\u5931\u6548\uFF0C\u672C\u6B21\u64CD\u4F5C\u5DF2\u505C\u6B62\u3002${E10_REAUTH_GUIDANCE}`;
|
|
716
806
|
|
|
717
807
|
// src/core/package-paths.ts
|
|
@@ -825,6 +915,83 @@ var XIAOE_SKILL_ETEAMID_API_PATH = "/spec-apps/api/app/rpachat/skill/extend/etea
|
|
|
825
915
|
var XIAOE_CLIENT_SETTINGS_SOURCE = "XiaoE/Robots/user_settings.json";
|
|
826
916
|
var XIAOE_USER_TOKEN_SOURCE = "XIAOE_USER_TOKEN";
|
|
827
917
|
var XIAOE_BUNDLED_ENV_SCRIPT_SOURCE = "bundled scripts/xiaoe_env.py";
|
|
918
|
+
var XIAOE_ETEAMID_TTL_MS = 72e5;
|
|
919
|
+
var XIAOE_DIAGNOSTIC_MAX_LENGTH = 300;
|
|
920
|
+
function redactXiaoEDiagnostic(message, secrets) {
|
|
921
|
+
let text = message;
|
|
922
|
+
for (const secret of secrets) {
|
|
923
|
+
if (secret && secret.length >= 8 && text.includes(secret)) {
|
|
924
|
+
text = text.split(secret).join("<redacted>");
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
const normalized = text.replace(/\s+/gu, " ").trim();
|
|
928
|
+
return normalized.length > XIAOE_DIAGNOSTIC_MAX_LENGTH ? `${normalized.slice(0, XIAOE_DIAGNOSTIC_MAX_LENGTH)}\u2026` : normalized;
|
|
929
|
+
}
|
|
930
|
+
function noteXiaoEStep(diagnostics, step) {
|
|
931
|
+
diagnostics?.attemptedSteps.push(step);
|
|
932
|
+
}
|
|
933
|
+
function tagXiaoEError(message, tags) {
|
|
934
|
+
return Object.assign(new CliError(message, 3 /* AuthError */), tags);
|
|
935
|
+
}
|
|
936
|
+
function readTag(error, key, type) {
|
|
937
|
+
if (!error || typeof error !== "object") return void 0;
|
|
938
|
+
const value = error[key];
|
|
939
|
+
return typeof value === type ? value : void 0;
|
|
940
|
+
}
|
|
941
|
+
function classifyXiaoEHttpStatus(status) {
|
|
942
|
+
if (status === 401 || status === 403) return "credential";
|
|
943
|
+
if (status >= 300 && status < 400) return "credential";
|
|
944
|
+
return status >= 400 ? "http" : "credential";
|
|
945
|
+
}
|
|
946
|
+
function classifyXiaoEError(error) {
|
|
947
|
+
const taggedKind = readTag(error, "errorKind", "string");
|
|
948
|
+
const taggedStatus = readTag(error, "status", "number");
|
|
949
|
+
const taggedCause = readTag(error, "causeCode", "string");
|
|
950
|
+
const causeCode = taggedCause || readErrorCauseCode(error);
|
|
951
|
+
const withCause = causeCode ? { causeCode } : {};
|
|
952
|
+
const withStatus = taggedStatus === void 0 ? {} : { status: taggedStatus };
|
|
953
|
+
if (taggedKind) return { kind: taggedKind, ...withCause, ...withStatus };
|
|
954
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
955
|
+
if (isAbortError(error)) return { kind: "network", causeCode: causeCode || "ETIMEDOUT" };
|
|
956
|
+
if (taggedStatus !== void 0) {
|
|
957
|
+
return { kind: classifyXiaoEHttpStatus(taggedStatus), ...withCause, status: taggedStatus };
|
|
958
|
+
}
|
|
959
|
+
if (causeCode && isNetworkErrorCode(causeCode)) return { kind: "network", causeCode };
|
|
960
|
+
const httpMatch = /\bHTTP (\d{3})\b/u.exec(message);
|
|
961
|
+
if (httpMatch) {
|
|
962
|
+
const status = Number(httpMatch[1]);
|
|
963
|
+
return { kind: classifyXiaoEHttpStatus(status), ...withCause, status };
|
|
964
|
+
}
|
|
965
|
+
if (looksLikeTransportMessage(message)) return { kind: "network", ...withCause };
|
|
966
|
+
return { kind: "credential", ...withCause };
|
|
967
|
+
}
|
|
968
|
+
function noteXiaoEError(diagnostics, error, secrets = [], stage = "e10_session") {
|
|
969
|
+
if (!diagnostics) return;
|
|
970
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
971
|
+
const redacted = redactXiaoEDiagnostic(message, secrets);
|
|
972
|
+
if (redacted) diagnostics.lastError = redacted;
|
|
973
|
+
const { kind, causeCode, status } = classifyXiaoEError(error);
|
|
974
|
+
const failure = {
|
|
975
|
+
stage: readTag(error, "stage", "string") ?? stage,
|
|
976
|
+
kind,
|
|
977
|
+
message: redacted,
|
|
978
|
+
...causeCode ? { causeCode } : {},
|
|
979
|
+
...status === void 0 ? {} : { httpStatus: status }
|
|
980
|
+
};
|
|
981
|
+
if (!diagnostics.failures) diagnostics.failures = [];
|
|
982
|
+
diagnostics.failures.push(failure);
|
|
983
|
+
}
|
|
984
|
+
function summarizeXiaoEFailureKind(diagnostics) {
|
|
985
|
+
const failures = diagnostics?.failures || [];
|
|
986
|
+
if (!failures.length) return void 0;
|
|
987
|
+
if (failures.some((failure) => failure.kind === "credential")) return "credential";
|
|
988
|
+
if (failures.some((failure) => failure.kind === "http")) return "http";
|
|
989
|
+
return failures.every((failure) => failure.kind === "network") ? "network" : void 0;
|
|
990
|
+
}
|
|
991
|
+
function lastXiaoEFailure(diagnostics) {
|
|
992
|
+
const failures = diagnostics?.failures || [];
|
|
993
|
+
return failures.length ? failures[failures.length - 1] : void 0;
|
|
994
|
+
}
|
|
828
995
|
function envString(env, ...keys) {
|
|
829
996
|
for (const key of keys) {
|
|
830
997
|
const value = env[key];
|
|
@@ -843,6 +1010,15 @@ function hasXiaoEEnv(env = process.env, options = {}) {
|
|
|
843
1010
|
const explicitAgentType = envString(env, "WEAVER_AGENT_TYPE");
|
|
844
1011
|
return explicitAgentType ? isXiaoERuntimeAgent(explicitAgentType) : false;
|
|
845
1012
|
}
|
|
1013
|
+
function resolveXiaoEClientType(env = process.env) {
|
|
1014
|
+
const raw = envString(env, "XIAOE_CLIENT_TYPE").toLowerCase();
|
|
1015
|
+
if (raw === "client" || raw === "desktop" || raw === "pc") return "client";
|
|
1016
|
+
if (raw === "cloud" || raw === "web" || raw === "browser") return "cloud";
|
|
1017
|
+
return void 0;
|
|
1018
|
+
}
|
|
1019
|
+
function isXiaoECloudRuntime(env = process.env) {
|
|
1020
|
+
return resolveXiaoEClientType(env) === "cloud";
|
|
1021
|
+
}
|
|
846
1022
|
function describeXiaoECredentialSource(source) {
|
|
847
1023
|
if (source === XIAOE_USER_TOKEN_SOURCE || source === XIAOE_BUNDLED_ENV_SCRIPT_SOURCE) {
|
|
848
1024
|
return {
|
|
@@ -882,6 +1058,13 @@ function readString(data, ...keys) {
|
|
|
882
1058
|
}
|
|
883
1059
|
return "";
|
|
884
1060
|
}
|
|
1061
|
+
function readExpiryTimes(data) {
|
|
1062
|
+
for (const key of ["expiryTimes", "expiryTime", "expiresAt", "expires_at"]) {
|
|
1063
|
+
const value = Number(data[key]);
|
|
1064
|
+
if (Number.isFinite(value) && value > 0) return Math.trunc(value);
|
|
1065
|
+
}
|
|
1066
|
+
return void 0;
|
|
1067
|
+
}
|
|
885
1068
|
function cookieString(value) {
|
|
886
1069
|
if (!value) return "";
|
|
887
1070
|
if (typeof value === "string") return value;
|
|
@@ -937,7 +1120,18 @@ function readXiaoECredentialRecord(value, source, fallbackBaseUrl = "") {
|
|
|
937
1120
|
const rawCookie = candidates.map((entry) => cookieString(entry.cookies || entry.cookie || entry.rawCookie || entry.raw_cookie)).find(Boolean) || "";
|
|
938
1121
|
const eteamsId = candidates.map((entry) => readString(entry, "eteamsId", "eteamsid", "ETEAMSID", "eteamId", "eteam_id", "eTeamId", "eteamID", "eteam_id")).find(Boolean) || cookieValue(rawCookie, "ETEAMSID");
|
|
939
1122
|
if (!baseUrl || !eteamsId) return null;
|
|
940
|
-
|
|
1123
|
+
const expiryTimes = candidates.map(readExpiryTimes).find((value2) => value2 !== void 0);
|
|
1124
|
+
return {
|
|
1125
|
+
baseUrl: normalizeUrl(baseUrl),
|
|
1126
|
+
eteamsId,
|
|
1127
|
+
source,
|
|
1128
|
+
rawCookie,
|
|
1129
|
+
...expiryTimes !== void 0 ? { expiryTimes } : {}
|
|
1130
|
+
};
|
|
1131
|
+
}
|
|
1132
|
+
function withDefaultXiaoEExpiry(credential) {
|
|
1133
|
+
if (!credential || credential.expiryTimes !== void 0) return credential;
|
|
1134
|
+
return { ...credential, expiryTimes: Date.now() + XIAOE_ETEAMID_TTL_MS };
|
|
941
1135
|
}
|
|
942
1136
|
function parseXiaoEUnifiedLoginMap(raw, source) {
|
|
943
1137
|
const value = raw.trim();
|
|
@@ -1201,14 +1395,18 @@ async function runXiaoETokenScript(baseUrl, env = process.env) {
|
|
|
1201
1395
|
async function resolveXiaoETokenScriptCredential(baseUrl, env = process.env) {
|
|
1202
1396
|
const tokenData = await runXiaoETokenScript(baseUrl, env);
|
|
1203
1397
|
if (!tokenData) return null;
|
|
1204
|
-
return
|
|
1398
|
+
return withDefaultXiaoEExpiry(
|
|
1399
|
+
readXiaoECredentialRecord(tokenData, "xiaoeUserData/tokens.py", baseUrl)
|
|
1400
|
+
);
|
|
1205
1401
|
}
|
|
1206
1402
|
async function resolveXiaoEBundledEnvScriptCredential(baseUrl, env = process.env) {
|
|
1207
1403
|
const scriptPath = xiaoEBundledEnvScriptPath();
|
|
1208
1404
|
if (!scriptPath) return null;
|
|
1209
1405
|
const tokenData = await runXiaoEPythonCredentialScript(scriptPath, baseUrl, env);
|
|
1210
1406
|
if (!tokenData) return null;
|
|
1211
|
-
return
|
|
1407
|
+
return withDefaultXiaoEExpiry(
|
|
1408
|
+
readXiaoECredentialRecord(tokenData, XIAOE_BUNDLED_ENV_SCRIPT_SOURCE, baseUrl)
|
|
1409
|
+
);
|
|
1212
1410
|
}
|
|
1213
1411
|
function xiaoEClientRobotsRoot(env = process.env) {
|
|
1214
1412
|
if (process.platform === "win32") {
|
|
@@ -1319,14 +1517,17 @@ function inspectXiaoEUnifiedLoginSources(options = {}) {
|
|
|
1319
1517
|
});
|
|
1320
1518
|
const platformCredential = hasXiaoEPlatformCredential(env);
|
|
1321
1519
|
const allowLocalDiscovery = options.allowLocalDiscovery !== false;
|
|
1322
|
-
const
|
|
1323
|
-
const
|
|
1520
|
+
const clientType = resolveXiaoEClientType(env);
|
|
1521
|
+
const allowDesktopChannels = clientType !== "cloud";
|
|
1522
|
+
const tokenScript = allowDesktopChannels && options.allowTokenScript !== false && hasXiaoETokenScript(env, allowLocalDiscovery);
|
|
1523
|
+
const clientCredential = allowDesktopChannels && hasXiaoEClientCredential(env, allowLocalDiscovery);
|
|
1324
1524
|
const environmentCredential = Boolean(baseUrl && resolveXiaoEUnifiedLoginCredential(baseUrl, env));
|
|
1325
1525
|
return {
|
|
1326
1526
|
platformCredential,
|
|
1327
1527
|
tokenScript,
|
|
1328
1528
|
clientCredential,
|
|
1329
1529
|
environmentCredential,
|
|
1530
|
+
clientType,
|
|
1330
1531
|
any: platformCredential || tokenScript || clientCredential || environmentCredential
|
|
1331
1532
|
};
|
|
1332
1533
|
}
|
|
@@ -1349,37 +1550,71 @@ async function fetchXiaoEClientEteamId(credential, domain) {
|
|
|
1349
1550
|
});
|
|
1350
1551
|
if (resp.status < 300 || resp.status >= 400) break;
|
|
1351
1552
|
if (redirects === 5) {
|
|
1352
|
-
throw
|
|
1553
|
+
throw tagXiaoEError("XiaoE client token endpoint redirected too many times.", {
|
|
1554
|
+
errorKind: "http"
|
|
1555
|
+
});
|
|
1353
1556
|
}
|
|
1354
1557
|
const location = resp.headers.get("location");
|
|
1355
1558
|
if (!location) {
|
|
1356
|
-
throw
|
|
1559
|
+
throw tagXiaoEError("XiaoE client token endpoint returned a redirect without Location.", {
|
|
1560
|
+
errorKind: "http",
|
|
1561
|
+
status: resp.status
|
|
1562
|
+
});
|
|
1357
1563
|
}
|
|
1358
1564
|
const next = new URL(location, endpoint);
|
|
1359
1565
|
const sameOrigin = next.origin === endpoint.origin;
|
|
1360
1566
|
const sameHostHttpsUpgrade = endpoint.protocol === "http:" && next.protocol === "https:" && next.hostname === endpoint.hostname;
|
|
1361
1567
|
const safeProtocol = next.protocol === "http:" || next.protocol === "https:";
|
|
1362
1568
|
if (!safeProtocol || next.username || next.password || !sameOrigin && !sameHostHttpsUpgrade) {
|
|
1363
|
-
throw
|
|
1569
|
+
throw tagXiaoEError("XiaoE client token endpoint attempted an unsafe cross-origin redirect.", {
|
|
1570
|
+
errorKind: "http",
|
|
1571
|
+
status: resp.status
|
|
1572
|
+
});
|
|
1364
1573
|
}
|
|
1365
1574
|
await resp.body?.cancel().catch(() => void 0);
|
|
1366
1575
|
endpoint = next;
|
|
1367
1576
|
}
|
|
1368
1577
|
if (!resp?.ok) {
|
|
1369
|
-
|
|
1578
|
+
const status = resp?.status || 0;
|
|
1579
|
+
throw tagXiaoEError(`XiaoE client token endpoint returned HTTP ${status}.`, {
|
|
1580
|
+
errorKind: classifyXiaoEHttpStatus(status),
|
|
1581
|
+
status
|
|
1582
|
+
});
|
|
1370
1583
|
}
|
|
1371
|
-
const data = await resp.json().catch(() =>
|
|
1584
|
+
const data = await resp.json().catch((error) => {
|
|
1585
|
+
if (isAbortError(error)) throw error;
|
|
1586
|
+
return null;
|
|
1587
|
+
});
|
|
1372
1588
|
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
|
1373
|
-
throw
|
|
1589
|
+
throw tagXiaoEError("XiaoE client token endpoint returned invalid JSON.", {
|
|
1590
|
+
errorKind: "http",
|
|
1591
|
+
status: resp.status
|
|
1592
|
+
});
|
|
1374
1593
|
}
|
|
1375
1594
|
const payload = data;
|
|
1376
1595
|
const businessCode = payload.code;
|
|
1377
1596
|
const businessData = payload.data && typeof payload.data === "object" && !Array.isArray(payload.data) ? payload.data : {};
|
|
1378
1597
|
if (businessCode !== "0000" && businessCode !== 0 && businessCode !== 200 || !readString(businessData, "eteamId")) {
|
|
1379
1598
|
const codeText = businessCode === void 0 ? "missing" : String(businessCode);
|
|
1380
|
-
throw
|
|
1599
|
+
throw tagXiaoEError(`XiaoE client token exchange failed with business code ${codeText}.`, {
|
|
1600
|
+
errorKind: "credential"
|
|
1601
|
+
});
|
|
1381
1602
|
}
|
|
1382
1603
|
return payload;
|
|
1604
|
+
} catch (error) {
|
|
1605
|
+
if (isAbortError(error)) {
|
|
1606
|
+
throw tagXiaoEError(
|
|
1607
|
+
`XiaoE client token endpoint timed out after ${XIAOE_CLIENT_TOKEN_TIMEOUT_MS} ms.`,
|
|
1608
|
+
{ errorKind: "network", causeCode: "ETIMEDOUT" }
|
|
1609
|
+
);
|
|
1610
|
+
}
|
|
1611
|
+
if (error instanceof CliError) throw error;
|
|
1612
|
+
const causeCode = readErrorCauseCode(error);
|
|
1613
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1614
|
+
throw tagXiaoEError(
|
|
1615
|
+
`XiaoE client token endpoint request failed${causeCode ? ` (${causeCode})` : ""}: ${message}`,
|
|
1616
|
+
{ errorKind: "network", ...causeCode ? { causeCode } : {} }
|
|
1617
|
+
);
|
|
1383
1618
|
} finally {
|
|
1384
1619
|
clearTimeout(timer);
|
|
1385
1620
|
}
|
|
@@ -1388,7 +1623,9 @@ async function resolveXiaoETokenCredential(credential, baseUrl) {
|
|
|
1388
1623
|
const targetBaseUrl = baseUrl || DEFAULT_E10_BASE_URL;
|
|
1389
1624
|
const payload = await fetchXiaoEClientEteamId(credential, targetBaseUrl);
|
|
1390
1625
|
const resolvedBaseUrl = payload.code === 0 ? credential.erpaUrl : targetBaseUrl;
|
|
1391
|
-
return
|
|
1626
|
+
return withDefaultXiaoEExpiry(
|
|
1627
|
+
readXiaoECredentialRecord(payload, credential.source, resolvedBaseUrl)
|
|
1628
|
+
);
|
|
1392
1629
|
}
|
|
1393
1630
|
async function resolveXiaoEPlatformCredential(baseUrl, env = process.env) {
|
|
1394
1631
|
const credential = readXiaoEPlatformCredential(env);
|
|
@@ -1426,26 +1663,58 @@ function createXiaoEUnifiedLoginUnavailableError(baseUrl = "") {
|
|
|
1426
1663
|
});
|
|
1427
1664
|
}
|
|
1428
1665
|
async function resolveUserInfo(baseUrl, eteamsId, rawCookie = "", agentType = "") {
|
|
1429
|
-
const
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1666
|
+
const { signal, clear } = createTimeoutSignal(E10_TEAMS_CHECK_TIMEOUT_MS);
|
|
1667
|
+
try {
|
|
1668
|
+
const resp = await fetch(`${baseUrl}/api/baseserver/layout/teamsCheck?clientType=not_xinchuang&client=WEB&domainName=${encodeURIComponent(baseUrl)}`, {
|
|
1669
|
+
method: "POST",
|
|
1670
|
+
headers: {
|
|
1671
|
+
accept: "application/json",
|
|
1672
|
+
"content-type": "application/json",
|
|
1673
|
+
eteamsid: eteamsId,
|
|
1674
|
+
cookie: buildE10CookieHeader(rawCookie, eteamsId, agentType),
|
|
1675
|
+
"user-agent": agentType ? `AgentType=${agentType},IsAgent=true` : "weaver-work-cli",
|
|
1676
|
+
origin: baseUrl
|
|
1677
|
+
},
|
|
1678
|
+
redirect: "manual",
|
|
1679
|
+
signal
|
|
1680
|
+
});
|
|
1681
|
+
const data = await resp.json().catch((error) => {
|
|
1682
|
+
if (isAbortError(error)) throw error;
|
|
1683
|
+
return {};
|
|
1684
|
+
});
|
|
1685
|
+
return { userInfo: readTeamsCheckUserInfo(resp, data), setCookie: extractRawSetCookie(resp), status: resp.status };
|
|
1686
|
+
} catch (error) {
|
|
1687
|
+
if (isAbortError(error)) {
|
|
1688
|
+
throw tagXiaoEError(
|
|
1689
|
+
`E10 teamsCheck timed out after ${E10_TEAMS_CHECK_TIMEOUT_MS} ms.`,
|
|
1690
|
+
{ errorKind: "network", stage: "teams_check", causeCode: "ETIMEDOUT" }
|
|
1691
|
+
);
|
|
1692
|
+
}
|
|
1693
|
+
if (error instanceof CliError) throw error;
|
|
1694
|
+
const causeCode = readErrorCauseCode(error);
|
|
1695
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1696
|
+
throw tagXiaoEError(
|
|
1697
|
+
`E10 teamsCheck request failed${causeCode ? ` (${causeCode})` : ""}: ${message}`,
|
|
1698
|
+
{ errorKind: "network", stage: "teams_check", ...causeCode ? { causeCode } : {} }
|
|
1699
|
+
);
|
|
1700
|
+
} finally {
|
|
1701
|
+
clear();
|
|
1702
|
+
}
|
|
1443
1703
|
}
|
|
1444
1704
|
async function saveXiaoEUnifiedLogin(input) {
|
|
1445
1705
|
const baseUrl = normalizeUrl(input.baseUrl);
|
|
1446
|
-
const { userInfo, setCookie } = await resolveUserInfo(baseUrl, input.eteamsId, input.rawCookie || "", XIAOE_AGENT_TYPE);
|
|
1706
|
+
const { userInfo, setCookie, status } = await resolveUserInfo(baseUrl, input.eteamsId, input.rawCookie || "", XIAOE_AGENT_TYPE);
|
|
1447
1707
|
if (!userInfo.userId) {
|
|
1448
|
-
|
|
1708
|
+
const statusText = status || 0;
|
|
1709
|
+
throw classifyXiaoEHttpStatus(statusText) === "http" ? tagXiaoEError(`E10 teamsCheck returned HTTP ${statusText}.`, {
|
|
1710
|
+
errorKind: "http",
|
|
1711
|
+
stage: "teams_check",
|
|
1712
|
+
status: statusText
|
|
1713
|
+
}) : tagXiaoEError("Could not resolve userId. Check whether XiaoE unified login is valid for this E10 domain.", {
|
|
1714
|
+
errorKind: "credential",
|
|
1715
|
+
stage: "teams_check",
|
|
1716
|
+
status: statusText
|
|
1717
|
+
});
|
|
1449
1718
|
}
|
|
1450
1719
|
const tenantKey = userInfo.tenantKey || input.tenantKeyFallback || "";
|
|
1451
1720
|
const profile = input.profileHint || profileNameFromUrl(baseUrl);
|
|
@@ -1466,6 +1735,7 @@ async function saveXiaoEUnifiedLogin(input) {
|
|
|
1466
1735
|
baseUrl,
|
|
1467
1736
|
passportUrl: baseUrl,
|
|
1468
1737
|
cookieSavedAt: Date.now(),
|
|
1738
|
+
...input.expiryTimes !== void 0 ? { expiryTimes: input.expiryTimes } : {},
|
|
1469
1739
|
loginSource: "xiaoe-unified",
|
|
1470
1740
|
credentialSourceStep: input.credentialSource.credentialSourceStep,
|
|
1471
1741
|
credentialSourceType: input.credentialSource.credentialSourceType,
|
|
@@ -1488,6 +1758,7 @@ async function saveXiaoEUnifiedLogin(input) {
|
|
|
1488
1758
|
agentType: XIAOE_AGENT_TYPE,
|
|
1489
1759
|
version: "",
|
|
1490
1760
|
loginSource: "xiaoe-unified",
|
|
1761
|
+
...input.expiryTimes !== void 0 ? { expiryTimes: input.expiryTimes } : {},
|
|
1491
1762
|
...input.credentialSource
|
|
1492
1763
|
}
|
|
1493
1764
|
};
|
|
@@ -1500,41 +1771,67 @@ async function tryXiaoEUnifiedLogin(options = {}) {
|
|
|
1500
1771
|
profileBaseUrl: options.profileBaseUrl,
|
|
1501
1772
|
env
|
|
1502
1773
|
});
|
|
1503
|
-
const mayUseTokenScript = options.allowTokenScript === true;
|
|
1504
|
-
|
|
1774
|
+
const mayUseTokenScript = options.allowTokenScript === true && !isXiaoECloudRuntime(env);
|
|
1775
|
+
const diagnostics = options.diagnostics;
|
|
1776
|
+
const platformCredentialDetected = hasXiaoEPlatformCredential(env);
|
|
1777
|
+
const secrets = [envString(env, "XIAOE_USER_TOKEN")];
|
|
1778
|
+
if (diagnostics) {
|
|
1779
|
+
diagnostics.baseUrl = baseUrl;
|
|
1780
|
+
diagnostics.platformCredentialDetected = platformCredentialDetected;
|
|
1781
|
+
diagnostics.clientType = resolveXiaoEClientType(env);
|
|
1782
|
+
}
|
|
1783
|
+
if (!baseUrl && !mayUseTokenScript) {
|
|
1784
|
+
noteXiaoEStep(diagnostics, "base_url:missing");
|
|
1785
|
+
return null;
|
|
1786
|
+
}
|
|
1505
1787
|
let credential = null;
|
|
1506
|
-
if (
|
|
1788
|
+
if (platformCredentialDetected) {
|
|
1507
1789
|
options.logger?.info("Trying XiaoE platform credential from XIAOE_USER_TOKEN...");
|
|
1508
1790
|
try {
|
|
1509
1791
|
credential = await resolveXiaoEPlatformCredential(baseUrl || DEFAULT_E10_BASE_URL, env);
|
|
1510
1792
|
} catch (error) {
|
|
1511
1793
|
const message = error instanceof Error ? error.message : String(error);
|
|
1794
|
+
noteXiaoEError(diagnostics, error, secrets, "platform_token");
|
|
1512
1795
|
options.logger?.warn("XiaoE platform credential failed. " + message);
|
|
1513
1796
|
}
|
|
1514
1797
|
if (!credential) {
|
|
1515
1798
|
options.logger?.warn(options.allowBundledEnvScript ? "XiaoE platform credential did not return usable ETEAMSID; will try the CLI-bundled xiaoe_env.py compatibility path next." : "XiaoE platform credential did not return usable ETEAMSID; will try xiaoeUserData/tokens.py next.");
|
|
1516
1799
|
}
|
|
1517
1800
|
}
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1801
|
+
noteXiaoEStep(
|
|
1802
|
+
diagnostics,
|
|
1803
|
+
credential ? "platform_token:ok" : `platform_token:${platformCredentialDetected ? "failed" : "missing"}`
|
|
1804
|
+
);
|
|
1805
|
+
if (!credential) {
|
|
1806
|
+
if (!options.allowBundledEnvScript) {
|
|
1807
|
+
noteXiaoEStep(diagnostics, "bundled_env_script:disabled");
|
|
1808
|
+
} else if (!platformCredentialDetected) {
|
|
1809
|
+
noteXiaoEStep(diagnostics, "bundled_env_script:missing");
|
|
1522
1810
|
} else {
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
options.logger?.
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1811
|
+
const scriptPath = xiaoEBundledEnvScriptPath();
|
|
1812
|
+
if (!scriptPath) {
|
|
1813
|
+
noteXiaoEStep(diagnostics, "bundled_env_script:missing");
|
|
1814
|
+
options.logger?.warn("CLI-bundled xiaoe_env.py was not found; will try desktop XiaoE credential sources next.");
|
|
1815
|
+
} else {
|
|
1816
|
+
options.logger?.info("Trying CLI-bundled xiaoe_env.py compatibility credential...");
|
|
1817
|
+
try {
|
|
1818
|
+
credential = await resolveXiaoEBundledEnvScriptCredential(baseUrl || DEFAULT_E10_BASE_URL, env);
|
|
1819
|
+
} catch (error) {
|
|
1820
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1821
|
+
noteXiaoEError(diagnostics, error, secrets, "bundled_env_script");
|
|
1822
|
+
options.logger?.warn("CLI-bundled xiaoe_env.py failed. " + message);
|
|
1823
|
+
}
|
|
1824
|
+
if (!credential) {
|
|
1825
|
+
options.logger?.warn("CLI-bundled xiaoe_env.py did not return usable ETEAMSID; will try xiaoeUserData/tokens.py next.");
|
|
1826
|
+
}
|
|
1827
|
+
noteXiaoEStep(diagnostics, `bundled_env_script:${credential ? "ok" : "failed"}`);
|
|
1532
1828
|
}
|
|
1533
1829
|
}
|
|
1534
1830
|
}
|
|
1535
1831
|
if (!credential && mayUseTokenScript) {
|
|
1536
1832
|
const tokenScriptPath = xiaoETokenScriptPath(env);
|
|
1537
1833
|
if (!tokenScriptPath) {
|
|
1834
|
+
noteXiaoEStep(diagnostics, "token_script:missing");
|
|
1538
1835
|
options.logger?.warn("XiaoE token script not found. Expected xiaoeUserData/tokens.py; will try the local XiaoE client session next.");
|
|
1539
1836
|
} else {
|
|
1540
1837
|
options.logger?.info("Trying XiaoE token script credential...");
|
|
@@ -1542,11 +1839,13 @@ async function tryXiaoEUnifiedLogin(options = {}) {
|
|
|
1542
1839
|
credential = await resolveXiaoETokenScriptCredential(baseUrl || DEFAULT_E10_BASE_URL, env);
|
|
1543
1840
|
} catch (error) {
|
|
1544
1841
|
const message = error instanceof Error ? error.message : String(error);
|
|
1842
|
+
noteXiaoEError(diagnostics, error, secrets, "token_script");
|
|
1545
1843
|
options.logger?.warn("XiaoE token script failed. " + message);
|
|
1546
1844
|
}
|
|
1547
1845
|
if (!credential) {
|
|
1548
1846
|
options.logger?.warn("XiaoE token script did not return usable ETEAMSID; will try the local XiaoE client session next.");
|
|
1549
1847
|
}
|
|
1848
|
+
noteXiaoEStep(diagnostics, `token_script:${credential ? "ok" : "failed"}`);
|
|
1550
1849
|
}
|
|
1551
1850
|
if (!credential && hasXiaoEClientCredential(env)) {
|
|
1552
1851
|
options.logger?.info("Trying built-in XiaoE client session credential...");
|
|
@@ -1554,27 +1853,47 @@ async function tryXiaoEUnifiedLogin(options = {}) {
|
|
|
1554
1853
|
credential = await resolveXiaoEClientCredential(baseUrl || DEFAULT_E10_BASE_URL, env);
|
|
1555
1854
|
} catch (error) {
|
|
1556
1855
|
const message = error instanceof Error ? error.message : String(error);
|
|
1856
|
+
noteXiaoEError(diagnostics, error, secrets, "client_session");
|
|
1557
1857
|
options.logger?.warn("Built-in XiaoE client credential failed. " + message);
|
|
1558
1858
|
}
|
|
1559
1859
|
if (!credential) {
|
|
1560
1860
|
options.logger?.warn("Built-in XiaoE client credential did not return usable ETEAMSID; will try WEAVER_XIAOE_* credentials next.");
|
|
1561
1861
|
}
|
|
1862
|
+
noteXiaoEStep(diagnostics, `client_session:${credential ? "ok" : "failed"}`);
|
|
1863
|
+
} else if (!credential) {
|
|
1864
|
+
noteXiaoEStep(diagnostics, "client_session:missing");
|
|
1562
1865
|
}
|
|
1866
|
+
} else if (!credential) {
|
|
1867
|
+
noteXiaoEStep(diagnostics, "token_script:disabled");
|
|
1868
|
+
noteXiaoEStep(diagnostics, "client_session:disabled");
|
|
1563
1869
|
}
|
|
1564
1870
|
if (!credential && baseUrl) credential = resolveXiaoEUnifiedLoginCredential(baseUrl, env);
|
|
1565
|
-
if (!credential)
|
|
1871
|
+
if (!credential) {
|
|
1872
|
+
noteXiaoEStep(diagnostics, "environment_map:empty");
|
|
1873
|
+
return null;
|
|
1874
|
+
}
|
|
1875
|
+
noteXiaoEStep(diagnostics, `credential_source:${credential.source}`);
|
|
1566
1876
|
options.logger?.info("Detected XiaoE unified login for this E10 domain. Trying XiaoE auth...");
|
|
1567
1877
|
try {
|
|
1568
|
-
|
|
1878
|
+
const login = await saveXiaoEUnifiedLogin({
|
|
1569
1879
|
baseUrl: credential.baseUrl || baseUrl || DEFAULT_E10_BASE_URL,
|
|
1570
1880
|
eteamsId: credential.eteamsId,
|
|
1571
1881
|
rawCookie: credential.rawCookie,
|
|
1882
|
+
expiryTimes: credential.expiryTimes,
|
|
1572
1883
|
tenantKeyFallback: options.tenantKeyFallback,
|
|
1573
1884
|
profileHint: options.profileHint,
|
|
1574
1885
|
credentialSource: describeXiaoECredentialSource(credential.source)
|
|
1575
1886
|
});
|
|
1887
|
+
noteXiaoEStep(diagnostics, "e10_session:ok");
|
|
1888
|
+
if (diagnostics) {
|
|
1889
|
+
delete diagnostics.lastError;
|
|
1890
|
+
delete diagnostics.failures;
|
|
1891
|
+
}
|
|
1892
|
+
return login;
|
|
1576
1893
|
} catch (error) {
|
|
1577
1894
|
const message = error instanceof Error ? error.message : String(error);
|
|
1895
|
+
noteXiaoEError(diagnostics, error, secrets, "e10_session");
|
|
1896
|
+
noteXiaoEStep(diagnostics, "e10_session:failed");
|
|
1578
1897
|
options.logger?.warn("XiaoE unified login failed. " + message);
|
|
1579
1898
|
return null;
|
|
1580
1899
|
}
|
|
@@ -1609,6 +1928,7 @@ export {
|
|
|
1609
1928
|
packagePath,
|
|
1610
1929
|
packageFileUrl,
|
|
1611
1930
|
normalizeGlobalOptions,
|
|
1931
|
+
readErrorCauseCode,
|
|
1612
1932
|
getE10AuthRoot,
|
|
1613
1933
|
getActiveProfile,
|
|
1614
1934
|
setActiveProfile,
|
|
@@ -1630,9 +1950,13 @@ export {
|
|
|
1630
1950
|
E10_REAUTH_GUIDANCE,
|
|
1631
1951
|
E10_AUTH_REQUIRED_MESSAGE,
|
|
1632
1952
|
E10_XIAOE_RECOVERY_FAILED_MESSAGE,
|
|
1953
|
+
E10_XIAOE_HOST_CREDENTIAL_MISSING_MESSAGE,
|
|
1954
|
+
E10_XIAOE_NETWORK_UNAVAILABLE_MESSAGE,
|
|
1633
1955
|
E10_SESSION_EXPIRED_MESSAGE,
|
|
1634
1956
|
isXiaoERuntimeAgent,
|
|
1635
1957
|
XIAOE_AGENT_TYPE,
|
|
1958
|
+
summarizeXiaoEFailureKind,
|
|
1959
|
+
lastXiaoEFailure,
|
|
1636
1960
|
hasXiaoEEnv,
|
|
1637
1961
|
inspectXiaoEUnifiedLoginSources,
|
|
1638
1962
|
resolveXiaoEPreferredBaseUrl,
|