@cloudbase/cli 2.10.0 → 2.11.0-beta.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 (205) hide show
  1. package/lib/auth/login.js +51 -65
  2. package/lib/auth/logout.js +3 -14
  3. package/lib/commands/account/login.js +136 -149
  4. package/lib/commands/account/logout.js +3 -14
  5. package/lib/commands/ag/base.js +203 -0
  6. package/lib/commands/ag/create.js +301 -0
  7. package/lib/commands/ag/debug/index.html +699 -0
  8. package/lib/commands/ag/delete.js +200 -0
  9. package/lib/commands/ag/deploy.js +185 -0
  10. package/lib/commands/ag/detail.js +113 -0
  11. package/lib/commands/ag/index.js +22 -0
  12. package/lib/commands/ag/list.js +155 -0
  13. package/lib/commands/ag/run.js +644 -0
  14. package/lib/commands/ai/index.js +76 -95
  15. package/lib/commands/cloudfunction/base.js +182 -203
  16. package/lib/commands/cloudrun/base.js +578 -603
  17. package/lib/commands/common.js +48 -63
  18. package/lib/commands/config/delete.js +16 -27
  19. package/lib/commands/config/get.js +13 -24
  20. package/lib/commands/config/list.js +16 -27
  21. package/lib/commands/config/set.js +33 -44
  22. package/lib/commands/db/base.js +221 -240
  23. package/lib/commands/env/base.js +36 -49
  24. package/lib/commands/env/domain.js +79 -94
  25. package/lib/commands/env/login.js +120 -135
  26. package/lib/commands/framework/index.js +32 -49
  27. package/lib/commands/fun/base.js +223 -244
  28. package/lib/commands/functions/alias/getRoute.js +33 -44
  29. package/lib/commands/functions/alias/setRoute.js +36 -47
  30. package/lib/commands/functions/code-download.js +43 -54
  31. package/lib/commands/functions/code-update.js +23 -34
  32. package/lib/commands/functions/concurrency/delete.js +11 -22
  33. package/lib/commands/functions/concurrency/list.js +20 -31
  34. package/lib/commands/functions/concurrency/set.js +13 -24
  35. package/lib/commands/functions/config-update.js +30 -41
  36. package/lib/commands/functions/copy.js +12 -23
  37. package/lib/commands/functions/delete.js +30 -41
  38. package/lib/commands/functions/deploy.js +184 -202
  39. package/lib/commands/functions/detail.js +23 -34
  40. package/lib/commands/functions/invoke.js +69 -75
  41. package/lib/commands/functions/layer/bind.js +102 -105
  42. package/lib/commands/functions/layer/create.js +29 -35
  43. package/lib/commands/functions/layer/delete.js +42 -48
  44. package/lib/commands/functions/layer/download.js +52 -58
  45. package/lib/commands/functions/layer/list.js +44 -50
  46. package/lib/commands/functions/layer/sort.js +39 -45
  47. package/lib/commands/functions/list.js +25 -36
  48. package/lib/commands/functions/log.js +65 -73
  49. package/lib/commands/functions/run.js +118 -116
  50. package/lib/commands/functions/trigger-create.js +32 -43
  51. package/lib/commands/functions/trigger-delete.js +50 -61
  52. package/lib/commands/functions/version/list.js +29 -40
  53. package/lib/commands/functions/version/publish.js +11 -22
  54. package/lib/commands/gateway/create.js +50 -61
  55. package/lib/commands/gateway/delete.js +38 -49
  56. package/lib/commands/gateway/domain.js +65 -80
  57. package/lib/commands/gateway/list.js +31 -42
  58. package/lib/commands/gateway/switch.js +48 -61
  59. package/lib/commands/helpers/init.js +226 -249
  60. package/lib/commands/helpers/new.js +35 -46
  61. package/lib/commands/helpers/open.js +22 -33
  62. package/lib/commands/hosting/hosting.js +157 -178
  63. package/lib/commands/index.js +1 -0
  64. package/lib/commands/lowcode/app.js +114 -144
  65. package/lib/commands/lowcode/comps.js +136 -127
  66. package/lib/commands/lowcode/utils.js +11 -22
  67. package/lib/commands/pull/pull.js +33 -46
  68. package/lib/commands/run/delete.js +35 -46
  69. package/lib/commands/run/image/delete.js +32 -39
  70. package/lib/commands/run/image/download.js +26 -33
  71. package/lib/commands/run/image/list.js +41 -48
  72. package/lib/commands/run/image/upload.js +26 -33
  73. package/lib/commands/run/list.js +32 -43
  74. package/lib/commands/run/service/config.js +17 -28
  75. package/lib/commands/run/service/deploy.js +15 -26
  76. package/lib/commands/run/service/list.js +48 -59
  77. package/lib/commands/run/service/update.js +7 -18
  78. package/lib/commands/run/standalonegateway/create.js +35 -42
  79. package/lib/commands/run/standalonegateway/destroy.js +23 -30
  80. package/lib/commands/run/standalonegateway/list.js +19 -26
  81. package/lib/commands/run/standalonegateway/package.js +31 -38
  82. package/lib/commands/run/standalonegateway/turn.js +27 -34
  83. package/lib/commands/run/version/create.js +198 -205
  84. package/lib/commands/run/version/delete.js +31 -38
  85. package/lib/commands/run/version/list.js +42 -49
  86. package/lib/commands/run/version/modify.js +27 -34
  87. package/lib/commands/run/version/update.js +201 -208
  88. package/lib/commands/runf/base.js +216 -237
  89. package/lib/commands/self-update.js +59 -72
  90. package/lib/commands/smart.js +66 -79
  91. package/lib/commands/storage/storage.js +192 -219
  92. package/lib/commands/third/thirdAttach.js +16 -27
  93. package/lib/commands/utils.js +119 -149
  94. package/lib/db/index.js +48 -67
  95. package/lib/decorators/captureError.js +10 -21
  96. package/lib/decorators/guard.js +11 -22
  97. package/lib/decorators/injectParams.js +29 -40
  98. package/lib/decorators/params/common.js +5 -2
  99. package/lib/decorators/params/index.js +3 -12
  100. package/lib/env/domain.js +13 -28
  101. package/lib/env/index.js +25 -44
  102. package/lib/env/login.js +30 -45
  103. package/lib/function/alias.js +31 -44
  104. package/lib/function/base.js +187 -215
  105. package/lib/function/code.js +8 -19
  106. package/lib/function/concurrency.js +43 -58
  107. package/lib/function/create.js +43 -53
  108. package/lib/function/delete.js +22 -35
  109. package/lib/function/layer/attach.js +33 -46
  110. package/lib/function/layer/create.js +34 -45
  111. package/lib/function/layer/delete.js +5 -16
  112. package/lib/function/layer/download.js +11 -22
  113. package/lib/function/layer/list.js +12 -25
  114. package/lib/function/layer/sort.js +6 -17
  115. package/lib/function/trigger.js +65 -82
  116. package/lib/function/update.js +24 -32
  117. package/lib/function/version.js +29 -42
  118. package/lib/function/vpc.js +12 -25
  119. package/lib/gateway/index.js +77 -104
  120. package/lib/hosting.js +157 -188
  121. package/lib/run/delete.js +3 -12
  122. package/lib/run/image/build.js +6 -15
  123. package/lib/run/image/delete.js +3 -12
  124. package/lib/run/image/info.js +3 -12
  125. package/lib/run/image/list.js +6 -15
  126. package/lib/run/list.js +19 -30
  127. package/lib/run/repo.js +6 -15
  128. package/lib/run/service/common.js +160 -173
  129. package/lib/run/service/config.js +44 -57
  130. package/lib/run/service/deployPackage.js +33 -44
  131. package/lib/run/service/list.js +8 -14
  132. package/lib/run/service/showLogs.js +69 -90
  133. package/lib/run/service/update.js +50 -63
  134. package/lib/run/standalonegateway/create.js +3 -12
  135. package/lib/run/standalonegateway/destroy.js +3 -12
  136. package/lib/run/standalonegateway/list.js +3 -12
  137. package/lib/run/standalonegateway/package/list.js +3 -12
  138. package/lib/run/standalonegateway/turn/off.js +3 -12
  139. package/lib/run/standalonegateway/turn/on.js +3 -12
  140. package/lib/run/version/create.js +41 -31
  141. package/lib/run/version/delete.js +3 -12
  142. package/lib/run/version/list.js +3 -12
  143. package/lib/run/version/modify.js +3 -12
  144. package/lib/run/version/repo.js +6 -15
  145. package/lib/run/version/update.js +37 -26
  146. package/lib/storage.js +62 -93
  147. package/lib/third/index.js +6 -17
  148. package/lib/utils/ai/banner.js +49 -60
  149. package/lib/utils/ai/claudeWindows.js +2 -2
  150. package/lib/utils/ai/config.js +169 -206
  151. package/lib/utils/ai/ensureFiles.js +6 -17
  152. package/lib/utils/ai/env.js +16 -27
  153. package/lib/utils/ai/envLocalManager.js +35 -52
  154. package/lib/utils/ai/router.js +927 -1005
  155. package/lib/utils/ai/setup.js +527 -563
  156. package/lib/utils/auth.js +3 -14
  157. package/lib/utils/checkTcbrEnv.js +20 -31
  158. package/lib/utils/cli-table.js +6 -1
  159. package/lib/utils/config.js +4 -13
  160. package/lib/utils/dts.js +98 -113
  161. package/lib/utils/env.js +154 -175
  162. package/lib/utils/function-packer.js +29 -42
  163. package/lib/utils/log.js +10 -21
  164. package/lib/utils/mcp-config-modifier.js +105 -120
  165. package/lib/utils/net/cloud-api-request.js +15 -23
  166. package/lib/utils/net/credential.js +26 -39
  167. package/lib/utils/net/http-request.js +63 -80
  168. package/lib/utils/net/manager-service.js +22 -35
  169. package/lib/utils/notice.js +16 -27
  170. package/lib/utils/output/loading.js +3 -12
  171. package/lib/utils/parallel.js +32 -43
  172. package/lib/utils/platform/mac.js +4 -15
  173. package/lib/utils/platform/port.js +4 -15
  174. package/lib/utils/prompt/select.js +6 -15
  175. package/lib/utils/report.js +28 -33
  176. package/lib/utils/reporter/agree.js +11 -22
  177. package/lib/utils/reporter/download.js +17 -28
  178. package/lib/utils/reporter/usage.js +12 -23
  179. package/lib/utils/store/auth.js +17 -30
  180. package/lib/utils/store/config.js +11 -25
  181. package/lib/utils/store/db.js +17 -36
  182. package/lib/utils/tcbrApi/callTcbrApi.js +19 -28
  183. package/lib/utils/template-manager.js +215 -242
  184. package/lib/utils/template.js +81 -96
  185. package/lib/utils/tools/common.js +45 -56
  186. package/lib/utils/tools/time.js +5 -16
  187. package/lib/utils/url.js +10 -4
  188. package/package.json +2 -2
  189. package/specs/ag-command/design.md +421 -0
  190. package/specs/ag-command/doc.md +204 -0
  191. package/specs/ag-command/requirements.md +173 -0
  192. package/specs/ag-command/summary.md +174 -0
  193. package/specs/ag-command/tasks.md +197 -0
  194. package/specs/ag-command/usage-guide.md +420 -0
  195. package/tsconfig.json +1 -1
  196. package/types/commands/ag/base.d.ts +44 -0
  197. package/types/commands/ag/create.d.ts +25 -0
  198. package/types/commands/ag/delete.d.ts +32 -0
  199. package/types/commands/ag/deploy.d.ts +31 -0
  200. package/types/commands/ag/detail.d.ts +28 -0
  201. package/types/commands/ag/index.d.ts +6 -0
  202. package/types/commands/ag/list.d.ts +35 -0
  203. package/types/commands/ag/run.d.ts +52 -0
  204. package/types/commands/cloudrun/base.d.ts +10 -0
  205. package/types/commands/index.d.ts +1 -0
@@ -22,15 +22,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
22
22
  __setModuleDefault(result, mod);
23
23
  return result;
24
24
  };
25
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
- return new (P || (P = Promise))(function (resolve, reject) {
28
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
- step((generator = generator.apply(thisArg, _arguments || [])).next());
32
- });
33
- };
34
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
35
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
36
27
  };
@@ -52,135 +43,125 @@ class AISetupWizard {
52
43
  this.aiConfigManager = new config_1.AIConfigManager();
53
44
  this.envId = envId;
54
45
  }
55
- setUpDefault(log, agent) {
56
- return __awaiter(this, void 0, void 0, function* () {
57
- log.info((0, i18n_1.t)('🤖 欢迎使用 CloudBase AI ToolKit CLI 配置向导'));
58
- try {
59
- this.showConfigInfo(log);
60
- const defaultAgent = agent || (yield this.selectAgent((0, i18n_1.t)('选择默认使用的 AI CLI 工具:'), false));
61
- yield this.aiConfigManager.updateDefaultAgent(defaultAgent);
62
- const currentAgent = defaultAgent;
63
- yield this.configureAgent(currentAgent, log);
64
- yield this.ensureGitignore();
65
- log.info((0, i18n_1.t)(' AI 配置完成!配置信息已保存到 .env.local 文件'));
66
- log.info((0, i18n_1.t)('💡 提示:请确保 .env.local 文件已添加到 .gitignore 以保护敏感信息'));
67
- log.info((0, i18n_1.t)('🚀 现在可以使用 tcb ai 命令了!'));
68
- return { defaultAgent };
69
- }
70
- catch (error) {
71
- throw new error_1.CloudBaseError((0, i18n_1.t)('配置向导执行失败'), { original: error });
72
- }
73
- });
46
+ async setUpDefault(log, agent) {
47
+ log.info((0, i18n_1.t)('🤖 欢迎使用 CloudBase AI ToolKit CLI 配置向导'));
48
+ try {
49
+ this.showConfigInfo(log);
50
+ const defaultAgent = agent || (await this.selectAgent((0, i18n_1.t)('选择默认使用的 AI CLI 工具:'), false));
51
+ await this.aiConfigManager.updateDefaultAgent(defaultAgent);
52
+ const currentAgent = defaultAgent;
53
+ await this.configureAgent(currentAgent, log);
54
+ await this.ensureGitignore();
55
+ log.info((0, i18n_1.t)('✅ AI 配置完成!配置信息已保存到 .env.local 文件'));
56
+ log.info((0, i18n_1.t)('💡 提示:请确保 .env.local 文件已添加到 .gitignore 以保护敏感信息'));
57
+ log.info((0, i18n_1.t)('🚀 现在可以使用 tcb ai 命令了!'));
58
+ return { defaultAgent };
59
+ }
60
+ catch (error) {
61
+ throw new error_1.CloudBaseError((0, i18n_1.t)('配置向导执行失败'), { original: error });
62
+ }
74
63
  }
75
- setUp(log) {
76
- return __awaiter(this, void 0, void 0, function* () {
77
- log.info((0, i18n_1.t)('🤖 欢迎使用 CloudBase AI ToolKit CLI 配置向导'));
78
- try {
79
- this.showConfigInfo(log);
80
- const currentAgent = yield this.selectCurrentAgent();
81
- if (currentAgent !== const_1.NONE.value) {
82
- yield this.configureAgent(currentAgent, log);
83
- }
84
- const defaultAgent = yield this.selectDefaultAgent(log);
85
- yield this.aiConfigManager.updateDefaultAgent(defaultAgent);
86
- yield this.ensureGitignore();
87
- log.info((0, i18n_1.t)('✅ AI 配置完成!配置信息已保存到 .env.local 文件'));
88
- log.info((0, i18n_1.t)('💡 提示:请确保 .env.local 文件已添加到 .gitignore 以保护敏感信息'));
89
- log.info((0, i18n_1.t)('🚀 现在可以使用 tcb ai 命令了!'));
90
- return { defaultAgent };
91
- }
92
- catch (error) {
93
- throw new error_1.CloudBaseError((0, i18n_1.t)('配置向导执行失败'), { original: error });
64
+ async setUp(log) {
65
+ log.info((0, i18n_1.t)('🤖 欢迎使用 CloudBase AI ToolKit CLI 配置向导'));
66
+ try {
67
+ this.showConfigInfo(log);
68
+ const currentAgent = await this.selectCurrentAgent();
69
+ if (currentAgent !== const_1.NONE.value) {
70
+ await this.configureAgent(currentAgent, log);
94
71
  }
95
- });
72
+ const defaultAgent = await this.selectDefaultAgent(log);
73
+ await this.aiConfigManager.updateDefaultAgent(defaultAgent);
74
+ await this.ensureGitignore();
75
+ log.info((0, i18n_1.t)('✅ AI 配置完成!配置信息已保存到 .env.local 文件'));
76
+ log.info((0, i18n_1.t)('💡 提示:请确保 .env.local 文件已添加到 .gitignore 以保护敏感信息'));
77
+ log.info((0, i18n_1.t)('🚀 现在可以使用 tcb ai 命令了!'));
78
+ return { defaultAgent };
79
+ }
80
+ catch (error) {
81
+ throw new error_1.CloudBaseError((0, i18n_1.t)('配置向导执行失败'), { original: error });
82
+ }
96
83
  }
97
- configureEnvId(log, _envId) {
98
- return __awaiter(this, void 0, void 0, function* () {
99
- let envId;
100
- if (_envId) {
101
- log.info((0, i18n_1.t)('使用传入的 envId {{envId}}', { envId: _envId }));
102
- envId = _envId;
84
+ async configureEnvId(log, _envId) {
85
+ let envId;
86
+ if (_envId) {
87
+ log.info((0, i18n_1.t)('使用传入的 envId {{envId}}', { envId: _envId }));
88
+ envId = _envId;
89
+ }
90
+ else {
91
+ log.info((0, i18n_1.t)('未传入 envId,从 cloudbaserc.json 中获取'));
92
+ const parser = (0, config_1.createConfigParser)();
93
+ const configEnvId = await parser.get('envId').catch(() => null);
94
+ if (!configEnvId || configEnvId === '{{env.ENV_ID}}') {
95
+ log.info((0, i18n_1.t)('cloudbaserc.json 中无 envId 配置!'));
96
+ const { authSupevisor } = await Promise.resolve().then(() => __importStar(require('../../utils/auth')));
97
+ let loginState = await authSupevisor.getLoginState();
98
+ if (!loginState) {
99
+ await (0, auth_1.checkLogin)();
100
+ loginState = await authSupevisor.getLoginState();
101
+ }
102
+ envId = await (0, utils_1.selectEnv)({ source: [constants_1.EnvSource.MINIAPP, constants_1.EnvSource.QCLOUD] });
103
+ log.info((0, i18n_1.t)('已选择 envId: {{envId}}', { envId }));
104
+ if (!configEnvId) {
105
+ parser.update('envId', '{{env.ENV_ID}}');
106
+ }
107
+ await this.aiConfigManager.updateEnvId(envId);
103
108
  }
104
109
  else {
105
- log.info((0, i18n_1.t)('未传入 envId,从 cloudbaserc.json 中获取'));
106
- const parser = (0, config_1.createConfigParser)();
107
- const configEnvId = yield parser.get('envId').catch(() => null);
108
- if (!configEnvId || configEnvId === '{{env.ENV_ID}}') {
109
- log.info((0, i18n_1.t)('cloudbaserc.json 中无 envId 配置!'));
110
- const { authSupevisor } = yield Promise.resolve().then(() => __importStar(require('../../utils/auth')));
111
- let loginState = yield authSupevisor.getLoginState();
112
- if (!loginState) {
113
- yield (0, auth_1.checkLogin)();
114
- loginState = yield authSupevisor.getLoginState();
110
+ envId = configEnvId;
111
+ log.info((0, i18n_1.t)('使用 cloudbaserc.json 中的 envId: {{envId}}', { envId: configEnvId }));
112
+ const { shouldUpdateEnvId } = await inquirer_1.default.prompt([
113
+ {
114
+ type: 'confirm',
115
+ name: 'shouldUpdateEnvId',
116
+ message: (0, i18n_1.t)('当前使用的 envId 为 {{envId}},是否需要更新? {{hint}}', {
117
+ envId: configEnvId,
118
+ hint: (0, const_1.getBooleanHint)(false)
119
+ }),
120
+ default: false
115
121
  }
116
- envId = yield (0, utils_1.selectEnv)({ source: [constants_1.EnvSource.MINIAPP, constants_1.EnvSource.QCLOUD] });
122
+ ]);
123
+ if (shouldUpdateEnvId) {
124
+ await (0, auth_1.checkLogin)();
125
+ envId = await (0, utils_1.selectEnv)({ source: [constants_1.EnvSource.MINIAPP, constants_1.EnvSource.QCLOUD] });
117
126
  log.info((0, i18n_1.t)('已选择 envId: {{envId}}', { envId }));
118
- if (!configEnvId) {
119
- parser.update('envId', '{{env.ENV_ID}}');
120
- }
121
- yield this.aiConfigManager.updateEnvId(envId);
122
- }
123
- else {
124
- envId = configEnvId;
125
- log.info((0, i18n_1.t)('使用 cloudbaserc.json 中的 envId: {{envId}}', { envId: configEnvId }));
126
- const { shouldUpdateEnvId } = yield inquirer_1.default.prompt([
127
- {
128
- type: 'confirm',
129
- name: 'shouldUpdateEnvId',
130
- message: (0, i18n_1.t)('当前使用的 envId 为 {{envId}},是否需要更新? {{hint}}', {
131
- envId: configEnvId,
132
- hint: (0, const_1.getBooleanHint)(false)
133
- }),
134
- default: false
135
- }
136
- ]);
137
- if (shouldUpdateEnvId) {
138
- yield (0, auth_1.checkLogin)();
139
- envId = yield (0, utils_1.selectEnv)({ source: [constants_1.EnvSource.MINIAPP, constants_1.EnvSource.QCLOUD] });
140
- log.info((0, i18n_1.t)('已选择 envId: {{envId}}', { envId }));
141
- yield this.aiConfigManager.updateEnvId(envId);
142
- }
127
+ await this.aiConfigManager.updateEnvId(envId);
143
128
  }
144
129
  }
145
- return envId;
146
- });
130
+ }
131
+ return envId;
147
132
  }
148
- selectDefaultAgent(log) {
149
- return __awaiter(this, void 0, void 0, function* () {
150
- const config = yield this.aiConfigManager.loadConfig().catch(() => null);
151
- const configuredAgents = (config === null || config === void 0 ? void 0 : config.agents) ? Object.keys(config.agents) : [];
152
- if (configuredAgents.length === 0) {
153
- const errorMsg = (0, i18n_1.t)('没有已配置的 AI 工具,请先运行 tcb ai --setup 进行配置');
154
- log.error(errorMsg);
155
- process.exit(1);
156
- }
157
- if (configuredAgents.length === 1) {
158
- const selectedAgent = configuredAgents[0];
159
- const agentInfo = [const_1.CLAUDE, const_1.QWEN, const_1.CODEX, const_1.CURSOR, const_1.AIDER].find((a) => a.value === selectedAgent);
160
- const agentName = (agentInfo === null || agentInfo === void 0 ? void 0 : agentInfo.name) || selectedAgent.toUpperCase();
161
- log.info((0, i18n_1.t)('🔧 自动选择已配置的唯一 AI 工具: {{agentName}}', { agentName }));
162
- return selectedAgent;
163
- }
164
- const availableChoices = configuredAgents.map((agent) => {
165
- const agentInfo = [const_1.CLAUDE, const_1.QWEN, const_1.CODEX, const_1.CURSOR, const_1.AIDER].find((a) => a.value === agent);
166
- return agentInfo || { name: agent.toUpperCase(), value: agent };
167
- });
168
- const { agent } = yield inquirer_1.default.prompt([
169
- {
170
- type: 'list',
171
- name: 'agent',
172
- message: (0, i18n_1.t)('选择默认使用的 AI CLI 工具: {{hint}}', { hint: const_1.LIST_HINT }),
173
- choices: availableChoices,
174
- default: configuredAgents[0]
175
- }
176
- ]);
177
- return agent;
133
+ async selectDefaultAgent(log) {
134
+ const config = await this.aiConfigManager.loadConfig().catch(() => null);
135
+ const configuredAgents = (config === null || config === void 0 ? void 0 : config.agents) ? Object.keys(config.agents) : [];
136
+ if (configuredAgents.length === 0) {
137
+ const errorMsg = (0, i18n_1.t)('没有已配置的 AI 工具,请先运行 tcb ai --setup 进行配置');
138
+ log.error(errorMsg);
139
+ process.exit(1);
140
+ }
141
+ if (configuredAgents.length === 1) {
142
+ const selectedAgent = configuredAgents[0];
143
+ const agentInfo = [const_1.CLAUDE, const_1.QWEN, const_1.CODEX, const_1.CURSOR, const_1.AIDER].find((a) => a.value === selectedAgent);
144
+ const agentName = (agentInfo === null || agentInfo === void 0 ? void 0 : agentInfo.name) || selectedAgent.toUpperCase();
145
+ log.info((0, i18n_1.t)('🔧 自动选择已配置的唯一 AI 工具: {{agentName}}', { agentName }));
146
+ return selectedAgent;
147
+ }
148
+ const availableChoices = configuredAgents.map((agent) => {
149
+ const agentInfo = [const_1.CLAUDE, const_1.QWEN, const_1.CODEX, const_1.CURSOR, const_1.AIDER].find((a) => a.value === agent);
150
+ return agentInfo || { name: agent.toUpperCase(), value: agent };
178
151
  });
152
+ const { agent } = await inquirer_1.default.prompt([
153
+ {
154
+ type: 'list',
155
+ name: 'agent',
156
+ message: (0, i18n_1.t)('选择默认使用的 AI CLI 工具: {{hint}}', { hint: const_1.LIST_HINT }),
157
+ choices: availableChoices,
158
+ default: configuredAgents[0]
159
+ }
160
+ ]);
161
+ return agent;
179
162
  }
180
- selectCurrentAgent() {
181
- return __awaiter(this, void 0, void 0, function* () {
182
- return this.selectAgent((0, i18n_1.t)('选择当前要配置的 AI CLI 工具:'), true);
183
- });
163
+ async selectCurrentAgent() {
164
+ return this.selectAgent((0, i18n_1.t)('选择当前要配置的 AI CLI 工具:'), true);
184
165
  }
185
166
  showConfigInfo(log) {
186
167
  log.info('');
@@ -191,517 +172,500 @@ class AISetupWizard {
191
172
  log.info((0, i18n_1.t)('• 您可以随时通过 tcb ai --reset 重置配置'));
192
173
  log.info('');
193
174
  }
194
- selectAgent(message, includeNone = false) {
195
- return __awaiter(this, void 0, void 0, function* () {
196
- const { agent } = yield inquirer_1.default.prompt([
197
- {
198
- type: 'list',
199
- name: 'agent',
200
- message: `${message} ${const_1.LIST_HINT}`,
201
- choices: [const_1.CODEBUDDY, const_1.CLAUDE, const_1.QWEN, const_1.CODEX, const_1.CURSOR, const_1.AIDER, ...(includeNone ? [const_1.NONE] : [])],
202
- default: const_1.CODEBUDDY.value
203
- }
204
- ]);
205
- return agent;
206
- });
207
- }
208
- configureAgent(agent, log) {
209
- return __awaiter(this, void 0, void 0, function* () {
210
- const agentInfo = [const_1.CLAUDE, const_1.QWEN, const_1.CODEX, const_1.AIDER, const_1.CURSOR, const_1.CODEBUDDY].find((a) => a.value === agent);
211
- log.info((0, i18n_1.t)('\n📝 配置 {{agentName}}:', { agentName: (agentInfo === null || agentInfo === void 0 ? void 0 : agentInfo.name) || agent.toUpperCase() }));
212
- switch (agent) {
213
- case const_1.CLAUDE.value:
214
- return yield this.configureClaudeAgent(log);
215
- case const_1.QWEN.value:
216
- return yield this.configureQwenAgent(log);
217
- case const_1.CODEX.value:
218
- return yield this.configureCodexAgent(log);
219
- case const_1.AIDER.value:
220
- return yield this.configureAiderAgent(log);
221
- case const_1.CURSOR.value:
222
- return yield this.configureCursorAgent(log);
223
- case const_1.CODEBUDDY.value:
224
- return yield this.configureCodebuddyAgent(log);
225
- default:
226
- throw new Error((0, i18n_1.t)('不支持的 AI 工具: {{agent}}', { agent }));
175
+ async selectAgent(message, includeNone = false) {
176
+ const { agent } = await inquirer_1.default.prompt([
177
+ {
178
+ type: 'list',
179
+ name: 'agent',
180
+ message: `${message} ${const_1.LIST_HINT}`,
181
+ choices: [const_1.CODEBUDDY, const_1.CLAUDE, const_1.QWEN, const_1.CODEX, const_1.CURSOR, const_1.AIDER, ...(includeNone ? [const_1.NONE] : [])],
182
+ default: const_1.CODEBUDDY.value
227
183
  }
228
- });
184
+ ]);
185
+ return agent;
186
+ }
187
+ async configureAgent(agent, log) {
188
+ const agentInfo = [const_1.CLAUDE, const_1.QWEN, const_1.CODEX, const_1.AIDER, const_1.CURSOR, const_1.CODEBUDDY].find((a) => a.value === agent);
189
+ log.info((0, i18n_1.t)('\n📝 配置 {{agentName}}:', { agentName: (agentInfo === null || agentInfo === void 0 ? void 0 : agentInfo.name) || agent.toUpperCase() }));
190
+ switch (agent) {
191
+ case const_1.CLAUDE.value:
192
+ return await this.configureClaudeAgent(log);
193
+ case const_1.QWEN.value:
194
+ return await this.configureQwenAgent(log);
195
+ case const_1.CODEX.value:
196
+ return await this.configureCodexAgent(log);
197
+ case const_1.AIDER.value:
198
+ return await this.configureAiderAgent(log);
199
+ case const_1.CURSOR.value:
200
+ return await this.configureCursorAgent(log);
201
+ case const_1.CODEBUDDY.value:
202
+ return await this.configureCodebuddyAgent(log);
203
+ default:
204
+ throw new Error((0, i18n_1.t)('不支持的 AI 工具: {{agent}}', { agent }));
205
+ }
229
206
  }
230
- configureClaudeAgent(log) {
231
- return __awaiter(this, void 0, void 0, function* () {
232
- log.info((0, i18n_1.t)('配置说明可参考 {{link}}', { link: (0, output_1.genClickableLink)('https://docs.cloudbase.net/cli-v1/ai/claude') }));
233
- const { configMethod } = yield inquirer_1.default.prompt([
207
+ async configureClaudeAgent(log) {
208
+ log.info((0, i18n_1.t)('配置说明可参考 {{link}}', { link: (0, output_1.genClickableLink)('https://docs.cloudbase.net/cli-v1/ai/claude') }));
209
+ const { configMethod } = await inquirer_1.default.prompt([
210
+ {
211
+ type: 'list',
212
+ name: 'configMethod',
213
+ message: (0, i18n_1.t)('选择配置方式: {{hint}}', { hint: const_1.LIST_HINT }),
214
+ choices: [
215
+ { name: (0, i18n_1.t)('使用 CloudBase 服务,一键登录,无需配置'), value: 'cloudbase' },
216
+ {
217
+ name: (0, i18n_1.t)('自配置 API KEY 和 Base URL,需要支持 Anthropic 协议的大模型'),
218
+ value: 'custom'
219
+ },
220
+ { name: (0, i18n_1.t)('暂不配置,使用 Claude Code 内置鉴权方式(如 OAuth)'), value: 'none' }
221
+ ],
222
+ default: 'cloudbase'
223
+ }
224
+ ]);
225
+ if (configMethod === 'cloudbase') {
226
+ await this.configureEnvId(log, this.envId);
227
+ const { provider, model, transformer } = await this.selectCloudBaseProvider();
228
+ await this.aiConfigManager.updateClaudeConfig('cloudbase', {
229
+ provider,
230
+ model,
231
+ ...(transformer && { transformer })
232
+ });
233
+ }
234
+ else if (configMethod === 'custom') {
235
+ const { baseUrlChoice } = await inquirer_1.default.prompt([
234
236
  {
235
237
  type: 'list',
236
- name: 'configMethod',
237
- message: (0, i18n_1.t)('选择配置方式: {{hint}}', { hint: const_1.LIST_HINT }),
238
+ name: 'baseUrlChoice',
239
+ message: (0, i18n_1.t)('选择 API Base URL: {{hint}}', { hint: const_1.LIST_HINT }),
238
240
  choices: [
239
- { name: (0, i18n_1.t)('使用 CloudBase 服务,一键登录,无需配置'), value: 'cloudbase' },
240
241
  {
241
- name: (0, i18n_1.t)('自配置 API KEY 和 Base URL,需要支持 Anthropic 协议的大模型'),
242
- value: 'custom'
242
+ name: 'Kimi - https://api.moonshot.cn/anthropic',
243
+ value: 'https://api.moonshot.cn/anthropic'
244
+ },
245
+ {
246
+ name: `${(0, i18n_1.t)('智谱')} - https://open.bigmodel.cn/api/anthropic`,
247
+ value: 'https://open.bigmodel.cn/api/anthropic'
248
+ },
249
+ {
250
+ name: 'Anthropic - https://api.anthropic.com',
251
+ value: 'https://api.anthropic.com'
252
+ },
253
+ {
254
+ name: 'DeepSeek - https://api.deepseek.com/anthropic',
255
+ value: 'https://api.deepseek.com/anthropic'
256
+ },
257
+ {
258
+ name: 'LongCat - https://api.longcat.chat/anthropic',
259
+ value: 'https://api.longcat.chat/anthropic'
243
260
  },
244
- { name: (0, i18n_1.t)('暂不配置,使用 Claude Code 内置鉴权方式(如 OAuth)'), value: 'none' }
261
+ { name: (0, i18n_1.t)('🛠️ 自定义 URL'), value: 'custom' }
245
262
  ],
246
- default: 'cloudbase'
263
+ default: 'https://api.moonshot.cn/anthropic'
247
264
  }
248
265
  ]);
249
- if (configMethod === 'cloudbase') {
250
- yield this.configureEnvId(log, this.envId);
251
- const { provider, model, transformer } = yield this.selectCloudBaseProvider();
252
- yield this.aiConfigManager.updateClaudeConfig('cloudbase', Object.assign({ provider,
253
- model }, (transformer && { transformer })));
254
- }
255
- else if (configMethod === 'custom') {
256
- const { baseUrlChoice } = yield inquirer_1.default.prompt([
257
- {
258
- type: 'list',
259
- name: 'baseUrlChoice',
260
- message: (0, i18n_1.t)('选择 API Base URL: {{hint}}', { hint: const_1.LIST_HINT }),
261
- choices: [
262
- {
263
- name: 'Kimi - https://api.moonshot.cn/anthropic',
264
- value: 'https://api.moonshot.cn/anthropic'
265
- },
266
- {
267
- name: `${(0, i18n_1.t)('智谱')} - https://open.bigmodel.cn/api/anthropic`,
268
- value: 'https://open.bigmodel.cn/api/anthropic'
269
- },
270
- {
271
- name: 'Anthropic - https://api.anthropic.com',
272
- value: 'https://api.anthropic.com'
273
- },
274
- {
275
- name: 'DeepSeek - https://api.deepseek.com/anthropic',
276
- value: 'https://api.deepseek.com/anthropic'
277
- },
278
- {
279
- name: 'LongCat - https://api.longcat.chat/anthropic',
280
- value: 'https://api.longcat.chat/anthropic'
281
- },
282
- { name: (0, i18n_1.t)('🛠️ 自定义 URL'), value: 'custom' }
283
- ],
284
- default: 'https://api.moonshot.cn/anthropic'
285
- }
286
- ]);
287
- let baseUrl;
288
- if (baseUrlChoice === 'custom') {
289
- const { customUrl } = yield inquirer_1.default.prompt([
290
- {
291
- type: 'input',
292
- name: 'customUrl',
293
- message: (0, i18n_1.t)('请输入自定义 API Base URL:'),
294
- validate: (input) => input.trim().length > 0 || (0, i18n_1.t)('请输入有效的 Base URL')
295
- }
296
- ]);
297
- baseUrl = customUrl;
298
- }
299
- else {
300
- baseUrl = baseUrlChoice;
301
- }
302
- const { apiKey } = yield inquirer_1.default.prompt([
303
- {
304
- type: 'password',
305
- name: 'apiKey',
306
- message: 'Auth Token:',
307
- validate: (input) => input.length > 0 || (0, i18n_1.t)('请输入有效的 Auth Token')
308
- }
309
- ]);
310
- let defaultModel;
311
- if (baseUrl === 'https://api.anthropic.com') {
312
- defaultModel = 'sonnet';
313
- }
314
- else if (baseUrl === 'https://api.moonshot.cn/anthropic') {
315
- defaultModel = 'kimi-k2-turbo-preview';
316
- }
317
- else if (baseUrl === 'https://open.bigmodel.cn/api/anthropic') {
318
- defaultModel = 'glm-4.5';
319
- }
320
- else if (baseUrl === 'https://api.deepseek.com/anthropic') {
321
- defaultModel = 'deepseek-chat';
322
- }
323
- else if (baseUrl === 'https://api.longcat.chat/anthropic') {
324
- defaultModel = 'LongCat-Flash-Chat';
325
- }
326
- else {
327
- defaultModel = '';
328
- }
329
- const { model } = yield inquirer_1.default.prompt([
266
+ let baseUrl;
267
+ if (baseUrlChoice === 'custom') {
268
+ const { customUrl } = await inquirer_1.default.prompt([
330
269
  {
331
270
  type: 'input',
332
- name: 'model',
333
- message: (0, i18n_1.t)('模型名称:'),
334
- default: defaultModel,
335
- validate: (input) => input.trim().length > 0 || (0, i18n_1.t)('请输入有效的模型名称')
271
+ name: 'customUrl',
272
+ message: (0, i18n_1.t)('请输入自定义 API Base URL:'),
273
+ validate: (input) => input.trim().length > 0 || (0, i18n_1.t)('请输入有效的 Base URL')
336
274
  }
337
275
  ]);
338
- yield this.aiConfigManager.updateClaudeConfig('custom', {
339
- baseUrl,
340
- apiKey,
341
- model
342
- });
276
+ baseUrl = customUrl;
343
277
  }
344
278
  else {
345
- yield this.aiConfigManager.updateClaudeConfig('none', {});
279
+ baseUrl = baseUrlChoice;
346
280
  }
347
- });
348
- }
349
- configureQwenAgent(log) {
350
- return __awaiter(this, void 0, void 0, function* () {
351
- log.info((0, i18n_1.t)('配置说明可参考 {{link}}', { link: (0, output_1.genClickableLink)('https://docs.cloudbase.net/cli-v1/ai/qwen') }));
352
- const { configMethod } = yield inquirer_1.default.prompt([
281
+ const { apiKey } = await inquirer_1.default.prompt([
353
282
  {
354
- type: 'list',
355
- name: 'configMethod',
356
- message: (0, i18n_1.t)('选择配置方式: {{hint}}', { hint: const_1.LIST_HINT }),
357
- choices: [
358
- { name: (0, i18n_1.t)('使用 CloudBase 服务,一键登录,无需配置'), value: 'cloudbase' },
359
- { name: (0, i18n_1.t)('自配置 API KEY 和 Base URL'), value: 'custom' },
360
- { name: (0, i18n_1.t)('暂不配置,使用 Qwen Code 内置鉴权方式(如 OAuth)'), value: 'none' }
361
- ],
362
- default: 'cloudbase'
283
+ type: 'password',
284
+ name: 'apiKey',
285
+ message: 'Auth Token:',
286
+ validate: (input) => input.length > 0 || (0, i18n_1.t)('请输入有效的 Auth Token')
363
287
  }
364
288
  ]);
365
- if (configMethod === 'cloudbase') {
366
- yield this.configureEnvId(log, this.envId);
367
- const { provider, model } = yield this.selectCloudBaseProvider();
368
- yield this.aiConfigManager.updateQwenConfig('cloudbase', {
369
- provider,
370
- model
371
- });
289
+ let defaultModel;
290
+ if (baseUrl === 'https://api.anthropic.com') {
291
+ defaultModel = 'sonnet';
372
292
  }
373
- else if (configMethod === 'custom') {
374
- const { apiKey, baseUrl, model } = yield inquirer_1.default.prompt([
375
- {
376
- type: 'input',
377
- name: 'baseUrl',
378
- message: (0, i18n_1.t)('API Base URL (留空使用默认):'),
379
- default: 'https://dashscope.aliyuncs.com/compatible-mode/v1'
380
- },
381
- {
382
- type: 'password',
383
- name: 'apiKey',
384
- message: 'API Key:',
385
- validate: (input) => input.length > 0 || (0, i18n_1.t)('请输入有效的 API Key')
386
- },
387
- {
388
- type: 'input',
389
- name: 'model',
390
- message: (0, i18n_1.t)('模型名称 (留空使用默认):'),
391
- default: 'qwen-turbo'
392
- }
393
- ]);
394
- yield this.aiConfigManager.updateQwenConfig('custom', { baseUrl, apiKey, model });
293
+ else if (baseUrl === 'https://api.moonshot.cn/anthropic') {
294
+ defaultModel = 'kimi-k2-turbo-preview';
295
+ }
296
+ else if (baseUrl === 'https://open.bigmodel.cn/api/anthropic') {
297
+ defaultModel = 'glm-4.5';
298
+ }
299
+ else if (baseUrl === 'https://api.deepseek.com/anthropic') {
300
+ defaultModel = 'deepseek-chat';
301
+ }
302
+ else if (baseUrl === 'https://api.longcat.chat/anthropic') {
303
+ defaultModel = 'LongCat-Flash-Chat';
395
304
  }
396
305
  else {
397
- yield this.aiConfigManager.updateQwenConfig('none', {});
306
+ defaultModel = '';
398
307
  }
399
- });
308
+ const { model } = await inquirer_1.default.prompt([
309
+ {
310
+ type: 'input',
311
+ name: 'model',
312
+ message: (0, i18n_1.t)('模型名称:'),
313
+ default: defaultModel,
314
+ validate: (input) => input.trim().length > 0 || (0, i18n_1.t)('请输入有效的模型名称')
315
+ }
316
+ ]);
317
+ await this.aiConfigManager.updateClaudeConfig('custom', {
318
+ baseUrl,
319
+ apiKey,
320
+ model
321
+ });
322
+ }
323
+ else {
324
+ await this.aiConfigManager.updateClaudeConfig('none', {});
325
+ }
400
326
  }
401
- configureCodexAgent(log) {
402
- return __awaiter(this, void 0, void 0, function* () {
403
- log.info((0, i18n_1.t)('配置说明可参考 {{link}}', { link: (0, output_1.genClickableLink)('https://docs.cloudbase.net/cli-v1/ai/codex') }));
404
- const { configMethod } = yield inquirer_1.default.prompt([
327
+ async configureQwenAgent(log) {
328
+ log.info((0, i18n_1.t)('配置说明可参考 {{link}}', { link: (0, output_1.genClickableLink)('https://docs.cloudbase.net/cli-v1/ai/qwen') }));
329
+ const { configMethod } = await inquirer_1.default.prompt([
330
+ {
331
+ type: 'list',
332
+ name: 'configMethod',
333
+ message: (0, i18n_1.t)('选择配置方式: {{hint}}', { hint: const_1.LIST_HINT }),
334
+ choices: [
335
+ { name: (0, i18n_1.t)('使用 CloudBase 服务,一键登录,无需配置'), value: 'cloudbase' },
336
+ { name: (0, i18n_1.t)('自配置 API KEY 和 Base URL'), value: 'custom' },
337
+ { name: (0, i18n_1.t)('暂不配置,使用 Qwen Code 内置鉴权方式(如 OAuth)'), value: 'none' }
338
+ ],
339
+ default: 'cloudbase'
340
+ }
341
+ ]);
342
+ if (configMethod === 'cloudbase') {
343
+ await this.configureEnvId(log, this.envId);
344
+ const { provider, model } = await this.selectCloudBaseProvider();
345
+ await this.aiConfigManager.updateQwenConfig('cloudbase', {
346
+ provider,
347
+ model
348
+ });
349
+ }
350
+ else if (configMethod === 'custom') {
351
+ const { apiKey, baseUrl, model } = await inquirer_1.default.prompt([
405
352
  {
406
- type: 'list',
407
- name: 'configMethod',
408
- message: (0, i18n_1.t)('选择配置方式: {{hint}}', { hint: const_1.LIST_HINT }),
409
- choices: [
410
- { name: (0, i18n_1.t)('使用 CloudBase 服务,一键登录,无需配置'), value: 'cloudbase' },
411
- { name: (0, i18n_1.t)('自配置 API KEY 和 Base URL'), value: 'custom' },
412
- { name: (0, i18n_1.t)('暂不配置,使用 OpenAI Codex 内置鉴权方式(如 OAuth)'), value: 'none' }
413
- ],
414
- default: 'cloudbase'
353
+ type: 'input',
354
+ name: 'baseUrl',
355
+ message: (0, i18n_1.t)('API Base URL (留空使用默认):'),
356
+ default: 'https://dashscope.aliyuncs.com/compatible-mode/v1'
357
+ },
358
+ {
359
+ type: 'password',
360
+ name: 'apiKey',
361
+ message: 'API Key:',
362
+ validate: (input) => input.length > 0 || (0, i18n_1.t)('请输入有效的 API Key')
363
+ },
364
+ {
365
+ type: 'input',
366
+ name: 'model',
367
+ message: (0, i18n_1.t)('模型名称 (留空使用默认):'),
368
+ default: 'qwen-turbo'
415
369
  }
416
370
  ]);
417
- if (configMethod === 'cloudbase') {
418
- yield this.configureEnvId(log, this.envId);
419
- const { provider, model } = yield this.selectCloudBaseProvider();
420
- yield this.aiConfigManager.updateCodexConfig('cloudbase', {
421
- provider,
422
- model
423
- });
371
+ await this.aiConfigManager.updateQwenConfig('custom', { baseUrl, apiKey, model });
372
+ }
373
+ else {
374
+ await this.aiConfigManager.updateQwenConfig('none', {});
375
+ }
376
+ }
377
+ async configureCodexAgent(log) {
378
+ log.info((0, i18n_1.t)('配置说明可参考 {{link}}', { link: (0, output_1.genClickableLink)('https://docs.cloudbase.net/cli-v1/ai/codex') }));
379
+ const { configMethod } = await inquirer_1.default.prompt([
380
+ {
381
+ type: 'list',
382
+ name: 'configMethod',
383
+ message: (0, i18n_1.t)('选择配置方式: {{hint}}', { hint: const_1.LIST_HINT }),
384
+ choices: [
385
+ { name: (0, i18n_1.t)('使用 CloudBase 服务,一键登录,无需配置'), value: 'cloudbase' },
386
+ { name: (0, i18n_1.t)('自配置 API KEY 和 Base URL'), value: 'custom' },
387
+ { name: (0, i18n_1.t)('暂不配置,使用 OpenAI Codex 内置鉴权方式(如 OAuth)'), value: 'none' }
388
+ ],
389
+ default: 'cloudbase'
424
390
  }
425
- else if (configMethod === 'custom') {
426
- const { baseUrlChoice } = yield inquirer_1.default.prompt([
427
- {
428
- type: 'list',
429
- name: 'baseUrlChoice',
430
- message: (0, i18n_1.t)('选择 API Base URL: {{hint}}', { hint: const_1.LIST_HINT }),
431
- choices: [
432
- {
433
- name: 'Kimi - https://api.moonshot.cn/v1',
434
- value: 'https://api.moonshot.cn/v1'
435
- },
436
- {
437
- name: `${(0, i18n_1.t)('智谱')} - https://open.bigmodel.cn/api/paas/v4`,
438
- value: 'https://open.bigmodel.cn/api/paas/v4'
439
- },
440
- {
441
- name: 'LongCat - https://api.longcat.chat/openai',
442
- value: 'https://api.longcat.chat/openai'
443
- },
444
- { name: (0, i18n_1.t)('🛠️ 自定义 URL'), value: 'custom' }
445
- ],
446
- default: 'https://api.moonshot.cn/v1'
447
- }
448
- ]);
449
- let baseUrl;
450
- if (baseUrlChoice === 'custom') {
451
- const { customUrl } = yield inquirer_1.default.prompt([
391
+ ]);
392
+ if (configMethod === 'cloudbase') {
393
+ await this.configureEnvId(log, this.envId);
394
+ const { provider, model } = await this.selectCloudBaseProvider();
395
+ await this.aiConfigManager.updateCodexConfig('cloudbase', {
396
+ provider,
397
+ model
398
+ });
399
+ }
400
+ else if (configMethod === 'custom') {
401
+ const { baseUrlChoice } = await inquirer_1.default.prompt([
402
+ {
403
+ type: 'list',
404
+ name: 'baseUrlChoice',
405
+ message: (0, i18n_1.t)('选择 API Base URL: {{hint}}', { hint: const_1.LIST_HINT }),
406
+ choices: [
452
407
  {
453
- type: 'input',
454
- name: 'customUrl',
455
- message: (0, i18n_1.t)('请输入自定义 API Base URL:'),
456
- validate: (input) => input.trim().length > 0 || (0, i18n_1.t)('请输入有效的 Base URL')
457
- }
458
- ]);
459
- baseUrl = customUrl;
460
- }
461
- else {
462
- baseUrl = baseUrlChoice;
408
+ name: 'Kimi - https://api.moonshot.cn/v1',
409
+ value: 'https://api.moonshot.cn/v1'
410
+ },
411
+ {
412
+ name: `${(0, i18n_1.t)('智谱')} - https://open.bigmodel.cn/api/paas/v4`,
413
+ value: 'https://open.bigmodel.cn/api/paas/v4'
414
+ },
415
+ {
416
+ name: 'LongCat - https://api.longcat.chat/openai',
417
+ value: 'https://api.longcat.chat/openai'
418
+ },
419
+ { name: (0, i18n_1.t)('🛠️ 自定义 URL'), value: 'custom' }
420
+ ],
421
+ default: 'https://api.moonshot.cn/v1'
463
422
  }
464
- const { apiKey, model } = yield inquirer_1.default.prompt([
465
- {
466
- type: 'password',
467
- name: 'apiKey',
468
- message: (0, i18n_1.t)('API Key:'),
469
- validate: (input) => input.length > 0 || (0, i18n_1.t)('请输入有效的 API Key')
470
- },
423
+ ]);
424
+ let baseUrl;
425
+ if (baseUrlChoice === 'custom') {
426
+ const { customUrl } = await inquirer_1.default.prompt([
471
427
  {
472
428
  type: 'input',
473
- name: 'model',
474
- message: (0, i18n_1.t)('模型名称 (留空使用默认):'),
475
- default: (0, const_1.getDefaultModelByBaseUrl)(baseUrl)
429
+ name: 'customUrl',
430
+ message: (0, i18n_1.t)('请输入自定义 API Base URL:'),
431
+ validate: (input) => input.trim().length > 0 || (0, i18n_1.t)('请输入有效的 Base URL')
476
432
  }
477
433
  ]);
478
- yield this.aiConfigManager.updateCodexConfig('custom', { baseUrl, apiKey, model });
434
+ baseUrl = customUrl;
479
435
  }
480
436
  else {
481
- yield this.aiConfigManager.updateCodexConfig('none', {});
437
+ baseUrl = baseUrlChoice;
482
438
  }
483
- });
439
+ const { apiKey, model } = await inquirer_1.default.prompt([
440
+ {
441
+ type: 'password',
442
+ name: 'apiKey',
443
+ message: (0, i18n_1.t)('API Key:'),
444
+ validate: (input) => input.length > 0 || (0, i18n_1.t)('请输入有效的 API Key')
445
+ },
446
+ {
447
+ type: 'input',
448
+ name: 'model',
449
+ message: (0, i18n_1.t)('模型名称 (留空使用默认):'),
450
+ default: (0, const_1.getDefaultModelByBaseUrl)(baseUrl)
451
+ }
452
+ ]);
453
+ await this.aiConfigManager.updateCodexConfig('custom', { baseUrl, apiKey, model });
454
+ }
455
+ else {
456
+ await this.aiConfigManager.updateCodexConfig('none', {});
457
+ }
484
458
  }
485
- configureAiderAgent(log) {
486
- return __awaiter(this, void 0, void 0, function* () {
487
- log.info((0, i18n_1.t)('配置说明可参考 {{link}}', { link: (0, output_1.genClickableLink)('https://docs.cloudbase.net/cli-v1/ai/aider') }));
488
- const { configMethod } = yield inquirer_1.default.prompt([
459
+ async configureAiderAgent(log) {
460
+ log.info((0, i18n_1.t)('配置说明可参考 {{link}}', { link: (0, output_1.genClickableLink)('https://docs.cloudbase.net/cli-v1/ai/aider') }));
461
+ const { configMethod } = await inquirer_1.default.prompt([
462
+ {
463
+ type: 'list',
464
+ name: 'configMethod',
465
+ message: (0, i18n_1.t)('选择配置方式: {{hint}}', { hint: const_1.LIST_HINT }),
466
+ choices: [
467
+ { name: (0, i18n_1.t)('使用 CloudBase 服务,一键登录,无需配置'), value: 'cloudbase' },
468
+ { name: (0, i18n_1.t)('自配置 API KEY 和 Base URL'), value: 'custom' }
469
+ ],
470
+ default: 'cloudbase'
471
+ }
472
+ ]);
473
+ if (configMethod === 'cloudbase') {
474
+ await this.configureEnvId(log, this.envId);
475
+ const { provider, model } = await this.selectCloudBaseProvider();
476
+ await this.aiConfigManager.updateAiderConfig('cloudbase', {
477
+ provider,
478
+ model
479
+ });
480
+ }
481
+ else {
482
+ const { baseUrlChoice } = await inquirer_1.default.prompt([
489
483
  {
490
484
  type: 'list',
491
- name: 'configMethod',
492
- message: (0, i18n_1.t)('选择配置方式: {{hint}}', { hint: const_1.LIST_HINT }),
485
+ name: 'baseUrlChoice',
486
+ message: (0, i18n_1.t)('选择 API Base URL: {{hint}}', { hint: const_1.LIST_HINT }),
493
487
  choices: [
494
- { name: (0, i18n_1.t)('使用 CloudBase 服务,一键登录,无需配置'), value: 'cloudbase' },
495
- { name: (0, i18n_1.t)('自配置 API KEY 和 Base URL'), value: 'custom' }
488
+ {
489
+ name: 'Kimi - https://api.moonshot.cn/v1',
490
+ value: 'https://api.moonshot.cn/v1'
491
+ },
492
+ {
493
+ name: `${(0, i18n_1.t)('智谱')} - https://open.bigmodel.cn/api/paas/v4`,
494
+ value: 'https://open.bigmodel.cn/api/paas/v4'
495
+ },
496
+ {
497
+ name: 'LongCat - https://api.longcat.chat/openai',
498
+ value: 'https://api.longcat.chat/openai'
499
+ },
500
+ { name: (0, i18n_1.t)('🛠️ 自定义 URL'), value: 'custom' }
496
501
  ],
497
- default: 'cloudbase'
502
+ default: 'https://api.moonshot.cn/v1'
498
503
  }
499
504
  ]);
500
- if (configMethod === 'cloudbase') {
501
- yield this.configureEnvId(log, this.envId);
502
- const { provider, model } = yield this.selectCloudBaseProvider();
503
- yield this.aiConfigManager.updateAiderConfig('cloudbase', {
504
- provider,
505
- model
506
- });
507
- }
508
- else {
509
- const { baseUrlChoice } = yield inquirer_1.default.prompt([
510
- {
511
- type: 'list',
512
- name: 'baseUrlChoice',
513
- message: (0, i18n_1.t)('选择 API Base URL: {{hint}}', { hint: const_1.LIST_HINT }),
514
- choices: [
515
- {
516
- name: 'Kimi - https://api.moonshot.cn/v1',
517
- value: 'https://api.moonshot.cn/v1'
518
- },
519
- {
520
- name: `${(0, i18n_1.t)('智谱')} - https://open.bigmodel.cn/api/paas/v4`,
521
- value: 'https://open.bigmodel.cn/api/paas/v4'
522
- },
523
- {
524
- name: 'LongCat - https://api.longcat.chat/openai',
525
- value: 'https://api.longcat.chat/openai'
526
- },
527
- { name: (0, i18n_1.t)('🛠️ 自定义 URL'), value: 'custom' }
528
- ],
529
- default: 'https://api.moonshot.cn/v1'
530
- }
531
- ]);
532
- let baseUrl;
533
- if (baseUrlChoice === 'custom') {
534
- const { customUrl } = yield inquirer_1.default.prompt([
535
- {
536
- type: 'input',
537
- name: 'customUrl',
538
- message: (0, i18n_1.t)('请输入自定义 API Base URL:'),
539
- validate: (input) => input.trim().length > 0 || (0, i18n_1.t)('请输入有效的 Base URL')
540
- }
541
- ]);
542
- baseUrl = customUrl;
543
- }
544
- else {
545
- baseUrl = baseUrlChoice;
546
- }
547
- const { apiKey, model } = yield inquirer_1.default.prompt([
548
- {
549
- type: 'password',
550
- name: 'apiKey',
551
- message: 'API Key:',
552
- validate: (input) => input.length > 0 || (0, i18n_1.t)('请输入有效的 API Key')
553
- },
505
+ let baseUrl;
506
+ if (baseUrlChoice === 'custom') {
507
+ const { customUrl } = await inquirer_1.default.prompt([
554
508
  {
555
509
  type: 'input',
556
- name: 'model',
557
- message: (0, i18n_1.t)('模型名称:'),
558
- default: (0, const_1.getDefaultModelByBaseUrl)(baseUrl),
559
- validate: (input) => input.length > 0 || (0, i18n_1.t)('请输入有效的模型名称')
510
+ name: 'customUrl',
511
+ message: (0, i18n_1.t)('请输入自定义 API Base URL:'),
512
+ validate: (input) => input.trim().length > 0 || (0, i18n_1.t)('请输入有效的 Base URL')
560
513
  }
561
514
  ]);
562
- yield this.aiConfigManager.updateAiderConfig('custom', { baseUrl, apiKey, model });
515
+ baseUrl = customUrl;
563
516
  }
564
- });
517
+ else {
518
+ baseUrl = baseUrlChoice;
519
+ }
520
+ const { apiKey, model } = await inquirer_1.default.prompt([
521
+ {
522
+ type: 'password',
523
+ name: 'apiKey',
524
+ message: 'API Key:',
525
+ validate: (input) => input.length > 0 || (0, i18n_1.t)('请输入有效的 API Key')
526
+ },
527
+ {
528
+ type: 'input',
529
+ name: 'model',
530
+ message: (0, i18n_1.t)('模型名称:'),
531
+ default: (0, const_1.getDefaultModelByBaseUrl)(baseUrl),
532
+ validate: (input) => input.length > 0 || (0, i18n_1.t)('请输入有效的模型名称')
533
+ }
534
+ ]);
535
+ await this.aiConfigManager.updateAiderConfig('custom', { baseUrl, apiKey, model });
536
+ }
565
537
  }
566
- configureCursorAgent(log) {
567
- return __awaiter(this, void 0, void 0, function* () {
568
- log.info((0, i18n_1.t)('配置说明可参考 {{link}}', { link: (0, output_1.genClickableLink)('https://docs.cloudbase.net/cli-v1/ai/cursor') }));
569
- yield this.aiConfigManager.updateCursorConfig('none');
570
- });
538
+ async configureCursorAgent(log) {
539
+ log.info((0, i18n_1.t)('配置说明可参考 {{link}}', { link: (0, output_1.genClickableLink)('https://docs.cloudbase.net/cli-v1/ai/cursor') }));
540
+ await this.aiConfigManager.updateCursorConfig('none');
571
541
  }
572
- ensureGitignore() {
573
- return __awaiter(this, void 0, void 0, function* () {
574
- const gitignorePath = path_1.default.join(process.cwd(), '.gitignore');
575
- try {
576
- let gitignoreContent = '';
577
- if (yield fs_extra_1.default.pathExists(gitignorePath)) {
578
- gitignoreContent = yield fs_extra_1.default.readFile(gitignorePath, 'utf8');
579
- }
580
- const patterns = ['.env.local', '.env'];
581
- let needsUpdate = false;
582
- for (const pattern of patterns) {
583
- if (!gitignoreContent.includes(pattern)) {
584
- if (!needsUpdate) {
585
- gitignoreContent += '\n# Environment variables\n';
586
- needsUpdate = true;
587
- }
588
- gitignoreContent += `${pattern}\n`;
542
+ async ensureGitignore() {
543
+ const gitignorePath = path_1.default.join(process.cwd(), '.gitignore');
544
+ try {
545
+ let gitignoreContent = '';
546
+ if (await fs_extra_1.default.pathExists(gitignorePath)) {
547
+ gitignoreContent = await fs_extra_1.default.readFile(gitignorePath, 'utf8');
548
+ }
549
+ const patterns = ['.env.local', '.env'];
550
+ let needsUpdate = false;
551
+ for (const pattern of patterns) {
552
+ if (!gitignoreContent.includes(pattern)) {
553
+ if (!needsUpdate) {
554
+ gitignoreContent += '\n# Environment variables\n';
555
+ needsUpdate = true;
589
556
  }
590
- }
591
- if (needsUpdate) {
592
- yield fs_extra_1.default.writeFile(gitignorePath, gitignoreContent);
557
+ gitignoreContent += `${pattern}\n`;
593
558
  }
594
559
  }
595
- catch (error) {
560
+ if (needsUpdate) {
561
+ await fs_extra_1.default.writeFile(gitignorePath, gitignoreContent);
596
562
  }
597
- });
563
+ }
564
+ catch (error) {
565
+ }
598
566
  }
599
- selectCloudBaseProvider() {
600
- return __awaiter(this, void 0, void 0, function* () {
601
- const { selectedProvider } = yield inquirer_1.default.prompt([
567
+ async selectCloudBaseProvider() {
568
+ const { selectedProvider } = await inquirer_1.default.prompt([
569
+ {
570
+ type: 'list',
571
+ name: 'selectedProvider',
572
+ message: (0, i18n_1.t)('选择大模型供应商: {{hint}}', { hint: const_1.LIST_HINT }),
573
+ choices: const_1.CLOUDBASE_PROVIDERS.map((p) => ({ name: p.name, value: p.value })),
574
+ default: 'kimi-exp'
575
+ }
576
+ ]);
577
+ if (selectedProvider === 'custom') {
578
+ const { provider, model } = await inquirer_1.default.prompt([
579
+ {
580
+ type: 'input',
581
+ name: 'provider',
582
+ message: (0, i18n_1.t)('请输入自定义供应商名称:'),
583
+ validate: (input) => input.trim().length > 0 || (0, i18n_1.t)('供应商名称不能为空')
584
+ },
585
+ {
586
+ type: 'input',
587
+ name: 'model',
588
+ message: (0, i18n_1.t)('请输入模型名称:'),
589
+ validate: (input) => input.trim().length > 0 || (0, i18n_1.t)('模型名称不能为空')
590
+ }
591
+ ]);
592
+ return { provider, model, isCustom: true, transformer: undefined };
593
+ }
594
+ else {
595
+ const selectedConfig = const_1.CLOUDBASE_PROVIDERS.find((p) => p.value === selectedProvider);
596
+ const modelChoices = [
597
+ ...selectedConfig.models.map((m) => ({ name: m, value: m }))
598
+ ];
599
+ const { selectedModel } = await inquirer_1.default.prompt([
602
600
  {
603
601
  type: 'list',
604
- name: 'selectedProvider',
605
- message: (0, i18n_1.t)('选择大模型供应商: {{hint}}', { hint: const_1.LIST_HINT }),
606
- choices: const_1.CLOUDBASE_PROVIDERS.map((p) => ({ name: p.name, value: p.value })),
607
- default: 'kimi-exp'
602
+ name: 'selectedModel',
603
+ message: (0, i18n_1.t)('选择模型: {{hint}}', { hint: const_1.LIST_HINT }),
604
+ choices: modelChoices,
605
+ default: selectedConfig.models[0]
608
606
  }
609
607
  ]);
610
- if (selectedProvider === 'custom') {
611
- const { provider, model } = yield inquirer_1.default.prompt([
608
+ let model;
609
+ if (selectedModel === 'custom') {
610
+ const { customModel } = await inquirer_1.default.prompt([
612
611
  {
613
612
  type: 'input',
614
- name: 'provider',
615
- message: (0, i18n_1.t)('请输入自定义供应商名称:'),
616
- validate: (input) => input.trim().length > 0 || (0, i18n_1.t)('供应商名称不能为空')
617
- },
618
- {
619
- type: 'input',
620
- name: 'model',
621
- message: (0, i18n_1.t)('请输入模型名称:'),
613
+ name: 'customModel',
614
+ message: (0, i18n_1.t)('请输入自定义模型名称:'),
622
615
  validate: (input) => input.trim().length > 0 || (0, i18n_1.t)('模型名称不能为空')
623
616
  }
624
617
  ]);
625
- return { provider, model, isCustom: true, transformer: undefined };
618
+ model = customModel;
626
619
  }
627
620
  else {
628
- const selectedConfig = const_1.CLOUDBASE_PROVIDERS.find((p) => p.value === selectedProvider);
629
- const modelChoices = [
630
- ...selectedConfig.models.map((m) => ({ name: m, value: m }))
631
- ];
632
- const { selectedModel } = yield inquirer_1.default.prompt([
621
+ model = selectedModel;
622
+ }
623
+ return {
624
+ provider: selectedProvider,
625
+ model,
626
+ isCustom: false,
627
+ transformer: selectedConfig.transformer
628
+ };
629
+ }
630
+ }
631
+ async configureCodebuddyAgent(log) {
632
+ log.info((0, i18n_1.t)('配置说明可参考 {{link}}', { link: (0, output_1.genClickableLink)('https://cnb.cool/codebuddy/codebuddy-code/-/blob/main/docs/cli-reference.md') }));
633
+ const { configMethod } = await inquirer_1.default.prompt([
634
+ {
635
+ type: 'list',
636
+ name: 'configMethod',
637
+ message: (0, i18n_1.t)('选择配置方式: {{hint}}', { hint: const_1.LIST_HINT }),
638
+ choices: [
633
639
  {
634
- type: 'list',
635
- name: 'selectedModel',
636
- message: (0, i18n_1.t)('选择模型: {{hint}}', { hint: const_1.LIST_HINT }),
637
- choices: modelChoices,
638
- default: selectedConfig.models[0]
640
+ name: (0, i18n_1.t)('使用 CodeBuddy 账号登录'),
641
+ value: 'none'
642
+ },
643
+ {
644
+ name: (0, i18n_1.t)('配置 CodeBuddy API KEY(用于无交互环境)'),
645
+ value: 'custom'
639
646
  }
640
- ]);
641
- let model;
642
- if (selectedModel === 'custom') {
643
- const { customModel } = yield inquirer_1.default.prompt([
644
- {
645
- type: 'input',
646
- name: 'customModel',
647
- message: (0, i18n_1.t)('请输入自定义模型名称:'),
648
- validate: (input) => input.trim().length > 0 || (0, i18n_1.t)('模型名称不能为空')
649
- }
650
- ]);
651
- model = customModel;
652
- }
653
- else {
654
- model = selectedModel;
655
- }
656
- return {
657
- provider: selectedProvider,
658
- model,
659
- isCustom: false,
660
- transformer: selectedConfig.transformer
661
- };
647
+ ],
648
+ default: 'none'
662
649
  }
663
- });
664
- }
665
- configureCodebuddyAgent(log) {
666
- return __awaiter(this, void 0, void 0, function* () {
667
- log.info((0, i18n_1.t)('配置说明可参考 {{link}}', { link: (0, output_1.genClickableLink)('https://cnb.cool/codebuddy/codebuddy-code/-/blob/main/docs/cli-reference.md') }));
668
- const { configMethod } = yield inquirer_1.default.prompt([
650
+ ]);
651
+ if (configMethod === 'custom') {
652
+ const { apiKey } = await inquirer_1.default.prompt([
669
653
  {
670
- type: 'list',
671
- name: 'configMethod',
672
- message: (0, i18n_1.t)('选择配置方式: {{hint}}', { hint: const_1.LIST_HINT }),
673
- choices: [
674
- {
675
- name: (0, i18n_1.t)('使用 CodeBuddy 账号登录'),
676
- value: 'none'
677
- },
678
- {
679
- name: (0, i18n_1.t)('配置 CodeBuddy API KEY(用于无交互环境)'),
680
- value: 'custom'
681
- }
682
- ],
683
- default: 'none'
654
+ type: 'password',
655
+ name: 'apiKey',
656
+ message: 'API Key:',
657
+ validate: (input) => input.trim().length > 0 || (0, i18n_1.t)('请输入有效的 API Key')
684
658
  }
685
659
  ]);
686
- if (configMethod === 'custom') {
687
- const { apiKey } = yield inquirer_1.default.prompt([
688
- {
689
- type: 'password',
690
- name: 'apiKey',
691
- message: 'API Key:',
692
- validate: (input) => input.trim().length > 0 || (0, i18n_1.t)('请输入有效的 API Key')
693
- }
694
- ]);
695
- yield this.aiConfigManager.updateCodebuddyConfig('custom', {
696
- apiKey
697
- });
698
- }
699
- else {
700
- yield this.aiConfigManager.updateCodebuddyConfig('none', {});
701
- }
702
- log.info((0, i18n_1.t)('✅ CodeBuddy Code 配置完成'));
703
- log.info((0, i18n_1.t)('💡 提示:首次使用时会自动打开浏览器进行 OAuth 身份验证'));
704
- });
660
+ await this.aiConfigManager.updateCodebuddyConfig('custom', {
661
+ apiKey
662
+ });
663
+ }
664
+ else {
665
+ await this.aiConfigManager.updateCodebuddyConfig('none', {});
666
+ }
667
+ log.info((0, i18n_1.t)('✅ CodeBuddy Code 配置完成'));
668
+ log.info((0, i18n_1.t)('💡 提示:首次使用时会自动打开浏览器进行 OAuth 身份验证'));
705
669
  }
706
670
  }
707
671
  exports.AISetupWizard = AISetupWizard;