weaver-work-cli 0.1.5 → 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 +48 -32
  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) {
@@ -155,6 +160,9 @@ function esc(value) {
155
160
  .replace(/"/g, '&quot;')
156
161
  .replace(/'/g, '&#39;');
157
162
  }
163
+ export function renderE10LoginSuccessPage(userId) {
164
+ return `<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>weaver-work-cli 登录成功</title><style>body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Arial,sans-serif;background:#f6f7f9;color:#20242a;display:grid;place-items:center;min-height:100vh;margin:0}.card{background:#fff;border:1px solid #e6e8ec;border-radius:8px;padding:28px 32px;box-shadow:0 8px 32px rgba(18,24,40,.08);min-width:320px;text-align:center}.title{font-size:20px;font-weight:600;margin-bottom:8px}.desc{color:#667085;font-size:14px;line-height:22px}.user{color:#98a2b3;font-size:12px;margin-top:12px}</style></head><body><main class="card"><div class="title">登录授权成功</div><div class="desc">你可以关闭此页面,返回智能体或终端继续使用。</div><div class="user">${esc(userId)}</div></main></body></html>`;
165
+ }
158
166
  export function resolveBrowserOpenCommand(url, platform = process.platform) {
159
167
  if (platform === 'win32') {
160
168
  return { file: 'rundll32.exe', args: ['url.dll,FileProtocolHandler', url] };
@@ -243,26 +251,16 @@ async function saveEteamsIdLogin(input) {
243
251
  version: input.version || '',
244
252
  };
245
253
  }
246
- async function tryXiaoEUnifiedLogin(ctx, baseUrl, tenantKeyFallback, profileHint) {
247
- const credential = resolveXiaoEUnifiedLoginCredential(baseUrl, ctx.env);
248
- if (!credential)
249
- return null;
250
- ctx.logger.info('Detected XiaoE unified login for this E10 domain. Trying XiaoE auth...');
251
- try {
252
- return await saveEteamsIdLogin({
253
- baseUrl,
254
- passportUrl: baseUrl,
255
- eteamsId: credential.eteamsId,
256
- tenantKeyFallback,
257
- agentType: XIAOE_AGENT_TYPE,
258
- profileHint,
259
- });
260
- }
261
- catch (error) {
262
- const message = error instanceof Error ? error.message : String(error);
263
- ctx.logger.warn('XiaoE unified login failed; falling back to browser OAuth. ' + message);
264
- return null;
265
- }
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;
266
264
  }
267
265
  async function oidcExchange(code, redirectUri, baseUrl, tenantKeyFallback, agentTypeFallback, profileHint) {
268
266
  const base = normalizeUrl(baseUrl);
@@ -358,7 +356,15 @@ async function oidcExchange(code, redirectUri, baseUrl, tenantKeyFallback, agent
358
356
  version,
359
357
  };
360
358
  }
361
- 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 = {}) {
362
368
  const commandOpts = asOptions(options);
363
369
  const globalOptions = ctx.getGlobalOptions();
364
370
  const profileFromGlobal = globalOptions.profile;
@@ -374,14 +380,17 @@ async function runBrowserLogin(ctx, options) {
374
380
  const port = Number.parseInt(portText, 10);
375
381
  const explicitAgentType = optionString(commandOpts, 'agentType', 'agent_type');
376
382
  const agentType = resolveAgentType(commandOpts, ctx.env);
377
- if (!baseUrl)
378
- throw new CliError('Missing --base-url', ExitCode.UsageError);
379
383
  if (!Number.isInteger(port) || port <= 0 || port > 65535) {
380
384
  throw new CliError('Invalid --port value', ExitCode.UsageError);
381
385
  }
382
- const xiaoEResult = await tryXiaoEUnifiedLogin(ctx, baseUrl, tenantKey, profileFromGlobal);
386
+ const xiaoEResult = await tryXiaoEUnifiedLogin(ctx, explicitBaseUrl, tenantKey, profileFromGlobal, behavior.allowXiaoETokenScript === true);
383
387
  if (xiaoEResult)
384
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);
385
394
  const redirectUri = `http://127.0.0.1:${port}/callback`;
386
395
  const loginUrl = buildE10AuthorizeUrl(baseUrl, redirectUri, agentType);
387
396
  ctx.logger.info('Open browser login: ' + loginUrl);
@@ -438,7 +447,7 @@ async function runBrowserLogin(ctx, options) {
438
447
  try {
439
448
  const result = await oidcExchange(code, redirectUri, baseUrl, tenantKey, redirectAgentType, profileFromGlobal);
440
449
  res.writeHead(200, { 'content-type': 'text/html; charset=utf-8' });
441
- res.end(`<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>weaver-work-cli login</title><style>body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Arial,sans-serif;background:#f6f7f9;color:#20242a;display:grid;place-items:center;min-height:100vh;margin:0}.card{background:#fff;border:1px solid #e6e8ec;border-radius:8px;padding:28px 32px;box-shadow:0 8px 32px rgba(18,24,40,.08);min-width:320px;text-align:center}.title{font-size:20px;font-weight:600;margin-bottom:8px}.desc{color:#667085;font-size:14px;line-height:22px}.user{color:#98a2b3;font-size:12px;margin-top:12px}</style></head><body><main class="card"><div class="title">Login completed</div><div class="desc">You can close this page and return to the terminal.</div><div class="user">${esc(result.userId)}</div></main></body></html>`);
450
+ res.end(renderE10LoginSuccessPage(result.userId));
442
451
  finish(null, result);
443
452
  }
444
453
  catch (exchangeError) {
@@ -499,7 +508,7 @@ function formatWhoami(title, data) {
499
508
  'User-Agent: ' + (data.userAgent || ''),
500
509
  ].join('\n');
501
510
  }
502
- function registerBrowserLoginCommand(auth, action, name, description) {
511
+ function registerBrowserLoginCommand(auth, action, name, description, behavior = {}) {
503
512
  auth.command(name)
504
513
  .description(description)
505
514
  .option('--base-url <url>', 'E10 base URL')
@@ -508,7 +517,7 @@ function registerBrowserLoginCommand(auth, action, name, description) {
508
517
  .option('--agent_type <value>', 'Agent type sent to E10 authorize endpoint')
509
518
  .option('--agent-type <value>', 'Alias of --agent_type')
510
519
  .action(action(async (ctx, options) => {
511
- const result = await runBrowserLogin(ctx, options);
520
+ const result = await runBrowserLogin(ctx, options, behavior);
512
521
  ctx.output.write(result, { text: formatLoginResult(result) });
513
522
  }));
514
523
  }
@@ -545,6 +554,10 @@ export function registerE10AuthCommands(parent, action) {
545
554
  profile: opts.profile || getActiveProfile(),
546
555
  authFile,
547
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 } : {}),
548
561
  valid,
549
562
  }
550
563
  : {
@@ -589,7 +602,10 @@ export function registerE10AuthCommands(parent, action) {
589
602
  }));
590
603
  registerBrowserLoginCommand(auth, action, 'login', 'Open browser OAuth2.0 login and save E10 auth');
591
604
  registerBrowserLoginCommand(auth, action, 'oidc', 'Alias of auth login for OAuth2.0 browser login');
592
- 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
+ });
593
609
  auth.command('logout')
594
610
  .alias('clear')
595
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
  }