weaver-work-cli 0.1.6 → 0.1.7

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 (225) hide show
  1. package/README.md +14 -9
  2. package/dist/cmd/skills/index.js +60 -0
  3. package/dist/internal/e10/auth/commands.js +44 -31
  4. package/dist/internal/e10/auth/session.js +44 -3
  5. package/dist/internal/e10/auth/xiaoe.js +363 -11
  6. package/dist/internal/e10/context.js +4 -2
  7. package/dist/internal/skills/detector.js +42 -0
  8. package/dist/internal/skills/install.js +50 -3
  9. package/dist/shortcuts/archive/render/search-format.js +12 -3
  10. package/dist/shortcuts/ebuilder-form/continuation.js +70 -0
  11. package/dist/shortcuts/ebuilder-form/errors.js +54 -0
  12. package/dist/shortcuts/ebuilder-form/host.js +1238 -0
  13. package/dist/shortcuts/ebuilder-form/index.js +108 -0
  14. package/dist/shortcuts/ebuilder-form/manifest.js +347 -0
  15. package/dist/shortcuts/ebuilder-form/operations/read.js +157 -0
  16. package/dist/shortcuts/ebuilder-form/operations/registry.js +56 -0
  17. package/dist/shortcuts/ebuilder-form/operations/shared.js +132 -0
  18. package/dist/shortcuts/ebuilder-form/operations/types.js +19 -0
  19. package/dist/shortcuts/ebuilder-form/operations/write.js +277 -0
  20. package/dist/shortcuts/ebuilder-form/operations.js +8 -0
  21. package/dist/shortcuts/ehr/operations/salary.js +2 -140
  22. package/dist/shortcuts/im/continuation.js +70 -0
  23. package/dist/shortcuts/{yimiaoban → im}/errors.js +14 -14
  24. package/dist/shortcuts/{yimiaoban → im}/host.js +26 -26
  25. package/dist/shortcuts/{yimiaoban → im}/index.js +42 -42
  26. package/dist/shortcuts/{yimiaoban → im}/manifest.js +7 -6
  27. package/dist/shortcuts/{yimiaoban → im}/operations/file-user.js +54 -41
  28. package/dist/shortcuts/{yimiaoban → im}/operations/group-read.js +46 -44
  29. package/dist/shortcuts/{yimiaoban → im}/operations/group-write.js +113 -66
  30. package/dist/shortcuts/{yimiaoban → im}/operations/msg-sync.js +164 -141
  31. package/dist/shortcuts/{yimiaoban → im}/operations/msg-write.js +47 -47
  32. package/dist/shortcuts/{yimiaoban → im}/operations/person.js +10 -10
  33. package/dist/shortcuts/{yimiaoban → im}/operations/registry.js +10 -8
  34. package/dist/shortcuts/{yimiaoban → im}/operations/session.js +82 -83
  35. package/dist/shortcuts/im/operations/shared.js +442 -0
  36. package/dist/shortcuts/{yimiaoban → im}/operations/types.js +1 -1
  37. package/dist/shortcuts/im/operations/user-remind.js +201 -0
  38. package/dist/shortcuts/{yimiaoban → im}/operations/write-util.js +7 -7
  39. package/dist/shortcuts/{yimiaoban → im}/operations.js +3 -3
  40. package/dist/shortcuts/index.js +10 -2
  41. package/dist/shortcuts/invoice/manifest.js +113 -10
  42. package/dist/shortcuts/invoice/operations/import.js +39 -14
  43. package/dist/shortcuts/invoice/operations/reim.js +38 -18
  44. package/dist/shortcuts/invoice/operations/shared.js +35 -6
  45. package/dist/shortcuts/jiuchuanhui/manifest.js +3 -3
  46. package/dist/shortcuts/jiuchuanhui/operations/registry.js +2 -2
  47. package/dist/shortcuts/{yimiaoban → okr}/continuation.js +10 -10
  48. package/dist/shortcuts/okr/errors.js +70 -0
  49. package/dist/shortcuts/okr/host.js +169 -0
  50. package/dist/shortcuts/okr/index.js +155 -0
  51. package/dist/shortcuts/okr/manifest.js +70 -0
  52. package/dist/shortcuts/okr/operations/link.js +305 -0
  53. package/dist/shortcuts/okr/operations/read.js +481 -0
  54. package/dist/shortcuts/okr/operations/registry.js +31 -0
  55. package/dist/shortcuts/okr/operations/shared.js +381 -0
  56. package/dist/shortcuts/okr/operations/types.js +88 -0
  57. package/dist/shortcuts/okr/operations/write.js +838 -0
  58. package/dist/shortcuts/okr/operations.js +8 -0
  59. package/dist/shortcuts/project/continuation.js +70 -0
  60. package/dist/shortcuts/project/errors.js +53 -0
  61. package/dist/shortcuts/project/host.js +160 -0
  62. package/dist/shortcuts/project/index.js +106 -0
  63. package/dist/shortcuts/project/manifest.js +36 -0
  64. package/dist/shortcuts/project/operations/read.js +551 -0
  65. package/dist/shortcuts/project/operations/registry.js +31 -0
  66. package/dist/shortcuts/project/operations/shared.js +68 -0
  67. package/dist/shortcuts/project/operations/types.js +39 -0
  68. package/dist/shortcuts/project/operations/write.js +266 -0
  69. package/dist/shortcuts/project/operations.js +8 -0
  70. package/dist/shortcuts/workflow/continuation.js +508 -0
  71. package/dist/shortcuts/workflow/endpoints.js +149 -0
  72. package/dist/shortcuts/workflow/errors.js +112 -0
  73. package/dist/shortcuts/workflow/host.js +224 -0
  74. package/dist/shortcuts/workflow/index.js +116 -0
  75. package/dist/shortcuts/workflow/manifest.js +30 -0
  76. package/dist/shortcuts/workflow/operations/form.js +4159 -0
  77. package/dist/shortcuts/workflow/operations/read.js +3778 -0
  78. package/dist/shortcuts/workflow/operations/registry.js +33 -0
  79. package/dist/shortcuts/workflow/operations/shared.js +167 -0
  80. package/dist/shortcuts/workflow/operations/types.js +44 -0
  81. package/dist/shortcuts/workflow/operations/write.js +1991 -0
  82. package/dist/shortcuts/workflow/operations.js +119 -0
  83. package/dist/shortcuts/workflow/state.js +182 -0
  84. package/docs/SKILL.md +5 -3
  85. package/docs/_catalog.md +10 -1
  86. package/docs/agent-invoice.md +2 -2
  87. package/docs/agent-skill-install.md +2 -2
  88. package/docs/e10-auth.md +3 -1
  89. package/docs/ebuilder-form.md +38 -0
  90. package/docs/im.md +104 -0
  91. package/docs/invoice.md +5 -5
  92. package/docs/okr.md +122 -0
  93. package/docs/operation-manual.md +10 -7
  94. package/docs/project.md +69 -0
  95. package/docs/skill-review-2026-09-19.md +68 -0
  96. package/package.json +3 -2
  97. package/scripts/package-skill.mjs +38 -11
  98. package/scripts/sync-connector-skills.mjs +172 -0
  99. package/skill-template/business-info.json +357 -16
  100. package/skill-template/domains/ebuilder-form.md +5 -0
  101. package/skill-template/domains/okr.md +18 -0
  102. package/skill-template/domains/shijingran.md +3 -0
  103. package/skill-template/domains/skill-maker.md +4 -4
  104. package/skill-template/domains/workflow.md +22 -0
  105. package/skill-template/domains/yepiaotong.md +4 -2
  106. package/skill-template/domains/yimiaoban.md +13 -10
  107. package/skill-template/product.json +5 -0
  108. package/skill-template/skill-template.md +1 -0
  109. package/skills/weaver-e10-calendar/SKILL.md +5 -1
  110. package/skills/weaver-e10-calendar/references/calendar-query.md +7 -0
  111. package/skills/weaver-e10-calendar/references/source-manifest.json +314 -32
  112. package/skills/weaver-e10-ebuilder-form/SKILL.md +123 -0
  113. package/skills/weaver-e10-ebuilder-form/references/context-routing.md +90 -0
  114. package/skills/weaver-e10-ebuilder-form/references/custom-api.md +86 -0
  115. package/skills/weaver-e10-ebuilder-form/references/disabled-capabilities.md +50 -0
  116. package/skills/weaver-e10-ebuilder-form/references/fields-browser.md +100 -0
  117. package/skills/weaver-e10-ebuilder-form/references/list-nlist.md +91 -0
  118. package/skills/weaver-e10-ebuilder-form/references/openapi-read.md +74 -0
  119. package/skills/weaver-e10-ebuilder-form/references/openapi-write.md +86 -0
  120. package/skills/weaver-e10-ebuilder-form/references/source-manifest.json +107 -0
  121. package/skills/weaver-e10-esb/SKILL.md +1 -1
  122. package/skills/weaver-e10-esb/references/source-manifest.json +15 -14
  123. package/skills/weaver-e10-hrm/SKILL.md +1 -1
  124. package/skills/weaver-e10-hrm/references/source-manifest.json +357 -38
  125. package/skills/weaver-e10-jiuchuanhui/SKILL.md +22 -4
  126. package/skills/weaver-e10-jiuchuanhui/references/clue.md +4 -2
  127. package/skills/weaver-e10-jiuchuanhui/references/contact.md +1 -1
  128. package/skills/weaver-e10-jiuchuanhui/references/customer.md +3 -3
  129. package/skills/weaver-e10-jiuchuanhui/references/disabled-capabilities.md +1 -1
  130. package/skills/weaver-e10-jiuchuanhui/references/discovery-config.md +10 -10
  131. package/skills/weaver-e10-jiuchuanhui/references/general-helpers.md +3 -3
  132. package/skills/weaver-e10-jiuchuanhui/references/sale.md +7 -7
  133. package/skills/weaver-e10-jiuchuanhui/references/source-manifest.json +3 -3
  134. package/skills/weaver-e10-jucailin/SKILL.md +2 -2
  135. package/skills/weaver-e10-mail/SKILL.md +22 -6
  136. package/skills/weaver-e10-meeting/SKILL.md +22 -1
  137. package/skills/weaver-e10-okr/SKILL.md +139 -0
  138. package/skills/weaver-e10-okr/references/okr-align.md +59 -0
  139. package/skills/weaver-e10-okr/references/okr-keyresult.md +68 -0
  140. package/skills/weaver-e10-okr/references/okr-link-routing.md +67 -0
  141. package/skills/weaver-e10-okr/references/okr-query.md +105 -0
  142. package/skills/weaver-e10-okr/references/okr-write.md +94 -0
  143. package/skills/weaver-e10-okr/references/source-manifest.json +672 -0
  144. package/skills/weaver-e10-plan/SKILL.md +3 -3
  145. package/skills/weaver-e10-plan/references/plan-report-write.md +1 -1
  146. package/skills/weaver-e10-plan/references/source-manifest.json +20 -20
  147. package/skills/weaver-e10-qiyecheng/SKILL.md +21 -1
  148. package/skills/weaver-e10-qiyecheng/references/source-manifest.json +17 -17
  149. package/skills/weaver-e10-shared/SKILL.md +79 -11
  150. package/skills/weaver-e10-shared/references/e10-auth-and-session.md +41 -8
  151. package/skills/weaver-e10-shared/references/non-interactive-environment.md +78 -0
  152. package/skills/weaver-e10-shared/references/weaver-e10-installation.md +39 -0
  153. package/skills/weaver-e10-shijingran/SKILL.md +83 -0
  154. package/skills/weaver-e10-shijingran/references/field-resolution.md +105 -0
  155. package/skills/weaver-e10-shijingran/references/operations.md +154 -0
  156. package/skills/weaver-e10-shijingran/references/source-manifest.json +1380 -0
  157. package/skills/weaver-e10-shijingran/references/write-operations.md +90 -0
  158. package/skills/weaver-e10-skill-maker/SKILL.md +26 -9
  159. package/skills/weaver-e10-skill-maker/references/business-skill-generation.md +39 -8
  160. package/skills/weaver-e10-skill-maker/references/detector-validation.md +25 -8
  161. package/skills/weaver-e10-skill-maker/references/module-cli-generation.md +66 -5
  162. package/skills/weaver-e10-skill-maker/references/module-gap-audit-and-repair.md +86 -0
  163. package/skills/weaver-e10-skill-maker/references/source-update-detection.md +59 -5
  164. package/skills/weaver-e10-skill-maker/references/weaver-skill-style.md +16 -8
  165. package/skills/weaver-e10-wenshuding/SKILL.md +28 -4
  166. package/skills/weaver-e10-wenshuding/references/archive-search.md +14 -0
  167. package/skills/weaver-e10-wenshuding/references/source-manifest.json +27 -26
  168. package/skills/weaver-e10-workflow/SKILL.md +250 -0
  169. package/skills/weaver-e10-workflow/references/source-manifest.json +1062 -0
  170. package/skills/weaver-e10-workflow/references/workflow-agent-entry.md +96 -0
  171. package/skills/weaver-e10-workflow/references/workflow-batch.md +275 -0
  172. package/skills/weaver-e10-workflow/references/workflow-create.md +182 -0
  173. package/skills/weaver-e10-workflow/references/workflow-edit.md +106 -0
  174. package/skills/weaver-e10-workflow/references/workflow-memory.md +165 -0
  175. package/skills/weaver-e10-workflow/references/workflow-operate.md +153 -0
  176. package/skills/weaver-e10-workflow/references/workflow-query.md +821 -0
  177. package/skills/weaver-e10-workflow/references/workflow-share.md +117 -0
  178. package/skills/weaver-e10-workflow/references/workflow-view.md +189 -0
  179. package/skills/weaver-e10-yepiaotong/SKILL.md +28 -28
  180. package/skills/weaver-e10-yepiaotong/references/invoice-disabled-capabilities.md +11 -5
  181. package/skills/weaver-e10-yepiaotong/references/invoice-import.md +14 -8
  182. package/skills/weaver-e10-yepiaotong/references/invoice-issuing-examples.md +9 -43
  183. package/skills/weaver-e10-yepiaotong/references/invoice-issuing.md +8 -0
  184. package/skills/weaver-e10-yepiaotong/references/invoice-reim.md +13 -17
  185. package/skills/weaver-e10-yepiaotong/references/reim-api-reference.md +6 -7
  186. package/skills/weaver-e10-yepiaotong/references/reim-examples.md +2 -2
  187. package/skills/weaver-e10-yepiaotong/references/source-manifest.json +1155 -553
  188. package/skills/weaver-e10-yimiaoban/SKILL.md +56 -38
  189. package/skills/weaver-e10-yimiaoban/references/ding-write.md +8 -8
  190. package/skills/weaver-e10-yimiaoban/references/error-codes.md +16 -0
  191. package/skills/weaver-e10-yimiaoban/references/field-resolution.md +10 -10
  192. package/skills/weaver-e10-yimiaoban/references/file-user-i18n.md +12 -12
  193. package/skills/weaver-e10-yimiaoban/references/group-read.md +16 -16
  194. package/skills/weaver-e10-yimiaoban/references/group-write.md +17 -15
  195. package/skills/weaver-e10-yimiaoban/references/msg-read.md +21 -17
  196. package/skills/weaver-e10-yimiaoban/references/msg-write.md +10 -10
  197. package/skills/weaver-e10-yimiaoban/references/person.md +6 -6
  198. package/skills/weaver-e10-yimiaoban/references/safety-boundaries.md +15 -11
  199. package/skills/weaver-e10-yimiaoban/references/session-sysmsg.md +11 -10
  200. package/skills/weaver-e10-yimiaoban/references/source-manifest.json +2164 -154
  201. package/skills/weaver-e10-yimiaoban/references/user-remind.md +75 -0
  202. package/skills/weaver-e10-ziguanjia/SKILL.md +4 -2
  203. package/skills/weaver-e10-ziguanjia/references/source-manifest.json +99 -29
  204. package/tools/weaver-skill-detector-1.0.13/SKILL.md +253 -0
  205. package/tools/weaver-skill-detector-1.0.13/_meta.json +6 -0
  206. package/tools/weaver-skill-detector-1.0.13/references/checklist.md +298 -0
  207. package/tools/weaver-skill-detector-1.0.13/scripts/validate_skill.py +4190 -0
  208. package/dist/shortcuts/yimiaoban/operations/shared.js +0 -236
  209. package/docs/yimiaoban.md +0 -86
  210. package/skills/weaver-e10-calendar/product.json +0 -8
  211. package/skills/weaver-e10-esb/product.json +0 -8
  212. package/skills/weaver-e10-hrm/product.json +0 -8
  213. package/skills/weaver-e10-jiuchuanhui/product.json +0 -8
  214. package/skills/weaver-e10-jucailin/product.json +0 -8
  215. package/skills/weaver-e10-mail/product.json +0 -8
  216. package/skills/weaver-e10-meeting/product.json +0 -8
  217. package/skills/weaver-e10-plan/product.json +0 -8
  218. package/skills/weaver-e10-qiyecheng/product.json +0 -8
  219. package/skills/weaver-e10-skill-maker/product.json +0 -8
  220. package/skills/weaver-e10-wenshuding/product.json +0 -8
  221. package/skills/weaver-e10-yepiaotong/product.json +0 -8
  222. package/skills/weaver-e10-yepiaotong/references/invoice-red.md +0 -261
  223. package/skills/weaver-e10-yimiaoban/product.json +0 -8
  224. package/skills/weaver-e10-ziguanjia/product.json +0 -8
  225. /package/dist/shortcuts/{yimiaoban → im}/operations/msg-parse.js +0 -0
package/README.md CHANGED
@@ -154,8 +154,9 @@ weaver-work-cli skills install yepiaotong --target-dir "$HOME/.workbuddy/skills"
154
154
  ```
155
155
 
156
156
  如果要让 Agent 根据用户提供的新业务模块文档或代码同步生成/更新业务 CLI 和
157
- weaver 风格的业务 Skill,在生成后按泛微技能检测工具做静态质检,并在检测
158
- 通过后询问是否安装到当前智能体,可安装 Skill Maker:
157
+ weaver 风格的业务 Skill,每次创建或更新 Skill 后先询问是否现在进行 Skill
158
+ 质检,用户确认后通过随包 `weaver-skill-detector-1.0.13` 做静态质检,并在
159
+ 检测通过后询问是否安装到当前智能体,可安装 Skill Maker:
159
160
 
160
161
  ```text
161
162
  weaver-work-cli skills install skill-maker
@@ -211,13 +212,17 @@ weaver-work-cli auth login --base-url "https://weapp.xxx.cn"
211
212
  weaver-work-cli auth oidc --base-url "https://weapp.xxx.cn"
212
213
  ```
213
214
 
214
- 在小 E 宿主环境中,`auth login` / `auth oidc` / `auth xiaoe` 会先读取宿主注入的
215
- `XIAOE_*` 环境变量,匹配当前登录域名对应的统一登录凭证。匹配成功时直接保存登录态,
216
- 并固定使用 `agentType=Xiao.E`;未显式传域名时,会优先使用小 E 环境变量里的首个
217
- 支持域名,其次才使用当前 profile 配置,仍没有支持域名时保留资料包默认域名
218
- `https://www.e-cology.com.cn`。小 E 凭证校验失败、当前域名不在支持范围内,
219
- 或客户切换了访问域名时,会自动降级到原浏览器 OAuth2.0 登录。业务命令在未显式
220
- 指定 `--auth` / `--profile` 时,也会自动优先尝试小 E 统一登录。也可以显式使用:
215
+ XiaoE 宿主环境中,`auth login` / `auth oidc` / `auth xiaoe` 会优先读取宿主
216
+ `xiaoeUserData/tokens.py`;脚本不可用(不存在、执行失败,或所用 Python 缺少
217
+ `requests` 等依赖)时,CLI 会改用内置的原生等价实现读取 XiaoE 客户端本地会话
218
+ (`XiaoE/Robots/*/user_settings.json` `XIAOE_USER_TOKEN`)换取 `eteamId`,
219
+ 不依赖本机 Python 环境;仍没有可用凭证时,再读取宿主注入的 `XIAOE_*`
220
+ 环境变量,匹配当前登录域名对应的统一登录凭证。匹配成功时直接保存登录态,
221
+ 并固定使用 `agentType=XiaoE`;凭证只返回 `eteamId` 时,会使用凭证中的
222
+ 域名或资料包默认域名 `https://www.e-cology.com.cn`;仍没有可用凭证时才考虑当前
223
+ profile 配置。XiaoE 凭证校验失败、当前域名不在支持范围内,
224
+ 或客户切换了访问域名时,`auth xiaoe` 会先反馈未拿到登录信息的原因,再自动降级到原浏览器 OAuth2.0 登录。业务命令在未显式
225
+ 指定 `--auth` / `--profile` 时,也会自动优先尝试 XiaoE 统一登录。也可以显式使用:
221
226
 
222
227
  ```text
223
228
  weaver-work-cli auth xiaoe
@@ -1,6 +1,8 @@
1
1
  import { existsSync } from 'node:fs';
2
+ import { spawnSync } from 'node:child_process';
2
3
  import { fileURLToPath } from 'node:url';
3
4
  import { CliError } from '../../core/errors.js';
5
+ import { resolveDetectorInfo } from '../../internal/skills/detector.js';
4
6
  import { defaultCodexSkillsRoot, installPackagedSkills } from '../../internal/skills/install.js';
5
7
  import { SkillReader } from '../../internal/skills/reader.js';
6
8
  const SKILLS_DIR = fileURLToPath(new URL('../../../skills/', import.meta.url));
@@ -16,6 +18,31 @@ function commandOptions(value) {
16
18
  const opts = value.opts();
17
19
  return opts && typeof opts === 'object' ? opts : {};
18
20
  }
21
+ function pythonInvocation(opts) {
22
+ if (opts.python)
23
+ return { command: opts.python, args: [] };
24
+ if (process.platform === 'win32')
25
+ return { command: 'py', args: ['-3'] };
26
+ return { command: 'python3', args: [] };
27
+ }
28
+ function detectorArgs(target, opts, globalJson) {
29
+ const args = [target];
30
+ if (opts.json || globalJson)
31
+ args.push('--json');
32
+ if (opts.noHtml || opts.html === false)
33
+ args.push('--no-html');
34
+ if (opts.out)
35
+ args.push('--out', opts.out);
36
+ if (typeof opts.html === 'string')
37
+ args.push('--html', opts.html);
38
+ if (opts.platform)
39
+ args.push('--platform', opts.platform);
40
+ if (opts.marketCatalog)
41
+ args.push('--market-catalog', opts.marketCatalog);
42
+ if (opts.marketLive)
43
+ args.push('--market-live');
44
+ return args;
45
+ }
19
46
  export const skillsCommand = {
20
47
  name: 'skills',
21
48
  description: 'Read packaged agent skill content',
@@ -68,5 +95,38 @@ export const skillsCommand = {
68
95
  ].join('\n'),
69
96
  });
70
97
  }));
98
+ skills.command('validate')
99
+ .description('Validate a generated skill using the packaged Weaver skill detector')
100
+ .argument('<target>', 'skill directory, SKILL.md, or skill zip')
101
+ .option('--detector-dir <path>', 'override detector directory; defaults to the packaged detector')
102
+ .option('--python <path>', 'Python executable; defaults to python3, or py -3 on Windows')
103
+ .option('--json', 'ask the detector to print JSON')
104
+ .option('--no-html', 'disable detector HTML report output')
105
+ .option('--out <path>', 'write detector markdown report')
106
+ .option('--html <path>', 'write detector HTML report')
107
+ .option('--platform <platform>', 'detector platform: weaver or qwenwork')
108
+ .option('--market-catalog <path>', 'detector market catalog JSON')
109
+ .option('--market-live', 'enable detector live market checks')
110
+ .action(action((ctx, target, options) => {
111
+ if (typeof target !== 'string')
112
+ throw new CliError('target must be a string');
113
+ const opts = options && typeof options === 'object' ? options : {};
114
+ const detector = resolveDetectorInfo(opts.detectorDir);
115
+ const python = pythonInvocation(opts);
116
+ const child = spawnSync(python.command, [
117
+ ...python.args,
118
+ detector.scriptPath,
119
+ ...detectorArgs(target, opts, Boolean(ctx.getGlobalOptions().json)),
120
+ ], { stdio: 'inherit' });
121
+ if (child.error)
122
+ throw new CliError(`failed to run Python detector: ${child.error.message}`);
123
+ if (typeof child.status === 'number') {
124
+ process.exitCode = child.status;
125
+ return;
126
+ }
127
+ if (child.signal)
128
+ throw new CliError(`detector terminated by signal: ${child.signal}`);
129
+ throw new CliError('detector exited without a status code');
130
+ }));
71
131
  },
72
132
  };
@@ -4,8 +4,8 @@ import { CliError, ExitCode } from '../../../core/errors.js';
4
4
  import { clearInvoiceTokenForSession } from '../../../shortcuts/invoice/host.js';
5
5
  import { buildE10CookieHeader, E10AuthSession, clearProfileAuthFile, extractRawSetCookie, findAuthFile, getActiveProfile, getProfileAuthPath, getProfileDir, listProfiles, profileNameFromUrl, readProfileConfig, readTeamsCheckUserInfo, saveAuthFile, saveProfileConfig, setActiveProfile, } from './session.js';
6
6
  import { getE10AuthRoot } from './paths.js';
7
- import { XIAOE_AGENT_TYPE, hasXiaoEEnv, resolveXiaoEPreferredBaseUrl, resolveXiaoEUnifiedLoginCredential, } from './xiaoe.js';
8
- export { DEFAULT_E10_BASE_URL, XIAOE_AGENT_TYPE, hasXiaoEEnv, resolveXiaoEDefaultBaseUrl, resolveXiaoEPreferredBaseUrl, resolveXiaoEUnifiedLoginCredential, } from './xiaoe.js';
7
+ import { XIAOE_AGENT_TYPE, hasXiaoEEnv, resolveXiaoEPreferredBaseUrl, tryXiaoEUnifiedLogin as tryXiaoEUnifiedSessionLogin, } from './xiaoe.js';
8
+ export { DEFAULT_E10_BASE_URL, XIAOE_AGENT_TYPE, hasXiaoEEnv, hasXiaoETokenScript, resolveXiaoEDefaultBaseUrl, resolveXiaoEPreferredBaseUrl, resolveXiaoEUnifiedLoginCredential, } from './xiaoe.js';
9
9
  const DEFAULT_AGENT_TYPE = 'weaver-work-cli';
10
10
  const EXPLICIT_AGENT_TYPE_ENV_KEYS = [
11
11
  'WEAVER_AGENT_TYPE',
@@ -83,8 +83,9 @@ function formatAuthStatus(status) {
83
83
  if (!status.loggedIn) {
84
84
  return [
85
85
  'Not logged in.',
86
- 'Run: weaver-work-cli auth login --base-url <url> --agent_type <agent_type>',
87
- 'Or: weaver-work-cli auth set --eteamsid <id> --base-url <url> --agent_type <agent_type>',
86
+ 'In the XiaoE host, run: weaver-work-cli auth xiaoe',
87
+ 'Otherwise: weaver-work-cli auth login --base-url <url> --agent_type <agent_type>',
88
+ 'Or: weaver-work-cli auth set --eteamsid <id> --base-url <url> --agent_type <agent_type>',
88
89
  ].join('\n');
89
90
  }
90
91
  const lines = [
@@ -115,6 +116,10 @@ function formatLoginResult(result) {
115
116
  'baseUrl: ' + result.baseUrl,
116
117
  'profile: ' + result.profile,
117
118
  'authFile: ' + result.authFile,
119
+ ...(result.loginSource ? ['loginSource: ' + result.loginSource] : []),
120
+ ...(result.credentialSourceStep ? ['credentialSourceStep: ' + result.credentialSourceStep] : []),
121
+ ...(result.credentialSourceType ? ['credentialSourceType: ' + result.credentialSourceType] : []),
122
+ ...(result.credentialSourceLabel ? ['credentialSourceLabel: ' + result.credentialSourceLabel] : []),
118
123
  ].join('\n');
119
124
  }
120
125
  async function clearInvoiceTokenCache(profile, authData) {
@@ -246,26 +251,16 @@ async function saveEteamsIdLogin(input) {
246
251
  version: input.version || '',
247
252
  };
248
253
  }
249
- async function tryXiaoEUnifiedLogin(ctx, baseUrl, tenantKeyFallback, profileHint) {
250
- const credential = resolveXiaoEUnifiedLoginCredential(baseUrl, ctx.env);
251
- if (!credential)
252
- return null;
253
- ctx.logger.info('Detected XiaoE unified login for this E10 domain. Trying XiaoE auth...');
254
- try {
255
- return await saveEteamsIdLogin({
256
- baseUrl,
257
- passportUrl: baseUrl,
258
- eteamsId: credential.eteamsId,
259
- tenantKeyFallback,
260
- agentType: XIAOE_AGENT_TYPE,
261
- profileHint,
262
- });
263
- }
264
- catch (error) {
265
- const message = error instanceof Error ? error.message : String(error);
266
- ctx.logger.warn('XiaoE unified login failed; falling back to browser OAuth. ' + message);
267
- return null;
268
- }
254
+ async function tryXiaoEUnifiedLogin(ctx, baseUrl, tenantKeyFallback, profileHint, allowTokenScript = false) {
255
+ const login = await tryXiaoEUnifiedSessionLogin({
256
+ env: ctx.env,
257
+ baseUrl,
258
+ tenantKeyFallback,
259
+ profileHint,
260
+ allowTokenScript,
261
+ logger: ctx.logger,
262
+ });
263
+ return login?.result || null;
269
264
  }
270
265
  async function oidcExchange(code, redirectUri, baseUrl, tenantKeyFallback, agentTypeFallback, profileHint) {
271
266
  const base = normalizeUrl(baseUrl);
@@ -361,7 +356,15 @@ async function oidcExchange(code, redirectUri, baseUrl, tenantKeyFallback, agent
361
356
  version,
362
357
  };
363
358
  }
364
- async function runBrowserLogin(ctx, options) {
359
+ function xiaoEUnifiedLoginUnavailableMessage(baseUrl) {
360
+ return [
361
+ '未获取到可用的 XiaoE 统一登录信息,准备降级打开网页登录。',
362
+ baseUrl ? `当前 E10 baseUrl: ${baseUrl}。` : '未从 XiaoE 凭证中解析到 E10 baseUrl。',
363
+ 'CLI 已依次尝试宿主 xiaoeUserData/tokens.py、内置 XiaoE 客户端凭证(XiaoE/Robots/*/user_settings.json)和 XIAOE_* 环境变量。',
364
+ "若脚本存在但报 No module named 'requests',请为脚本使用的 Python 安装 requests,或用 XIAOE_TOKEN_SCRIPT_PYTHON 指定一个自带 requests 的解释器。",
365
+ ].join(' ');
366
+ }
367
+ async function runBrowserLogin(ctx, options, behavior = {}) {
365
368
  const commandOpts = asOptions(options);
366
369
  const globalOptions = ctx.getGlobalOptions();
367
370
  const profileFromGlobal = globalOptions.profile;
@@ -377,14 +380,17 @@ async function runBrowserLogin(ctx, options) {
377
380
  const port = Number.parseInt(portText, 10);
378
381
  const explicitAgentType = optionString(commandOpts, 'agentType', 'agent_type');
379
382
  const agentType = resolveAgentType(commandOpts, ctx.env);
380
- if (!baseUrl)
381
- throw new CliError('Missing --base-url', ExitCode.UsageError);
382
383
  if (!Number.isInteger(port) || port <= 0 || port > 65535) {
383
384
  throw new CliError('Invalid --port value', ExitCode.UsageError);
384
385
  }
385
- const xiaoEResult = await tryXiaoEUnifiedLogin(ctx, baseUrl, tenantKey, profileFromGlobal);
386
+ const xiaoEResult = await tryXiaoEUnifiedLogin(ctx, explicitBaseUrl, tenantKey, profileFromGlobal, behavior.allowXiaoETokenScript === true);
386
387
  if (xiaoEResult)
387
388
  return xiaoEResult;
389
+ if (behavior.explainXiaoEFallback) {
390
+ ctx.logger.warn(xiaoEUnifiedLoginUnavailableMessage(baseUrl));
391
+ }
392
+ if (!baseUrl)
393
+ throw new CliError('Missing --base-url', ExitCode.UsageError);
388
394
  const redirectUri = `http://127.0.0.1:${port}/callback`;
389
395
  const loginUrl = buildE10AuthorizeUrl(baseUrl, redirectUri, agentType);
390
396
  ctx.logger.info('Open browser login: ' + loginUrl);
@@ -502,7 +508,7 @@ function formatWhoami(title, data) {
502
508
  'User-Agent: ' + (data.userAgent || ''),
503
509
  ].join('\n');
504
510
  }
505
- function registerBrowserLoginCommand(auth, action, name, description) {
511
+ function registerBrowserLoginCommand(auth, action, name, description, behavior = {}) {
506
512
  auth.command(name)
507
513
  .description(description)
508
514
  .option('--base-url <url>', 'E10 base URL')
@@ -511,7 +517,7 @@ function registerBrowserLoginCommand(auth, action, name, description) {
511
517
  .option('--agent_type <value>', 'Agent type sent to E10 authorize endpoint')
512
518
  .option('--agent-type <value>', 'Alias of --agent_type')
513
519
  .action(action(async (ctx, options) => {
514
- const result = await runBrowserLogin(ctx, options);
520
+ const result = await runBrowserLogin(ctx, options, behavior);
515
521
  ctx.output.write(result, { text: formatLoginResult(result) });
516
522
  }));
517
523
  }
@@ -548,6 +554,10 @@ export function registerE10AuthCommands(parent, action) {
548
554
  profile: opts.profile || getActiveProfile(),
549
555
  authFile,
550
556
  hasEteamsId: Boolean(session.eteamsId),
557
+ ...(session.loginSource ? { loginSource: session.loginSource } : {}),
558
+ ...(session.credentialSourceStep ? { credentialSourceStep: session.credentialSourceStep } : {}),
559
+ ...(session.credentialSourceType ? { credentialSourceType: session.credentialSourceType } : {}),
560
+ ...(session.credentialSourceLabel ? { credentialSourceLabel: session.credentialSourceLabel } : {}),
551
561
  valid,
552
562
  }
553
563
  : {
@@ -592,7 +602,10 @@ export function registerE10AuthCommands(parent, action) {
592
602
  }));
593
603
  registerBrowserLoginCommand(auth, action, 'login', 'Open browser OAuth2.0 login and save E10 auth');
594
604
  registerBrowserLoginCommand(auth, action, 'oidc', 'Alias of auth login for OAuth2.0 browser login');
595
- registerBrowserLoginCommand(auth, action, 'xiaoe', 'Try XiaoE unified login before browser OAuth2.0 login');
605
+ registerBrowserLoginCommand(auth, action, 'xiaoe', 'Try XiaoE unified login and explain before browser OAuth fallback', {
606
+ allowXiaoETokenScript: true,
607
+ explainXiaoEFallback: true,
608
+ });
596
609
  auth.command('logout')
597
610
  .alias('clear')
598
611
  .description('Clear saved E10 auth for the current or selected profile')
@@ -87,11 +87,33 @@ export function getProfileConfigPath(name) {
87
87
  export function getActiveConfigPath() {
88
88
  return getProfileConfigPath(getActiveProfile());
89
89
  }
90
+ const MULTI_LABEL_PUBLIC_SUFFIXES = new Set([
91
+ 'com.cn', 'net.cn', 'org.cn', 'gov.cn', 'edu.cn', 'ac.cn',
92
+ 'com.hk', 'net.hk', 'org.hk', 'edu.hk', 'gov.hk',
93
+ 'com.tw', 'net.tw', 'org.tw', 'edu.tw', 'gov.tw',
94
+ 'com.mo', 'net.mo', 'org.mo', 'edu.mo', 'gov.mo',
95
+ 'co.uk', 'org.uk', 'me.uk', 'ac.uk', 'gov.uk',
96
+ 'co.jp', 'ne.jp', 'or.jp', 'ac.jp', 'go.jp',
97
+ 'com.au', 'net.au', 'org.au', 'co.nz', 'net.nz',
98
+ 'com.sg', 'com.my', 'com.br', 'com.mx', 'com.tr',
99
+ ]);
90
100
  export function profileNameFromUrl(baseUrl) {
91
101
  try {
92
- const host = new URL(baseUrl).hostname;
93
- const parts = host.split('.');
94
- return parts.length >= 2 ? parts[parts.length - 2] : host;
102
+ const host = new URL(baseUrl).hostname.toLowerCase();
103
+ if (!host)
104
+ return 'default';
105
+ // An IPv4 host has no registrable label, so keep it intact for uniqueness.
106
+ if (/^(\d{1,3}\.){3}\d{1,3}$/u.test(host))
107
+ return host.replace(/[^0-9a-z]+/gu, '-');
108
+ const parts = host.split('.').filter(Boolean);
109
+ if (parts.length <= 1)
110
+ return parts[0] || 'default';
111
+ // `*.com.cn` style hosts must skip the two-label suffix, otherwise every
112
+ // such tenant collapses onto the same profile name (e.g. "com").
113
+ const hasMultiLabelSuffix = parts.length >= 3
114
+ && MULTI_LABEL_PUBLIC_SUFFIXES.has(parts.slice(-2).join('.'));
115
+ const index = hasMultiLabelSuffix ? parts.length - 3 : parts.length - 2;
116
+ return parts[index] || parts[0] || 'default';
95
117
  }
96
118
  catch {
97
119
  return 'default';
@@ -243,6 +265,18 @@ export class E10AuthSession {
243
265
  get version() {
244
266
  return this.data.version || this.data.baselineVersion || '';
245
267
  }
268
+ get loginSource() {
269
+ return this.data.loginSource || '';
270
+ }
271
+ get credentialSourceStep() {
272
+ return this.data.credentialSourceStep;
273
+ }
274
+ get credentialSourceType() {
275
+ return this.data.credentialSourceType || '';
276
+ }
277
+ get credentialSourceLabel() {
278
+ return this.data.credentialSourceLabel || '';
279
+ }
246
280
  getBaseUrl() {
247
281
  return (this.data.baseUrl || '').replace(/\/$/, '');
248
282
  }
@@ -257,6 +291,12 @@ export class E10AuthSession {
257
291
  return this.agentType ? `AgentType=${this.agentType},IsAgent=true` : 'weaver-work-cli';
258
292
  }
259
293
  toJSON() {
294
+ const sourceInfo = {
295
+ ...(this.loginSource ? { loginSource: this.loginSource } : {}),
296
+ ...(this.credentialSourceStep ? { credentialSourceStep: this.credentialSourceStep } : {}),
297
+ ...(this.credentialSourceType ? { credentialSourceType: this.credentialSourceType } : {}),
298
+ ...(this.credentialSourceLabel ? { credentialSourceLabel: this.credentialSourceLabel } : {}),
299
+ };
260
300
  return {
261
301
  userId: this.userId,
262
302
  tenantKey: this.tenantKey,
@@ -272,6 +312,7 @@ export class E10AuthSession {
272
312
  redirectUrl: this.data.redirectUrl,
273
313
  cookieSavedAt: this.data.cookieSavedAt,
274
314
  mainUrl: this.data.mainUrl,
315
+ ...sourceInfo,
275
316
  hasEteamsId: Boolean(this.eteamsId),
276
317
  };
277
318
  }