@xagent-ai/cli 1.2.2 → 1.3.1

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