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.
Files changed (197) hide show
  1. package/README.md +4 -2
  2. package/dist/chunks/{archive-ENZYBBME.js → archive-J4I6MCKF.js} +2 -2
  3. package/dist/chunks/{archive-oa-YWLEC5V4.js → archive-oa-BRZKKTO4.js} +2 -2
  4. package/dist/chunks/{asset-OOV6DWPA.js → asset-L7D4FAOZ.js} +2 -2
  5. package/dist/chunks/{asset-idle-RE632MY5.js → asset-idle-DADLLV75.js} +2 -2
  6. package/dist/chunks/{attachment-content-RWN2FCLL.js → attachment-content-K4C7VLWQ.js} +3 -3
  7. package/dist/chunks/{blog-PEPOJAL7.js → blog-BVGQ7NZL.js} +2 -2
  8. package/dist/chunks/{caizhilian-WYIQDVPJ.js → caizhilian-SAADNFD6.js} +2 -2
  9. package/dist/chunks/{calendar-CIARBAOX.js → calendar-Q7NQY5Z2.js} +61 -23
  10. package/dist/chunks/{chunk-F2EQXUEE.js → chunk-3KTFS4IA.js} +397 -159
  11. package/dist/chunks/{chunk-G2JSIUWF.js → chunk-4PD5NWAX.js} +89 -0
  12. package/dist/chunks/{chunk-HJYVHXUQ.js → chunk-4RAE6JXP.js} +1 -1
  13. package/dist/chunks/{chunk-CQHGNCK2.js → chunk-72CKAUAG.js} +41 -8
  14. package/dist/chunks/{chunk-K3RUEEOL.js → chunk-APVFJUQH.js} +2 -2
  15. package/dist/chunks/{chunk-BJGXMFGD.js → chunk-BBKDXQEC.js} +2 -2
  16. package/dist/chunks/chunk-BIPYLLVS.js +501 -0
  17. package/dist/chunks/{chunk-GVPJZXJ2.js → chunk-EKWAQSLU.js} +92 -50
  18. package/dist/chunks/{chunk-XXJOSZTQ.js → chunk-FOAA27U5.js} +381 -57
  19. package/dist/chunks/{chunk-I2HB737U.js → chunk-G4UR6NXN.js} +2 -2
  20. package/dist/chunks/{chunk-YS5DPN4T.js → chunk-GEWYMQME.js} +1 -1
  21. package/dist/chunks/{chunk-P2DAISYW.js → chunk-GHXCDPTM.js} +1 -1
  22. package/dist/chunks/{chunk-L4N7B7ZD.js → chunk-IZ7S7QUS.js} +4 -4
  23. package/dist/chunks/{chunk-NLK2RZKG.js → chunk-JPRO6ER2.js} +122 -2214
  24. package/dist/chunks/{chunk-36DIFZAH.js → chunk-LADPYOWC.js} +2 -2
  25. package/dist/chunks/chunk-LDZQPUIA.js +1238 -0
  26. package/dist/chunks/chunk-NKZRQXST.js +2546 -0
  27. package/dist/chunks/{chunk-EINRJHQ3.js → chunk-QKNKR4RH.js} +3 -3
  28. package/dist/chunks/{chunk-T7JDJJ7H.js → chunk-R4CHUSKC.js} +126 -19
  29. package/dist/chunks/{chunk-EZGFHJFW.js → chunk-SA6VBIHY.js} +88 -15
  30. package/dist/chunks/{chunk-ZXRNHZTE.js → chunk-TTPJJJC4.js} +2 -2
  31. package/dist/chunks/{chunk-KTCB5R5H.js → chunk-W7BEHOSR.js} +2 -2
  32. package/dist/chunks/{chunk-MUQUHKPG.js → chunk-YRSZQUD2.js} +2 -2
  33. package/dist/chunks/{conflict-DRMDOL56.js → conflict-F2OMZRTO.js} +2 -2
  34. package/dist/chunks/{contract-73MERZWN.js → contract-5BETHRSG.js} +2 -2
  35. package/dist/chunks/{cowork-HNGBPD7A.js → cowork-3MN6EQQO.js} +27 -10
  36. package/dist/chunks/create-flow-5FQNNMVO.js +55 -0
  37. package/dist/chunks/{ebuilder-form-OY6DVNRK.js → ebuilder-form-SBHOYBUD.js} +3 -3
  38. package/dist/chunks/{ehr-RAQNEQO7.js → ehr-KMOJULKG.js} +432 -1234
  39. package/dist/chunks/env-LB7NBL2O.js +19 -0
  40. package/dist/chunks/{esb-6XV7C7YV.js → esb-W2PJCFCX.js} +4 -4
  41. package/dist/chunks/factory-6ZFQXQ46.js +30 -0
  42. package/dist/chunks/{fna-XTSRB7G7.js → fna-ZQPCUV4R.js} +2 -2
  43. package/dist/chunks/group-chat-2HHAJN46.js +20 -0
  44. package/dist/chunks/{host-YMBXWFWX.js → host-4CBHGOHT.js} +3 -3
  45. package/dist/chunks/{host-A7J6GDUP.js → host-ATKVNZAT.js} +3 -3
  46. package/dist/chunks/{host-3F5UM5GN.js → host-BQH22NTQ.js} +3 -3
  47. package/dist/chunks/{host-YAQAPYNP.js → host-X2CSLFM6.js} +3 -3
  48. package/dist/chunks/{host-VGPVP7YF.js → host-YTODKMSL.js} +3 -3
  49. package/dist/chunks/{hrm-TLHKC545.js → hrm-FFM4UJFS.js} +4 -4
  50. package/dist/chunks/{im-YOUCFMUK.js → im-VEHKDQPB.js} +8 -8
  51. package/dist/chunks/{invoice-WNBS2B4C.js → invoice-LVIKSIIF.js} +3 -3
  52. package/dist/chunks/{jiuchuanhui-XABWS5RN.js → jiuchuanhui-X6DINO5P.js} +2 -2
  53. package/dist/chunks/{lazy-dispatch-NLZ5UQQI.js → lazy-dispatch-KSWTN5L6.js} +4 -4
  54. package/dist/chunks/{mail-LRYMBFNL.js → mail-VDKRGUD3.js} +9 -4
  55. package/dist/chunks/{meeting-ESXL6MFI.js → meeting-CLC6HP3Z.js} +12 -10
  56. package/dist/chunks/{okr-EOV65SSF.js → okr-CHG4OO3U.js} +2 -2
  57. package/dist/chunks/{plan-YFPVKW6Y.js → plan-XWR75667.js} +2 -2
  58. package/dist/chunks/{project-MDVZUYQW.js → project-5BXOOKMG.js} +40 -23
  59. package/dist/chunks/recruit-stage-DGMFNNDE.js +4507 -0
  60. package/dist/chunks/{registry-VT5Y2HLA.js → registry-7FFOXIAW.js} +4 -4
  61. package/dist/chunks/{registry-QCLZEDAP.js → registry-BKBZPBAJ.js} +10 -8
  62. package/dist/chunks/{registry-YX4CSEMD.js → registry-RHMW6ANW.js} +2 -2
  63. package/dist/chunks/{registry-NYPYMZXG.js → registry-Z43434VG.js} +1 -1
  64. package/dist/chunks/{room-recommend-L3MWH4JW.js → room-recommend-62H7ZQQ6.js} +4 -4
  65. package/dist/chunks/{schedule-UASAVDVD.js → schedule-FNXKH3DQ.js} +4 -4
  66. package/dist/chunks/{workflow-KDGIUCNW.js → workflow-ADHKCAJK.js} +4 -4
  67. package/dist/index.js +33 -28
  68. package/dist/internal/e10/auth/commands.js +110 -56
  69. package/dist/internal/e10/auth/messages.js +6 -0
  70. package/dist/internal/e10/auth/session.js +28 -1
  71. package/dist/internal/e10/auth/xiaoe.js +315 -48
  72. package/dist/internal/e10/auth-recovery.js +36 -5
  73. package/dist/internal/e10/client.js +13 -0
  74. package/dist/internal/e10/context.js +61 -9
  75. package/dist/internal/e10/index.js +1 -1
  76. package/dist/internal/e10/network-error.js +93 -0
  77. package/dist/internal/e10/request-runtime.js +15 -0
  78. package/dist/shortcuts/calendar/operations/read.js +31 -22
  79. package/dist/shortcuts/calendar/operations/write.js +45 -1
  80. package/dist/shortcuts/cowork/operations/discuss-write.js +5 -1
  81. package/dist/shortcuts/cowork/operations/item-write.js +5 -3
  82. package/dist/shortcuts/cowork/operations/member-write.js +3 -1
  83. package/dist/shortcuts/cowork/operations/permission-write.js +5 -1
  84. package/dist/shortcuts/cowork/operations/shared.js +7 -0
  85. package/dist/shortcuts/ehr/operations/attend-write.js +43 -1
  86. package/dist/shortcuts/ehr/operations/hr-contact.js +7 -4
  87. package/dist/shortcuts/ehr/operations/hr-report.js +13 -7
  88. package/dist/shortcuts/ehr/operations/recruit-candidate-import.js +134 -59
  89. package/dist/shortcuts/ehr/operations/recruit-write.js +262 -17
  90. package/dist/shortcuts/ehr/operations/recruit.js +10 -4
  91. package/dist/shortcuts/ehr/operations/shared.js +47 -0
  92. package/dist/shortcuts/hrm/operations/org.js +118 -0
  93. package/dist/shortcuts/index.js +5 -0
  94. package/dist/shortcuts/mail/operations/mail-send.js +8 -2
  95. package/dist/shortcuts/meeting/operations/eb/catalog.js +9 -2
  96. package/dist/shortcuts/meeting/operations/eb/create-flow.js +461 -127
  97. package/dist/shortcuts/meeting/operations/eb/crm-search.js +87 -5
  98. package/dist/shortcuts/meeting/operations/eb/factory.js +33 -0
  99. package/dist/shortcuts/meeting/operations/eb/flow-memory.js +49 -0
  100. package/dist/shortcuts/meeting/operations/eb/group-chat.js +605 -0
  101. package/dist/shortcuts/meeting/operations/eb/index.js +2 -0
  102. package/dist/shortcuts/meeting/operations/eb/person-cache.js +96 -0
  103. package/dist/shortcuts/meeting/operations/eb/room-recommend.js +44 -6
  104. package/dist/shortcuts/meeting/operations/eb/room-summary.js +2 -0
  105. package/dist/shortcuts/meeting/operations/eb/usage-cache.js +99 -0
  106. package/dist/shortcuts/meeting/operations/from-group-chat.js +35 -12
  107. package/dist/shortcuts/project/operations/read.js +6 -25
  108. package/dist/shortcuts/project/operations/shared.js +22 -0
  109. package/dist/shortcuts/project/operations/write.js +28 -2
  110. package/dist/shortcuts/recruit-stage/context.js +119 -0
  111. package/dist/shortcuts/recruit-stage/continuation.js +73 -0
  112. package/dist/shortcuts/recruit-stage/errors.js +65 -0
  113. package/dist/shortcuts/recruit-stage/host.js +109 -0
  114. package/dist/shortcuts/recruit-stage/index.js +115 -0
  115. package/dist/shortcuts/recruit-stage/manifest.js +29 -0
  116. package/dist/shortcuts/recruit-stage/operations/interview-arrange.js +722 -0
  117. package/dist/shortcuts/recruit-stage/operations/interview-feedback.js +269 -0
  118. package/dist/shortcuts/recruit-stage/operations/jd-create.js +630 -0
  119. package/dist/shortcuts/recruit-stage/operations/list.js +431 -0
  120. package/dist/shortcuts/recruit-stage/operations/registry.js +38 -0
  121. package/dist/shortcuts/recruit-stage/operations/resume-import.js +1198 -0
  122. package/dist/shortcuts/recruit-stage/operations/search.js +158 -0
  123. package/dist/shortcuts/recruit-stage/operations/types.js +25 -0
  124. package/dist/shortcuts/recruit-stage/school-tiers.json +318 -0
  125. package/dist/shortcuts/recruit-stage/shared.js +608 -0
  126. package/dist/shortcuts/workflow/operations/form.js +21 -2
  127. package/dist/shortcuts/workflow/operations/todoSmartConvert/aigroupRules.js +52 -1
  128. package/dist/shortcuts/workflow/operations/todoSmartConvert/detailFieldRules.js +4 -2
  129. package/dist/shortcuts/workflow/operations/todoSmartConvert/summaryCache.js +19 -11
  130. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailCache.js +17 -24
  131. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoDetailFetcher.js +14 -9
  132. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.collect.js +78 -10
  133. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.core.js +3 -1
  134. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.detail.js +17 -11
  135. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.group.js +16 -40
  136. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.groupSummary.js +3 -2
  137. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.js +52 -15
  138. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.pipeline.js +16 -1
  139. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.smartGroup.js +151 -63
  140. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.subGroup.js +56 -0
  141. package/dist/shortcuts/workflow/operations/todoSmartConvert/todoSmartConvert.summary.js +53 -16
  142. package/docs/e10-auth.md +22 -1
  143. package/docs/operation-manual.md +8 -0
  144. package/package.json +1 -1
  145. package/scripts/install-skill-to-xiaoe.mjs +105 -0
  146. package/scripts/mcp-meeting.mjs +234 -0
  147. package/scripts/package-skill.mjs +4 -2
  148. package/skill-template/business-info.json +24 -0
  149. package/skill-template/domains/recruit-stage.md +29 -0
  150. package/skills/weaver-e10-calendar/SKILL.md +2 -1
  151. package/skills/weaver-e10-calendar/references/calendar-write.md +54 -0
  152. package/skills/weaver-e10-cowork/SKILL.md +1 -1
  153. package/skills/weaver-e10-cowork/references/cowork-write.md +3 -1
  154. package/skills/weaver-e10-jucailin/SKILL.md +1 -1
  155. package/skills/weaver-e10-jucailin/references/attend-write.md +8 -0
  156. package/skills/weaver-e10-jucailin/references/hr-contact.md +8 -0
  157. package/skills/weaver-e10-jucailin/references/hr-report.md +8 -0
  158. package/skills/weaver-e10-jucailin/references/recruit-create.md +2 -2
  159. package/skills/weaver-e10-jucailin/references/recruit-read.md +1 -1
  160. package/skills/weaver-e10-jucailin/references/recruit-write.md +4 -3
  161. package/skills/weaver-e10-mail/SKILL.md +1 -1
  162. package/skills/weaver-e10-mail/references/mail-send.md +2 -0
  163. package/skills/weaver-e10-meeting/SKILL.md +119 -26
  164. package/skills/weaver-e10-meeting/references/meeting-minute-file.md +25 -11
  165. package/skills/weaver-e10-meeting.zip +0 -0
  166. package/skills/weaver-e10-recruit-stage/SKILL.md +226 -0
  167. package/skills/weaver-e10-recruit-stage/agents/openai.yaml +119 -0
  168. package/skills/weaver-e10-recruit-stage/lib/recruit-xiaoe-file.mjs +188 -0
  169. package/skills/weaver-e10-recruit-stage/references/recruit-arrange-interview.md +322 -0
  170. package/skills/weaver-e10-recruit-stage/references/recruit-capability-check.md +127 -0
  171. package/skills/weaver-e10-recruit-stage/references/recruit-check-install.md +65 -0
  172. package/skills/weaver-e10-recruit-stage/references/recruit-detail-process.md +63 -0
  173. package/skills/weaver-e10-recruit-stage/references/recruit-edit-interview-feedback.md +142 -0
  174. package/skills/weaver-e10-recruit-stage/references/recruit-jd-create.md +73 -0
  175. package/skills/weaver-e10-recruit-stage/references/recruit-jd-template.md +56 -0
  176. package/skills/weaver-e10-recruit-stage/references/recruit-list-candidate.md +101 -0
  177. package/skills/weaver-e10-recruit-stage/references/recruit-list-interview.md +148 -0
  178. package/skills/weaver-e10-recruit-stage/references/recruit-match-candidates.md +77 -0
  179. package/skills/weaver-e10-recruit-stage/references/recruit-output-links.md +59 -0
  180. package/skills/weaver-e10-recruit-stage/references/recruit-resolve-creator.md +69 -0
  181. package/skills/weaver-e10-recruit-stage/references/recruit-resolve-metadata.md +241 -0
  182. package/skills/weaver-e10-recruit-stage/references/recruit-resume-import.md +438 -0
  183. package/skills/weaver-e10-recruit-stage/references/recruit-resume-parse.md +128 -0
  184. package/skills/weaver-e10-recruit-stage/references/recruit-search-candidate.md +146 -0
  185. package/skills/weaver-e10-recruit-stage/references/recruit-urge-feedback.md +69 -0
  186. package/skills/weaver-e10-shared/SKILL.md +2 -2
  187. package/skills/weaver-e10-shared/references/e10-auth-and-session.md +4 -2
  188. package/skills/weaver-e10-shijingran/SKILL.md +3 -2
  189. package/skills/weaver-e10-shijingran/references/operations.md +3 -1
  190. package/skills/weaver-e10-shijingran/references/source-manifest.json +41 -40
  191. package/skills/weaver-e10-shijingran/references/write-operations.md +2 -0
  192. package/skills/weaver-e10-workflow/SKILL.md +7 -1
  193. package/skills/weaver-e10-workflow/aigroup/default.json +23 -9
  194. package/skills/weaver-e10-workflow/references/todo-smart-convert.md +37 -21
  195. package/skills/weaver-e10-workflow/tools/todo-summary.cjs +135 -43
  196. package/skills/weaver-e10-yepiaotong/SKILL.md +9 -10
  197. 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 asRecord(value) {
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 = asRecord(data);
367
- const nested = asRecord(root.data);
368
- const currentUser = asRecord(root.currentUser || nested.currentUser);
369
- const currentTenant = asRecord(root.currentTenant || nested.currentTenant);
370
- const department = asRecord(currentUser.department);
371
- const position = asRecord(currentUser.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
- return { baseUrl: normalizeUrl(baseUrl), eteamsId, source, rawCookie };
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 readXiaoECredentialRecord(tokenData, "xiaoeUserData/tokens.py", baseUrl);
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 readXiaoECredentialRecord(tokenData, XIAOE_BUNDLED_ENV_SCRIPT_SOURCE, baseUrl);
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 tokenScript = options.allowTokenScript !== false && hasXiaoETokenScript(env, allowLocalDiscovery);
1323
- const clientCredential = hasXiaoEClientCredential(env, allowLocalDiscovery);
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 new CliError("XiaoE client token endpoint redirected too many times.", 3 /* AuthError */);
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 new CliError("XiaoE client token endpoint returned a redirect without Location.", 3 /* AuthError */);
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 new CliError("XiaoE client token endpoint attempted an unsafe cross-origin redirect.", 3 /* AuthError */);
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
- throw new CliError(`XiaoE client token endpoint returned HTTP ${resp?.status || 0}.`, 3 /* AuthError */);
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(() => null);
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 new CliError("XiaoE client token endpoint returned invalid JSON.", 3 /* AuthError */);
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 new CliError(`XiaoE client token exchange failed with business code ${codeText}.`, 3 /* AuthError */);
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 readXiaoECredentialRecord(payload, credential.source, resolvedBaseUrl);
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 resp = await fetch(`${baseUrl}/api/baseserver/layout/teamsCheck?clientType=not_xinchuang&client=WEB&domainName=${encodeURIComponent(baseUrl)}`, {
1430
- method: "POST",
1431
- headers: {
1432
- accept: "application/json",
1433
- "content-type": "application/json",
1434
- eteamsid: eteamsId,
1435
- cookie: buildE10CookieHeader(rawCookie, eteamsId, agentType),
1436
- "user-agent": agentType ? `AgentType=${agentType},IsAgent=true` : "weaver-work-cli",
1437
- origin: baseUrl
1438
- },
1439
- redirect: "manual"
1440
- });
1441
- const data = await resp.json().catch(() => ({}));
1442
- return { userInfo: readTeamsCheckUserInfo(resp, data), setCookie: extractRawSetCookie(resp) };
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
- throw new CliError("Could not resolve userId. Check whether XiaoE unified login is valid for this E10 domain.", 3 /* AuthError */);
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
- if (!baseUrl && !mayUseTokenScript) return null;
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 (hasXiaoEPlatformCredential(env)) {
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
- if (!credential && options.allowBundledEnvScript && hasXiaoEPlatformCredential(env)) {
1519
- const scriptPath = xiaoEBundledEnvScriptPath();
1520
- if (!scriptPath) {
1521
- options.logger?.warn("CLI-bundled xiaoe_env.py was not found; will try desktop XiaoE credential sources next.");
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
- options.logger?.info("Trying CLI-bundled xiaoe_env.py compatibility credential...");
1524
- try {
1525
- credential = await resolveXiaoEBundledEnvScriptCredential(baseUrl || DEFAULT_E10_BASE_URL, env);
1526
- } catch (error) {
1527
- const message = error instanceof Error ? error.message : String(error);
1528
- options.logger?.warn("CLI-bundled xiaoe_env.py failed. " + message);
1529
- }
1530
- if (!credential) {
1531
- options.logger?.warn("CLI-bundled xiaoe_env.py did not return usable ETEAMSID; will try xiaoeUserData/tokens.py next.");
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) return null;
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
- return await saveXiaoEUnifiedLogin({
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,