@xagent-ai/cli 1.2.2 → 1.3.0

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 (568) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +38 -38
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +20 -20
  3. package/.github/workflows/ci.yml +72 -0
  4. package/.github/workflows/release.yml +109 -0
  5. package/.gitmodules +3 -3
  6. package/README.md +326 -280
  7. package/README_CN.md +325 -279
  8. package/dist/ai-client/factory.d.ts +52 -0
  9. package/dist/ai-client/factory.d.ts.map +1 -0
  10. package/dist/ai-client/factory.js +132 -0
  11. package/dist/ai-client/factory.js.map +1 -0
  12. package/dist/ai-client/index.d.ts +20 -0
  13. package/dist/ai-client/index.d.ts.map +1 -0
  14. package/dist/ai-client/index.js +49 -0
  15. package/dist/ai-client/index.js.map +1 -0
  16. package/dist/ai-client/providers/anthropic.d.ts +57 -0
  17. package/dist/ai-client/providers/anthropic.d.ts.map +1 -0
  18. package/dist/ai-client/providers/anthropic.js +400 -0
  19. package/dist/ai-client/providers/anthropic.js.map +1 -0
  20. package/dist/ai-client/providers/openai.d.ts +57 -0
  21. package/dist/ai-client/providers/openai.d.ts.map +1 -0
  22. package/dist/ai-client/providers/openai.js +286 -0
  23. package/dist/ai-client/providers/openai.js.map +1 -0
  24. package/dist/ai-client/providers/remote.d.ts +111 -0
  25. package/dist/ai-client/providers/remote.d.ts.map +1 -0
  26. package/dist/ai-client/providers/remote.js +351 -0
  27. package/dist/ai-client/providers/remote.js.map +1 -0
  28. package/dist/ai-client/registry.d.ts +51 -0
  29. package/dist/ai-client/registry.d.ts.map +1 -0
  30. package/dist/ai-client/registry.js +81 -0
  31. package/dist/ai-client/registry.js.map +1 -0
  32. package/dist/ai-client/types.d.ts +260 -0
  33. package/dist/ai-client/types.d.ts.map +1 -0
  34. package/dist/ai-client/types.js +73 -0
  35. package/dist/ai-client/types.js.map +1 -0
  36. package/dist/ai-client-factory.d.ts +62 -0
  37. package/dist/ai-client-factory.d.ts.map +1 -0
  38. package/dist/ai-client-factory.js +157 -0
  39. package/dist/ai-client-factory.js.map +1 -0
  40. package/dist/auth.d.ts +23 -1
  41. package/dist/auth.d.ts.map +1 -1
  42. package/dist/auth.js +160 -168
  43. package/dist/auth.js.map +1 -1
  44. package/dist/cancellation.d.ts +5 -4
  45. package/dist/cancellation.d.ts.map +1 -1
  46. package/dist/cancellation.js +55 -32
  47. package/dist/cancellation.js.map +1 -1
  48. package/dist/checkpoint.d.ts +1 -1
  49. package/dist/checkpoint.d.ts.map +1 -1
  50. package/dist/checkpoint.js +2 -2
  51. package/dist/checkpoint.js.map +1 -1
  52. package/dist/cli.js +626 -13
  53. package/dist/cli.js.map +1 -1
  54. package/dist/config.d.ts +10 -4
  55. package/dist/config.d.ts.map +1 -1
  56. package/dist/config.js +62 -25
  57. package/dist/config.js.map +1 -1
  58. package/dist/context-compressor.d.ts +81 -16
  59. package/dist/context-compressor.d.ts.map +1 -1
  60. package/dist/context-compressor.js +712 -153
  61. package/dist/context-compressor.js.map +1 -1
  62. package/dist/gui-subagent/action-parser/actionParser.d.ts.map +1 -1
  63. package/dist/gui-subagent/action-parser/actionParser.js +4 -2
  64. package/dist/gui-subagent/action-parser/actionParser.js.map +1 -1
  65. package/dist/gui-subagent/agent/gui-agent.d.ts +29 -2
  66. package/dist/gui-subagent/agent/gui-agent.d.ts.map +1 -1
  67. package/dist/gui-subagent/agent/gui-agent.js +87 -45
  68. package/dist/gui-subagent/agent/gui-agent.js.map +1 -1
  69. package/dist/gui-subagent/index.d.ts +16 -1
  70. package/dist/gui-subagent/index.d.ts.map +1 -1
  71. package/dist/gui-subagent/index.js +4 -0
  72. package/dist/gui-subagent/index.js.map +1 -1
  73. package/dist/gui-subagent/operator/base-operator.d.ts.map +1 -1
  74. package/dist/gui-subagent/operator/base-operator.js +0 -1
  75. package/dist/gui-subagent/operator/base-operator.js.map +1 -1
  76. package/dist/gui-subagent/operator/computer-operator.d.ts.map +1 -1
  77. package/dist/gui-subagent/operator/computer-operator.js +29 -8
  78. package/dist/gui-subagent/operator/computer-operator.js.map +1 -1
  79. package/dist/gui-subagent/types/actions.d.ts +1 -1
  80. package/dist/gui-subagent/types/actions.d.ts.map +1 -1
  81. package/dist/gui-subagent/types/actions.js +0 -1
  82. package/dist/gui-subagent/types/actions.js.map +1 -1
  83. package/dist/gui-subagent/types/operator.d.ts +1 -1
  84. package/dist/gui-subagent/types/operator.d.ts.map +1 -1
  85. package/dist/index.d.ts +1 -2
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +1 -2
  88. package/dist/index.js.map +1 -1
  89. package/dist/input-processor.d.ts.map +1 -1
  90. package/dist/input-processor.js +6 -3
  91. package/dist/input-processor.js.map +1 -1
  92. package/dist/mcp.d.ts +5 -0
  93. package/dist/mcp.d.ts.map +1 -1
  94. package/dist/mcp.js +81 -35
  95. package/dist/mcp.js.map +1 -1
  96. package/dist/ripgrep.d.ts +29 -0
  97. package/dist/ripgrep.d.ts.map +1 -0
  98. package/dist/ripgrep.js +292 -0
  99. package/dist/ripgrep.js.map +1 -0
  100. package/dist/session.d.ts +23 -7
  101. package/dist/session.d.ts.map +1 -1
  102. package/dist/session.js +624 -243
  103. package/dist/session.js.map +1 -1
  104. package/dist/shell.d.ts +33 -0
  105. package/dist/shell.d.ts.map +1 -0
  106. package/dist/shell.js +125 -0
  107. package/dist/shell.js.map +1 -0
  108. package/dist/skill-installer.d.ts +38 -0
  109. package/dist/skill-installer.d.ts.map +1 -0
  110. package/dist/skill-installer.js +447 -0
  111. package/dist/skill-installer.js.map +1 -0
  112. package/dist/skill-invoker.d.ts +7 -1
  113. package/dist/skill-invoker.d.ts.map +1 -1
  114. package/dist/skill-invoker.js +34 -13
  115. package/dist/skill-invoker.js.map +1 -1
  116. package/dist/skill-loader.d.ts +8 -3
  117. package/dist/skill-loader.d.ts.map +1 -1
  118. package/dist/skill-loader.js +46 -44
  119. package/dist/skill-loader.js.map +1 -1
  120. package/dist/skill-manager.d.ts +85 -0
  121. package/dist/skill-manager.d.ts.map +1 -0
  122. package/dist/skill-manager.js +340 -0
  123. package/dist/skill-manager.js.map +1 -0
  124. package/dist/slash-commands.d.ts +38 -1
  125. package/dist/slash-commands.d.ts.map +1 -1
  126. package/dist/slash-commands.js +912 -296
  127. package/dist/slash-commands.js.map +1 -1
  128. package/dist/smart-approval.d.ts.map +1 -1
  129. package/dist/smart-approval.js +67 -55
  130. package/dist/smart-approval.js.map +1 -1
  131. package/dist/system-prompt-generator.d.ts +6 -0
  132. package/dist/system-prompt-generator.d.ts.map +1 -1
  133. package/dist/system-prompt-generator.js +84 -34
  134. package/dist/system-prompt-generator.js.map +1 -1
  135. package/dist/terminal.d.ts +28 -0
  136. package/dist/terminal.d.ts.map +1 -0
  137. package/dist/terminal.js +82 -0
  138. package/dist/terminal.js.map +1 -0
  139. package/dist/tools.d.ts +23 -7
  140. package/dist/tools.d.ts.map +1 -1
  141. package/dist/tools.js +797 -437
  142. package/dist/tools.js.map +1 -1
  143. package/dist/truncate.d.ts +55 -0
  144. package/dist/truncate.d.ts.map +1 -0
  145. package/dist/truncate.js +130 -0
  146. package/dist/truncate.js.map +1 -0
  147. package/dist/types.d.ts +27 -9
  148. package/dist/types.d.ts.map +1 -1
  149. package/dist/update.d.ts.map +1 -1
  150. package/dist/update.js +17 -28
  151. package/dist/update.js.map +1 -1
  152. package/dist/workflow.d.ts +5 -1
  153. package/dist/workflow.d.ts.map +1 -1
  154. package/dist/workflow.js +60 -47
  155. package/dist/workflow.js.map +1 -1
  156. package/docs/architecture/mcp-integration-guide.md +304 -194
  157. package/docs/architecture/overview.md +169 -169
  158. package/docs/architecture/tool-system-design.md +134 -134
  159. package/docs/cli/commands.md +349 -238
  160. package/docs/smart-mode.md +281 -281
  161. package/docs/third-party-models.md +439 -439
  162. package/find-skills/SKILL.md +133 -0
  163. package/package.json +89 -90
  164. package/scripts/install-ripgrep.js +241 -0
  165. package/src/ai-client/factory.ts +151 -0
  166. package/src/ai-client/index.ts +61 -0
  167. package/src/ai-client/providers/anthropic.ts +466 -0
  168. package/src/ai-client/providers/openai.ts +342 -0
  169. package/src/ai-client/providers/remote.ts +436 -0
  170. package/src/ai-client/registry.ts +97 -0
  171. package/src/ai-client/types.ts +345 -0
  172. package/src/ai-client-factory.ts +204 -0
  173. package/src/auth.ts +663 -614
  174. package/src/cancellation.ts +205 -176
  175. package/src/checkpoint.ts +219 -219
  176. package/src/cli.ts +1406 -743
  177. package/src/config.ts +341 -297
  178. package/src/context-compressor.ts +982 -290
  179. package/src/conversation.ts +288 -288
  180. package/src/gui-subagent/action-parser/actionParser.ts +318 -315
  181. package/src/gui-subagent/action-parser/constants.ts +14 -14
  182. package/src/gui-subagent/action-parser/index.ts +8 -8
  183. package/src/gui-subagent/action-parser/types.ts +31 -31
  184. package/src/gui-subagent/agent/gui-agent.ts +1151 -1089
  185. package/src/gui-subagent/agent/index.ts +5 -5
  186. package/src/gui-subagent/index.ts +177 -163
  187. package/src/gui-subagent/operator/base-operator.ts +244 -245
  188. package/src/gui-subagent/operator/computer-operator.ts +540 -520
  189. package/src/gui-subagent/operator/index.ts +6 -6
  190. package/src/gui-subagent/types/actions.ts +260 -262
  191. package/src/gui-subagent/types/index.ts +6 -6
  192. package/src/gui-subagent/types/operator.ts +106 -106
  193. package/src/gui-subagent/utils.ts +51 -51
  194. package/src/index.ts +17 -18
  195. package/src/input-processor.ts +6 -3
  196. package/src/logger.ts +438 -438
  197. package/src/mcp.ts +730 -682
  198. package/src/memory.ts +344 -344
  199. package/src/ripgrep.ts +368 -0
  200. package/src/session-manager.ts +308 -308
  201. package/src/session.ts +948 -386
  202. package/src/shell.ts +133 -0
  203. package/src/skill-installer.ts +518 -0
  204. package/src/skill-invoker.ts +960 -935
  205. package/src/skill-loader.ts +501 -496
  206. package/src/skill-manager.ts +384 -0
  207. package/src/slash-commands.ts +2181 -1389
  208. package/src/smart-approval.ts +117 -73
  209. package/src/system-prompt-generator.ts +89 -34
  210. package/src/terminal.ts +96 -0
  211. package/src/theme.ts +738 -738
  212. package/src/tools.ts +1336 -773
  213. package/src/truncate.ts +173 -0
  214. package/src/types.ts +219 -198
  215. package/src/update.ts +22 -32
  216. package/src/workflow.ts +523 -508
  217. package/tsconfig.json +22 -22
  218. package/vitest.config.ts +19 -19
  219. package/dist/ai-client.d.ts +0 -86
  220. package/dist/ai-client.d.ts.map +0 -1
  221. package/dist/ai-client.js +0 -1372
  222. package/dist/ai-client.js.map +0 -1
  223. package/dist/gui-subagent/operator/browser-operator.d.ts +0 -36
  224. package/dist/gui-subagent/operator/browser-operator.d.ts.map +0 -1
  225. package/dist/gui-subagent/operator/browser-operator.js +0 -306
  226. package/dist/gui-subagent/operator/browser-operator.js.map +0 -1
  227. package/dist/gui-subagent/operator/desktop-operator.d.ts +0 -55
  228. package/dist/gui-subagent/operator/desktop-operator.d.ts.map +0 -1
  229. package/dist/gui-subagent/operator/desktop-operator.js +0 -527
  230. package/dist/gui-subagent/operator/desktop-operator.js.map +0 -1
  231. package/dist/hook.d.ts +0 -73
  232. package/dist/hook.d.ts.map +0 -1
  233. package/dist/hook.js +0 -156
  234. package/dist/hook.js.map +0 -1
  235. package/dist/input-history.d.ts +0 -24
  236. package/dist/input-history.d.ts.map +0 -1
  237. package/dist/input-history.js +0 -94
  238. package/dist/input-history.js.map +0 -1
  239. package/dist/keyboard-manager.d.ts +0 -151
  240. package/dist/keyboard-manager.d.ts.map +0 -1
  241. package/dist/keyboard-manager.js +0 -396
  242. package/dist/keyboard-manager.js.map +0 -1
  243. package/dist/print-system-prompt.d.ts +0 -2
  244. package/dist/print-system-prompt.d.ts.map +0 -1
  245. package/dist/print-system-prompt.js +0 -40
  246. package/dist/print-system-prompt.js.map +0 -1
  247. package/dist/remote-ai-client.d.ts +0 -104
  248. package/dist/remote-ai-client.d.ts.map +0 -1
  249. package/dist/remote-ai-client.js +0 -552
  250. package/dist/remote-ai-client.js.map +0 -1
  251. package/dist/sdk-output-adapter.d.ts +0 -232
  252. package/dist/sdk-output-adapter.d.ts.map +0 -1
  253. package/dist/sdk-output-adapter.js +0 -636
  254. package/dist/sdk-output-adapter.js.map +0 -1
  255. package/dist/sdk-session-v2.d.ts +0 -13
  256. package/dist/sdk-session-v2.d.ts.map +0 -1
  257. package/dist/sdk-session-v2.js +0 -46
  258. package/dist/sdk-session-v2.js.map +0 -1
  259. package/dist/sdk-session.d.ts +0 -13
  260. package/dist/sdk-session.d.ts.map +0 -1
  261. package/dist/sdk-session.js +0 -48
  262. package/dist/sdk-session.js.map +0 -1
  263. package/dist/test-boundary-conditions.d.ts.map +0 -1
  264. package/dist/test-boundary-conditions.js.map +0 -1
  265. package/dist/test-cancellation-fix.d.ts.map +0 -1
  266. package/dist/test-cancellation-fix.js.map +0 -1
  267. package/dist/test-input-history.d.ts.map +0 -1
  268. package/dist/test-input-history.js.map +0 -1
  269. package/dist/test-interaction-flow.d.ts.map +0 -1
  270. package/dist/test-interaction-flow.js.map +0 -1
  271. package/dist/test-quick.d.ts.map +0 -1
  272. package/dist/test-quick.js.map +0 -1
  273. package/dist/test-user-interaction.d.ts.map +0 -1
  274. package/dist/test-user-interaction.js.map +0 -1
  275. package/dist/tools/edit-diff.d.ts +0 -32
  276. package/dist/tools/edit-diff.d.ts.map +0 -1
  277. package/dist/tools/edit-diff.js +0 -185
  278. package/dist/tools/edit-diff.js.map +0 -1
  279. package/dist/tools/edit.d.ts +0 -11
  280. package/dist/tools/edit.d.ts.map +0 -1
  281. package/dist/tools/edit.js +0 -129
  282. package/dist/tools/edit.js.map +0 -1
  283. package/dist/unified-session.d.ts +0 -42
  284. package/dist/unified-session.d.ts.map +0 -1
  285. package/dist/unified-session.js +0 -271
  286. package/dist/unified-session.js.map +0 -1
  287. package/skills/.claude-plugin/marketplace.json +0 -45
  288. package/skills/README.md +0 -94
  289. package/skills/THIRD_PARTY_NOTICES.md +0 -405
  290. package/skills/skills/algorithmic-art/LICENSE.txt +0 -202
  291. package/skills/skills/algorithmic-art/SKILL.md +0 -405
  292. package/skills/skills/algorithmic-art/templates/generator_template.js +0 -223
  293. package/skills/skills/algorithmic-art/templates/viewer.html +0 -599
  294. package/skills/skills/brand-guidelines/LICENSE.txt +0 -202
  295. package/skills/skills/brand-guidelines/SKILL.md +0 -73
  296. package/skills/skills/canvas-design/LICENSE.txt +0 -202
  297. package/skills/skills/canvas-design/SKILL.md +0 -130
  298. package/skills/skills/canvas-design/canvas-fonts/ArsenalSC-OFL.txt +0 -93
  299. package/skills/skills/canvas-design/canvas-fonts/ArsenalSC-Regular.ttf +0 -0
  300. package/skills/skills/canvas-design/canvas-fonts/BigShoulders-Bold.ttf +0 -0
  301. package/skills/skills/canvas-design/canvas-fonts/BigShoulders-OFL.txt +0 -93
  302. package/skills/skills/canvas-design/canvas-fonts/BigShoulders-Regular.ttf +0 -0
  303. package/skills/skills/canvas-design/canvas-fonts/Boldonse-OFL.txt +0 -93
  304. package/skills/skills/canvas-design/canvas-fonts/Boldonse-Regular.ttf +0 -0
  305. package/skills/skills/canvas-design/canvas-fonts/BricolageGrotesque-Bold.ttf +0 -0
  306. package/skills/skills/canvas-design/canvas-fonts/BricolageGrotesque-OFL.txt +0 -93
  307. package/skills/skills/canvas-design/canvas-fonts/BricolageGrotesque-Regular.ttf +0 -0
  308. package/skills/skills/canvas-design/canvas-fonts/CrimsonPro-Bold.ttf +0 -0
  309. package/skills/skills/canvas-design/canvas-fonts/CrimsonPro-Italic.ttf +0 -0
  310. package/skills/skills/canvas-design/canvas-fonts/CrimsonPro-OFL.txt +0 -93
  311. package/skills/skills/canvas-design/canvas-fonts/CrimsonPro-Regular.ttf +0 -0
  312. package/skills/skills/canvas-design/canvas-fonts/DMMono-OFL.txt +0 -93
  313. package/skills/skills/canvas-design/canvas-fonts/DMMono-Regular.ttf +0 -0
  314. package/skills/skills/canvas-design/canvas-fonts/EricaOne-OFL.txt +0 -94
  315. package/skills/skills/canvas-design/canvas-fonts/EricaOne-Regular.ttf +0 -0
  316. package/skills/skills/canvas-design/canvas-fonts/GeistMono-Bold.ttf +0 -0
  317. package/skills/skills/canvas-design/canvas-fonts/GeistMono-OFL.txt +0 -93
  318. package/skills/skills/canvas-design/canvas-fonts/GeistMono-Regular.ttf +0 -0
  319. package/skills/skills/canvas-design/canvas-fonts/Gloock-OFL.txt +0 -93
  320. package/skills/skills/canvas-design/canvas-fonts/Gloock-Regular.ttf +0 -0
  321. package/skills/skills/canvas-design/canvas-fonts/IBMPlexMono-Bold.ttf +0 -0
  322. package/skills/skills/canvas-design/canvas-fonts/IBMPlexMono-OFL.txt +0 -93
  323. package/skills/skills/canvas-design/canvas-fonts/IBMPlexMono-Regular.ttf +0 -0
  324. package/skills/skills/canvas-design/canvas-fonts/IBMPlexSerif-Bold.ttf +0 -0
  325. package/skills/skills/canvas-design/canvas-fonts/IBMPlexSerif-BoldItalic.ttf +0 -0
  326. package/skills/skills/canvas-design/canvas-fonts/IBMPlexSerif-Italic.ttf +0 -0
  327. package/skills/skills/canvas-design/canvas-fonts/IBMPlexSerif-Regular.ttf +0 -0
  328. package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-Bold.ttf +0 -0
  329. package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-BoldItalic.ttf +0 -0
  330. package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-Italic.ttf +0 -0
  331. package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-OFL.txt +0 -93
  332. package/skills/skills/canvas-design/canvas-fonts/InstrumentSans-Regular.ttf +0 -0
  333. package/skills/skills/canvas-design/canvas-fonts/InstrumentSerif-Italic.ttf +0 -0
  334. package/skills/skills/canvas-design/canvas-fonts/InstrumentSerif-Regular.ttf +0 -0
  335. package/skills/skills/canvas-design/canvas-fonts/Italiana-OFL.txt +0 -93
  336. package/skills/skills/canvas-design/canvas-fonts/Italiana-Regular.ttf +0 -0
  337. package/skills/skills/canvas-design/canvas-fonts/JetBrainsMono-Bold.ttf +0 -0
  338. package/skills/skills/canvas-design/canvas-fonts/JetBrainsMono-OFL.txt +0 -93
  339. package/skills/skills/canvas-design/canvas-fonts/JetBrainsMono-Regular.ttf +0 -0
  340. package/skills/skills/canvas-design/canvas-fonts/Jura-Light.ttf +0 -0
  341. package/skills/skills/canvas-design/canvas-fonts/Jura-Medium.ttf +0 -0
  342. package/skills/skills/canvas-design/canvas-fonts/Jura-OFL.txt +0 -93
  343. package/skills/skills/canvas-design/canvas-fonts/LibreBaskerville-OFL.txt +0 -93
  344. package/skills/skills/canvas-design/canvas-fonts/LibreBaskerville-Regular.ttf +0 -0
  345. package/skills/skills/canvas-design/canvas-fonts/Lora-Bold.ttf +0 -0
  346. package/skills/skills/canvas-design/canvas-fonts/Lora-BoldItalic.ttf +0 -0
  347. package/skills/skills/canvas-design/canvas-fonts/Lora-Italic.ttf +0 -0
  348. package/skills/skills/canvas-design/canvas-fonts/Lora-OFL.txt +0 -93
  349. package/skills/skills/canvas-design/canvas-fonts/Lora-Regular.ttf +0 -0
  350. package/skills/skills/canvas-design/canvas-fonts/NationalPark-Bold.ttf +0 -0
  351. package/skills/skills/canvas-design/canvas-fonts/NationalPark-OFL.txt +0 -93
  352. package/skills/skills/canvas-design/canvas-fonts/NationalPark-Regular.ttf +0 -0
  353. package/skills/skills/canvas-design/canvas-fonts/NothingYouCouldDo-OFL.txt +0 -93
  354. package/skills/skills/canvas-design/canvas-fonts/NothingYouCouldDo-Regular.ttf +0 -0
  355. package/skills/skills/canvas-design/canvas-fonts/Outfit-Bold.ttf +0 -0
  356. package/skills/skills/canvas-design/canvas-fonts/Outfit-OFL.txt +0 -93
  357. package/skills/skills/canvas-design/canvas-fonts/Outfit-Regular.ttf +0 -0
  358. package/skills/skills/canvas-design/canvas-fonts/PixelifySans-Medium.ttf +0 -0
  359. package/skills/skills/canvas-design/canvas-fonts/PixelifySans-OFL.txt +0 -93
  360. package/skills/skills/canvas-design/canvas-fonts/PoiretOne-OFL.txt +0 -93
  361. package/skills/skills/canvas-design/canvas-fonts/PoiretOne-Regular.ttf +0 -0
  362. package/skills/skills/canvas-design/canvas-fonts/RedHatMono-Bold.ttf +0 -0
  363. package/skills/skills/canvas-design/canvas-fonts/RedHatMono-OFL.txt +0 -93
  364. package/skills/skills/canvas-design/canvas-fonts/RedHatMono-Regular.ttf +0 -0
  365. package/skills/skills/canvas-design/canvas-fonts/Silkscreen-OFL.txt +0 -93
  366. package/skills/skills/canvas-design/canvas-fonts/Silkscreen-Regular.ttf +0 -0
  367. package/skills/skills/canvas-design/canvas-fonts/SmoochSans-Medium.ttf +0 -0
  368. package/skills/skills/canvas-design/canvas-fonts/SmoochSans-OFL.txt +0 -93
  369. package/skills/skills/canvas-design/canvas-fonts/Tektur-Medium.ttf +0 -0
  370. package/skills/skills/canvas-design/canvas-fonts/Tektur-OFL.txt +0 -93
  371. package/skills/skills/canvas-design/canvas-fonts/Tektur-Regular.ttf +0 -0
  372. package/skills/skills/canvas-design/canvas-fonts/WorkSans-Bold.ttf +0 -0
  373. package/skills/skills/canvas-design/canvas-fonts/WorkSans-BoldItalic.ttf +0 -0
  374. package/skills/skills/canvas-design/canvas-fonts/WorkSans-Italic.ttf +0 -0
  375. package/skills/skills/canvas-design/canvas-fonts/WorkSans-OFL.txt +0 -93
  376. package/skills/skills/canvas-design/canvas-fonts/WorkSans-Regular.ttf +0 -0
  377. package/skills/skills/canvas-design/canvas-fonts/YoungSerif-OFL.txt +0 -93
  378. package/skills/skills/canvas-design/canvas-fonts/YoungSerif-Regular.ttf +0 -0
  379. package/skills/skills/doc-coauthoring/SKILL.md +0 -375
  380. package/skills/skills/docx/LICENSE.txt +0 -30
  381. package/skills/skills/docx/SKILL.md +0 -197
  382. package/skills/skills/docx/docx-js.md +0 -350
  383. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  384. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  385. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  386. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  387. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  388. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  389. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  390. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  391. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  392. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  393. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  394. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  395. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  396. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  397. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  398. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  399. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  400. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  401. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  402. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  403. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  404. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  405. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  406. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  407. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  408. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  409. package/skills/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  410. package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  411. package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  412. package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  413. package/skills/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  414. package/skills/skills/docx/ooxml/schemas/mce/mc.xsd +0 -75
  415. package/skills/skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +0 -560
  416. package/skills/skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +0 -67
  417. package/skills/skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +0 -14
  418. package/skills/skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +0 -20
  419. package/skills/skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +0 -13
  420. package/skills/skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  421. package/skills/skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +0 -8
  422. package/skills/skills/docx/ooxml/scripts/pack.py +0 -159
  423. package/skills/skills/docx/ooxml/scripts/unpack.py +0 -29
  424. package/skills/skills/docx/ooxml/scripts/validate.py +0 -69
  425. package/skills/skills/docx/ooxml/scripts/validation/__init__.py +0 -15
  426. package/skills/skills/docx/ooxml/scripts/validation/base.py +0 -951
  427. package/skills/skills/docx/ooxml/scripts/validation/docx.py +0 -274
  428. package/skills/skills/docx/ooxml/scripts/validation/pptx.py +0 -315
  429. package/skills/skills/docx/ooxml/scripts/validation/redlining.py +0 -279
  430. package/skills/skills/docx/ooxml.md +0 -610
  431. package/skills/skills/docx/scripts/__init__.py +0 -1
  432. package/skills/skills/docx/scripts/document.py +0 -1276
  433. package/skills/skills/docx/scripts/templates/comments.xml +0 -3
  434. package/skills/skills/docx/scripts/templates/commentsExtended.xml +0 -3
  435. package/skills/skills/docx/scripts/templates/commentsExtensible.xml +0 -3
  436. package/skills/skills/docx/scripts/templates/commentsIds.xml +0 -3
  437. package/skills/skills/docx/scripts/templates/people.xml +0 -3
  438. package/skills/skills/docx/scripts/utilities.py +0 -374
  439. package/skills/skills/frontend-design/LICENSE.txt +0 -177
  440. package/skills/skills/frontend-design/SKILL.md +0 -42
  441. package/skills/skills/internal-comms/LICENSE.txt +0 -202
  442. package/skills/skills/internal-comms/SKILL.md +0 -32
  443. package/skills/skills/internal-comms/examples/3p-updates.md +0 -47
  444. package/skills/skills/internal-comms/examples/company-newsletter.md +0 -65
  445. package/skills/skills/internal-comms/examples/faq-answers.md +0 -30
  446. package/skills/skills/internal-comms/examples/general-comms.md +0 -16
  447. package/skills/skills/mcp-builder/LICENSE.txt +0 -202
  448. package/skills/skills/mcp-builder/SKILL.md +0 -236
  449. package/skills/skills/mcp-builder/reference/evaluation.md +0 -602
  450. package/skills/skills/mcp-builder/reference/mcp_best_practices.md +0 -249
  451. package/skills/skills/mcp-builder/reference/node_mcp_server.md +0 -970
  452. package/skills/skills/mcp-builder/reference/python_mcp_server.md +0 -719
  453. package/skills/skills/mcp-builder/scripts/connections.py +0 -151
  454. package/skills/skills/mcp-builder/scripts/evaluation.py +0 -373
  455. package/skills/skills/mcp-builder/scripts/example_evaluation.xml +0 -22
  456. package/skills/skills/mcp-builder/scripts/requirements.txt +0 -2
  457. package/skills/skills/pdf/LICENSE.txt +0 -30
  458. package/skills/skills/pdf/SKILL.md +0 -294
  459. package/skills/skills/pdf/forms.md +0 -205
  460. package/skills/skills/pdf/reference.md +0 -612
  461. package/skills/skills/pdf/scripts/check_bounding_boxes.py +0 -70
  462. package/skills/skills/pdf/scripts/check_bounding_boxes_test.py +0 -226
  463. package/skills/skills/pdf/scripts/check_fillable_fields.py +0 -12
  464. package/skills/skills/pdf/scripts/convert_pdf_to_images.py +0 -35
  465. package/skills/skills/pdf/scripts/create_validation_image.py +0 -41
  466. package/skills/skills/pdf/scripts/extract_form_field_info.py +0 -152
  467. package/skills/skills/pdf/scripts/fill_fillable_fields.py +0 -114
  468. package/skills/skills/pdf/scripts/fill_pdf_form_with_annotations.py +0 -108
  469. package/skills/skills/pptx/LICENSE.txt +0 -30
  470. package/skills/skills/pptx/SKILL.md +0 -484
  471. package/skills/skills/pptx/html2pptx.md +0 -625
  472. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +0 -1499
  473. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +0 -146
  474. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +0 -1085
  475. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +0 -11
  476. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +0 -3081
  477. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +0 -23
  478. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +0 -185
  479. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +0 -287
  480. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +0 -1676
  481. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +0 -28
  482. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +0 -144
  483. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +0 -174
  484. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +0 -25
  485. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +0 -18
  486. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +0 -59
  487. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +0 -56
  488. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +0 -195
  489. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +0 -582
  490. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +0 -25
  491. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +0 -4439
  492. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +0 -570
  493. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +0 -509
  494. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +0 -12
  495. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +0 -108
  496. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +0 -96
  497. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +0 -3646
  498. package/skills/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +0 -116
  499. package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +0 -42
  500. package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +0 -50
  501. package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +0 -49
  502. package/skills/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +0 -33
  503. package/skills/skills/pptx/ooxml/schemas/mce/mc.xsd +0 -75
  504. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +0 -560
  505. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +0 -67
  506. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +0 -14
  507. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +0 -20
  508. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +0 -13
  509. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +0 -4
  510. package/skills/skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +0 -8
  511. package/skills/skills/pptx/ooxml/scripts/pack.py +0 -159
  512. package/skills/skills/pptx/ooxml/scripts/unpack.py +0 -29
  513. package/skills/skills/pptx/ooxml/scripts/validate.py +0 -69
  514. package/skills/skills/pptx/ooxml/scripts/validation/__init__.py +0 -15
  515. package/skills/skills/pptx/ooxml/scripts/validation/base.py +0 -951
  516. package/skills/skills/pptx/ooxml/scripts/validation/docx.py +0 -274
  517. package/skills/skills/pptx/ooxml/scripts/validation/pptx.py +0 -315
  518. package/skills/skills/pptx/ooxml/scripts/validation/redlining.py +0 -279
  519. package/skills/skills/pptx/ooxml.md +0 -427
  520. package/skills/skills/pptx/scripts/html2pptx.js +0 -979
  521. package/skills/skills/pptx/scripts/inventory.py +0 -1020
  522. package/skills/skills/pptx/scripts/rearrange.py +0 -231
  523. package/skills/skills/pptx/scripts/replace.py +0 -385
  524. package/skills/skills/pptx/scripts/thumbnail.py +0 -450
  525. package/skills/skills/skill-creator/LICENSE.txt +0 -202
  526. package/skills/skills/skill-creator/SKILL.md +0 -356
  527. package/skills/skills/skill-creator/references/output-patterns.md +0 -82
  528. package/skills/skills/skill-creator/references/workflows.md +0 -28
  529. package/skills/skills/skill-creator/scripts/init_skill.py +0 -303
  530. package/skills/skills/skill-creator/scripts/package_skill.py +0 -110
  531. package/skills/skills/skill-creator/scripts/quick_validate.py +0 -95
  532. package/skills/skills/slack-gif-creator/LICENSE.txt +0 -202
  533. package/skills/skills/slack-gif-creator/SKILL.md +0 -254
  534. package/skills/skills/slack-gif-creator/core/easing.py +0 -234
  535. package/skills/skills/slack-gif-creator/core/frame_composer.py +0 -176
  536. package/skills/skills/slack-gif-creator/core/gif_builder.py +0 -269
  537. package/skills/skills/slack-gif-creator/core/validators.py +0 -136
  538. package/skills/skills/slack-gif-creator/requirements.txt +0 -4
  539. package/skills/skills/theme-factory/LICENSE.txt +0 -202
  540. package/skills/skills/theme-factory/SKILL.md +0 -59
  541. package/skills/skills/theme-factory/theme-showcase.pdf +0 -0
  542. package/skills/skills/theme-factory/themes/arctic-frost.md +0 -19
  543. package/skills/skills/theme-factory/themes/botanical-garden.md +0 -19
  544. package/skills/skills/theme-factory/themes/desert-rose.md +0 -19
  545. package/skills/skills/theme-factory/themes/forest-canopy.md +0 -19
  546. package/skills/skills/theme-factory/themes/golden-hour.md +0 -19
  547. package/skills/skills/theme-factory/themes/midnight-galaxy.md +0 -19
  548. package/skills/skills/theme-factory/themes/modern-minimalist.md +0 -19
  549. package/skills/skills/theme-factory/themes/ocean-depths.md +0 -19
  550. package/skills/skills/theme-factory/themes/sunset-boulevard.md +0 -19
  551. package/skills/skills/theme-factory/themes/tech-innovation.md +0 -19
  552. package/skills/skills/web-artifacts-builder/LICENSE.txt +0 -202
  553. package/skills/skills/web-artifacts-builder/SKILL.md +0 -74
  554. package/skills/skills/web-artifacts-builder/scripts/bundle-artifact.sh +0 -54
  555. package/skills/skills/web-artifacts-builder/scripts/init-artifact.sh +0 -322
  556. package/skills/skills/webapp-testing/LICENSE.txt +0 -202
  557. package/skills/skills/webapp-testing/SKILL.md +0 -96
  558. package/skills/skills/webapp-testing/examples/console_logging.py +0 -35
  559. package/skills/skills/webapp-testing/examples/element_discovery.py +0 -40
  560. package/skills/skills/webapp-testing/examples/static_html_automation.py +0 -33
  561. package/skills/skills/webapp-testing/scripts/with_server.py +0 -106
  562. package/skills/skills/xlsx/LICENSE.txt +0 -30
  563. package/skills/skills/xlsx/SKILL.md +0 -289
  564. package/skills/skills/xlsx/recalc.py +0 -178
  565. package/skills/spec/agent-skills-spec.md +0 -3
  566. package/skills/template/SKILL.md +0 -6
  567. package/src/ai-client.ts +0 -1560
  568. package/src/remote-ai-client.ts +0 -664
package/src/auth.ts CHANGED
@@ -1,614 +1,663 @@
1
- import axios from 'axios';
2
- import open from 'open';
3
- import inquirer from 'inquirer';
4
- import https from 'https';
5
- import { AuthConfig, AuthType } from './types.js';
6
- import { getLogger } from './logger.js';
7
-
8
- const logger = getLogger();
9
-
10
- // Extended AuthConfig for xAgent with additional fields
11
- interface XAgentAuthConfig extends AuthConfig {
12
- xagentApiBaseUrl?: string;
13
- }
14
-
15
- interface VLMProviderInfo {
16
- name: string;
17
- provider: string;
18
- baseUrl: string;
19
- defaultModel: string;
20
- models: string[];
21
- }
22
-
23
- const VLM_PROVIDERS: VLMProviderInfo[] = [
24
- {
25
- name: 'OpenAI',
26
- provider: 'openai',
27
- baseUrl: 'https://api.openai.com/v1',
28
- defaultModel: 'gpt-4o',
29
- models: ['gpt-5', 'gpt-4o', 'gpt-4o-mini', 'gpt-5-mini']
30
- },
31
- {
32
- name: 'Volcengine (Doubao)',
33
- provider: 'volcengine',
34
- baseUrl: 'https://ark.cn-beijing.volces.com/api/v3',
35
- defaultModel: 'doubao-seed-1-8-251228',
36
- models: ['doubao-seed-1-8-251228', 'doubao-1-5-ui-tars-250428', 'seed1.5-vl']
37
- },
38
- {
39
- name: 'Anthropic',
40
- provider: 'anthropic',
41
- baseUrl: 'https://api.anthropic.com/v1',
42
- defaultModel: 'claude-sonnet-4-5',
43
- models: ['claude-sonnet-4-5', 'claude-opus-4-5', 'claude-sonnet-4', 'claude-opus-4']
44
- }
45
- ];
46
-
47
- interface ThirdPartyProvider {
48
- name: string;
49
- baseUrl: string;
50
- defaultModel: string;
51
- description: string;
52
- models?: string[];
53
- }
54
-
55
- const THIRD_PARTY_PROVIDERS: ThirdPartyProvider[] = [
56
- {
57
- name: 'Zhipu AI (GLM-4)',
58
- baseUrl: 'https://open.bigmodel.cn/api/coding/paas/v4/',
59
- defaultModel: 'glm-4.7',
60
- description: 'Zhipu AI GLM-4 series models',
61
- models: ['glm-4.7', 'glm-4', 'glm-4-plus', 'glm-4-0520', 'glm-4-air', 'glm-4-airx', 'glm-4-flash', 'glm-4.7-plus']
62
- },
63
- {
64
- name: 'DeepSeek',
65
- baseUrl: 'https://api.deepseek.com/v1',
66
- defaultModel: 'deepseek-chat',
67
- description: 'DeepSeek DeepSeek series models',
68
- models: ['deepseek-chat', 'deepseek-coder', 'deepseek-reasoner']
69
- },
70
- {
71
- name: 'Alibaba Tongyi Qianwen',
72
- baseUrl: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
73
- defaultModel: 'qwen-max',
74
- description: 'Alibaba Cloud Tongyi Qianwen series models',
75
- models: ['qwen-max', 'qwen-plus', 'qwen-turbo', 'qwen-long', 'qwen-vl-max', 'qwen-vl-plus']
76
- },
77
- {
78
- name: 'Baidu Wenxin Yiyan',
79
- baseUrl: 'https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat',
80
- defaultModel: 'ernie-bot-4',
81
- description: 'Baidu Intelligent Cloud Wenxin Yiyan series models',
82
- models: ['ernie-bot-4', 'ernie-bot-turbo', 'ernie-speed', 'ernie-speed-128k', 'ernie-lite-8k']
83
- },
84
- {
85
- name: 'Moonshot AI (Kimi)',
86
- baseUrl: 'https://api.moonshot.cn/v1',
87
- defaultModel: 'moonshot-v1-8k',
88
- description: 'Moonshot AI Kimi series models',
89
- models: ['moonshot-v1-8k', 'moonshot-v1-32k', 'moonshot-v1-128k']
90
- },
91
- {
92
- name: 'MiniMax',
93
- baseUrl: 'https://api.minimax.chat/anthropic',
94
- defaultModel: 'MiniMax-M2.1',
95
- description: 'MiniMax (Anthropic-compatible format)',
96
- models: ['MiniMax-M2.1', 'MiniMax-M2.1-lightning', 'MiniMax-M2', 'MiniMax-M2-Stable']
97
- },
98
- {
99
- name: '01.AI (Yi)',
100
- baseUrl: 'https://api.lingyiwanwu.com/v1',
101
- defaultModel: 'yi-large',
102
- description: '01.AI Yi series models',
103
- models: ['yi-large', 'yi-large-turbo', 'yi-medium', 'yi-spark', 'yi-vision']
104
- },
105
- {
106
- name: 'Baichuan Intelligence (Baichuan)',
107
- baseUrl: 'https://api.baichuan-ai.com/v1',
108
- defaultModel: 'Baichuan4',
109
- description: 'Baichuan Intelligence Baichuan series models',
110
- models: ['Baichuan4', 'Baichuan3-Turbo', 'Baichuan3-Turbo-128k', 'Baichuan-Text-Embedding']
111
- },
112
- {
113
- name: 'Tencent Hunyuan',
114
- baseUrl: 'https://hunyuan.cloud.tencent.com/hyllm/v1',
115
- defaultModel: 'hunyuan-pro',
116
- description: 'Tencent Hunyuan series models',
117
- models: ['hunyuan-pro', 'hunyuan-standard', 'hunyuan-lite', 'hunyuan-vision']
118
- },
119
- {
120
- name: 'iFlytek (SparkDesk)',
121
- baseUrl: 'https://spark-api-open.xf-yun.com/v1',
122
- defaultModel: 'spark-pro',
123
- description: 'iFlytek Spark cognitive large model',
124
- models: ['spark-pro', 'spark-ultra', 'spark-max', 'spark-lite']
125
- },
126
- {
127
- name: 'Custom',
128
- baseUrl: '',
129
- defaultModel: '',
130
- description: 'Manually enter API configuration',
131
- models: []
132
- }
133
- ];
134
-
135
- export class AuthService {
136
- private authConfig: XAgentAuthConfig;
137
-
138
- constructor(authConfig: AuthConfig) {
139
- this.authConfig = authConfig;
140
- }
141
-
142
- async authenticate(): Promise<boolean> {
143
- let result: boolean;
144
- switch (this.authConfig.type) {
145
- case AuthType.OAUTH_XAGENT:
146
- result = await this.authenticateWithXAgent();
147
- break;
148
- case AuthType.OPENAI_COMPATIBLE:
149
- result = await this.authenticateWithOpenAICompatible();
150
- break;
151
- default:
152
- throw new Error(`Unknown auth type: ${this.authConfig.type}`);
153
- }
154
-
155
- return result;
156
- }
157
-
158
- private async authenticateWithXAgent(): Promise<boolean> {
159
- logger.info('Authenticating with xAgent...', 'Please complete the authentication in your browser');
160
-
161
- try {
162
- // 1. Start HTTP server to receive callback
163
- const token = await this.retrieveXAgentToken();
164
-
165
- // 2. 调用后端验证用户
166
- const xagentApiBaseUrl = this.authConfig.xagentApiBaseUrl || 'https://www.xagent-colife.net';
167
- const httpsAgent = new https.Agent({ rejectUnauthorized: false });
168
- const response = await axios.get(`${xagentApiBaseUrl}/api/auth/me`, {
169
- headers: { 'Authorization': `Bearer ${token}` },
170
- httpsAgent
171
- });
172
-
173
- // 3. Set authentication configuration
174
- this.authConfig.baseUrl = 'https://www.xagent-colife.net/v1';
175
- this.authConfig.xagentApiBaseUrl = xagentApiBaseUrl;
176
- this.authConfig.apiKey = token;
177
- this.authConfig.type = AuthType.OAUTH_XAGENT;
178
-
179
- logger.success('Successfully authenticated with xAgent!');
180
- return true;
181
- } catch (error: any) {
182
- logger.error('Authentication failed', error.message || 'Unknown error');
183
- logger.debug('Full error:', JSON.stringify(error.response?.data || error.message));
184
- return false;
185
- }
186
- }
187
-
188
- private async authenticateWithOpenAICompatible(): Promise<boolean> {
189
- logger.info('Configuring third-party model API...\n');
190
-
191
- const { provider } = await inquirer.prompt([
192
- {
193
- type: 'list',
194
- name: 'provider',
195
- message: 'Select third-party model provider:',
196
- choices: THIRD_PARTY_PROVIDERS.map(p => ({
197
- name: `${p.name} - ${p.description}`,
198
- value: p
199
- }))
200
- }
201
- ]);
202
-
203
- const selectedProvider = provider as ThirdPartyProvider;
204
-
205
- let baseUrl = selectedProvider.baseUrl;
206
- let modelName = selectedProvider.defaultModel;
207
-
208
- if (selectedProvider.name === 'Custom') {
209
- const customAnswers = await inquirer.prompt([
210
- {
211
- type: 'input',
212
- name: 'baseUrl',
213
- message: 'Enter API Base URL:',
214
- default: 'https://api.openai.com/v1',
215
- validate: (input: string) => {
216
- if (!input || input.trim().length === 0) {
217
- return 'Base URL cannot be empty';
218
- }
219
- return true;
220
- }
221
- },
222
- {
223
- type: 'input',
224
- name: 'modelName',
225
- message: 'Enter model name:',
226
- default: 'gpt-4',
227
- validate: (input: string) => {
228
- if (!input || input.trim().length === 0) {
229
- return 'Model name cannot be empty';
230
- }
231
- return true;
232
- }
233
- }
234
- ]);
235
-
236
- baseUrl = (customAnswers.baseUrl as string).trim();
237
- modelName = (customAnswers.modelName as string).trim();
238
- } else {
239
- logger.info(`\nSelected: ${selectedProvider.name}`);
240
- logger.info(`API URL: ${baseUrl}`);
241
-
242
- if (selectedProvider.models && selectedProvider.models.length > 0) {
243
- logger.info(`Available models: ${selectedProvider.models.join(', ')}`);
244
-
245
- const { selectedModel } = await inquirer.prompt([
246
- {
247
- type: 'list',
248
- name: 'selectedModel',
249
- message: 'Select model:',
250
- choices: selectedProvider.models.map(model => ({
251
- name: model === selectedProvider.defaultModel ? `${model} (default)` : model,
252
- value: model
253
- }))
254
- }
255
- ]);
256
-
257
- modelName = selectedModel;
258
- } else {
259
- logger.info(`Default model: ${modelName}\n`);
260
-
261
- const { confirmModel } = await inquirer.prompt([
262
- {
263
- type: 'input',
264
- name: 'modelName',
265
- message: `Enter model name (press Enter to use default value ${modelName}):`,
266
- default: modelName,
267
- validate: (input: string) => {
268
- if (!input || input.trim().length === 0) {
269
- return 'Model name cannot be empty';
270
- }
271
- return true;
272
- }
273
- }
274
- ]);
275
-
276
- modelName = (confirmModel as string).trim();
277
- }
278
- }
279
-
280
- const { apiKey } = await inquirer.prompt([
281
- {
282
- type: 'password',
283
- name: 'apiKey',
284
- message: `Enter ${selectedProvider.name} API Key:`,
285
- mask: '*',
286
- validate: (input: string) => {
287
- if (!input || input.trim().length === 0) {
288
- return 'API Key cannot be empty';
289
- }
290
- return true;
291
- }
292
- }
293
- ]);
294
-
295
- this.authConfig.baseUrl = baseUrl;
296
- this.authConfig.apiKey = (apiKey as string).trim();
297
- this.authConfig.modelName = modelName;
298
- this.authConfig.type = AuthType.OPENAI_COMPATIBLE;
299
-
300
- const isValid = await this.validateApiKey();
301
- if (isValid) {
302
- logger.success(`${selectedProvider.name} configured successfully!`, `Model: ${modelName}, API: ${baseUrl}`);
303
- logger.info(` Model: ${modelName}`);
304
- logger.info(` API URL: ${baseUrl}`);
305
- return true;
306
- } else {
307
- logger.error(`${selectedProvider.name} configuration verification failed, please check API Key and network connection.`, 'Verify your API Key and network connection');
308
- return false;
309
- }
310
- }
311
-
312
- private async validateApiKey(): Promise<boolean> {
313
- try {
314
- // Check if it's MiniMax-M2 (uses Anthropic format)
315
- if ((this.authConfig.baseUrl?.includes('minimax.chat') ||
316
- this.authConfig.baseUrl?.includes('minimaxi.com')) &&
317
- this.authConfig.baseUrl?.includes('anthropic')) {
318
- // MiniMax-M2 uses Anthropic format with x-api-key header
319
- const response = await axios.post(
320
- `${this.authConfig.baseUrl}/v1/messages`,
321
- {
322
- model: 'MiniMax-M2',
323
- max_tokens: 1,
324
- messages: [{ role: 'user', content: 'test' }]
325
- },
326
- {
327
- headers: {
328
- 'x-api-key': this.authConfig.apiKey,
329
- 'anthropic-version': '2023-06-01',
330
- 'Content-Type': 'application/json'
331
- },
332
- timeout: 10000
333
- }
334
- );
335
- return response.status === 200;
336
- }
337
-
338
- // Standard OpenAI compatible API
339
- const response = await axios.get(
340
- `${this.authConfig.baseUrl}/models`,
341
- {
342
- headers: {
343
- 'Authorization': `Bearer ${this.authConfig.apiKey}`,
344
- 'Content-Type': 'application/json'
345
- },
346
- timeout: 10000
347
- }
348
- );
349
- return response.status === 200;
350
- } catch (error: any) {
351
- // Provide user-friendly error messages without exposing stack traces
352
- if (error.response) {
353
- const status = error.response.status;
354
-
355
- if (status === 401) {
356
- logger.error('API Key verification failed: Invalid or expired API Key', `Verify your API Key is correct and has not expired`);
357
- } else if (status === 403) {
358
- logger.error('API Key verification failed: Access denied', `Check if your API Key has permission to access`);
359
- } else if (status === 404) {
360
- logger.error('API request failed: API endpoint not found', `Verify your API Base URL is correct`);
361
- } else if (status === 429) {
362
- logger.error('API rate limit exceeded', `Please wait before retrying`);
363
- } else {
364
- logger.error(`API Key verification failed (HTTP ${status})`, `Verify your API Key and network connection`);
365
- }
366
- } else if (error.code === 'ECONNREFUSED') {
367
- logger.error('Failed to connect to API server', `Verify your API Base URL and network connection`);
368
- } else if (error.code === 'ETIMEDOUT' || error.code === 'ECONNABORTED') {
369
- logger.error('API request timed out', `Check your network connection and try again`);
370
- } else {
371
- logger.error('API Key verification failed', `Verify your API Key and network connection`);
372
- }
373
- return false;
374
- }
375
- }
376
-
377
- private async retrieveXAgentToken(): Promise<string> {
378
- // Use xagentApiBaseUrl from config, fallback to default
379
- const webBaseUrl = this.authConfig.xagentApiBaseUrl || 'https://www.xagent-colife.net';
380
- const authUrl = `${webBaseUrl}/login`;
381
- // Callback URL tells frontend where to store token
382
- const callbackUrl = 'https://www.xagent-colife.net/callback';
383
-
384
- // 如果已有保存的token,通过URL参数传给Web页面
385
- const existingToken = this.authConfig.apiKey;
386
- const existingRefreshToken = this.authConfig.refreshToken;
387
-
388
- // 构建登录URL - 如果已有token也传给Web
389
- let loginUrl = `${authUrl}?callback=${encodeURIComponent(callbackUrl)}`;
390
- if (existingToken) {
391
- loginUrl += `&existingToken=${encodeURIComponent(existingToken)}`;
392
- if (existingRefreshToken) {
393
- loginUrl += `&existingRefreshToken=${encodeURIComponent(existingRefreshToken)}`;
394
- }
395
- }
396
-
397
- // Open browser for login, then poll server for token
398
- await open(loginUrl);
399
- logger.info('Waiting for authentication...', 'Please complete login in your browser');
400
-
401
- // Poll server to get token
402
- return new Promise((resolve, reject) => {
403
- const pollInterval = 2000; // Poll every 2 seconds
404
- const maxWaitTime = 30 * 60 * 1000; // 30 minutes timeout
405
- const startTime = Date.now();
406
-
407
- const poll = async () => {
408
- if (Date.now() - startTime > maxWaitTime) {
409
- logger.warn('Authentication timeout after 30 minutes');
410
- reject(new Error('Authentication timeout'));
411
- return;
412
- }
413
-
414
- try {
415
- // Create HTTPS agent that ignores certificate errors (for IP-based access)
416
- const httpsAgent = new https.Agent({ rejectUnauthorized: false });
417
-
418
- const response = await axios.get(`${webBaseUrl}/api/cli/get-token`, {
419
- timeout: 10000,
420
- httpsAgent
421
- });
422
-
423
- if (response.data.token) {
424
- logger.success('Authentication successful! Received token');
425
- logger.debug('[CLI-Auth] Token stored, key:', response.data.token.substring(0, 20) + '...');
426
- // Save refresh token if provided
427
- if (response.data.refreshToken) {
428
- this.authConfig.refreshToken = response.data.refreshToken;
429
- }
430
- resolve(response.data.token);
431
- return;
432
- }
433
- } catch (error: any) {
434
- if (error.response?.status === 404) {
435
- // Token not ready yet, continue polling
436
- } else {
437
- console.error('[CLI-Auth] Polling error:', error.message);
438
- }
439
- }
440
-
441
- // Continue polling
442
- setTimeout(poll, pollInterval);
443
- };
444
-
445
- // Start polling
446
- setTimeout(poll, pollInterval);
447
- });
448
- }
449
-
450
- getAuthConfig(): AuthConfig {
451
- return { ...this.authConfig, type: this.authConfig.type };
452
- }
453
-
454
- updateAuthConfig(config: Partial<AuthConfig>): void {
455
- this.authConfig = { ...this.authConfig, ...config };
456
- }
457
-
458
- /**
459
- * Configure and validate VLM for GUI Agent
460
- * Returns { model, baseUrl, apiKey } if successful, null if failed or cancelled
461
- */
462
- async configureAndValidateVLM(): Promise<{ model: string; baseUrl: string; apiKey: string } | null> {
463
- logger.info('\n🔧 Configuring VLM for GUI Agent...', 'Vision-Language Model for browser/desktop automation\n');
464
-
465
- const { provider } = await inquirer.prompt([
466
- {
467
- type: 'list',
468
- name: 'provider',
469
- message: 'Select VLM provider for GUI automation:',
470
- choices: VLM_PROVIDERS.map(p => ({
471
- name: `${p.name}`,
472
- value: p
473
- }))
474
- }
475
- ]);
476
-
477
- const selectedProvider = provider as VLMProviderInfo;
478
-
479
- logger.info(`\nSelected: ${selectedProvider.name}`);
480
- logger.info(`API URL: ${selectedProvider.baseUrl}`);
481
- logger.info(`Available models: ${selectedProvider.models.join(', ')}`);
482
-
483
- const { selectedModel } = await inquirer.prompt([
484
- {
485
- type: 'list',
486
- name: 'selectedModel',
487
- message: 'Select VLM model:',
488
- choices: selectedProvider.models.map(model => ({
489
- name: model === selectedProvider.defaultModel ? `${model} (default)` : model,
490
- value: model
491
- }))
492
- }
493
- ]);
494
-
495
- const { baseUrl } = await inquirer.prompt([
496
- {
497
- type: 'input',
498
- name: 'baseUrl',
499
- message: 'Enter VLM API Base URL:',
500
- default: selectedProvider.baseUrl,
501
- validate: (input: string) => {
502
- if (!input || input.trim().length === 0) {
503
- return 'Base URL cannot be empty';
504
- }
505
- return true;
506
- }
507
- }
508
- ]);
509
-
510
- const { apiKey } = await inquirer.prompt([
511
- {
512
- type: 'password',
513
- name: 'apiKey',
514
- message: `Enter ${selectedProvider.name} API Key:`,
515
- mask: '*',
516
- validate: (input: string) => {
517
- if (!input || input.trim().length === 0) {
518
- return 'API Key cannot be empty';
519
- }
520
- return true;
521
- }
522
- }
523
- ]);
524
-
525
- const vlmConfig = {
526
- model: selectedModel as string,
527
- baseUrl: (baseUrl as string).trim(),
528
- apiKey: (apiKey as string).trim()
529
- };
530
-
531
- const isValid = await this.validateVLMApiKey(vlmConfig.baseUrl, vlmConfig.apiKey);
532
- if (isValid) {
533
- logger.success(`${selectedProvider.name} VLM configured successfully!`, `Model: ${vlmConfig.model}`);
534
- return vlmConfig;
535
- } else {
536
- return null;
537
- }
538
- }
539
-
540
- private async validateVLMApiKey(baseUrl: string, apiKey: string): Promise<boolean> {
541
- try {
542
- const headers: Record<string, string> = {
543
- 'Content-Type': 'application/json'
544
- };
545
-
546
- // Anthropic uses x-api-key header
547
- if (baseUrl.includes('anthropic.com')) {
548
- headers['x-api-key'] = apiKey;
549
- headers['anthropic-version'] = '2023-06-01';
550
- } else {
551
- headers['Authorization'] = `Bearer ${apiKey}`;
552
- }
553
-
554
- const response = await axios.get(
555
- `${baseUrl}/models`,
556
- { headers, timeout: 10000 }
557
- );
558
- return response.status === 200;
559
- } catch (error: any) {
560
- // Provide user-friendly error messages without exposing stack traces
561
- // Distinguish between API Key errors and Base URL errors
562
-
563
- // Check if we received an HTTP response from server
564
- if (error.response) {
565
- const status = error.response.status;
566
-
567
- // Server responded but with error - API Key or permissions issue
568
- if (status === 401 || status === 403) {
569
- logger.error('VLM API authentication failed: Invalid API Key', `Verify your API Key is correct and has not expired`);
570
- } else if (status === 429) {
571
- logger.error('VLM API rate limit exceeded', `Please wait before retrying`);
572
- } else if (status === 404) {
573
- // 404 with valid response means base URL is valid but endpoint doesn't exist
574
- logger.error('VLM API error: API endpoint not found (404)', `Verify your API Base URL is correct`);
575
- } else {
576
- logger.error(`VLM API request failed (HTTP ${status})`, `Verify your API Base URL and API Key`);
577
- }
578
- return false;
579
- }
580
-
581
- // No HTTP response - server not reached or URL invalid
582
- // These indicate Base URL issues
583
- const networkErrors = ['ECONNREFUSED', 'ETIMEDOUT', 'ECONNABORTED', 'ENOTFOUND', 'EAI_AGAIN', 'EPROTO', 'ERR_INVALID_URL'];
584
-
585
- if (networkErrors.includes(error.code) ||
586
- error.message?.includes('Invalid URL') ||
587
- error.message?.includes('getaddrinfo') ||
588
- error.message?.includes('socket hang up')) {
589
- logger.error('VLM API connection failed: Unable to reach the server', `Verify your API Base URL is correct and accessible`);
590
- return false;
591
- }
592
-
593
- // Fallback for unknown errors
594
- logger.error('VLM API request failed', `Verify your API Base URL and API Key`);
595
- return false;
596
- }
597
- }
598
- }
599
-
600
- export async function selectAuthType(): Promise<AuthType> {
601
- const { authType } = await inquirer.prompt([
602
- {
603
- type: 'list',
604
- name: 'authType',
605
- message: 'Select authentication method:',
606
- choices: [
607
- { name: 'Log in with xAgent – Start your free trial', value: AuthType.OAUTH_XAGENT },
608
- { name: 'Use third-party model APIs (e.g., Zhipu GLM-4.7, MiniMax)', value: AuthType.OPENAI_COMPATIBLE }
609
- ]
610
- }
611
- ]);
612
-
613
- return authType;
614
- }
1
+ import axios from 'axios';
2
+ import open from 'open';
3
+ import { select, confirm, text, password } from '@clack/prompts';
4
+ import https from 'https';
5
+ import { AuthConfig, AuthType } from './types.js';
6
+ import { getLogger } from './logger.js';
7
+
8
+ const logger = getLogger();
9
+
10
+ // Debug: Log environment variable at module load time
11
+ logger.debug('[AUTH-MODULE] XAGENT_BASE_URL:', process.env.XAGENT_BASE_URL || '(not set)');
12
+
13
+ // Extended AuthConfig for xAgent with additional fields
14
+ interface XAgentAuthConfig extends AuthConfig {
15
+ xagentApiBaseUrl?: string;
16
+ remote_llmModelName?: string; // Remote mode LLM Model Name
17
+ remote_vlmModelName?: string; // Remote mode VLM Model Name
18
+ }
19
+
20
+ export interface VLMProviderInfo {
21
+ name: string;
22
+ provider: string;
23
+ baseUrl: string;
24
+ defaultModel: string;
25
+ models: string[];
26
+ }
27
+
28
+ export const VLM_PROVIDERS: VLMProviderInfo[] = [
29
+ {
30
+ name: 'OpenAI',
31
+ provider: 'openai',
32
+ baseUrl: 'https://api.openai.com/v1',
33
+ defaultModel: 'gpt-4o',
34
+ models: ['gpt-5', 'gpt-4o', 'gpt-4o-mini', 'gpt-5-mini'],
35
+ },
36
+ {
37
+ name: 'Volcengine (Doubao)',
38
+ provider: 'volcengine',
39
+ baseUrl: 'https://ark.cn-beijing.volces.com/api/v3',
40
+ defaultModel: 'doubao-seed-1-8-251228',
41
+ models: ['doubao-seed-1-8-251228', 'doubao-1-5-ui-tars-250428', 'seed1.5-vl'],
42
+ },
43
+ {
44
+ name: 'Anthropic',
45
+ provider: 'anthropic',
46
+ baseUrl: 'https://api.anthropic.com/v1',
47
+ defaultModel: 'claude-sonnet-4-5',
48
+ models: ['claude-sonnet-4-5', 'claude-opus-4-5', 'claude-sonnet-4', 'claude-opus-4'],
49
+ },
50
+ ];
51
+
52
+ export interface ThirdPartyProvider {
53
+ name: string;
54
+ baseUrl: string;
55
+ defaultModel: string;
56
+ description: string;
57
+ models?: string[];
58
+ }
59
+
60
+ export const THIRD_PARTY_PROVIDERS: ThirdPartyProvider[] = [
61
+ {
62
+ name: 'Zhipu AI (GLM-4)',
63
+ baseUrl: 'https://open.bigmodel.cn/api/coding/paas/v4/',
64
+ defaultModel: 'glm-4.7',
65
+ description: 'Zhipu AI GLM-4 series models',
66
+ models: [
67
+ 'glm-4.7',
68
+ 'glm-4',
69
+ 'glm-4-plus',
70
+ 'glm-4-0520',
71
+ 'glm-4-air',
72
+ 'glm-4-airx',
73
+ 'glm-4-flash',
74
+ 'glm-4.7-plus',
75
+ ],
76
+ },
77
+ {
78
+ name: 'DeepSeek',
79
+ baseUrl: 'https://api.deepseek.com/v1',
80
+ defaultModel: 'deepseek-chat',
81
+ description: 'DeepSeek DeepSeek series models',
82
+ models: ['deepseek-chat', 'deepseek-coder', 'deepseek-reasoner'],
83
+ },
84
+ {
85
+ name: 'Alibaba Tongyi Qianwen',
86
+ baseUrl: 'https://dashscope.aliyuncs.com/compatible-mode/v1',
87
+ defaultModel: 'qwen-max',
88
+ description: 'Alibaba Cloud Tongyi Qianwen series models',
89
+ models: ['qwen-max', 'qwen-plus', 'qwen-turbo', 'qwen-long', 'qwen-vl-max', 'qwen-vl-plus'],
90
+ },
91
+ {
92
+ name: 'Baidu Wenxin Yiyan',
93
+ baseUrl: 'https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat',
94
+ defaultModel: 'ernie-bot-4',
95
+ description: 'Baidu Intelligent Cloud Wenxin Yiyan series models',
96
+ models: ['ernie-bot-4', 'ernie-bot-turbo', 'ernie-speed', 'ernie-speed-128k', 'ernie-lite-8k'],
97
+ },
98
+ {
99
+ name: 'Moonshot AI (Kimi)',
100
+ baseUrl: 'https://api.moonshot.cn/v1',
101
+ defaultModel: 'moonshot-v1-8k',
102
+ description: 'Moonshot AI Kimi series models',
103
+ models: ['moonshot-v1-8k', 'moonshot-v1-32k', 'moonshot-v1-128k'],
104
+ },
105
+ {
106
+ name: 'MiniMax',
107
+ baseUrl: 'https://api.minimax.chat/anthropic',
108
+ defaultModel: 'MiniMax-M2.1',
109
+ description: 'MiniMax (Anthropic-compatible format)',
110
+ models: ['MiniMax-M2.1', 'MiniMax-M2.1-lightning', 'MiniMax-M2', 'MiniMax-M2-Stable'],
111
+ },
112
+ {
113
+ name: '01.AI (Yi)',
114
+ baseUrl: 'https://api.lingyiwanwu.com/v1',
115
+ defaultModel: 'yi-large',
116
+ description: '01.AI Yi series models',
117
+ models: ['yi-large', 'yi-large-turbo', 'yi-medium', 'yi-spark', 'yi-vision'],
118
+ },
119
+ {
120
+ name: 'Baichuan Intelligence (Baichuan)',
121
+ baseUrl: 'https://api.baichuan-ai.com/v1',
122
+ defaultModel: 'Baichuan4',
123
+ description: 'Baichuan Intelligence Baichuan series models',
124
+ models: ['Baichuan4', 'Baichuan3-Turbo', 'Baichuan3-Turbo-128k', 'Baichuan-Text-Embedding'],
125
+ },
126
+ {
127
+ name: 'Tencent Hunyuan',
128
+ baseUrl: 'https://hunyuan.cloud.tencent.com/hyllm/v1',
129
+ defaultModel: 'hunyuan-pro',
130
+ description: 'Tencent Hunyuan series models',
131
+ models: ['hunyuan-pro', 'hunyuan-standard', 'hunyuan-lite', 'hunyuan-vision'],
132
+ },
133
+ {
134
+ name: 'iFlytek (SparkDesk)',
135
+ baseUrl: 'https://spark-api-open.xf-yun.com/v1',
136
+ defaultModel: 'spark-pro',
137
+ description: 'iFlytek Spark cognitive large model',
138
+ models: ['spark-pro', 'spark-ultra', 'spark-max', 'spark-lite'],
139
+ },
140
+ {
141
+ name: 'Custom',
142
+ baseUrl: '',
143
+ defaultModel: '',
144
+ description: 'Manually enter API configuration',
145
+ models: [],
146
+ },
147
+ ];
148
+
149
+ export class AuthService {
150
+ private authConfig: XAgentAuthConfig;
151
+
152
+ constructor(authConfig: XAgentAuthConfig) {
153
+ this.authConfig = authConfig;
154
+ }
155
+
156
+ async authenticate(): Promise<boolean> {
157
+ let result: boolean;
158
+ switch (this.authConfig.type) {
159
+ case AuthType.OAUTH_XAGENT:
160
+ result = await this.authenticateWithXAgent();
161
+ break;
162
+ case AuthType.OPENAI_COMPATIBLE:
163
+ result = await this.authenticateWithOpenAICompatible();
164
+ break;
165
+ default:
166
+ throw new Error(`Unknown auth type: ${this.authConfig.type}`);
167
+ }
168
+
169
+ return result;
170
+ }
171
+
172
+ private async authenticateWithXAgent(): Promise<boolean> {
173
+ logger.info(
174
+ 'Authenticating with xAgent...',
175
+ 'Please complete the authentication in your browser'
176
+ );
177
+
178
+ try {
179
+ // 1. Start HTTP server to receive callback
180
+ const token = await this.retrieveXAgentToken();
181
+
182
+ // 2. 调用后端验证用户
183
+ const xagentApiBaseUrl = this.authConfig.xagentApiBaseUrl || 'https://www.xagent-colife.net';
184
+ const httpsAgent = new https.Agent({ rejectUnauthorized: false });
185
+ const response = await axios.get(`${xagentApiBaseUrl}/api/auth/me`, {
186
+ headers: { Authorization: `Bearer ${token}` },
187
+ httpsAgent,
188
+ });
189
+
190
+ // 3. Set authentication configuration
191
+ this.authConfig.baseUrl = `${xagentApiBaseUrl}/v1`;
192
+ this.authConfig.xagentApiBaseUrl = xagentApiBaseUrl;
193
+ this.authConfig.apiKey = token;
194
+ this.authConfig.type = AuthType.OAUTH_XAGENT;
195
+
196
+ logger.success('Successfully authenticated with xAgent!');
197
+ return true;
198
+ } catch (error: any) {
199
+ logger.error('Authentication failed', error.message || 'Unknown error');
200
+ logger.debug('Full error:', JSON.stringify(error.response?.data || error.message));
201
+ return false;
202
+ }
203
+ }
204
+
205
+ private async authenticateWithOpenAICompatible(): Promise<boolean> {
206
+ logger.info('Configuring third-party model API...\n');
207
+
208
+ const provider = await select({
209
+ message: 'Select third-party model provider:',
210
+ options: THIRD_PARTY_PROVIDERS.map((p) => ({
211
+ value: p,
212
+ label: `${p.name} - ${p.description}`,
213
+ })),
214
+ });
215
+
216
+ const selectedProvider = provider as ThirdPartyProvider;
217
+
218
+ let baseUrl = selectedProvider.baseUrl;
219
+ let modelName = selectedProvider.defaultModel;
220
+
221
+ if (selectedProvider.name === 'Custom') {
222
+ baseUrl = (await text({
223
+ message: 'Enter API Base URL:',
224
+ defaultValue: 'https://api.openai.com/v1',
225
+ validate: (value: string | undefined) => {
226
+ if (!value || value.trim().length === 0) {
227
+ return 'Base URL cannot be empty';
228
+ }
229
+ return undefined;
230
+ },
231
+ })) as string;
232
+
233
+ modelName = (await text({
234
+ message: 'Enter model name:',
235
+ defaultValue: 'gpt-4',
236
+ validate: (value: string | undefined) => {
237
+ if (!value || value.trim().length === 0) {
238
+ return 'Model name cannot be empty';
239
+ }
240
+ return undefined;
241
+ },
242
+ })) as string;
243
+
244
+ baseUrl = baseUrl.trim();
245
+ modelName = modelName.trim();
246
+ } else {
247
+ logger.info(`\nSelected: ${selectedProvider.name}`);
248
+ logger.info(`API URL: ${baseUrl}`);
249
+
250
+ if (selectedProvider.models && selectedProvider.models.length > 0) {
251
+ logger.info(`Available models: ${selectedProvider.models.join(', ')}`);
252
+
253
+ const selectedModel = await select({
254
+ message: 'Select model:',
255
+ options: selectedProvider.models.map((model) => ({
256
+ value: model,
257
+ label: model === selectedProvider.defaultModel ? `${model} (default)` : model,
258
+ })),
259
+ });
260
+
261
+ modelName = selectedModel as string;
262
+ } else {
263
+ logger.info(`Default model: ${modelName}\n`);
264
+
265
+ const confirmModel = (await text({
266
+ message: `Enter model name (press Enter to use default value ${modelName}):`,
267
+ defaultValue: modelName,
268
+ validate: (value: string | undefined) => {
269
+ if (!value || value.trim().length === 0) {
270
+ return 'Model name cannot be empty';
271
+ }
272
+ return undefined;
273
+ },
274
+ })) as string;
275
+
276
+ modelName = confirmModel.trim();
277
+ }
278
+ }
279
+
280
+ const apiKey = (await password({
281
+ message: `Enter ${selectedProvider.name} API Key:`,
282
+ validate: (value: string | undefined) => {
283
+ if (!value || value.trim().length === 0) {
284
+ return 'API Key cannot be empty';
285
+ }
286
+ return undefined;
287
+ },
288
+ })) as string;
289
+
290
+ this.authConfig.baseUrl = baseUrl;
291
+ this.authConfig.apiKey = apiKey.trim();
292
+ this.authConfig.modelName = modelName;
293
+ this.authConfig.type = AuthType.OPENAI_COMPATIBLE;
294
+
295
+ const isValid = await this.validateApiKey();
296
+ if (isValid) {
297
+ logger.success(
298
+ `${selectedProvider.name} configured successfully!`,
299
+ `Model: ${modelName}, API: ${baseUrl}`
300
+ );
301
+ logger.info(` Model: ${modelName}`);
302
+ logger.info(` API URL: ${baseUrl}`);
303
+ return true;
304
+ } else {
305
+ logger.error(
306
+ `${selectedProvider.name} configuration verification failed, please check API Key and network connection.`,
307
+ 'Verify your API Key and network connection'
308
+ );
309
+ return false;
310
+ }
311
+ }
312
+
313
+ private async validateApiKey(): Promise<boolean> {
314
+ try {
315
+ // Check if it's MiniMax-M2 (uses Anthropic format)
316
+ if (
317
+ (this.authConfig.baseUrl?.includes('minimax.chat') ||
318
+ this.authConfig.baseUrl?.includes('minimaxi.com')) &&
319
+ this.authConfig.baseUrl?.includes('anthropic')
320
+ ) {
321
+ // MiniMax-M2 uses Anthropic format with x-api-key header
322
+ const response = await axios.post(
323
+ `${this.authConfig.baseUrl}/v1/messages`,
324
+ {
325
+ model: 'MiniMax-M2',
326
+ max_tokens: 1,
327
+ messages: [{ role: 'user', content: 'test' }],
328
+ },
329
+ {
330
+ headers: {
331
+ 'x-api-key': this.authConfig.apiKey,
332
+ 'anthropic-version': '2023-06-01',
333
+ 'Content-Type': 'application/json',
334
+ },
335
+ timeout: 10000,
336
+ }
337
+ );
338
+ return response.status === 200;
339
+ }
340
+
341
+ // Standard OpenAI compatible API
342
+ const response = await axios.get(`${this.authConfig.baseUrl}/models`, {
343
+ headers: {
344
+ Authorization: `Bearer ${this.authConfig.apiKey}`,
345
+ 'Content-Type': 'application/json',
346
+ },
347
+ timeout: 10000,
348
+ });
349
+ return response.status === 200;
350
+ } catch (error: any) {
351
+ // Provide user-friendly error messages without exposing stack traces
352
+ if (error.response) {
353
+ const status = error.response.status;
354
+
355
+ if (status === 401) {
356
+ logger.error(
357
+ 'API Key verification failed: Invalid or expired API Key',
358
+ `Verify your API Key is correct and has not expired`
359
+ );
360
+ } else if (status === 403) {
361
+ logger.error(
362
+ 'API Key verification failed: Access denied',
363
+ `Check if your API Key has permission to access`
364
+ );
365
+ } else if (status === 404) {
366
+ logger.error(
367
+ 'API request failed: API endpoint not found',
368
+ `Verify your API Base URL is correct`
369
+ );
370
+ } else if (status === 429) {
371
+ logger.error('API rate limit exceeded', `Please wait before retrying`);
372
+ } else {
373
+ logger.error(
374
+ `API Key verification failed (HTTP ${status})`,
375
+ `Verify your API Key and network connection`
376
+ );
377
+ }
378
+ } else if (error.code === 'ECONNREFUSED') {
379
+ logger.error(
380
+ 'Failed to connect to API server',
381
+ `Verify your API Base URL and network connection`
382
+ );
383
+ } else if (error.code === 'ETIMEDOUT' || error.code === 'ECONNABORTED') {
384
+ logger.error('API request timed out', `Check your network connection and try again`);
385
+ } else {
386
+ logger.error('API Key verification failed', `Verify your API Key and network connection`);
387
+ }
388
+ return false;
389
+ }
390
+ }
391
+
392
+ private async retrieveXAgentToken(): Promise<string> {
393
+ // Debug: Log environment variable at method call time
394
+ logger.debug('[AUTH-METHOD] XAGENT_BASE_URL:', process.env.XAGENT_BASE_URL || '(not set)');
395
+
396
+ // Use xagentApiBaseUrl from config, fallback to default
397
+ const webBaseUrl = this.authConfig.xagentApiBaseUrl || 'https://www.xagent-colife.net';
398
+ logger.debug('[AUTH] authConfig.xagentApiBaseUrl:', this.authConfig.xagentApiBaseUrl);
399
+ logger.debug('[AUTH] webBaseUrl:', webBaseUrl);
400
+
401
+ // Determine if we're in local development mode
402
+ const isLocalDev = webBaseUrl.includes('localhost') || webBaseUrl.includes('127.0.0.1');
403
+
404
+ // Use frontend URL for login - both local dev and production use frontend routing
405
+ // Local dev: frontend runs on port 3000
406
+ // Production: frontend is served via nginx reverse proxy at the same domain
407
+ let loginUrl: string;
408
+ let callbackUrl: string;
409
+
410
+ // Always use frontend URL for login page
411
+ const frontendUrl = isLocalDev
412
+ ? process.env.FRONTEND_URL || 'http://localhost:3000'
413
+ : webBaseUrl;
414
+
415
+ callbackUrl = `${webBaseUrl}/callback`;
416
+ loginUrl = `${frontendUrl}/login?callback=${encodeURIComponent(callbackUrl)}`;
417
+
418
+ // 如果已有保存的token,通过URL参数传给Web页面
419
+ const existingToken = this.authConfig.apiKey;
420
+ const existingRefreshToken = this.authConfig.refreshToken;
421
+
422
+ // 构建登录URL - 如果已有token也传给Web
423
+ if (existingToken) {
424
+ loginUrl += `&existingToken=${encodeURIComponent(existingToken)}`;
425
+ if (existingRefreshToken) {
426
+ loginUrl += `&existingRefreshToken=${encodeURIComponent(existingRefreshToken)}`;
427
+ }
428
+ }
429
+
430
+ logger.debug('[AUTH] Opening login URL:', loginUrl);
431
+
432
+ // Open browser for login, then poll server for token
433
+ await open(loginUrl);
434
+ logger.info('Waiting for authentication...', 'Please complete login in your browser');
435
+
436
+ // Poll server to get token
437
+ return new Promise((resolve, reject) => {
438
+ const pollInterval = 2000; // Poll every 2 seconds
439
+ const maxWaitTime = 30 * 60 * 1000; // 30 minutes timeout
440
+ const startTime = Date.now();
441
+
442
+ const poll = async () => {
443
+ if (Date.now() - startTime > maxWaitTime) {
444
+ logger.warn('Authentication timeout after 30 minutes');
445
+ reject(new Error('Authentication timeout'));
446
+ return;
447
+ }
448
+
449
+ try {
450
+ // Create HTTPS agent that ignores certificate errors (for IP-based access)
451
+ const httpsAgent = new https.Agent({ rejectUnauthorized: false });
452
+
453
+ const response = await axios.get(`${webBaseUrl}/api/cli/get-token`, {
454
+ timeout: 10000,
455
+ httpsAgent,
456
+ });
457
+
458
+ if (response.data.token) {
459
+ logger.success('Authentication successful! Received token');
460
+ logger.debug(
461
+ '[CLI-Auth] Token stored, key:',
462
+ response.data.token.substring(0, 20) + '...'
463
+ );
464
+ // Save refresh token if provided
465
+ if (response.data.refreshToken) {
466
+ this.authConfig.refreshToken = response.data.refreshToken;
467
+ }
468
+ resolve(response.data.token);
469
+ return;
470
+ }
471
+ } catch (error: any) {
472
+ if (error.response?.status === 404) {
473
+ // Token not ready yet, continue polling
474
+ } else {
475
+ console.error('[CLI-Auth] Polling error:', error.message);
476
+ }
477
+ }
478
+
479
+ // Continue polling
480
+ setTimeout(poll, pollInterval);
481
+ };
482
+
483
+ // Start polling
484
+ setTimeout(poll, pollInterval);
485
+ });
486
+ }
487
+
488
+ getAuthConfig(): AuthConfig {
489
+ return { ...this.authConfig, type: this.authConfig.type };
490
+ }
491
+
492
+ updateAuthConfig(config: Partial<AuthConfig>): void {
493
+ this.authConfig = { ...this.authConfig, ...config };
494
+ }
495
+
496
+ /**
497
+ * Configure and validate VLM for GUI Agent
498
+ * Returns { model, baseUrl, apiKey } if successful, null if failed or cancelled
499
+ */
500
+ async configureAndValidateVLM(): Promise<{
501
+ model: string;
502
+ baseUrl: string;
503
+ apiKey: string;
504
+ } | null> {
505
+ logger.info(
506
+ '\n🔧 Configuring VLM for GUI Agent...',
507
+ 'Vision-Language Model for browser/desktop automation\n'
508
+ );
509
+
510
+ const provider = await select({
511
+ message: 'Select VLM provider for GUI automation:',
512
+ options: VLM_PROVIDERS.map((p) => ({
513
+ value: p,
514
+ label: `${p.name}`,
515
+ })),
516
+ });
517
+
518
+ const selectedProvider = provider as VLMProviderInfo;
519
+
520
+ logger.info(`\nSelected: ${selectedProvider.name}`);
521
+ logger.info(`API URL: ${selectedProvider.baseUrl}`);
522
+ logger.info(`Available models: ${selectedProvider.models.join(', ')}`);
523
+
524
+ const selectedModel = await select({
525
+ message: 'Select VLM model:',
526
+ options: selectedProvider.models.map((model) => ({
527
+ value: model,
528
+ label: model === selectedProvider.defaultModel ? `${model} (default)` : model,
529
+ })),
530
+ });
531
+
532
+ const baseUrl = (await text({
533
+ message: 'Enter VLM API Base URL:',
534
+ defaultValue: selectedProvider.baseUrl,
535
+ validate: (value: string | undefined) => {
536
+ if (!value || value.trim().length === 0) {
537
+ return 'Base URL cannot be empty';
538
+ }
539
+ return undefined;
540
+ },
541
+ })) as string;
542
+
543
+ const apiKey = (await password({
544
+ message: `Enter ${selectedProvider.name} API Key:`,
545
+ validate: (value: string | undefined) => {
546
+ if (!value || value.trim().length === 0) {
547
+ return 'API Key cannot be empty';
548
+ }
549
+ return undefined;
550
+ },
551
+ })) as string;
552
+
553
+ const vlmConfig = {
554
+ model: selectedModel as string,
555
+ baseUrl: baseUrl.trim(),
556
+ apiKey: apiKey.trim(),
557
+ };
558
+
559
+ const isValid = await this.validateVLMApiKey(vlmConfig.baseUrl, vlmConfig.apiKey);
560
+ if (isValid) {
561
+ logger.success(
562
+ `${selectedProvider.name} VLM configured successfully!`,
563
+ `Model: ${vlmConfig.model}`
564
+ );
565
+ return vlmConfig;
566
+ } else {
567
+ return null;
568
+ }
569
+ }
570
+
571
+ private async validateVLMApiKey(baseUrl: string, apiKey: string): Promise<boolean> {
572
+ try {
573
+ const headers: Record<string, string> = {
574
+ 'Content-Type': 'application/json',
575
+ };
576
+
577
+ // Anthropic uses x-api-key header
578
+ if (baseUrl.includes('anthropic.com')) {
579
+ headers['x-api-key'] = apiKey;
580
+ headers['anthropic-version'] = '2023-06-01';
581
+ } else {
582
+ headers['Authorization'] = `Bearer ${apiKey}`;
583
+ }
584
+
585
+ const response = await axios.get(`${baseUrl}/models`, { headers, timeout: 10000 });
586
+ return response.status === 200;
587
+ } catch (error: any) {
588
+ // Provide user-friendly error messages without exposing stack traces
589
+ // Distinguish between API Key errors and Base URL errors
590
+
591
+ // Check if we received an HTTP response from server
592
+ if (error.response) {
593
+ const status = error.response.status;
594
+
595
+ // Server responded but with error - API Key or permissions issue
596
+ if (status === 401 || status === 403) {
597
+ logger.error(
598
+ 'VLM API authentication failed: Invalid API Key',
599
+ `Verify your API Key is correct and has not expired`
600
+ );
601
+ } else if (status === 429) {
602
+ logger.error('VLM API rate limit exceeded', `Please wait before retrying`);
603
+ } else if (status === 404) {
604
+ // 404 with valid response means base URL is valid but endpoint doesn't exist
605
+ logger.error(
606
+ 'VLM API error: API endpoint not found (404)',
607
+ `Verify your API Base URL is correct`
608
+ );
609
+ } else {
610
+ logger.error(
611
+ `VLM API request failed (HTTP ${status})`,
612
+ `Verify your API Base URL and API Key`
613
+ );
614
+ }
615
+ return false;
616
+ }
617
+
618
+ // No HTTP response - server not reached or URL invalid
619
+ // These indicate Base URL issues
620
+ const networkErrors = [
621
+ 'ECONNREFUSED',
622
+ 'ETIMEDOUT',
623
+ 'ECONNABORTED',
624
+ 'ENOTFOUND',
625
+ 'EAI_AGAIN',
626
+ 'EPROTO',
627
+ 'ERR_INVALID_URL',
628
+ ];
629
+
630
+ if (
631
+ networkErrors.includes(error.code) ||
632
+ error.message?.includes('Invalid URL') ||
633
+ error.message?.includes('getaddrinfo') ||
634
+ error.message?.includes('socket hang up')
635
+ ) {
636
+ logger.error(
637
+ 'VLM API connection failed: Unable to reach the server',
638
+ `Verify your API Base URL is correct and accessible`
639
+ );
640
+ return false;
641
+ }
642
+
643
+ // Fallback for unknown errors
644
+ logger.error('VLM API request failed', `Verify your API Base URL and API Key`);
645
+ return false;
646
+ }
647
+ }
648
+ }
649
+
650
+ export async function selectAuthType(): Promise<AuthType> {
651
+ const authType = (await select({
652
+ message: 'Select authentication method:',
653
+ options: [
654
+ { value: AuthType.OAUTH_XAGENT, label: 'Log in with xAgent – Start your free trial' },
655
+ {
656
+ value: AuthType.OPENAI_COMPATIBLE,
657
+ label: 'Use third-party model APIs (e.g., Zhipu GLM-4.7, MiniMax)',
658
+ },
659
+ ],
660
+ })) as AuthType;
661
+
662
+ return authType;
663
+ }