@cloudbase/cli 2.10.0-beta.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,22 +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
- var __asyncValues = (this && this.__asyncValues) || function (o) {
35
- if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
36
- var m = o[Symbol.asyncIterator], i;
37
- return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
38
- function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
39
- function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
40
- };
41
25
  var __importDefault = (this && this.__importDefault) || function (mod) {
42
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
43
27
  };
@@ -103,288 +87,258 @@ class AICommandRouter {
103
87
  constructor() {
104
88
  this.configManager = new config_1.AIConfigManager();
105
89
  }
106
- execute({ agent, addtionalArgs, log, template, useDefaultConfig }) {
90
+ async execute({ agent, addtionalArgs, log, template, useDefaultConfig }) {
107
91
  var _a;
108
- return __awaiter(this, void 0, void 0, function* () {
109
- if ((0, config_1.isValidAgent)(agent) !== true) {
110
- log.error((0, i18n_1.t)('❌ 无效的 agent: {{agent}}', { agent }));
111
- return;
112
- }
113
- const config = yield this.configManager.loadConfig();
114
- if (!config) {
115
- log.warn((0, i18n_1.t)("⚠️ 未检测到 AI ToolKit CLI 配置,请运行 'tcb ai --setup' 进行配置"));
116
- return;
117
- }
118
- const agentUpperCased = agent.toUpperCase();
119
- const agentConfig = (_a = config.agents) === null || _a === void 0 ? void 0 : _a[agent];
120
- if (!agentConfig) {
121
- log.warn((0, i18n_1.t)('⚠️ 未找到 {{agent}} 配置,请运行 tcb ai --setup 进行配置', { agent: agentUpperCased }));
122
- return;
123
- }
124
- log.info((0, i18n_1.t)('🚀 启动 {{agent}} AI CLI 工具', { agent: chalk_1.default.bold(agentUpperCased) }));
125
- try {
126
- yield this.checkToolkitConfig({ agent, log, template, useDefaultConfig });
127
- }
128
- catch (e) {
129
- log.warn((0, i18n_1.t)('⚠️ 云开发功能检查失败,但 AI 工具仍可正常使用'));
130
- }
131
- const isValid = yield this.validateAgentConfig(agent, agentConfig, log);
132
- if (!isValid) {
133
- log.warn((0, i18n_1.t)('⚠️ {{agent}} 配置无效,请重新配置', { agent: agent.toUpperCase() }));
92
+ if ((0, config_1.isValidAgent)(agent) !== true) {
93
+ log.error((0, i18n_1.t)('❌ 无效的 agent: {{agent}}', { agent }));
94
+ return;
95
+ }
96
+ const config = await this.configManager.loadConfig();
97
+ if (!config) {
98
+ log.warn((0, i18n_1.t)("⚠️ 未检测到 AI ToolKit CLI 配置,请运行 'tcb ai --setup' 进行配置"));
99
+ return;
100
+ }
101
+ const agentUpperCased = agent.toUpperCase();
102
+ const agentConfig = (_a = config.agents) === null || _a === void 0 ? void 0 : _a[agent];
103
+ if (!agentConfig) {
104
+ log.warn((0, i18n_1.t)('⚠️ 未找到 {{agent}} 配置,请运行 tcb ai --setup 进行配置', { agent: agentUpperCased }));
105
+ return;
106
+ }
107
+ log.info((0, i18n_1.t)('🚀 启动 {{agent}} AI CLI 工具', { agent: chalk_1.default.bold(agentUpperCased) }));
108
+ try {
109
+ await this.checkToolkitConfig({ agent, log, template, useDefaultConfig });
110
+ }
111
+ catch (e) {
112
+ log.warn((0, i18n_1.t)('⚠️ 云开发功能检查失败,但 AI 工具仍可正常使用'));
113
+ }
114
+ const isValid = await this.validateAgentConfig(agent, agentConfig, log);
115
+ if (!isValid) {
116
+ log.warn((0, i18n_1.t)('⚠️ {{agent}} 配置无效,请重新配置', { agent: agent.toUpperCase() }));
117
+ return;
118
+ }
119
+ this.executeAgentWithConfig(agent, agentConfig, this.parseArgs(addtionalArgs), log);
120
+ }
121
+ async checkToolkitConfig(checkOptions) {
122
+ const { agent, log, template, useDefaultConfig } = checkOptions;
123
+ const { missingFiles } = await this.configManager.checkToolkitConfig(agent);
124
+ if (missingFiles.length > 0) {
125
+ const skipTemplate = await this.checkSkipTemplateConfig();
126
+ if (skipTemplate) {
127
+ log.info((0, i18n_1.t)('🚫 已跳过模板下载,无法使用云开发 MCP 及 AI 规则。如需使用,请参考 tcb pull --help'));
134
128
  return;
135
129
  }
136
- this.executeAgentWithConfig(agent, agentConfig, this.parseArgs(addtionalArgs), log);
137
- });
130
+ log.log('');
131
+ await this.downloadTemplate({ log, template, agent, useDefaultConfig });
132
+ log.log('');
133
+ }
138
134
  }
139
- checkToolkitConfig(checkOptions) {
140
- return __awaiter(this, void 0, void 0, function* () {
141
- const { agent, log, template, useDefaultConfig } = checkOptions;
142
- const { missingFiles } = yield this.configManager.checkToolkitConfig(agent);
143
- if (missingFiles.length > 0) {
144
- const skipTemplate = yield this.checkSkipTemplateConfig();
145
- if (skipTemplate) {
146
- log.info((0, i18n_1.t)('🚫 已跳过模板下载,无法使用云开发 MCP 及 AI 规则。如需使用,请参考 tcb pull --help'));
147
- return;
148
- }
149
- log.log('');
150
- yield this.downloadTemplate({ log, template, agent, useDefaultConfig });
151
- log.log('');
152
- }
153
- });
135
+ async checkSkipTemplateConfig() {
136
+ try {
137
+ const fs = await Promise.resolve().then(() => __importStar(require('fs-extra')));
138
+ const path = await Promise.resolve().then(() => __importStar(require('path')));
139
+ const skipFile = path.join(process.cwd(), '.skip-template');
140
+ return await fs.pathExists(skipFile);
141
+ }
142
+ catch {
143
+ return false;
144
+ }
154
145
  }
155
- checkSkipTemplateConfig() {
156
- return __awaiter(this, void 0, void 0, function* () {
157
- try {
158
- const fs = yield Promise.resolve().then(() => __importStar(require('fs-extra')));
159
- const path = yield Promise.resolve().then(() => __importStar(require('path')));
160
- const skipFile = path.join(process.cwd(), '.skip-template');
161
- return yield fs.pathExists(skipFile);
162
- }
163
- catch (_a) {
164
- return false;
165
- }
166
- });
146
+ async saveSkipTemplateConfig() {
147
+ try {
148
+ const fs = await Promise.resolve().then(() => __importStar(require('fs-extra')));
149
+ const path = await Promise.resolve().then(() => __importStar(require('path')));
150
+ const skipFile = path.join(process.cwd(), '.skip-template');
151
+ await fs.writeFile(skipFile, new Date().toISOString());
152
+ }
153
+ catch (error) {
154
+ }
167
155
  }
168
- saveSkipTemplateConfig() {
169
- return __awaiter(this, void 0, void 0, function* () {
170
- try {
171
- const fs = yield Promise.resolve().then(() => __importStar(require('fs-extra')));
172
- const path = yield Promise.resolve().then(() => __importStar(require('path')));
173
- const skipFile = path.join(process.cwd(), '.skip-template');
174
- yield fs.writeFile(skipFile, new Date().toISOString());
175
- }
176
- catch (error) {
156
+ async downloadTemplate(options) {
157
+ const { log, template, agent, useDefaultConfig } = options;
158
+ try {
159
+ let templateType;
160
+ if (template) {
161
+ templateType = template;
177
162
  }
178
- });
179
- }
180
- downloadTemplate(options) {
181
- return __awaiter(this, void 0, void 0, function* () {
182
- const { log, template, agent, useDefaultConfig } = options;
183
- try {
184
- let templateType;
185
- if (template) {
186
- templateType = template;
163
+ else {
164
+ if (useDefaultConfig) {
165
+ templateType = 'rules';
187
166
  }
188
167
  else {
189
- if (useDefaultConfig) {
190
- templateType = 'rules';
191
- }
192
- else {
193
- const { templateType: selectedType } = yield inquirer_1.default.prompt([
194
- {
195
- type: 'list',
196
- name: 'templateType',
197
- message: (0, i18n_1.t)('下载模板以获取完整的开发体验: {{hint}}', { hint: const_1.LIST_HINT }),
198
- choices: [
199
- { name: (0, i18n_1.t)('🟦 微信小程序 + CloudBase'), value: 'miniprogram' },
200
- { name: (0, i18n_1.t)('🚀 Web 应用 - React + CloudBase'), value: 'react' },
201
- { name: (0, i18n_1.t)('🟢 Web 应用 - Vue + CloudBase'), value: 'vue' },
202
- { name: (0, i18n_1.t)('🌈 跨端应用 - UniApp + CloudBase'), value: 'uniapp' },
203
- { name: (0, i18n_1.t)('🧩 只下载 AI 规则和配置'), value: 'rules' },
204
- { name: (0, i18n_1.t)('🚫 不下载模板'), value: 'none' }
205
- ],
206
- default: 'miniprogram'
207
- }
208
- ]);
209
- templateType = selectedType;
210
- }
211
- }
212
- if (templateType === 'none') {
213
- log.info((0, i18n_1.t)('🚫 跳过模板下载'));
214
- yield this.saveSkipTemplateConfig();
215
- return;
168
+ const { templateType: selectedType } = await inquirer_1.default.prompt([
169
+ {
170
+ type: 'list',
171
+ name: 'templateType',
172
+ message: (0, i18n_1.t)('下载模板以获取完整的开发体验: {{hint}}', { hint: const_1.LIST_HINT }),
173
+ choices: [
174
+ { name: (0, i18n_1.t)('🟦 微信小程序 + CloudBase'), value: 'miniprogram' },
175
+ { name: (0, i18n_1.t)('🚀 Web 应用 - React + CloudBase'), value: 'react' },
176
+ { name: (0, i18n_1.t)('🟢 Web 应用 - Vue + CloudBase'), value: 'vue' },
177
+ { name: (0, i18n_1.t)('🌈 跨端应用 - UniApp + CloudBase'), value: 'uniapp' },
178
+ { name: (0, i18n_1.t)('🧩 只下载 AI 规则和配置'), value: 'rules' },
179
+ { name: (0, i18n_1.t)('🚫 不下载模板'), value: 'none' }
180
+ ],
181
+ default: 'miniprogram'
182
+ }
183
+ ]);
184
+ templateType = selectedType;
216
185
  }
217
- log.info((0, i18n_1.t)('📦 正在下载并解压 {{templateType}} 模板...', { templateType }));
218
- yield this.downloadAndExtractTemplate({ templateType, log, agent: agent, useDefaultConfig: useDefaultConfig || false });
219
- log.info((0, i18n_1.t)('✅ {{templateType}} 模板配置完成', { templateType }));
220
186
  }
221
- catch (error) {
222
- log.error((0, i18n_1.t)(' 配置失败: {{error}}', { error: error.message }));
223
- throw new error_1.CloudBaseError((0, i18n_1.t)('模板下载失败'), { original: error });
187
+ if (templateType === 'none') {
188
+ log.info((0, i18n_1.t)('🚫 跳过模板下载'));
189
+ await this.saveSkipTemplateConfig();
190
+ return;
224
191
  }
225
- });
192
+ log.info((0, i18n_1.t)('📦 正在下载并解压 {{templateType}} 模板...', { templateType }));
193
+ await this.downloadAndExtractTemplate({ templateType, log, agent: agent, useDefaultConfig: useDefaultConfig || false });
194
+ log.info((0, i18n_1.t)('✅ {{templateType}} 模板配置完成', { templateType }));
195
+ }
196
+ catch (error) {
197
+ log.error((0, i18n_1.t)('❌ 配置失败: {{error}}', { error: error.message }));
198
+ throw new error_1.CloudBaseError((0, i18n_1.t)('模板下载失败'), { original: error });
199
+ }
226
200
  }
227
- downloadAndExtractTemplate(options) {
228
- var _a, e_1, _b, _c;
229
- return __awaiter(this, void 0, void 0, function* () {
230
- const fs = yield Promise.resolve().then(() => __importStar(require('fs-extra')));
231
- const path = yield Promise.resolve().then(() => __importStar(require('path')));
232
- const os = yield Promise.resolve().then(() => __importStar(require('os')));
233
- const unzipper = yield Promise.resolve().then(() => __importStar(require('unzipper')));
234
- const https = yield Promise.resolve().then(() => __importStar(require('https')));
235
- let ConfigParser;
236
- const { templateType, log, agent, useDefaultConfig } = options;
237
- try {
238
- ConfigParser = (yield Promise.resolve().then(() => __importStar(require('@cloudbase/toolbox')))).ConfigParser;
239
- }
240
- catch (_d) {
241
- ConfigParser = undefined;
201
+ async downloadAndExtractTemplate(options) {
202
+ const fs = await Promise.resolve().then(() => __importStar(require('fs-extra')));
203
+ const path = await Promise.resolve().then(() => __importStar(require('path')));
204
+ const os = await Promise.resolve().then(() => __importStar(require('os')));
205
+ const unzipper = await Promise.resolve().then(() => __importStar(require('unzipper')));
206
+ const https = await Promise.resolve().then(() => __importStar(require('https')));
207
+ let ConfigParser;
208
+ const { templateType, log, agent, useDefaultConfig } = options;
209
+ try {
210
+ ConfigParser = (await Promise.resolve().then(() => __importStar(require('@cloudbase/toolbox')))).ConfigParser;
211
+ }
212
+ catch {
213
+ ConfigParser = undefined;
214
+ }
215
+ const templateMap = {
216
+ rules: {
217
+ url: 'https://static.cloudbase.net/cloudbase-examples/web-cloudbase-project.zip'
218
+ },
219
+ react: {
220
+ url: 'https://static.cloudbase.net/cloudbase-examples/web-cloudbase-react-template.zip'
221
+ },
222
+ vue: {
223
+ url: 'https://static.cloudbase.net/cloudbase-examples/web-cloudbase-vue-template.zip'
224
+ },
225
+ miniprogram: {
226
+ url: 'https://static.cloudbase.net/cloudbase-examples/miniprogram-cloudbase-miniprogram-template.zip'
227
+ },
228
+ uniapp: {
229
+ url: 'https://static.cloudbase.net/cloudbase-examples/universal-cloudbase-uniapp-template.zip'
242
230
  }
243
- const templateMap = {
244
- rules: {
245
- url: 'https://static.cloudbase.net/cloudbase-examples/web-cloudbase-project.zip'
246
- },
247
- react: {
248
- url: 'https://static.cloudbase.net/cloudbase-examples/web-cloudbase-react-template.zip'
249
- },
250
- vue: {
251
- url: 'https://static.cloudbase.net/cloudbase-examples/web-cloudbase-vue-template.zip'
252
- },
253
- miniprogram: {
254
- url: 'https://static.cloudbase.net/cloudbase-examples/miniprogram-cloudbase-miniprogram-template.zip'
255
- },
256
- uniapp: {
257
- url: 'https://static.cloudbase.net/cloudbase-examples/universal-cloudbase-uniapp-template.zip'
231
+ };
232
+ const template = templateMap[templateType];
233
+ if (!template)
234
+ throw new error_1.CloudBaseError((0, i18n_1.t)('未知模板类型'));
235
+ const tmpDir = os.tmpdir();
236
+ const zipPath = path.join(tmpDir, `cloudbase-template-${templateType}-${Date.now()}.zip`);
237
+ await new Promise((resolve, reject) => {
238
+ const file = fs.createWriteStream(zipPath);
239
+ https
240
+ .get(template.url, (response) => {
241
+ if (response.statusCode !== 200) {
242
+ reject(new Error((0, i18n_1.t)('下载失败: {{statusCode}}', { statusCode: response.statusCode })));
243
+ return;
258
244
  }
259
- };
260
- const template = templateMap[templateType];
261
- if (!template)
262
- throw new error_1.CloudBaseError((0, i18n_1.t)('未知模板类型'));
263
- const tmpDir = os.tmpdir();
264
- const zipPath = path.join(tmpDir, `cloudbase-template-${templateType}-${Date.now()}.zip`);
265
- yield new Promise((resolve, reject) => {
266
- const file = fs.createWriteStream(zipPath);
267
- https
268
- .get(template.url, (response) => {
269
- if (response.statusCode !== 200) {
270
- reject(new Error((0, i18n_1.t)('下载失败: {{statusCode}}', { statusCode: response.statusCode })));
271
- return;
272
- }
273
- response.pipe(file);
274
- file.on('finish', () => {
275
- file.close();
276
- resolve();
277
- });
278
- })
279
- .on('error', (err) => {
280
- fs.unlink(zipPath);
281
- reject(err);
245
+ response.pipe(file);
246
+ file.on('finish', () => {
247
+ file.close();
248
+ resolve();
282
249
  });
250
+ })
251
+ .on('error', (err) => {
252
+ fs.unlink(zipPath);
253
+ reject(err);
283
254
  });
284
- const extractDir = process.cwd();
285
- const zipStream = fs.createReadStream(zipPath).pipe(unzipper.Parse({ forceStream: true }));
286
- const agentDirs = ['.claude', '.codex', '.qwen', '.codebuddy', '.cursor'];
287
- try {
288
- for (var _e = true, _f = __asyncValues(zipStream), _g; _g = yield _f.next(), _a = _g.done, !_a;) {
289
- _c = _g.value;
290
- _e = false;
291
- try {
292
- const entry = _c;
293
- const entryPath = entry.path;
294
- const destPath = path.join(extractDir, entryPath);
295
- if (useDefaultConfig && agent) {
296
- const currentAgentDir = `.${agent}`;
297
- const isAgentDir = agentDirs.some(dir => entryPath.startsWith(dir + '/') || entryPath === dir);
298
- if (isAgentDir && !entryPath.startsWith(currentAgentDir + '/') && entryPath !== currentAgentDir) {
299
- log.debug && log.debug((0, i18n_1.t)('跳过不匹配的 agent 目录: {{entryPath}} (当前 agent: {{agent}})', { entryPath, agent }));
300
- entry.autodrain();
301
- continue;
302
- }
303
- }
304
- if (entry.type === 'Directory') {
305
- yield fs.ensureDir(destPath);
306
- entry.autodrain();
307
- continue;
308
- }
309
- if (MCP_CONFIG_SET.has(entryPath)) {
310
- try {
311
- yield this.mergeMcpConfig(entry, destPath, inferConfigFormat(entryPath), log);
312
- }
313
- catch (e) {
314
- log.warn((0, i18n_1.t)('MCP 配置合并失败 {{entryPath}}:{{error}},已跳过', { entryPath, error: e.message }));
315
- }
316
- continue;
317
- }
318
- if (entryPath === 'cloudbaserc.json' && (yield fs.pathExists(destPath))) {
319
- try {
320
- const templateContent = yield entry.buffer();
321
- const templateJson = JSON.parse(templateContent.toString('utf8'));
322
- const localJson = yield fs.readJson(destPath);
323
- const deepMerge = (target, source) => {
324
- if (typeof target !== 'object' ||
325
- typeof source !== 'object' ||
326
- !target ||
327
- !source)
328
- return target;
329
- const result = Object.assign(Object.assign({}, source), target);
330
- for (const key of Object.keys(source)) {
331
- if (key in target &&
332
- typeof target[key] === 'object' &&
333
- typeof source[key] === 'object') {
334
- result[key] = deepMerge(target[key], source[key]);
335
- }
336
- }
337
- return result;
338
- };
339
- let merged = deepMerge(localJson, templateJson);
340
- yield fs.writeJson(destPath, merged, { spaces: 2 });
341
- }
342
- catch (e) {
343
- log.warn((0, i18n_1.t)('cloudbaserc.json 合并失败,已跳过: {{error}}', { error: e.message }));
344
- }
345
- continue;
346
- }
347
- if (yield fs.pathExists(destPath)) {
348
- if (useDefaultConfig) {
349
- entry.autodrain();
350
- continue;
351
- }
352
- const { confirmOverwriteFile } = yield inquirer_1.default.prompt([
353
- {
354
- type: 'confirm',
355
- name: 'confirmOverwriteFile',
356
- message: (0, i18n_1.t)('检测到已存在文件 {{entryPath}},是否覆盖? {{hint}}', {
357
- entryPath,
358
- hint: (0, const_1.getBooleanHint)(false)
359
- }),
360
- default: false
361
- }
362
- ]);
363
- if (!confirmOverwriteFile) {
364
- entry.autodrain();
365
- continue;
255
+ });
256
+ const extractDir = process.cwd();
257
+ const zipStream = fs.createReadStream(zipPath).pipe(unzipper.Parse({ forceStream: true }));
258
+ const agentDirs = ['.claude', '.codex', '.qwen', '.codebuddy', '.cursor'];
259
+ for await (const entry of zipStream) {
260
+ const entryPath = entry.path;
261
+ const destPath = path.join(extractDir, entryPath);
262
+ if (useDefaultConfig && agent) {
263
+ const currentAgentDir = `.${agent}`;
264
+ const isAgentDir = agentDirs.some(dir => entryPath.startsWith(dir + '/') || entryPath === dir);
265
+ if (isAgentDir && !entryPath.startsWith(currentAgentDir + '/') && entryPath !== currentAgentDir) {
266
+ log.debug && log.debug((0, i18n_1.t)('跳过不匹配的 agent 目录: {{entryPath}} (当前 agent: {{agent}})', { entryPath, agent }));
267
+ entry.autodrain();
268
+ continue;
269
+ }
270
+ }
271
+ if (entry.type === 'Directory') {
272
+ await fs.ensureDir(destPath);
273
+ entry.autodrain();
274
+ continue;
275
+ }
276
+ if (MCP_CONFIG_SET.has(entryPath)) {
277
+ try {
278
+ await this.mergeMcpConfig(entry, destPath, inferConfigFormat(entryPath), log);
279
+ }
280
+ catch (e) {
281
+ log.warn((0, i18n_1.t)('MCP 配置合并失败 {{entryPath}}:{{error}},已跳过', { entryPath, error: e.message }));
282
+ }
283
+ continue;
284
+ }
285
+ if (entryPath === 'cloudbaserc.json' && (await fs.pathExists(destPath))) {
286
+ try {
287
+ const templateContent = await entry.buffer();
288
+ const templateJson = JSON.parse(templateContent.toString('utf8'));
289
+ const localJson = await fs.readJson(destPath);
290
+ const deepMerge = (target, source) => {
291
+ if (typeof target !== 'object' ||
292
+ typeof source !== 'object' ||
293
+ !target ||
294
+ !source)
295
+ return target;
296
+ const result = { ...source, ...target };
297
+ for (const key of Object.keys(source)) {
298
+ if (key in target &&
299
+ typeof target[key] === 'object' &&
300
+ typeof source[key] === 'object') {
301
+ result[key] = deepMerge(target[key], source[key]);
366
302
  }
367
303
  }
368
- yield fs.ensureDir(path.dirname(destPath));
369
- yield new Promise((res, rej) => {
370
- entry.pipe(fs.createWriteStream(destPath)).on('finish', res).on('error', rej);
371
- });
372
- }
373
- finally {
374
- _e = true;
375
- }
304
+ return result;
305
+ };
306
+ let merged = deepMerge(localJson, templateJson);
307
+ await fs.writeJson(destPath, merged, { spaces: 2 });
376
308
  }
309
+ catch (e) {
310
+ log.warn((0, i18n_1.t)('cloudbaserc.json 合并失败,已跳过: {{error}}', { error: e.message }));
311
+ }
312
+ continue;
377
313
  }
378
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
379
- finally {
380
- try {
381
- if (!_e && !_a && (_b = _f.return)) yield _b.call(_f);
314
+ if (await fs.pathExists(destPath)) {
315
+ if (useDefaultConfig) {
316
+ entry.autodrain();
317
+ continue;
318
+ }
319
+ const { confirmOverwriteFile } = await inquirer_1.default.prompt([
320
+ {
321
+ type: 'confirm',
322
+ name: 'confirmOverwriteFile',
323
+ message: (0, i18n_1.t)('检测到已存在文件 {{entryPath}},是否覆盖? {{hint}}', {
324
+ entryPath,
325
+ hint: (0, const_1.getBooleanHint)(false)
326
+ }),
327
+ default: false
328
+ }
329
+ ]);
330
+ if (!confirmOverwriteFile) {
331
+ entry.autodrain();
332
+ continue;
382
333
  }
383
- finally { if (e_1) throw e_1.error; }
384
334
  }
385
- yield fs.unlink(zipPath);
386
- yield this.modifyMCPConfigs(extractDir, log);
387
- });
335
+ await fs.ensureDir(path.dirname(destPath));
336
+ await new Promise((res, rej) => {
337
+ entry.pipe(fs.createWriteStream(destPath)).on('finish', res).on('error', rej);
338
+ });
339
+ }
340
+ await fs.unlink(zipPath);
341
+ await this.modifyMCPConfigs(extractDir, log);
388
342
  }
389
343
  getInstallCommand(agent) {
390
344
  switch (agent) {
@@ -427,807 +381,778 @@ class AICommandRouter {
427
381
  return { success: false, message: (0, i18n_1.t)('# 请查阅 {{agent}} 的官方安装文档', { agent }) };
428
382
  }
429
383
  }
430
- executeCommand(command, args, env, log) {
431
- return __awaiter(this, void 0, void 0, function* () {
432
- return new Promise((resolve, reject) => {
433
- const useShell = process.platform === 'win32';
434
- const child = (0, child_process_1.spawn)(command, args, {
435
- stdio: 'inherit',
436
- env,
437
- shell: useShell
438
- });
439
- child.on('close', (code) => {
440
- if (code === 0) {
441
- resolve();
442
- }
443
- else {
444
- const errorMsg = (0, i18n_1.t)('命令执行失败: {{command}} {{args}} (退出码: {{code}})', {
445
- command,
446
- args: args.join(' '),
447
- code
448
- });
449
- log.error((0, i18n_1.t)('❌ {{errorMsg}}', { errorMsg }));
450
- if (code === 127) {
451
- log.info((0, i18n_1.t)('💡 命令未找到,请检查是否正确安装'));
452
- log.info((0, i18n_1.t)('📦 安装命令: {{installCmd}}', { installCmd: this.getInstallCommand(command).message }));
453
- }
454
- else if (code === 1) {
455
- log.info((0, i18n_1.t)('💡 可能是参数错误或配置问题'));
456
- log.info((0, i18n_1.t)('🔧 请检查 API 密钥、模型名称等配置是否正确'));
457
- }
458
- if (command === 'ccr') {
459
- log.info((0, i18n_1.t)('🔧 请前往 {{logPath}} 查看日志', { logPath: const_1.CLAUDE_CODE_ROUTER_LOG_PATH }));
460
- }
461
- reject(new Error(errorMsg));
462
- }
463
- });
464
- child.on('error', (err) => {
465
- const errorMsg = (0, i18n_1.t)('启动失败: {{command}} ({{error}})', { command, error: err.message });
384
+ async executeCommand(command, args, env, log) {
385
+ return new Promise((resolve, reject) => {
386
+ const useShell = process.platform === 'win32';
387
+ const child = (0, child_process_1.spawn)(command, args, {
388
+ stdio: 'inherit',
389
+ env,
390
+ shell: useShell
391
+ });
392
+ child.on('close', (code) => {
393
+ if (code === 0) {
394
+ resolve();
395
+ }
396
+ else {
397
+ const errorMsg = (0, i18n_1.t)('命令执行失败: {{command}} {{args}} (退出码: {{code}})', {
398
+ command,
399
+ args: args.join(' '),
400
+ code
401
+ });
466
402
  log.error((0, i18n_1.t)('❌ {{errorMsg}}', { errorMsg }));
467
- if (err.message.includes('ENOENT')) {
468
- log.info((0, i18n_1.t)('💡 命令不存在,请先安装对应的 AI CLI 工具'));
403
+ if (code === 127) {
404
+ log.info((0, i18n_1.t)('💡 命令未找到,请检查是否正确安装'));
469
405
  log.info((0, i18n_1.t)('📦 安装命令: {{installCmd}}', { installCmd: this.getInstallCommand(command).message }));
470
406
  }
471
- else if (err.message.includes('EACCES')) {
472
- log.info((0, i18n_1.t)('💡 权限不足,请检查文件权限或使用管理员权限'));
407
+ else if (code === 1) {
408
+ log.info((0, i18n_1.t)('💡 可能是参数错误或配置问题'));
409
+ log.info((0, i18n_1.t)('🔧 请检查 API 密钥、模型名称等配置是否正确'));
410
+ }
411
+ if (command === 'ccr') {
412
+ log.info((0, i18n_1.t)('🔧 请前往 {{logPath}} 查看日志', { logPath: const_1.CLAUDE_CODE_ROUTER_LOG_PATH }));
473
413
  }
474
414
  reject(new Error(errorMsg));
475
- });
415
+ }
416
+ });
417
+ child.on('error', (err) => {
418
+ const errorMsg = (0, i18n_1.t)('启动失败: {{command}} ({{error}})', { command, error: err.message });
419
+ log.error((0, i18n_1.t)('❌ {{errorMsg}}', { errorMsg }));
420
+ if (err.message.includes('ENOENT')) {
421
+ log.info((0, i18n_1.t)('💡 命令不存在,请先安装对应的 AI CLI 工具'));
422
+ log.info((0, i18n_1.t)('📦 安装命令: {{installCmd}}', { installCmd: this.getInstallCommand(command).message }));
423
+ }
424
+ else if (err.message.includes('EACCES')) {
425
+ log.info((0, i18n_1.t)('💡 权限不足,请检查文件权限或使用管理员权限'));
426
+ }
427
+ reject(new Error(errorMsg));
476
428
  });
477
429
  });
478
430
  }
479
- isToolAvailable(command) {
480
- return __awaiter(this, void 0, void 0, function* () {
481
- return new Promise((resolve) => {
482
- const child = (0, child_process_1.spawn)(command, ['--version'], {
483
- stdio: 'pipe',
484
- shell: true
485
- });
486
- child.on('close', (code) => {
487
- resolve(code === 0);
488
- });
489
- child.on('error', () => {
490
- resolve(false);
491
- });
431
+ async isToolAvailable(command) {
432
+ return new Promise((resolve) => {
433
+ const child = (0, child_process_1.spawn)(command, ['--version'], {
434
+ stdio: 'pipe',
435
+ shell: true
436
+ });
437
+ child.on('close', (code) => {
438
+ resolve(code === 0);
439
+ });
440
+ child.on('error', () => {
441
+ resolve(false);
492
442
  });
493
443
  });
494
444
  }
495
- validateAgentConfig(agent, agentConfig, log) {
496
- return __awaiter(this, void 0, void 0, function* () {
497
- if (!agentConfig) {
498
- log.error((0, i18n_1.t)('❌ Agent 配置为空'));
499
- return false;
500
- }
501
- const validateResult = (0, const_1.getAgentConfigValidator)(agent)(agentConfig);
502
- if (validateResult.success === true) {
503
- log.debug((0, i18n_1.t)('✅ Agent 配置验证通过'));
504
- return true;
505
- }
506
- else {
507
- log.error((0, i18n_1.t)('❌ {{agent}} 配置无效: {{error}}', { agent, error: validateResult.error }));
508
- return false;
509
- }
510
- });
445
+ async validateAgentConfig(agent, agentConfig, log) {
446
+ if (!agentConfig) {
447
+ log.error((0, i18n_1.t)('❌ Agent 配置为空'));
448
+ return false;
449
+ }
450
+ const validateResult = (0, const_1.getAgentConfigValidator)(agent)(agentConfig);
451
+ if (validateResult.success === true) {
452
+ log.debug((0, i18n_1.t)('✅ Agent 配置验证通过'));
453
+ return true;
454
+ }
455
+ else {
456
+ log.error((0, i18n_1.t)('❌ {{agent}} 配置无效: {{error}}', { agent, error: validateResult.error }));
457
+ return false;
458
+ }
511
459
  }
512
- executeAgentWithConfig(agent, agentConfig, additionalArgs, log) {
513
- return __awaiter(this, void 0, void 0, function* () {
514
- switch (agent) {
515
- case const_1.CLAUDE.value:
516
- try {
517
- if (agentConfig.type === 'cloudbase') {
518
- return yield this.executeClaudeCloudbaseAgent(agentConfig, additionalArgs, log);
519
- }
520
- else if (agentConfig.type === 'custom') {
521
- return yield this.executeClaudeAgent(agentConfig, additionalArgs, log);
522
- }
523
- else {
524
- return yield this.executeNoneClaudeAgent(additionalArgs, log);
525
- }
526
- }
527
- catch (_) {
528
- (0, claudeWindows_1.claudeWindowsCheck)(log);
529
- return process.exit(1);
530
- }
531
- case const_1.QWEN.value:
532
- if (agentConfig.type === 'cloudbase') {
533
- return yield this.executeQwenCloudbaseAgent(agentConfig, additionalArgs, log);
534
- }
535
- else if (agentConfig.type === 'custom') {
536
- return yield this.executeQwenAgent(agentConfig, additionalArgs, log);
537
- }
538
- else {
539
- return yield this.executeNoneQwenAgent(additionalArgs, log);
540
- }
541
- case const_1.CODEX.value:
460
+ async executeAgentWithConfig(agent, agentConfig, additionalArgs, log) {
461
+ switch (agent) {
462
+ case const_1.CLAUDE.value:
463
+ try {
542
464
  if (agentConfig.type === 'cloudbase') {
543
- return yield this.executeCodexCloudbaseAgent(agentConfig, additionalArgs, log);
465
+ return await this.executeClaudeCloudbaseAgent(agentConfig, additionalArgs, log);
544
466
  }
545
467
  else if (agentConfig.type === 'custom') {
546
- return yield this.executeCodexAgent(agentConfig, additionalArgs, log);
547
- }
548
- else {
549
- return yield this.executeNoneCodexAgent(additionalArgs, log);
550
- }
551
- case const_1.AIDER.value:
552
- if (agentConfig.type === 'cloudbase') {
553
- return yield this.executeAiderCloudbaseAgent(agentConfig, additionalArgs, log);
554
- }
555
- else {
556
- return yield this.executeAiderAgent(agentConfig, additionalArgs, log);
557
- }
558
- case const_1.CURSOR.value:
559
- return yield this.executeNoneCursorAgent(additionalArgs, log);
560
- case const_1.CODEBUDDY.value:
561
- if (agentConfig.type === 'custom') {
562
- return yield this.executeCodebuddyAgent(agentConfig, additionalArgs, log);
468
+ return await this.executeClaudeAgent(agentConfig, additionalArgs, log);
563
469
  }
564
470
  else {
565
- return yield this.executeNoneCodebuddyAgent(additionalArgs, log);
471
+ return await this.executeNoneClaudeAgent(additionalArgs, log);
566
472
  }
567
- default:
568
- throw new Error((0, i18n_1.t)('不支持的 AI 工具: {{agent}}', { agent }));
569
- }
570
- });
473
+ }
474
+ catch (_) {
475
+ (0, claudeWindows_1.claudeWindowsCheck)(log);
476
+ return process.exit(1);
477
+ }
478
+ case const_1.QWEN.value:
479
+ if (agentConfig.type === 'cloudbase') {
480
+ return await this.executeQwenCloudbaseAgent(agentConfig, additionalArgs, log);
481
+ }
482
+ else if (agentConfig.type === 'custom') {
483
+ return await this.executeQwenAgent(agentConfig, additionalArgs, log);
484
+ }
485
+ else {
486
+ return await this.executeNoneQwenAgent(additionalArgs, log);
487
+ }
488
+ case const_1.CODEX.value:
489
+ if (agentConfig.type === 'cloudbase') {
490
+ return await this.executeCodexCloudbaseAgent(agentConfig, additionalArgs, log);
491
+ }
492
+ else if (agentConfig.type === 'custom') {
493
+ return await this.executeCodexAgent(agentConfig, additionalArgs, log);
494
+ }
495
+ else {
496
+ return await this.executeNoneCodexAgent(additionalArgs, log);
497
+ }
498
+ case const_1.AIDER.value:
499
+ if (agentConfig.type === 'cloudbase') {
500
+ return await this.executeAiderCloudbaseAgent(agentConfig, additionalArgs, log);
501
+ }
502
+ else {
503
+ return await this.executeAiderAgent(agentConfig, additionalArgs, log);
504
+ }
505
+ case const_1.CURSOR.value:
506
+ return await this.executeNoneCursorAgent(additionalArgs, log);
507
+ case const_1.CODEBUDDY.value:
508
+ if (agentConfig.type === 'custom') {
509
+ return await this.executeCodebuddyAgent(agentConfig, additionalArgs, log);
510
+ }
511
+ else {
512
+ return await this.executeNoneCodebuddyAgent(additionalArgs, log);
513
+ }
514
+ default:
515
+ throw new Error((0, i18n_1.t)('不支持的 AI 工具: {{agent}}', { agent }));
516
+ }
571
517
  }
572
- executeClaudeAgent({ apiKey, baseUrl, model }, additionalArgs, log) {
573
- return __awaiter(this, void 0, void 0, function* () {
574
- (0, nodeVersion_1.ensureNodeVersion)('v18.0.0', log);
575
- yield this.ensureClaudeCode(log);
576
- yield this.executeCommand('claude', additionalArgs, Object.assign(Object.assign({}, process.env), { ANTHROPIC_AUTH_TOKEN: apiKey, ANTHROPIC_BASE_URL: baseUrl, ANTHROPIC_MODEL: model }), log);
577
- });
518
+ async executeClaudeAgent({ apiKey, baseUrl, model }, additionalArgs, log) {
519
+ (0, nodeVersion_1.ensureNodeVersion)('v18.0.0', log);
520
+ await this.ensureClaudeCode(log);
521
+ await this.executeCommand('claude', additionalArgs, {
522
+ ...process.env,
523
+ ANTHROPIC_AUTH_TOKEN: apiKey,
524
+ ANTHROPIC_BASE_URL: baseUrl,
525
+ ANTHROPIC_MODEL: model
526
+ }, log);
578
527
  }
579
- executeNoneClaudeAgent(additionalArgs, log) {
580
- return __awaiter(this, void 0, void 0, function* () {
581
- yield this.ensureClaudeCode(log);
582
- yield this.executeCommand('claude', additionalArgs, Object.assign({}, process.env), log);
583
- });
528
+ async executeNoneClaudeAgent(additionalArgs, log) {
529
+ await this.ensureClaudeCode(log);
530
+ await this.executeCommand('claude', additionalArgs, { ...process.env }, log);
584
531
  }
585
- executeQwenAgent({ apiKey, baseUrl, model }, additionalArgs, log) {
586
- return __awaiter(this, void 0, void 0, function* () {
587
- (0, nodeVersion_1.ensureNodeVersion)('v20.0.0', log);
588
- yield this.ensureQwenCode(log);
589
- yield this.executeCommand('qwen', additionalArgs, Object.assign(Object.assign({}, process.env), { OPENAI_API_KEY: apiKey, OPENAI_BASE_URL: baseUrl, OPENAI_MODEL: model }), log);
590
- });
532
+ async executeQwenAgent({ apiKey, baseUrl, model }, additionalArgs, log) {
533
+ (0, nodeVersion_1.ensureNodeVersion)('v20.0.0', log);
534
+ await this.ensureQwenCode(log);
535
+ await this.executeCommand('qwen', additionalArgs, {
536
+ ...process.env,
537
+ OPENAI_API_KEY: apiKey,
538
+ OPENAI_BASE_URL: baseUrl,
539
+ OPENAI_MODEL: model
540
+ }, log);
591
541
  }
592
- executeNoneQwenAgent(additionalArgs, log) {
593
- return __awaiter(this, void 0, void 0, function* () {
594
- yield this.ensureQwenCode(log);
595
- yield this.executeCommand('qwen', additionalArgs, Object.assign({}, process.env), log);
596
- });
542
+ async executeNoneQwenAgent(additionalArgs, log) {
543
+ await this.ensureQwenCode(log);
544
+ await this.executeCommand('qwen', additionalArgs, { ...process.env }, log);
597
545
  }
598
- executeQwenCloudbaseAgent({ provider, model }, additionalArgs, log) {
599
- return __awaiter(this, void 0, void 0, function* () {
600
- (0, nodeVersion_1.ensureNodeVersion)('v20.0.0', log);
601
- yield this.ensureQwenCode(log);
602
- const _envId = yield (0, config_1.createConfigParser)().get('envId');
603
- yield (0, auth_1.checkLogin)();
604
- const credential = yield (0, utils_1.getCredential)({}, {});
605
- const envId = yield (0, env_1.ensureValidEnv)(_envId, log);
606
- const accessToken = yield (0, utils_1.rawFetchAccessToken)({
607
- envId,
608
- secretId: credential.secretId,
609
- secretKey: credential.secretKey,
610
- token: credential.token
611
- });
612
- if (!accessToken.access_token) {
613
- log.error((0, i18n_1.t)('获取云开发 Access Token 失败,请运行 tcb login 后再重试,{{token}}', {
614
- token: JSON.stringify(accessToken)
615
- }));
616
- process.exit(1);
617
- }
618
- const baseUrl = `${(0, url_1.getGatewayUrl)(envId)}/v1/ai/${provider}`;
619
- const apiKey = accessToken.access_token;
620
- yield this.executeCommand('qwen', additionalArgs, Object.assign(Object.assign({}, process.env), { OPENAI_API_KEY: apiKey, OPENAI_BASE_URL: baseUrl, OPENAI_MODEL: model }), log);
546
+ async executeQwenCloudbaseAgent({ provider, model }, additionalArgs, log) {
547
+ (0, nodeVersion_1.ensureNodeVersion)('v20.0.0', log);
548
+ await this.ensureQwenCode(log);
549
+ const _envId = await (0, config_1.createConfigParser)().get('envId');
550
+ await (0, auth_1.checkLogin)();
551
+ const credential = await (0, utils_1.getCredential)({}, {});
552
+ const envId = await (0, env_1.ensureValidEnv)(_envId, log);
553
+ const accessToken = await (0, utils_1.rawFetchAccessToken)({
554
+ envId,
555
+ secretId: credential.secretId,
556
+ secretKey: credential.secretKey,
557
+ token: credential.token
621
558
  });
559
+ if (!accessToken.access_token) {
560
+ log.error((0, i18n_1.t)('获取云开发 Access Token 失败,请运行 tcb login 后再重试,{{token}}', {
561
+ token: JSON.stringify(accessToken)
562
+ }));
563
+ process.exit(1);
564
+ }
565
+ const baseUrl = `${(0, url_1.getGatewayUrl)(envId)}/v1/ai/${provider}`;
566
+ const apiKey = accessToken.access_token;
567
+ await this.executeCommand('qwen', additionalArgs, {
568
+ ...process.env,
569
+ OPENAI_API_KEY: apiKey,
570
+ OPENAI_BASE_URL: baseUrl,
571
+ OPENAI_MODEL: model
572
+ }, log);
622
573
  }
623
- executeClaudeCloudbaseAgent({ provider, model, transformer }, additionalArgs, log) {
624
- return __awaiter(this, void 0, void 0, function* () {
625
- (0, nodeVersion_1.ensureNodeVersion)('v18.19.0', log);
626
- yield this.ensureClaudeCodeRouter(log);
627
- yield this.ensureClaudeCode(log);
628
- yield this.configureClaudeCodeRouter(provider, model, transformer, log);
629
- yield this.restartClaudeCodeRouter(log);
630
- yield this.executeCommand('ccr', ['code', ...additionalArgs], Object.assign({}, process.env), log);
631
- });
574
+ async executeClaudeCloudbaseAgent({ provider, model, transformer }, additionalArgs, log) {
575
+ (0, nodeVersion_1.ensureNodeVersion)('v18.19.0', log);
576
+ await this.ensureClaudeCodeRouter(log);
577
+ await this.ensureClaudeCode(log);
578
+ await this.configureClaudeCodeRouter(provider, model, transformer, log);
579
+ await this.restartClaudeCodeRouter(log);
580
+ await this.executeCommand('ccr', ['code', ...additionalArgs], { ...process.env }, log);
632
581
  }
633
- restartClaudeCodeRouter(log) {
634
- return __awaiter(this, void 0, void 0, function* () {
635
- try {
636
- yield this.executeCommand('ccr', ['restart'], process.env, log);
637
- }
638
- catch (e) {
639
- log.error((0, i18n_1.t)('执行 ccr restart 失败,尝试执行 ccr stop && ccr start'));
640
- yield this.executeCommand('ccr', ['stop'], process.env, log);
641
- this.executeCommand('ccr', ['start'], process.env, log);
642
- const max = 3;
643
- let current = 0;
644
- while (current < max) {
645
- current++;
646
- if (current > max) {
647
- throw new Error((0, i18n_1.t)('ccr 重启完成失败,可前往 {{logPath}} 查看日志', { logPath: const_1.CLAUDE_CODE_ROUTER_LOG_PATH }));
648
- }
649
- log.info((0, i18n_1.t)('{{current}}/{{max}}等待 ccr 重启完成...', { current, max }));
650
- const isRunning = yield this.isClaudeCodeRouterRunning();
651
- if (isRunning) {
652
- log.info((0, i18n_1.t)('ccr 重启完成'));
653
- break;
654
- }
582
+ async restartClaudeCodeRouter(log) {
583
+ try {
584
+ await this.executeCommand('ccr', ['restart'], process.env, log);
585
+ }
586
+ catch (e) {
587
+ log.error((0, i18n_1.t)('执行 ccr restart 失败,尝试执行 ccr stop && ccr start'));
588
+ await this.executeCommand('ccr', ['stop'], process.env, log);
589
+ this.executeCommand('ccr', ['start'], process.env, log);
590
+ const max = 3;
591
+ let current = 0;
592
+ while (current < max) {
593
+ current++;
594
+ if (current > max) {
595
+ throw new Error((0, i18n_1.t)('ccr 重启完成失败,可前往 {{logPath}} 查看日志', { logPath: const_1.CLAUDE_CODE_ROUTER_LOG_PATH }));
596
+ }
597
+ log.info((0, i18n_1.t)('{{current}}/{{max}}等待 ccr 重启完成...', { current, max }));
598
+ const isRunning = await this.isClaudeCodeRouterRunning();
599
+ if (isRunning) {
600
+ log.info((0, i18n_1.t)('ccr 重启完成'));
601
+ break;
655
602
  }
656
603
  }
657
- });
604
+ }
658
605
  }
659
- isClaudeCodeRouterRunning() {
660
- return __awaiter(this, void 0, void 0, function* () {
661
- return new Promise((resolve) => {
662
- const child = (0, child_process_1.spawn)('ccr', ['status'], {
663
- stdio: 'pipe',
664
- env: process.env,
665
- shell: process.platform === 'win32'
666
- });
667
- child.stdout.on('data', (data) => {
668
- const str = data.toString();
669
- if (str.includes('Status: Running')) {
670
- resolve(true);
671
- child.kill();
672
- }
673
- });
674
- setTimeout(() => {
675
- resolve(false);
606
+ async isClaudeCodeRouterRunning() {
607
+ return new Promise((resolve) => {
608
+ const child = (0, child_process_1.spawn)('ccr', ['status'], {
609
+ stdio: 'pipe',
610
+ env: process.env,
611
+ shell: process.platform === 'win32'
612
+ });
613
+ child.stdout.on('data', (data) => {
614
+ const str = data.toString();
615
+ if (str.includes('Status: Running')) {
616
+ resolve(true);
676
617
  child.kill();
677
- }, 3000);
618
+ }
678
619
  });
620
+ setTimeout(() => {
621
+ resolve(false);
622
+ child.kill();
623
+ }, 3000);
679
624
  });
680
625
  }
681
- configureClaudeCodeRouter(provider, model, transformer, log) {
682
- return __awaiter(this, void 0, void 0, function* () {
683
- const fs = yield Promise.resolve().then(() => __importStar(require('fs-extra')));
684
- const _envId = yield (0, config_1.createConfigParser)().get('envId');
685
- yield (0, auth_1.checkLogin)();
686
- const credential = yield (0, utils_1.getCredential)({}, {});
687
- const envId = yield (0, env_1.ensureValidEnv)(_envId, log);
688
- const accessToken = yield (0, utils_1.rawFetchAccessToken)({
689
- envId,
690
- secretId: credential.secretId,
691
- secretKey: credential.secretKey,
692
- token: credential.token
693
- });
694
- if (!accessToken.access_token) {
695
- log.error((0, i18n_1.t)('获取云开发 Access Token 失败,请运行 tcb login 后再重试,{{token}}', {
696
- token: JSON.stringify(accessToken)
697
- }));
626
+ async configureClaudeCodeRouter(provider, model, transformer, log) {
627
+ const fs = await Promise.resolve().then(() => __importStar(require('fs-extra')));
628
+ const _envId = await (0, config_1.createConfigParser)().get('envId');
629
+ await (0, auth_1.checkLogin)();
630
+ const credential = await (0, utils_1.getCredential)({}, {});
631
+ const envId = await (0, env_1.ensureValidEnv)(_envId, log);
632
+ const accessToken = await (0, utils_1.rawFetchAccessToken)({
633
+ envId,
634
+ secretId: credential.secretId,
635
+ secretKey: credential.secretKey,
636
+ token: credential.token
637
+ });
638
+ if (!accessToken.access_token) {
639
+ log.error((0, i18n_1.t)('获取云开发 Access Token 失败,请运行 tcb login 后再重试,{{token}}', {
640
+ token: JSON.stringify(accessToken)
641
+ }));
642
+ process.exit(1);
643
+ }
644
+ const cloudbaseProvider = {
645
+ name: 'cloudbase',
646
+ api_base_url: `${(0, url_1.getGatewayUrl)(envId)}/v1/ai/${provider}/chat/completions`,
647
+ api_key: accessToken.access_token,
648
+ models: [model]
649
+ };
650
+ if (transformer && transformer.trim().length > 0) {
651
+ cloudbaseProvider.transformer = { use: [transformer] };
652
+ }
653
+ await fs.ensureFile(const_1.CLAUDE_CODE_ROUTER_CONFIG_PATH);
654
+ const claudeCodeRouterConfig = await fs.readFile(const_1.CLAUDE_CODE_ROUTER_CONFIG_PATH, 'utf-8');
655
+ if (claudeCodeRouterConfig.trim().length === 0) {
656
+ log.debug((0, i18n_1.t)('🛠️ claude-code-router 配置为空,写入 Cloudbase 配置...'));
657
+ await fs.writeJson(const_1.CLAUDE_CODE_ROUTER_CONFIG_PATH, { Providers: [cloudbaseProvider] });
658
+ log.debug((0, i18n_1.t)('✅ claude-code-router 配置完成'));
659
+ }
660
+ else {
661
+ const config = safeParseJson(claudeCodeRouterConfig);
662
+ if (!config) {
663
+ const { shouldOverwrite } = await inquirer_1.default.prompt([
664
+ {
665
+ type: 'confirm',
666
+ name: 'shouldOverwrite',
667
+ message: (0, i18n_1.t)('claude-code-router 配置文件非合法 JSON ,是否覆盖? {{hint}}', { hint: (0, const_1.getBooleanHint)() })
668
+ }
669
+ ]);
670
+ if (shouldOverwrite) {
671
+ await fs.writeJson(const_1.CLAUDE_CODE_ROUTER_CONFIG_PATH, {
672
+ Providers: [cloudbaseProvider]
673
+ }, { spaces: 2 });
674
+ log.debug((0, i18n_1.t)('✅ claude-code-router 配置完成'));
675
+ }
676
+ else {
677
+ log.error((0, i18n_1.t)('❌ claude-code-router 配置文件非合法 JSON ,请手动修复'));
678
+ process.exit(1);
679
+ }
680
+ }
681
+ if (typeof config !== 'object' || config === null) {
682
+ log.error((0, i18n_1.t)('❌ 未知 claude-code-router 配置文件格式请手动修复'));
698
683
  process.exit(1);
699
684
  }
700
- const cloudbaseProvider = {
701
- name: 'cloudbase',
702
- api_base_url: `${(0, url_1.getGatewayUrl)(envId)}/v1/ai/${provider}/chat/completions`,
703
- api_key: accessToken.access_token,
704
- models: [model]
705
- };
706
- if (transformer && transformer.trim().length > 0) {
707
- cloudbaseProvider.transformer = { use: [transformer] };
685
+ if (!('Providers' in config)) {
686
+ config.Providers = [cloudbaseProvider];
687
+ }
688
+ if (!Array.isArray(config.Providers)) {
689
+ log.error((0, i18n_1.t)('❌ claude-code-router 配置文件 Providers 字段非数组类型,请手动修复'));
690
+ process.exit(1);
708
691
  }
709
- yield fs.ensureFile(const_1.CLAUDE_CODE_ROUTER_CONFIG_PATH);
710
- const claudeCodeRouterConfig = yield fs.readFile(const_1.CLAUDE_CODE_ROUTER_CONFIG_PATH, 'utf-8');
711
- if (claudeCodeRouterConfig.trim().length === 0) {
712
- log.debug((0, i18n_1.t)('🛠️ claude-code-router 配置为空,写入 Cloudbase 配置...'));
713
- yield fs.writeJson(const_1.CLAUDE_CODE_ROUTER_CONFIG_PATH, { Providers: [cloudbaseProvider] });
714
- log.debug((0, i18n_1.t)('✅ claude-code-router 配置完成'));
692
+ const providers = config.Providers;
693
+ const index = providers.findIndex((p) => typeof p === 'object' && (p === null || p === void 0 ? void 0 : p.name) === 'cloudbase');
694
+ if (index !== -1) {
695
+ providers[index] = cloudbaseProvider;
715
696
  }
716
697
  else {
717
- const config = safeParseJson(claudeCodeRouterConfig);
718
- if (!config) {
719
- const { shouldOverwrite } = yield inquirer_1.default.prompt([
720
- {
721
- type: 'confirm',
722
- name: 'shouldOverwrite',
723
- message: (0, i18n_1.t)('claude-code-router 配置文件非合法 JSON ,是否覆盖? {{hint}}', { hint: (0, const_1.getBooleanHint)() })
724
- }
725
- ]);
726
- if (shouldOverwrite) {
727
- yield fs.writeJson(const_1.CLAUDE_CODE_ROUTER_CONFIG_PATH, {
728
- Providers: [cloudbaseProvider]
729
- }, { spaces: 2 });
730
- log.debug((0, i18n_1.t)('✅ claude-code-router 配置完成'));
731
- }
732
- else {
733
- log.error((0, i18n_1.t)('❌ claude-code-router 配置文件非合法 JSON ,请手动修复'));
734
- process.exit(1);
735
- }
736
- }
737
- if (typeof config !== 'object' || config === null) {
738
- log.error((0, i18n_1.t)('❌ 未知 claude-code-router 配置文件格式请手动修复'));
739
- process.exit(1);
740
- }
741
- if (!('Providers' in config)) {
742
- config.Providers = [cloudbaseProvider];
743
- }
744
- if (!Array.isArray(config.Providers)) {
745
- log.error((0, i18n_1.t)('❌ claude-code-router 配置文件 Providers 字段非数组类型,请手动修复'));
746
- process.exit(1);
747
- }
748
- const providers = config.Providers;
749
- const index = providers.findIndex((p) => typeof p === 'object' && (p === null || p === void 0 ? void 0 : p.name) === 'cloudbase');
750
- if (index !== -1) {
751
- providers[index] = cloudbaseProvider;
752
- }
753
- else {
754
- providers.push(cloudbaseProvider);
755
- }
756
- if (!('Router' in config) ||
757
- typeof config.Router !== 'object' ||
758
- config.Router === null) {
759
- config.Router = {};
760
- }
761
- config.Router.default = `cloudbase,${model}`;
762
- config.Log = true;
763
- yield fs.writeJson(const_1.CLAUDE_CODE_ROUTER_CONFIG_PATH, config, { spaces: 2 });
764
- log.debug((0, i18n_1.t)('✅ claude-code-router 配置完成'));
698
+ providers.push(cloudbaseProvider);
765
699
  }
766
- });
700
+ if (!('Router' in config) ||
701
+ typeof config.Router !== 'object' ||
702
+ config.Router === null) {
703
+ config.Router = {};
704
+ }
705
+ config.Router.default = `cloudbase,${model}`;
706
+ config.Log = true;
707
+ await fs.writeJson(const_1.CLAUDE_CODE_ROUTER_CONFIG_PATH, config, { spaces: 2 });
708
+ log.debug((0, i18n_1.t)('✅ claude-code-router 配置完成'));
709
+ }
767
710
  }
768
711
  parseArgs(args) {
769
712
  return args.filter((arg) => typeof arg === 'string' && arg.trim().length > 0);
770
713
  }
771
- ensureClaudeCodeRouter(log) {
772
- return __awaiter(this, void 0, void 0, function* () {
773
- const isAvailable = yield new Promise((resolve) => {
774
- const child = (0, child_process_1.spawn)('ccr', ['--version'], {
775
- stdio: 'pipe',
776
- shell: true
777
- });
778
- child.stdout.on('data', (data) => {
779
- data.toString().includes('Usage: ccr [command]') && resolve(true);
780
- });
781
- child.on('close', (code) => {
782
- resolve(code === 0);
783
- });
784
- child.on('error', () => {
785
- resolve(false);
786
- });
714
+ async ensureClaudeCodeRouter(log) {
715
+ const isAvailable = await new Promise((resolve) => {
716
+ const child = (0, child_process_1.spawn)('ccr', ['--version'], {
717
+ stdio: 'pipe',
718
+ shell: true
719
+ });
720
+ child.stdout.on('data', (data) => {
721
+ data.toString().includes('Usage: ccr [command]') && resolve(true);
787
722
  });
788
- if (isAvailable) {
789
- log.debug((0, i18n_1.t)('claude code router 已安装!'));
723
+ child.on('close', (code) => {
724
+ resolve(code === 0);
725
+ });
726
+ child.on('error', () => {
727
+ resolve(false);
728
+ });
729
+ });
730
+ if (isAvailable) {
731
+ log.debug((0, i18n_1.t)('claude code router 已安装!'));
732
+ }
733
+ else {
734
+ const { shouldInstall } = await inquirer_1.default.prompt([
735
+ {
736
+ type: 'confirm',
737
+ name: 'shouldInstall',
738
+ message: (0, i18n_1.t)('AI 开发缺少 claude code router 依赖,是否安装? {{hint}}', {
739
+ hint: (0, const_1.getBooleanHint)(true)
740
+ })
741
+ }
742
+ ]);
743
+ if (shouldInstall) {
744
+ await this.executeCommand('npm', ['install', '-g', '@musistudio/claude-code-router'], process.env, log);
745
+ log.info((0, i18n_1.t)('✅ claude-code-router 安装完成'));
790
746
  }
791
747
  else {
792
- const { shouldInstall } = yield inquirer_1.default.prompt([
793
- {
794
- type: 'confirm',
795
- name: 'shouldInstall',
796
- message: (0, i18n_1.t)('AI 开发缺少 claude code router 依赖,是否安装? {{hint}}', {
797
- hint: (0, const_1.getBooleanHint)(true)
798
- })
799
- }
800
- ]);
801
- if (shouldInstall) {
802
- yield this.executeCommand('npm', ['install', '-g', '@musistudio/claude-code-router'], process.env, log);
803
- log.info((0, i18n_1.t)('✅ claude-code-router 安装完成'));
804
- }
805
- else {
806
- log.info((0, i18n_1.t)('❌ claude code router 未安装,请手动安装'));
807
- process.exit(1);
808
- }
748
+ log.info((0, i18n_1.t)('❌ claude code router 未安装,请手动安装'));
749
+ process.exit(1);
809
750
  }
810
- });
751
+ }
811
752
  }
812
- ensureClaudeCode(log) {
813
- return __awaiter(this, void 0, void 0, function* () {
814
- if (yield this.isToolAvailable('claude')) {
815
- log.debug((0, i18n_1.t)('claude code 已安装!'));
816
- }
817
- else {
818
- const { shouldInstall } = yield inquirer_1.default.prompt([
819
- {
820
- type: 'confirm',
821
- name: 'shouldInstall',
822
- message: (0, i18n_1.t)('AI 开发缺少 claude code 依赖,是否安装? {{hint}}', { hint: (0, const_1.getBooleanHint)(true) })
823
- }
824
- ]);
825
- if (shouldInstall) {
826
- const platform = process.platform;
827
- if (platform === 'win32') {
828
- yield this.executeCommand('npm', ['install', '-g', '@anthropic-ai/claude-code'], process.env, log);
753
+ async ensureClaudeCode(log) {
754
+ if (await this.isToolAvailable('claude')) {
755
+ log.debug((0, i18n_1.t)('claude code 已安装!'));
756
+ }
757
+ else {
758
+ const { shouldInstall } = await inquirer_1.default.prompt([
759
+ {
760
+ type: 'confirm',
761
+ name: 'shouldInstall',
762
+ message: (0, i18n_1.t)('AI 开发缺少 claude code 依赖,是否安装? {{hint}}', { hint: (0, const_1.getBooleanHint)(true) })
763
+ }
764
+ ]);
765
+ if (shouldInstall) {
766
+ const platform = process.platform;
767
+ if (platform === 'win32') {
768
+ await this.executeCommand('npm', ['install', '-g', '@anthropic-ai/claude-code'], process.env, log);
769
+ }
770
+ else {
771
+ try {
772
+ await this.executeCommand('sh', ['-c', 'curl -fsSL https://claude.ai/install.sh | bash'], process.env, log);
829
773
  }
830
- else {
774
+ catch (error) {
775
+ log.warn((0, i18n_1.t)('⚠️ curl 安装失败,尝试使用 npm 安装...'));
831
776
  try {
832
- yield this.executeCommand('sh', ['-c', 'curl -fsSL https://claude.ai/install.sh | bash'], process.env, log);
777
+ await this.executeCommand('npm', ['install', '-g', '@anthropic-ai/claude-code'], process.env, log);
833
778
  }
834
- catch (error) {
835
- log.warn((0, i18n_1.t)('⚠️ curl 安装失败,尝试使用 npm 安装...'));
836
- try {
837
- yield this.executeCommand('npm', ['install', '-g', '@anthropic-ai/claude-code'], process.env, log);
838
- }
839
- catch (npmError) {
840
- log.error((0, i18n_1.t)('❌ claude code 安装失败'));
841
- log.error((0, i18n_1.t)('请手动安装 claude code:'));
842
- log.error((0, i18n_1.t)('📖 安装文档: {{link}}', {
843
- link: (0, output_1.genClickableLink)('https://docs.anthropic.com/en/docs/claude-code/setup')
844
- }));
845
- process.exit(1);
846
- }
779
+ catch (npmError) {
780
+ log.error((0, i18n_1.t)(' claude code 安装失败'));
781
+ log.error((0, i18n_1.t)('请手动安装 claude code:'));
782
+ log.error((0, i18n_1.t)('📖 安装文档: {{link}}', {
783
+ link: (0, output_1.genClickableLink)('https://docs.anthropic.com/en/docs/claude-code/setup')
784
+ }));
785
+ process.exit(1);
847
786
  }
848
787
  }
849
- log.info((0, i18n_1.t)('✅ claude code 安装完成'));
850
- }
851
- else {
852
- log.info((0, i18n_1.t)('❌ claude code 未安装,请手动安装'));
853
- log.info((0, i18n_1.t)('📖 安装文档: {{link}}', {
854
- link: (0, output_1.genClickableLink)('https://docs.anthropic.com/en/docs/claude-code/setup')
855
- }));
856
- process.exit(1);
857
788
  }
789
+ log.info((0, i18n_1.t)('✅ claude code 安装完成'));
858
790
  }
859
- });
791
+ else {
792
+ log.info((0, i18n_1.t)('❌ claude code 未安装,请手动安装'));
793
+ log.info((0, i18n_1.t)('📖 安装文档: {{link}}', {
794
+ link: (0, output_1.genClickableLink)('https://docs.anthropic.com/en/docs/claude-code/setup')
795
+ }));
796
+ process.exit(1);
797
+ }
798
+ }
860
799
  }
861
- ensureQwenCode(log) {
862
- return __awaiter(this, void 0, void 0, function* () {
863
- if (yield this.isToolAvailable('qwen')) {
864
- log.debug((0, i18n_1.t)('qwen code 已安装!'));
800
+ async ensureQwenCode(log) {
801
+ if (await this.isToolAvailable('qwen')) {
802
+ log.debug((0, i18n_1.t)('qwen code 已安装!'));
803
+ }
804
+ else {
805
+ const { shouldInstall } = await inquirer_1.default.prompt([
806
+ {
807
+ type: 'confirm',
808
+ name: 'shouldInstall',
809
+ message: (0, i18n_1.t)('AI 开发缺少 qwen code 依赖,是否安装? {{hint}}', { hint: (0, const_1.getBooleanHint)(true) })
810
+ }
811
+ ]);
812
+ if (shouldInstall) {
813
+ await this.executeCommand('npm', ['install', '-g', '@qwen-code/qwen-code'], process.env, log);
814
+ log.info((0, i18n_1.t)('✅ qwen code 安装完成'));
865
815
  }
866
816
  else {
867
- const { shouldInstall } = yield inquirer_1.default.prompt([
868
- {
869
- type: 'confirm',
870
- name: 'shouldInstall',
871
- message: (0, i18n_1.t)('AI 开发缺少 qwen code 依赖,是否安装? {{hint}}', { hint: (0, const_1.getBooleanHint)(true) })
872
- }
873
- ]);
874
- if (shouldInstall) {
875
- yield this.executeCommand('npm', ['install', '-g', '@qwen-code/qwen-code'], process.env, log);
876
- log.info((0, i18n_1.t)('✅ qwen code 安装完成'));
877
- }
878
- else {
879
- log.info((0, i18n_1.t)('❌ qwen code 未安装,请手动安装'));
880
- process.exit(1);
881
- }
817
+ log.info((0, i18n_1.t)('❌ qwen code 未安装,请手动安装'));
818
+ process.exit(1);
882
819
  }
883
- });
820
+ }
884
821
  }
885
- executeCodexAgent({ apiKey, baseUrl, model }, additionalArgs, log) {
886
- return __awaiter(this, void 0, void 0, function* () {
887
- yield this.ensureCodexCode(log);
888
- const codexArgs = [
889
- ...(model ? ['--config', `model=${model}`] : []),
890
- '--config',
891
- 'model_providers.custom.name=Custom OpenAI',
892
- ...(baseUrl ? ['--config', `model_providers.custom.base_url=${baseUrl}`] : []),
893
- '--config',
894
- 'model_providers.custom.env_key=OPENAI_API_KEY',
895
- '--config',
896
- 'model_provider=custom',
897
- ...additionalArgs
898
- ];
899
- yield this.executeCommand('codex', codexArgs, Object.assign(Object.assign({}, process.env), { OPENAI_API_KEY: apiKey }), log);
900
- });
822
+ async executeCodexAgent({ apiKey, baseUrl, model }, additionalArgs, log) {
823
+ await this.ensureCodexCode(log);
824
+ const codexArgs = [
825
+ ...(model ? ['--config', `model=${model}`] : []),
826
+ '--config',
827
+ 'model_providers.custom.name=Custom OpenAI',
828
+ ...(baseUrl ? ['--config', `model_providers.custom.base_url=${baseUrl}`] : []),
829
+ '--config',
830
+ 'model_providers.custom.env_key=OPENAI_API_KEY',
831
+ '--config',
832
+ 'model_provider=custom',
833
+ ...additionalArgs
834
+ ];
835
+ await this.executeCommand('codex', codexArgs, {
836
+ ...process.env,
837
+ OPENAI_API_KEY: apiKey
838
+ }, log);
901
839
  }
902
- executeNoneCodexAgent(additionalArgs, log) {
903
- return __awaiter(this, void 0, void 0, function* () {
904
- yield this.ensureCodexCode(log);
905
- yield this.executeCommand('codex', additionalArgs, Object.assign({}, process.env), log);
906
- });
840
+ async executeNoneCodexAgent(additionalArgs, log) {
841
+ await this.ensureCodexCode(log);
842
+ await this.executeCommand('codex', additionalArgs, { ...process.env }, log);
907
843
  }
908
- executeCodexCloudbaseAgent({ provider, model }, additionalArgs, log) {
909
- return __awaiter(this, void 0, void 0, function* () {
910
- yield this.ensureCodexCode(log);
911
- const _envId = yield (0, config_1.createConfigParser)().get('envId');
912
- yield (0, auth_1.checkLogin)();
913
- const credential = yield (0, utils_1.getCredential)({}, {});
914
- const envId = yield (0, env_1.ensureValidEnv)(_envId, log);
915
- const accessToken = yield (0, utils_1.rawFetchAccessToken)({
916
- envId,
917
- secretId: credential.secretId,
918
- secretKey: credential.secretKey,
919
- token: credential.token
920
- });
921
- if (!accessToken.access_token) {
922
- log.error((0, i18n_1.t)('获取云开发 Access Token 失败,请运行 tcb login 后再重试,{{token}}', {
923
- token: JSON.stringify(accessToken)
924
- }));
925
- process.exit(1);
926
- }
927
- const baseUrl = `${(0, url_1.getGatewayUrl)(envId)}/v1/ai/${provider}`;
928
- const apiKey = accessToken.access_token;
929
- const codexArgs = [
930
- '--config',
931
- `model=${model}`,
932
- '--config',
933
- 'model_providers.cloudbase.name=CloudBase AI',
934
- '--config',
935
- `model_providers.cloudbase.base_url=${baseUrl}`,
936
- '--config',
937
- 'model_providers.cloudbase.env_key=CLOUDBASE_ACCESS_TOKEN',
938
- '--config',
939
- 'model_provider=cloudbase',
940
- ...additionalArgs
941
- ];
942
- yield this.executeCommand('codex', codexArgs, Object.assign(Object.assign({}, process.env), { CLOUDBASE_ACCESS_TOKEN: apiKey }), log);
844
+ async executeCodexCloudbaseAgent({ provider, model }, additionalArgs, log) {
845
+ await this.ensureCodexCode(log);
846
+ const _envId = await (0, config_1.createConfigParser)().get('envId');
847
+ await (0, auth_1.checkLogin)();
848
+ const credential = await (0, utils_1.getCredential)({}, {});
849
+ const envId = await (0, env_1.ensureValidEnv)(_envId, log);
850
+ const accessToken = await (0, utils_1.rawFetchAccessToken)({
851
+ envId,
852
+ secretId: credential.secretId,
853
+ secretKey: credential.secretKey,
854
+ token: credential.token
943
855
  });
856
+ if (!accessToken.access_token) {
857
+ log.error((0, i18n_1.t)('获取云开发 Access Token 失败,请运行 tcb login 后再重试,{{token}}', {
858
+ token: JSON.stringify(accessToken)
859
+ }));
860
+ process.exit(1);
861
+ }
862
+ const baseUrl = `${(0, url_1.getGatewayUrl)(envId)}/v1/ai/${provider}`;
863
+ const apiKey = accessToken.access_token;
864
+ const codexArgs = [
865
+ '--config',
866
+ `model=${model}`,
867
+ '--config',
868
+ 'model_providers.cloudbase.name=CloudBase AI',
869
+ '--config',
870
+ `model_providers.cloudbase.base_url=${baseUrl}`,
871
+ '--config',
872
+ 'model_providers.cloudbase.env_key=CLOUDBASE_ACCESS_TOKEN',
873
+ '--config',
874
+ 'model_provider=cloudbase',
875
+ ...additionalArgs
876
+ ];
877
+ await this.executeCommand('codex', codexArgs, {
878
+ ...process.env,
879
+ CLOUDBASE_ACCESS_TOKEN: apiKey
880
+ }, log);
944
881
  }
945
- executeNoneCursorAgent(additionalArgs, log) {
946
- return __awaiter(this, void 0, void 0, function* () {
947
- yield this.ensureCursor(log);
948
- yield this.executeCommand('cursor-agent', additionalArgs, Object.assign({}, process.env), log);
949
- });
882
+ async executeNoneCursorAgent(additionalArgs, log) {
883
+ await this.ensureCursor(log);
884
+ await this.executeCommand('cursor-agent', additionalArgs, { ...process.env }, log);
950
885
  }
951
- ensureCursor(log) {
952
- return __awaiter(this, void 0, void 0, function* () {
953
- if (yield this.isToolAvailable('cursor-agent')) {
954
- log.debug((0, i18n_1.t)('Cursor CLI 已安装!'));
886
+ async ensureCursor(log) {
887
+ if (await this.isToolAvailable('cursor-agent')) {
888
+ log.debug((0, i18n_1.t)('Cursor CLI 已安装!'));
889
+ }
890
+ else {
891
+ const { shouldInstall } = await inquirer_1.default.prompt([
892
+ {
893
+ type: 'confirm',
894
+ name: 'shouldInstall',
895
+ message: (0, i18n_1.t)('AI 开发缺少 Cursor CLI 依赖,是否安装? {{hint}}', { hint: (0, const_1.getBooleanHint)(true) })
896
+ }
897
+ ]);
898
+ if (shouldInstall) {
899
+ log.info((0, i18n_1.t)('正在安装 Cursor CLI...'));
900
+ await this.executeCommand('sh', ['-c', 'curl https://cursor.com/install -fsS | bash'], process.env, log);
901
+ log.info((0, i18n_1.t)('✅ Cursor CLI 安装完成'));
955
902
  }
956
903
  else {
957
- const { shouldInstall } = yield inquirer_1.default.prompt([
958
- {
959
- type: 'confirm',
960
- name: 'shouldInstall',
961
- message: (0, i18n_1.t)('AI 开发缺少 Cursor CLI 依赖,是否安装? {{hint}}', { hint: (0, const_1.getBooleanHint)(true) })
962
- }
963
- ]);
964
- if (shouldInstall) {
965
- log.info((0, i18n_1.t)('正在安装 Cursor CLI...'));
966
- yield this.executeCommand('sh', ['-c', 'curl https://cursor.com/install -fsS | bash'], process.env, log);
967
- log.info((0, i18n_1.t)('✅ Cursor CLI 安装完成'));
968
- }
969
- else {
970
- log.info((0, i18n_1.t)('❌ Cursor CLI 未安装,请手动安装'));
971
- process.exit(1);
972
- }
904
+ log.info((0, i18n_1.t)('❌ Cursor CLI 未安装,请手动安装'));
905
+ process.exit(1);
973
906
  }
974
- });
907
+ }
975
908
  }
976
- ensureCodexCode(log) {
977
- return __awaiter(this, void 0, void 0, function* () {
978
- if (yield this.isToolAvailable('codex')) {
979
- log.debug((0, i18n_1.t)('codex 已安装!'));
909
+ async ensureCodexCode(log) {
910
+ if (await this.isToolAvailable('codex')) {
911
+ log.debug((0, i18n_1.t)('codex 已安装!'));
912
+ }
913
+ else {
914
+ const { shouldInstall } = await inquirer_1.default.prompt([
915
+ {
916
+ type: 'confirm',
917
+ name: 'shouldInstall',
918
+ message: (0, i18n_1.t)('AI 开发缺少 codex 依赖,是否安装? {{hint}}', { hint: (0, const_1.getBooleanHint)(true) })
919
+ }
920
+ ]);
921
+ if (shouldInstall) {
922
+ await this.executeCommand('npm', ['install', '-g', '@openai/codex'], process.env, log);
923
+ log.info((0, i18n_1.t)('✅ codex 安装完成'));
980
924
  }
981
925
  else {
982
- const { shouldInstall } = yield inquirer_1.default.prompt([
983
- {
984
- type: 'confirm',
985
- name: 'shouldInstall',
986
- message: (0, i18n_1.t)('AI 开发缺少 codex 依赖,是否安装? {{hint}}', { hint: (0, const_1.getBooleanHint)(true) })
987
- }
988
- ]);
989
- if (shouldInstall) {
990
- yield this.executeCommand('npm', ['install', '-g', '@openai/codex'], process.env, log);
991
- log.info((0, i18n_1.t)('✅ codex 安装完成'));
992
- }
993
- else {
994
- log.info((0, i18n_1.t)('❌ codex 未安装,请手动安装'));
995
- process.exit(1);
996
- }
926
+ log.info((0, i18n_1.t)('❌ codex 未安装,请手动安装'));
927
+ process.exit(1);
997
928
  }
998
- });
929
+ }
999
930
  }
1000
- executeAiderAgent(config, additionalArgs, log) {
1001
- return __awaiter(this, void 0, void 0, function* () {
1002
- yield this.ensureAider(log);
1003
- const { apiKey, baseUrl, model } = config;
1004
- const aiderArgs = ['--model', `openai/${model}`, ...additionalArgs];
1005
- const env = Object.assign(Object.assign({}, process.env), { OPENAI_API_KEY: apiKey, OPENAI_API_BASE: baseUrl });
1006
- yield this.executeCommand('aider', aiderArgs, env, log);
1007
- });
931
+ async executeAiderAgent(config, additionalArgs, log) {
932
+ await this.ensureAider(log);
933
+ const { apiKey, baseUrl, model } = config;
934
+ const aiderArgs = ['--model', `openai/${model}`, ...additionalArgs];
935
+ const env = {
936
+ ...process.env,
937
+ OPENAI_API_KEY: apiKey,
938
+ OPENAI_API_BASE: baseUrl
939
+ };
940
+ await this.executeCommand('aider', aiderArgs, env, log);
1008
941
  }
1009
- executeAiderCloudbaseAgent(config, additionalArgs, log) {
1010
- return __awaiter(this, void 0, void 0, function* () {
1011
- yield this.ensureAider(log);
1012
- const { provider, model } = config;
1013
- const _envId = yield (0, config_1.createConfigParser)().get('envId');
1014
- yield (0, auth_1.checkLogin)();
1015
- const credential = yield (0, utils_1.getCredential)({}, {});
1016
- const envId = yield (0, env_1.ensureValidEnv)(_envId, log);
1017
- const accessToken = yield (0, utils_1.rawFetchAccessToken)({
1018
- envId,
1019
- secretId: credential.secretId,
1020
- secretKey: credential.secretKey,
1021
- token: credential.token
1022
- });
1023
- if (!accessToken.access_token) {
1024
- log.error((0, i18n_1.t)('获取云开发 Access Token 失败,请运行 tcb login 后再重试,{{token}}', {
1025
- token: JSON.stringify(accessToken)
1026
- }));
1027
- process.exit(1);
1028
- }
1029
- const baseUrl = `${(0, url_1.getGatewayUrl)(envId)}/v1/ai/${provider}`;
1030
- const apiKey = accessToken.access_token;
1031
- const aiderArgs = ['--model', `openai/${model}`, ...additionalArgs];
1032
- const env = Object.assign(Object.assign({}, process.env), { OPENAI_API_KEY: apiKey, OPENAI_API_BASE: baseUrl });
1033
- yield this.executeCommand('aider', aiderArgs, env, log);
942
+ async executeAiderCloudbaseAgent(config, additionalArgs, log) {
943
+ await this.ensureAider(log);
944
+ const { provider, model } = config;
945
+ const _envId = await (0, config_1.createConfigParser)().get('envId');
946
+ await (0, auth_1.checkLogin)();
947
+ const credential = await (0, utils_1.getCredential)({}, {});
948
+ const envId = await (0, env_1.ensureValidEnv)(_envId, log);
949
+ const accessToken = await (0, utils_1.rawFetchAccessToken)({
950
+ envId,
951
+ secretId: credential.secretId,
952
+ secretKey: credential.secretKey,
953
+ token: credential.token
1034
954
  });
955
+ if (!accessToken.access_token) {
956
+ log.error((0, i18n_1.t)('获取云开发 Access Token 失败,请运行 tcb login 后再重试,{{token}}', {
957
+ token: JSON.stringify(accessToken)
958
+ }));
959
+ process.exit(1);
960
+ }
961
+ const baseUrl = `${(0, url_1.getGatewayUrl)(envId)}/v1/ai/${provider}`;
962
+ const apiKey = accessToken.access_token;
963
+ const aiderArgs = ['--model', `openai/${model}`, ...additionalArgs];
964
+ const env = {
965
+ ...process.env,
966
+ OPENAI_API_KEY: apiKey,
967
+ OPENAI_API_BASE: baseUrl
968
+ };
969
+ await this.executeCommand('aider', aiderArgs, env, log);
1035
970
  }
1036
- ensureAider(log) {
1037
- return __awaiter(this, void 0, void 0, function* () {
1038
- if (yield this.isToolAvailable('aider')) {
1039
- log.debug((0, i18n_1.t)('aider 已安装!'));
1040
- }
1041
- else {
1042
- const { shouldInstall } = yield inquirer_1.default.prompt([
1043
- {
1044
- type: 'confirm',
1045
- name: 'shouldInstall',
1046
- message: (0, i18n_1.t)('AI 开发缺少 aider 依赖,是否安装? {{hint}}', { hint: (0, const_1.getBooleanHint)(true) })
1047
- }
1048
- ]);
1049
- if (shouldInstall) {
1050
- log.info((0, i18n_1.t)('正在安装 aider...'));
1051
- const platform = process.platform;
1052
- if (platform === 'win32') {
1053
- yield this.executeCommand('powershell', ['-c', 'irm https://aider.chat/install.ps1 | iex'], process.env, log);
1054
- }
1055
- else {
1056
- yield this.executeCommand('sh', ['-c', 'curl -LsSf https://aider.chat/install.sh | sh'], process.env, log);
1057
- }
1058
- log.info((0, i18n_1.t)('✅ aider 安装完成'));
971
+ async ensureAider(log) {
972
+ if (await this.isToolAvailable('aider')) {
973
+ log.debug((0, i18n_1.t)('aider 已安装!'));
974
+ }
975
+ else {
976
+ const { shouldInstall } = await inquirer_1.default.prompt([
977
+ {
978
+ type: 'confirm',
979
+ name: 'shouldInstall',
980
+ message: (0, i18n_1.t)('AI 开发缺少 aider 依赖,是否安装? {{hint}}', { hint: (0, const_1.getBooleanHint)(true) })
1059
981
  }
1060
- else {
1061
- log.info((0, i18n_1.t)('❌ aider 未安装,请手动安装'));
1062
- process.exit(1);
982
+ ]);
983
+ if (shouldInstall) {
984
+ log.info((0, i18n_1.t)('正在安装 aider...'));
985
+ const platform = process.platform;
986
+ if (platform === 'win32') {
987
+ await this.executeCommand('powershell', ['-c', 'irm https://aider.chat/install.ps1 | iex'], process.env, log);
1063
988
  }
1064
- }
1065
- });
1066
- }
1067
- modifyMCPConfigs(extractDir, log) {
1068
- return __awaiter(this, void 0, void 0, function* () {
1069
- const fs = yield Promise.resolve().then(() => __importStar(require('fs-extra')));
1070
- const path = yield Promise.resolve().then(() => __importStar(require('path')));
1071
- try {
1072
- log.info((0, i18n_1.t)('🔧 正在修改 MCP 配置文件...'));
1073
- for (const [, files] of Object.entries(IDE_FILE_MAPPINGS)) {
1074
- for (const descriptor of files) {
1075
- if (!descriptor.isMcpConfig)
1076
- continue;
1077
- const filePath = path.join(extractDir, descriptor.path);
1078
- if (yield fs.pathExists(filePath)) {
1079
- const format = inferConfigFormat(descriptor.path);
1080
- if (format === 'json') {
1081
- yield this.modifyMCPJsonFile(filePath, log);
1082
- }
1083
- else if (format === 'toml') {
1084
- yield this.modifyMCPTomlFile(filePath, log);
1085
- }
1086
- }
1087
- }
989
+ else {
990
+ await this.executeCommand('sh', ['-c', 'curl -LsSf https://aider.chat/install.sh | sh'], process.env, log);
1088
991
  }
1089
- log.info((0, i18n_1.t)('✅ MCP 配置文件修改完成'));
992
+ log.info((0, i18n_1.t)('✅ aider 安装完成'));
1090
993
  }
1091
- catch (error) {
1092
- log.warn((0, i18n_1.t)('⚠️ MCP 配置文件修改失败: {{error}}', { error: error.message }));
994
+ else {
995
+ log.info((0, i18n_1.t)(' aider 未安装,请手动安装'));
996
+ process.exit(1);
1093
997
  }
1094
- });
998
+ }
1095
999
  }
1096
- modifyMCPJsonFile(filePath, log) {
1097
- return __awaiter(this, void 0, void 0, function* () {
1098
- const fs = yield Promise.resolve().then(() => __importStar(require('fs-extra')));
1099
- try {
1100
- const content = yield fs.readFile(filePath, 'utf-8');
1101
- const config = JSON.parse(content);
1102
- let modified = false;
1103
- const modifyCommands = (obj) => {
1104
- if (typeof obj !== 'object' || obj === null) {
1105
- return obj;
1106
- }
1107
- if (Array.isArray(obj)) {
1108
- return obj.map((item) => modifyCommands(item));
1109
- }
1110
- const result = Object.assign({}, obj);
1111
- if (result.command === 'npx' && Array.isArray(result.args)) {
1112
- const argsStr = result.args.join(' ');
1113
- if (argsStr.includes('npm-global-exec@latest') &&
1114
- argsStr.includes('@cloudbase/cloudbase-mcp@latest')) {
1115
- result.command = 'cloudbase-mcp';
1116
- result.args = [];
1117
- result.env = {
1118
- INTEGRATION_IDE: process.env.INTEGRATION_IDE || 'CloudBaseCLI'
1119
- };
1120
- modified = true;
1121
- log.debug((0, i18n_1.t)('修改配置文件 {{filePath}}: npx -> cloudbase-mcp', { filePath }));
1000
+ async modifyMCPConfigs(extractDir, log) {
1001
+ const fs = await Promise.resolve().then(() => __importStar(require('fs-extra')));
1002
+ const path = await Promise.resolve().then(() => __importStar(require('path')));
1003
+ try {
1004
+ log.info((0, i18n_1.t)('🔧 正在修改 MCP 配置文件...'));
1005
+ for (const [, files] of Object.entries(IDE_FILE_MAPPINGS)) {
1006
+ for (const descriptor of files) {
1007
+ if (!descriptor.isMcpConfig)
1008
+ continue;
1009
+ const filePath = path.join(extractDir, descriptor.path);
1010
+ if (await fs.pathExists(filePath)) {
1011
+ const format = inferConfigFormat(descriptor.path);
1012
+ if (format === 'json') {
1013
+ await this.modifyMCPJsonFile(filePath, log);
1014
+ }
1015
+ else if (format === 'toml') {
1016
+ await this.modifyMCPTomlFile(filePath, log);
1122
1017
  }
1123
1018
  }
1124
- for (const [key, value] of Object.entries(result)) {
1125
- result[key] = modifyCommands(value);
1126
- }
1127
- return result;
1128
- };
1129
- const modifiedConfig = modifyCommands(config);
1130
- if (modified) {
1131
- yield fs.writeJson(filePath, modifiedConfig, { spaces: 2 });
1132
- log.debug((0, i18n_1.t)('✅ 已修改 {{filePath}}', { filePath }));
1133
1019
  }
1134
1020
  }
1135
- catch (error) {
1136
- log.warn((0, i18n_1.t)('⚠️ 修改配置文件 {{filePath}} 失败: {{error}}', { filePath, error: error.message }));
1137
- }
1138
- });
1021
+ log.info((0, i18n_1.t)('✅ MCP 配置文件修改完成'));
1022
+ }
1023
+ catch (error) {
1024
+ log.warn((0, i18n_1.t)('⚠️ MCP 配置文件修改失败: {{error}}', { error: error.message }));
1025
+ }
1139
1026
  }
1140
- modifyMCPTomlFile(filePath, log) {
1141
- return __awaiter(this, void 0, void 0, function* () {
1142
- const fs = yield Promise.resolve().then(() => __importStar(require('fs-extra')));
1143
- const toml = yield Promise.resolve().then(() => __importStar(require('toml')));
1144
- try {
1145
- const content = yield fs.readFile(filePath, 'utf-8');
1146
- const config = toml.parse(content);
1147
- let modified = false;
1148
- const modifyCommands = (obj) => {
1149
- if (typeof obj !== 'object' || obj === null) {
1150
- return obj;
1151
- }
1152
- if (Array.isArray(obj)) {
1153
- return obj.map((item) => modifyCommands(item));
1154
- }
1155
- const result = Object.assign({}, obj);
1156
- if (result.command === 'npx' && Array.isArray(result.args)) {
1157
- const argsStr = result.args.join(' ');
1158
- if (argsStr.includes('@cloudbase/cloudbase-mcp@latest')) {
1159
- result.command = 'cloudbase-mcp';
1160
- result.args = [];
1161
- result.env = {
1162
- INTEGRATION_IDE: process.env.INTEGRATION_IDE || 'CloudBaseCLI'
1163
- };
1164
- modified = true;
1165
- log.debug((0, i18n_1.t)('修改配置文件 {{filePath}}: npx -> cloudbase-mcp', { filePath }));
1166
- }
1167
- }
1168
- for (const [key, value] of Object.entries(result)) {
1169
- result[key] = modifyCommands(value);
1027
+ async modifyMCPJsonFile(filePath, log) {
1028
+ const fs = await Promise.resolve().then(() => __importStar(require('fs-extra')));
1029
+ try {
1030
+ const content = await fs.readFile(filePath, 'utf-8');
1031
+ const config = JSON.parse(content);
1032
+ let modified = false;
1033
+ const modifyCommands = (obj) => {
1034
+ if (typeof obj !== 'object' || obj === null) {
1035
+ return obj;
1036
+ }
1037
+ if (Array.isArray(obj)) {
1038
+ return obj.map((item) => modifyCommands(item));
1039
+ }
1040
+ const result = { ...obj };
1041
+ if (result.command === 'npx' && Array.isArray(result.args)) {
1042
+ const argsStr = result.args.join(' ');
1043
+ if (argsStr.includes('npm-global-exec@latest') &&
1044
+ argsStr.includes('@cloudbase/cloudbase-mcp@latest')) {
1045
+ result.command = 'cloudbase-mcp';
1046
+ result.args = [];
1047
+ result.env = {
1048
+ INTEGRATION_IDE: process.env.INTEGRATION_IDE || 'CloudBaseCLI'
1049
+ };
1050
+ modified = true;
1051
+ log.debug((0, i18n_1.t)('修改配置文件 {{filePath}}: npx -> cloudbase-mcp', { filePath }));
1170
1052
  }
1171
- return result;
1172
- };
1173
- const modifiedConfig = modifyCommands(config);
1174
- if (modified) {
1175
- const tomlString = this.objectToToml(modifiedConfig);
1176
- yield fs.writeFile(filePath, tomlString, 'utf-8');
1177
- log.debug((0, i18n_1.t)('✅ 已修改 {{filePath}}', { filePath }));
1178
1053
  }
1054
+ for (const [key, value] of Object.entries(result)) {
1055
+ result[key] = modifyCommands(value);
1056
+ }
1057
+ return result;
1058
+ };
1059
+ const modifiedConfig = modifyCommands(config);
1060
+ if (modified) {
1061
+ await fs.writeJson(filePath, modifiedConfig, { spaces: 2 });
1062
+ log.debug((0, i18n_1.t)('✅ 已修改 {{filePath}}', { filePath }));
1179
1063
  }
1180
- catch (error) {
1181
- log.warn((0, i18n_1.t)('⚠️ 修改配置文件 {{filePath}} 失败: {{error}}', { filePath, error: error.message }));
1182
- }
1183
- });
1064
+ }
1065
+ catch (error) {
1066
+ log.warn((0, i18n_1.t)('⚠️ 修改配置文件 {{filePath}} 失败: {{error}}', { filePath, error: error.message }));
1067
+ }
1184
1068
  }
1185
- mergeMcpConfig(entry, destPath, format, log) {
1186
- return __awaiter(this, void 0, void 0, function* () {
1187
- const fs = yield Promise.resolve().then(() => __importStar(require('fs-extra')));
1188
- const path = yield Promise.resolve().then(() => __importStar(require('path')));
1189
- const incomingStr = (yield entry.buffer()).toString('utf8');
1190
- const deepMerge = (target, source) => {
1191
- if (typeof target !== 'object' || typeof source !== 'object' || !target || !source) {
1192
- return target;
1069
+ async modifyMCPTomlFile(filePath, log) {
1070
+ const fs = await Promise.resolve().then(() => __importStar(require('fs-extra')));
1071
+ const toml = await Promise.resolve().then(() => __importStar(require('toml')));
1072
+ try {
1073
+ const content = await fs.readFile(filePath, 'utf-8');
1074
+ const config = toml.parse(content);
1075
+ let modified = false;
1076
+ const modifyCommands = (obj) => {
1077
+ if (typeof obj !== 'object' || obj === null) {
1078
+ return obj;
1079
+ }
1080
+ if (Array.isArray(obj)) {
1081
+ return obj.map((item) => modifyCommands(item));
1193
1082
  }
1194
- const result = Array.isArray(target) ? [...target] : Object.assign(Object.assign({}, source), target);
1195
- for (const key of Object.keys(source)) {
1196
- if (key in target &&
1197
- typeof target[key] === 'object' &&
1198
- typeof source[key] === 'object') {
1199
- result[key] = deepMerge(target[key], source[key]);
1083
+ const result = { ...obj };
1084
+ if (result.command === 'npx' && Array.isArray(result.args)) {
1085
+ const argsStr = result.args.join(' ');
1086
+ if (argsStr.includes('@cloudbase/cloudbase-mcp@latest')) {
1087
+ result.command = 'cloudbase-mcp';
1088
+ result.args = [];
1089
+ result.env = {
1090
+ INTEGRATION_IDE: process.env.INTEGRATION_IDE || 'CloudBaseCLI'
1091
+ };
1092
+ modified = true;
1093
+ log.debug((0, i18n_1.t)('修改配置文件 {{filePath}}: npx -> cloudbase-mcp', { filePath }));
1200
1094
  }
1201
1095
  }
1096
+ for (const [key, value] of Object.entries(result)) {
1097
+ result[key] = modifyCommands(value);
1098
+ }
1202
1099
  return result;
1203
1100
  };
1204
- yield fs.ensureDir(path.dirname(destPath));
1205
- if (format === 'json') {
1206
- const incomingObj = JSON.parse(incomingStr);
1207
- if (yield fs.pathExists(destPath)) {
1208
- const existingObj = yield fs.readJson(destPath);
1209
- const merged = deepMerge(existingObj, incomingObj);
1210
- yield fs.writeJson(destPath, merged, { spaces: 2 });
1211
- }
1212
- else {
1213
- yield fs.writeJson(destPath, incomingObj, { spaces: 2 });
1101
+ const modifiedConfig = modifyCommands(config);
1102
+ if (modified) {
1103
+ const tomlString = this.objectToToml(modifiedConfig);
1104
+ await fs.writeFile(filePath, tomlString, 'utf-8');
1105
+ log.debug((0, i18n_1.t)('✅ 已修改 {{filePath}}', { filePath }));
1106
+ }
1107
+ }
1108
+ catch (error) {
1109
+ log.warn((0, i18n_1.t)('⚠️ 修改配置文件 {{filePath}} 失败: {{error}}', { filePath, error: error.message }));
1110
+ }
1111
+ }
1112
+ async mergeMcpConfig(entry, destPath, format, log) {
1113
+ const fs = await Promise.resolve().then(() => __importStar(require('fs-extra')));
1114
+ const path = await Promise.resolve().then(() => __importStar(require('path')));
1115
+ const incomingStr = (await entry.buffer()).toString('utf8');
1116
+ const deepMerge = (target, source) => {
1117
+ if (typeof target !== 'object' || typeof source !== 'object' || !target || !source) {
1118
+ return target;
1119
+ }
1120
+ const result = Array.isArray(target) ? [...target] : { ...source, ...target };
1121
+ for (const key of Object.keys(source)) {
1122
+ if (key in target &&
1123
+ typeof target[key] === 'object' &&
1124
+ typeof source[key] === 'object') {
1125
+ result[key] = deepMerge(target[key], source[key]);
1214
1126
  }
1215
- return;
1216
1127
  }
1217
- const toml = yield Promise.resolve().then(() => __importStar(require('toml')));
1218
- const incomingObj = toml.parse(incomingStr);
1219
- if (yield fs.pathExists(destPath)) {
1220
- const existingStr = yield fs.readFile(destPath, 'utf-8');
1221
- const existingObj = toml.parse(existingStr);
1128
+ return result;
1129
+ };
1130
+ await fs.ensureDir(path.dirname(destPath));
1131
+ if (format === 'json') {
1132
+ const incomingObj = JSON.parse(incomingStr);
1133
+ if (await fs.pathExists(destPath)) {
1134
+ const existingObj = await fs.readJson(destPath);
1222
1135
  const merged = deepMerge(existingObj, incomingObj);
1223
- const out = this.objectToToml(merged);
1224
- yield fs.writeFile(destPath, out, 'utf-8');
1136
+ await fs.writeJson(destPath, merged, { spaces: 2 });
1225
1137
  }
1226
1138
  else {
1227
- const out = this.objectToToml(incomingObj);
1228
- yield fs.writeFile(destPath, out, 'utf-8');
1139
+ await fs.writeJson(destPath, incomingObj, { spaces: 2 });
1229
1140
  }
1230
- });
1141
+ return;
1142
+ }
1143
+ const toml = await Promise.resolve().then(() => __importStar(require('toml')));
1144
+ const incomingObj = toml.parse(incomingStr);
1145
+ if (await fs.pathExists(destPath)) {
1146
+ const existingStr = await fs.readFile(destPath, 'utf-8');
1147
+ const existingObj = toml.parse(existingStr);
1148
+ const merged = deepMerge(existingObj, incomingObj);
1149
+ const out = this.objectToToml(merged);
1150
+ await fs.writeFile(destPath, out, 'utf-8');
1151
+ }
1152
+ else {
1153
+ const out = this.objectToToml(incomingObj);
1154
+ await fs.writeFile(destPath, out, 'utf-8');
1155
+ }
1231
1156
  }
1232
1157
  objectToToml(obj, prefix = '') {
1233
1158
  const lines = [];
@@ -1257,42 +1182,39 @@ class AICommandRouter {
1257
1182
  }
1258
1183
  return lines.join('\n');
1259
1184
  }
1260
- executeCodebuddyAgent({ apiKey }, additionalArgs, log) {
1261
- return __awaiter(this, void 0, void 0, function* () {
1262
- yield this.ensureCodebuddy(log);
1263
- yield this.executeCommand('codebuddy', additionalArgs, Object.assign(Object.assign({}, process.env), (apiKey && { CODEBUDDY_API_KEY: apiKey })), log);
1264
- });
1185
+ async executeCodebuddyAgent({ apiKey }, additionalArgs, log) {
1186
+ await this.ensureCodebuddy(log);
1187
+ await this.executeCommand('codebuddy', additionalArgs, {
1188
+ ...process.env,
1189
+ ...(apiKey && { CODEBUDDY_API_KEY: apiKey })
1190
+ }, log);
1265
1191
  }
1266
- executeNoneCodebuddyAgent(additionalArgs, log) {
1267
- return __awaiter(this, void 0, void 0, function* () {
1268
- yield this.ensureCodebuddy(log);
1269
- yield this.executeCommand('codebuddy', additionalArgs, Object.assign({}, process.env), log);
1270
- });
1192
+ async executeNoneCodebuddyAgent(additionalArgs, log) {
1193
+ await this.ensureCodebuddy(log);
1194
+ await this.executeCommand('codebuddy', additionalArgs, { ...process.env }, log);
1271
1195
  }
1272
- ensureCodebuddy(log) {
1273
- return __awaiter(this, void 0, void 0, function* () {
1274
- if (yield this.isToolAvailable('codebuddy')) {
1275
- log.debug((0, i18n_1.t)('codebuddy 已安装!'));
1196
+ async ensureCodebuddy(log) {
1197
+ if (await this.isToolAvailable('codebuddy')) {
1198
+ log.debug((0, i18n_1.t)('codebuddy 已安装!'));
1199
+ }
1200
+ else {
1201
+ const { shouldInstall } = await inquirer_1.default.prompt([
1202
+ {
1203
+ type: 'confirm',
1204
+ name: 'shouldInstall',
1205
+ message: (0, i18n_1.t)('AI 开发缺少 codebuddy 依赖,是否安装? {{hint}}', { hint: (0, const_1.getBooleanHint)(true) })
1206
+ }
1207
+ ]);
1208
+ if (shouldInstall) {
1209
+ await this.executeCommand('npm', ['install', '-g', '@tencent-ai/codebuddy-code'], process.env, log);
1210
+ log.info((0, i18n_1.t)('✅ codebuddy 安装完成'));
1276
1211
  }
1277
1212
  else {
1278
- const { shouldInstall } = yield inquirer_1.default.prompt([
1279
- {
1280
- type: 'confirm',
1281
- name: 'shouldInstall',
1282
- message: (0, i18n_1.t)('AI 开发缺少 codebuddy 依赖,是否安装? {{hint}}', { hint: (0, const_1.getBooleanHint)(true) })
1283
- }
1284
- ]);
1285
- if (shouldInstall) {
1286
- yield this.executeCommand('npm', ['install', '-g', '@tencent-ai/codebuddy-code'], process.env, log);
1287
- log.info((0, i18n_1.t)('✅ codebuddy 安装完成'));
1288
- }
1289
- else {
1290
- log.info((0, i18n_1.t)('❌ codebuddy 未安装,请手动安装'));
1291
- log.info((0, i18n_1.t)('📦 安装命令: npm install -g @tencent-ai/codebuddy-code'));
1292
- process.exit(1);
1293
- }
1213
+ log.info((0, i18n_1.t)('❌ codebuddy 未安装,请手动安装'));
1214
+ log.info((0, i18n_1.t)('📦 安装命令: npm install -g @tencent-ai/codebuddy-code'));
1215
+ process.exit(1);
1294
1216
  }
1295
- });
1217
+ }
1296
1218
  }
1297
1219
  }
1298
1220
  exports.AICommandRouter = AICommandRouter;