@cloudbase/cli 2.8.0-beta.3 → 2.8.0-beta.5

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.
package/README.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  CloudBase CLI 是一个开源的命令行界面交互工具,用于帮助用户快速、方便的部署项目,管理云开发资源。
4
4
 
5
+ ## 主要功能
6
+
7
+ - **云开发资源管理**:快速部署项目,管理云函数、数据库、存储等资源
8
+ - **AI 开发助手**:集成多种 AI 工具(Claude、Qwen、Codex、Aider 等),提升开发效率
9
+ - **MCP 协议支持**:内置 `cloudbase-mcp` 命令,支持 Model Context Protocol,无需额外安装
10
+ - **模板下载**:提供多种项目模板,自动配置 IDE 和 MCP 环境
11
+
5
12
  ## 安装 CloudBase CLI
6
13
 
7
14
  ### npm
@@ -19,9 +26,14 @@ yarn global add @cloudbase/cli
19
26
  安装完成后,你可以使用 `cloudbase -v` 验证是否安装成功,如果输出了类似下面的版本号,则表明 CloudBase CLI 被成功安装到您的计算机中。
20
27
 
21
28
  ```text
22
- 0.6.0
29
+ 2.7.8
23
30
  ```
24
31
 
32
+ ## 可用命令
33
+
34
+ - `cloudbase` 或 `tcb`:主要的 CLI 命令
35
+ - `cloudbase-mcp`:内置的 MCP 服务器命令,支持 Model Context Protocol
36
+
25
37
  ## CloudBase CLI 运行要求
26
38
 
27
39
  **Node.js 8.6.0+**
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+
3
+ // 直接调用内置的 @cloudbase/cloudbase-mcp 包的 CLI
4
+ const path = require('path')
5
+ const { spawn } = require('child_process')
6
+
7
+ // 获取内置包的路径并拼接 CLI 路径
8
+ const mcpPackagePath = require.resolve('@cloudbase/cloudbase-mcp')
9
+ const mcpCliPath = path.join(path.dirname(mcpPackagePath), 'cli.js')
10
+
11
+ // 执行内置的 MCP CLI
12
+ const child = spawn('node', [mcpCliPath, ...process.argv.slice(2)], {
13
+ stdio: 'inherit',
14
+ env: process.env
15
+ })
16
+
17
+ child.on('close', (code) => {
18
+ process.exit(code)
19
+ })
20
+
21
+ child.on('error', (err) => {
22
+ console.error('Error executing cloudbase-mcp:', err)
23
+ process.exit(1)
24
+ })
@@ -0,0 +1,3 @@
1
+ {
2
+ "envId": "{{env.ENV_ID}}"
3
+ }
@@ -39,7 +39,7 @@ let AICommand = class AICommand extends common_1.Command {
39
39
  options: [
40
40
  {
41
41
  flags: '-a, --agent <agent>',
42
- desc: 'AI CLI 工具 (claude, codex, gemini)'
42
+ desc: 'AI CLI 工具 (claude, qwen, codex, aider)'
43
43
  },
44
44
  {
45
45
  flags: '-e, --envId <envId>',
@@ -25,7 +25,7 @@ const notFoundError = () => {
25
25
  });
26
26
  };
27
27
  function isValidAgent(agent) {
28
- return ['claude', 'qwen', 'codex'].includes(agent);
28
+ return ['claude', 'qwen', 'codex', 'aider'].includes(agent);
29
29
  }
30
30
  exports.isValidAgent = isValidAgent;
31
31
  exports.TOOLKIT_CONFIGS = {
@@ -38,8 +38,10 @@ exports.TOOLKIT_CONFIGS = {
38
38
  rules: 'QWEN.md'
39
39
  },
40
40
  [const_1.CODEX.value]: {
41
- config: '.env.local',
42
- rules: 'CODEX.md'
41
+ config: '.env.local'
42
+ },
43
+ [const_1.AIDER.value]: {
44
+ config: '.aider.conf.yml'
43
45
  }
44
46
  };
45
47
  function createConfigParser() {
@@ -212,6 +214,30 @@ class AIConfigManager {
212
214
  }
213
215
  });
214
216
  }
217
+ updateAiderConfig(type, config) {
218
+ return __awaiter(this, void 0, void 0, function* () {
219
+ yield this.updateConfig('ai.agents.aider.type', type);
220
+ if (type === 'custom') {
221
+ if (config.apiKey) {
222
+ yield this.updateConfig('ai.agents.aider.apiKey', config.apiKey, 'AI_AIDER_API_KEY');
223
+ }
224
+ if (config.baseUrl) {
225
+ yield this.updateConfig('ai.agents.aider.baseUrl', config.baseUrl, 'AI_AIDER_BASE_URL');
226
+ }
227
+ if (config.model) {
228
+ yield this.updateConfig('ai.agents.aider.model', config.model, 'AI_AIDER_MODEL');
229
+ }
230
+ }
231
+ else if (type === 'cloudbase') {
232
+ if (config.provider) {
233
+ yield this.updateConfig('ai.agents.aider.provider', config.provider);
234
+ }
235
+ if (config.model) {
236
+ yield this.updateConfig('ai.agents.aider.model', config.model);
237
+ }
238
+ }
239
+ });
240
+ }
215
241
  updateConfig(key, value, env) {
216
242
  return __awaiter(this, void 0, void 0, function* () {
217
243
  const configParser = createConfigParser();
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getAgentConfigValidator = exports.getDefaultConfig = exports.AGENTS = exports.NONE = exports.CODEX = exports.QWEN = exports.CLAUDE = exports.DEFAULT_CONFIG = exports.CLOUDBASE_MCP_CONFIG_PATH = exports.CLAUDE_CODE_ROUTER_CONFIG_PATH = exports.ENV_LOCAL_PATH = exports.CONFIG_PATH = void 0;
6
+ exports.getDefaultModelByBaseUrl = exports.BASE_URL_MODEL_MAPPING = exports.getAgentConfigValidator = exports.getDefaultConfig = exports.CLOUDBASE_PROVIDERS = exports.AGENTS = exports.NONE = exports.AIDER = exports.CODEX = exports.QWEN = exports.CLAUDE = exports.DEFAULT_CONFIG = exports.CLOUDBASE_MCP_CONFIG_PATH = exports.CLAUDE_CODE_ROUTER_CONFIG_PATH = exports.ENV_LOCAL_PATH = exports.CONFIG_PATH = void 0;
7
7
  const os_1 = __importDefault(require("os"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const v3_1 = __importDefault(require("zod/v3"));
@@ -31,7 +31,7 @@ exports.CLAUDE = {
31
31
  return data.baseUrl && data.apiKey;
32
32
  }
33
33
  else if (data.type === 'cloudbase') {
34
- return data.provider && data.model && data.transformer;
34
+ return data.provider && data.model;
35
35
  }
36
36
  return false;
37
37
  })
@@ -78,11 +78,46 @@ exports.CODEX = {
78
78
  return false;
79
79
  })
80
80
  };
81
+ exports.AIDER = {
82
+ name: 'aider',
83
+ value: 'aider',
84
+ configSchema: v3_1.default
85
+ .object({
86
+ type: v3_1.default.enum(['custom', 'cloudbase']).optional(),
87
+ apiKey: v3_1.default.string().optional(),
88
+ baseUrl: v3_1.default.string().optional(),
89
+ model: v3_1.default.string().optional(),
90
+ provider: v3_1.default.string().optional()
91
+ })
92
+ .refine((data) => {
93
+ if (data.type === 'custom' || !data.type) {
94
+ return data.baseUrl && data.apiKey && data.model;
95
+ }
96
+ else if (data.type === 'cloudbase') {
97
+ return data.provider && data.model;
98
+ }
99
+ return false;
100
+ })
101
+ };
81
102
  exports.NONE = {
82
103
  name: '暂不配置',
83
104
  value: 'none'
84
105
  };
85
- exports.AGENTS = [exports.CLAUDE, exports.QWEN, exports.CODEX, exports.NONE];
106
+ exports.AGENTS = [exports.CLAUDE, exports.QWEN, exports.CODEX, exports.AIDER, exports.NONE];
107
+ exports.CLOUDBASE_PROVIDERS = [
108
+ {
109
+ name: 'DeepSeek',
110
+ value: 'deepseek',
111
+ models: ['deepseek-v3'],
112
+ transformer: 'deepseek'
113
+ },
114
+ {
115
+ name: '自定义',
116
+ value: 'custom',
117
+ models: [],
118
+ transformer: undefined
119
+ }
120
+ ];
86
121
  function getDefaultConfig(agent) {
87
122
  const agentConfig = exports.AGENTS.find((a) => a.value === agent);
88
123
  if (!agentConfig) {
@@ -105,3 +140,11 @@ function getAgentConfigValidator(agent) {
105
140
  : () => ({ success: true });
106
141
  }
107
142
  exports.getAgentConfigValidator = getAgentConfigValidator;
143
+ exports.BASE_URL_MODEL_MAPPING = {
144
+ 'https://api.moonshot.cn/v1': 'kimi-k2-0711-preview',
145
+ 'https://open.bigmodel.cn/api/paas/v4': 'glm-4.5'
146
+ };
147
+ function getDefaultModelByBaseUrl(baseUrl) {
148
+ return exports.BASE_URL_MODEL_MAPPING[baseUrl] || 'gpt-4';
149
+ }
150
+ exports.getDefaultModelByBaseUrl = getDefaultModelByBaseUrl;
@@ -51,6 +51,68 @@ const chalk_1 = __importDefault(require("chalk"));
51
51
  const const_1 = require("./const");
52
52
  const utils_1 = require("../../commands/utils");
53
53
  const auth_1 = require("../../auth");
54
+ const IDE_FILE_MAPPINGS = {
55
+ "cursor": [
56
+ ".cursor/rules/cloudbase-rules.mdc",
57
+ ".cursor/mcp.json"
58
+ ],
59
+ "windsurf": [
60
+ ".windsurf/rules/cloudbase-rules.md"
61
+ ],
62
+ "codebuddy": [
63
+ ".rules/cloudbase-rules.md"
64
+ ],
65
+ "claude-code": [
66
+ "CLAUDE.md",
67
+ ".mcp.json"
68
+ ],
69
+ "cline": [
70
+ ".clinerules/cloudbase-rules.mdc"
71
+ ],
72
+ "gemini-cli": [
73
+ ".gemini/GEMINI.md",
74
+ ".gemini/settings.json"
75
+ ],
76
+ "opencode": [
77
+ ".opencode.json"
78
+ ],
79
+ "qwen-code": [
80
+ ".qwen/QWEN.md",
81
+ ".qwen/settings.json"
82
+ ],
83
+ "baidu-comate": [
84
+ ".comate/rules/cloudbase-rules.mdr",
85
+ ".comate/rules/cloudbaase-rules.mdr",
86
+ ".comate/mcp.json"
87
+ ],
88
+ "openai-codex-cli": [
89
+ ".codex/config.toml",
90
+ "AGENTS.md",
91
+ ],
92
+ "augment-code": [
93
+ ".augment-guidelines"
94
+ ],
95
+ "github-copilot": [
96
+ ".github/copilot-instructions.md"
97
+ ],
98
+ "roocode": [
99
+ ".roo/rules/cloudbaase-rules.md",
100
+ ".roo/mcp.json"
101
+ ],
102
+ "tongyi-lingma": [
103
+ ".lingma/rules/cloudbaase-rules.md"
104
+ ],
105
+ "trae": [
106
+ ".trae/rules/cloudbase-rules.md"
107
+ ],
108
+ "vscode": [
109
+ ".vscode/mcp.json",
110
+ ".vscode/settings.json"
111
+ ],
112
+ "aider": [
113
+ "mcp.json"
114
+ ]
115
+ };
54
116
  class AICommandRouter {
55
117
  constructor() {
56
118
  this.configManager = new config_1.AIConfigManager();
@@ -92,7 +154,6 @@ class AICommandRouter {
92
154
  return __awaiter(this, void 0, void 0, function* () {
93
155
  const { missingFiles } = yield this.configManager.checkToolkitConfig(agent);
94
156
  if (missingFiles.length > 0) {
95
- log.warn(`⚠️ 缺少 AI ToolKit CLI 配置文件: ${missingFiles.join(', ')}`);
96
157
  const shouldDownload = yield this.promptForTemplateDownload(log);
97
158
  if (shouldDownload) {
98
159
  log.log('');
@@ -120,7 +181,7 @@ class AICommandRouter {
120
181
  {
121
182
  type: 'confirm',
122
183
  name: 'downloadTemplate',
123
- message: '是否下载 CloudBase AI ToolKit 模板?',
184
+ message: '是否下载 CloudBase AI ToolKit 模板?(建议下载以获取完整的开发体验)',
124
185
  default: true
125
186
  }
126
187
  ]);
@@ -141,11 +202,11 @@ class AICommandRouter {
141
202
  name: 'templateType',
142
203
  message: '选择要下载的模板类型:',
143
204
  choices: [
144
- { name: '🧩 AI编辑器配置模板(包含所有主流编辑器配置)', value: 'rules' },
145
- { name: '⚛️ React + CloudBase 全栈应用模板', value: 'react' },
146
- { name: '🟢 Vue + CloudBase 全栈应用模板', value: 'vue' },
147
- { name: '🟦 微信小程序 + 云开发模板', value: 'miniprogram' },
148
- { name: '🌈 UniApp + CloudBase 跨端应用模板', value: 'uniapp' }
205
+ { name: '🚀 Web 应用 - React + CloudBase', value: 'react' },
206
+ { name: '🟢 Web 应用 - Vue + CloudBase', value: 'vue' },
207
+ { name: '🟦 微信小程序 + CloudBase', value: 'miniprogram' },
208
+ { name: '🌈 跨端应用 - UniApp + CloudBase', value: 'uniapp' },
209
+ { name: '🧩 只下载 AI 规则和配置', value: 'rules' }
149
210
  ],
150
211
  default: 'rules'
151
212
  }
@@ -295,6 +356,7 @@ class AICommandRouter {
295
356
  finally { if (e_1) throw e_1.error; }
296
357
  }
297
358
  yield fs.unlink(zipPath);
359
+ yield this.modifyMCPConfigs(extractDir, log);
298
360
  });
299
361
  }
300
362
  validateTemplateIntegrity(templateType, extractDir, log) {
@@ -467,6 +529,13 @@ class AICommandRouter {
467
529
  else {
468
530
  return yield this.executeCodexAgent(agentConfig, additionalArgs, log);
469
531
  }
532
+ case const_1.AIDER.value:
533
+ if (agentConfig.type === 'cloudbase') {
534
+ return yield this.executeAiderCloudbaseAgent(agentConfig, additionalArgs, log);
535
+ }
536
+ else {
537
+ return yield this.executeAiderAgent(agentConfig, additionalArgs, log);
538
+ }
470
539
  default:
471
540
  throw new Error(`不支持的 AI 工具: ${agent}`);
472
541
  }
@@ -582,9 +651,11 @@ class AICommandRouter {
582
651
  name: 'cloudbase',
583
652
  api_base_url: `https://${envId}.api.tcloudbasegateway.com/v1/ai/${provider}/chat/completions`,
584
653
  api_key: accessToken.access_token,
585
- models: [model],
586
- transformer: { use: [transformer] }
654
+ models: [model]
587
655
  };
656
+ if (transformer) {
657
+ cloudbaseProvider.transformer = { use: [transformer] };
658
+ }
588
659
  yield fs.ensureFile(const_1.CLAUDE_CODE_ROUTER_CONFIG_PATH);
589
660
  const claudeCodeRouterConfig = yield fs.readFile(const_1.CLAUDE_CODE_ROUTER_CONFIG_PATH, 'utf-8');
590
661
  if (claudeCodeRouterConfig.trim().length === 0) {
@@ -671,12 +742,12 @@ class AICommandRouter {
671
742
  {
672
743
  type: 'confirm',
673
744
  name: 'shouldInstall',
674
- message: 'claude code router 未安装,是否安装?'
745
+ message: 'AI 开发缺少 claude code router 依赖,是否安装?'
675
746
  }
676
747
  ]);
677
748
  if (shouldInstall) {
678
749
  yield this.executeCommand('npm', ['install', '-g', '@musistudio/claude-code-router'], process.env, log);
679
- log.debug('✅ claude-code-router 安装完成');
750
+ log.info('✅ claude-code-router 安装完成');
680
751
  }
681
752
  else {
682
753
  log.info('❌ claude code router 未安装,请手动安装');
@@ -695,12 +766,12 @@ class AICommandRouter {
695
766
  {
696
767
  type: 'confirm',
697
768
  name: 'shouldInstall',
698
- message: 'claude code 未安装,是否安装?'
769
+ message: 'AI 开发缺少 claude code 依赖,是否安装?'
699
770
  }
700
771
  ]);
701
772
  if (shouldInstall) {
702
773
  yield this.executeCommand('npm', ['install', '-g', '@anthropic-ai/claude-code'], process.env, log);
703
- log.debug('✅ claude code 安装完成');
774
+ log.info('✅ claude code 安装完成');
704
775
  }
705
776
  else {
706
777
  log.info('❌ claude code 未安装,请手动安装');
@@ -719,12 +790,12 @@ class AICommandRouter {
719
790
  {
720
791
  type: 'confirm',
721
792
  name: 'shouldInstall',
722
- message: 'qwen code 未安装,是否安装?'
793
+ message: 'AI 开发缺少 qwen code 依赖,是否安装?'
723
794
  }
724
795
  ]);
725
796
  if (shouldInstall) {
726
797
  yield this.executeCommand('npm', ['install', '-g', '@qwen-code/qwen-code'], process.env, log);
727
- log.debug('✅ qwen code 安装完成');
798
+ log.info('✅ qwen code 安装完成');
728
799
  }
729
800
  else {
730
801
  log.info('❌ qwen code 未安装,请手动安装');
@@ -738,10 +809,13 @@ class AICommandRouter {
738
809
  yield this.ensureCodexCode(log);
739
810
  const codexArgs = [
740
811
  ...(model ? ['--config', `model=${model}`] : []),
741
- '--config', 'model_providers.custom.name=Custom OpenAI',
812
+ '--config',
813
+ 'model_providers.custom.name=Custom OpenAI',
742
814
  ...(baseUrl ? ['--config', `model_providers.custom.base_url=${baseUrl}`] : []),
743
- '--config', 'model_providers.custom.env_key=OPENAI_API_KEY',
744
- '--config', 'model_provider=custom',
815
+ '--config',
816
+ 'model_providers.custom.env_key=OPENAI_API_KEY',
817
+ '--config',
818
+ 'model_provider=custom',
745
819
  ...additionalArgs
746
820
  ];
747
821
  yield this.executeCommand('codex', codexArgs, Object.assign(Object.assign({}, process.env), { OPENAI_API_KEY: apiKey }), log);
@@ -766,11 +840,16 @@ class AICommandRouter {
766
840
  const baseUrl = `https://${envId}.api.tcloudbasegateway.com/v1/ai/${provider}`;
767
841
  const apiKey = accessToken.access_token;
768
842
  const codexArgs = [
769
- '--config', `model=${model}`,
770
- '--config', 'model_providers.cloudbase.name=CloudBase AI',
771
- '--config', `model_providers.cloudbase.base_url=${baseUrl}`,
772
- '--config', 'model_providers.cloudbase.env_key=CLOUDBASE_ACCESS_TOKEN',
773
- '--config', 'model_provider=cloudbase',
843
+ '--config',
844
+ `model=${model}`,
845
+ '--config',
846
+ 'model_providers.cloudbase.name=CloudBase AI',
847
+ '--config',
848
+ `model_providers.cloudbase.base_url=${baseUrl}`,
849
+ '--config',
850
+ 'model_providers.cloudbase.env_key=CLOUDBASE_ACCESS_TOKEN',
851
+ '--config',
852
+ 'model_provider=cloudbase',
774
853
  ...additionalArgs
775
854
  ];
776
855
  yield this.executeCommand('codex', codexArgs, Object.assign(Object.assign({}, process.env), { CLOUDBASE_ACCESS_TOKEN: apiKey }), log);
@@ -779,27 +858,225 @@ class AICommandRouter {
779
858
  ensureCodexCode(log) {
780
859
  return __awaiter(this, void 0, void 0, function* () {
781
860
  if (yield this.isToolAvailable('codex')) {
782
- log.debug('codex code 已安装!');
861
+ log.debug('codex 已安装!');
783
862
  }
784
863
  else {
785
864
  const { shouldInstall } = yield inquirer_1.default.prompt([
786
865
  {
787
866
  type: 'confirm',
788
867
  name: 'shouldInstall',
789
- message: 'codex code 未安装,是否安装?'
868
+ message: 'AI 开发缺少 codex 依赖,是否安装?'
790
869
  }
791
870
  ]);
792
871
  if (shouldInstall) {
793
872
  yield this.executeCommand('npm', ['install', '-g', '@openai/codex'], process.env, log);
794
- log.debug('✅ codex code 安装完成');
873
+ log.info('✅ codex 安装完成');
874
+ }
875
+ else {
876
+ log.info('❌ codex 未安装,请手动安装');
877
+ process.exit(1);
878
+ }
879
+ }
880
+ });
881
+ }
882
+ executeAiderAgent(config, additionalArgs, log) {
883
+ return __awaiter(this, void 0, void 0, function* () {
884
+ yield this.ensureAider(log);
885
+ const { apiKey, baseUrl, model } = config;
886
+ const aiderArgs = ['--model', `openai/${model}`, ...additionalArgs];
887
+ const env = Object.assign(Object.assign({}, process.env), { OPENAI_API_KEY: apiKey, OPENAI_API_BASE: baseUrl });
888
+ yield this.executeCommand('aider', aiderArgs, env, log);
889
+ });
890
+ }
891
+ executeAiderCloudbaseAgent(config, additionalArgs, log) {
892
+ return __awaiter(this, void 0, void 0, function* () {
893
+ yield this.ensureAider(log);
894
+ const { provider, model } = config;
895
+ const envId = yield (0, config_1.createConfigParser)().get('envId');
896
+ yield (0, auth_1.checkLogin)();
897
+ const credential = yield (0, utils_1.getCredential)({}, {});
898
+ const accessToken = yield (0, utils_1.rawFetchAccessToken)({
899
+ envId,
900
+ secretId: credential.secretId,
901
+ secretKey: credential.secretKey,
902
+ token: credential.token
903
+ });
904
+ if (!accessToken.access_token) {
905
+ log.error(`获取云开发 Access Token 失败,请运行 tcb login 后再重试,${JSON.stringify(accessToken)}`);
906
+ process.exit(1);
907
+ }
908
+ const baseUrl = `https://${envId}.api.tcloudbasegateway.com/v1/ai/${provider}`;
909
+ const apiKey = accessToken.access_token;
910
+ const aiderArgs = ['--model', `openai/${model}`, ...additionalArgs];
911
+ const env = Object.assign(Object.assign({}, process.env), { OPENAI_API_KEY: apiKey, OPENAI_API_BASE: baseUrl });
912
+ yield this.executeCommand('aider', aiderArgs, env, log);
913
+ });
914
+ }
915
+ ensureAider(log) {
916
+ return __awaiter(this, void 0, void 0, function* () {
917
+ if (yield this.isToolAvailable('aider')) {
918
+ log.debug('aider 已安装!');
919
+ }
920
+ else {
921
+ const { shouldInstall } = yield inquirer_1.default.prompt([
922
+ {
923
+ type: 'confirm',
924
+ name: 'shouldInstall',
925
+ message: 'AI 开发缺少 aider 依赖,是否安装?'
926
+ }
927
+ ]);
928
+ if (shouldInstall) {
929
+ log.info('正在安装 aider...');
930
+ const platform = process.platform;
931
+ if (platform === 'win32') {
932
+ yield this.executeCommand('powershell', ['-c', 'irm https://aider.chat/install.ps1 | iex'], process.env, log);
933
+ }
934
+ else {
935
+ yield this.executeCommand('sh', ['-c', 'curl -LsSf https://aider.chat/install.sh | sh'], process.env, log);
936
+ }
937
+ log.info('✅ aider 安装完成');
795
938
  }
796
939
  else {
797
- log.info('❌ codex code 未安装,请手动安装');
940
+ log.info('❌ aider 未安装,请手动安装');
798
941
  process.exit(1);
799
942
  }
800
943
  }
801
944
  });
802
945
  }
946
+ modifyMCPConfigs(extractDir, log) {
947
+ return __awaiter(this, void 0, void 0, function* () {
948
+ const fs = yield Promise.resolve().then(() => __importStar(require('fs-extra')));
949
+ const path = yield Promise.resolve().then(() => __importStar(require('path')));
950
+ try {
951
+ log.info('🔧 正在修改 MCP 配置文件...');
952
+ for (const [ide, files] of Object.entries(IDE_FILE_MAPPINGS)) {
953
+ for (const file of files) {
954
+ const filePath = path.join(extractDir, file);
955
+ if (yield fs.pathExists(filePath)) {
956
+ if (file.endsWith('.json')) {
957
+ yield this.modifyMCPJsonFile(filePath, log);
958
+ }
959
+ else if (file.endsWith('.toml')) {
960
+ yield this.modifyMCPTomlFile(filePath, log);
961
+ }
962
+ }
963
+ }
964
+ }
965
+ log.info('✅ MCP 配置文件修改完成');
966
+ }
967
+ catch (error) {
968
+ log.warn(`⚠️ MCP 配置文件修改失败: ${error.message}`);
969
+ }
970
+ });
971
+ }
972
+ modifyMCPJsonFile(filePath, log) {
973
+ return __awaiter(this, void 0, void 0, function* () {
974
+ const fs = yield Promise.resolve().then(() => __importStar(require('fs-extra')));
975
+ try {
976
+ const content = yield fs.readFile(filePath, 'utf-8');
977
+ const config = JSON.parse(content);
978
+ let modified = false;
979
+ const modifyCommands = (obj) => {
980
+ if (typeof obj !== 'object' || obj === null) {
981
+ return obj;
982
+ }
983
+ if (Array.isArray(obj)) {
984
+ return obj.map(item => modifyCommands(item));
985
+ }
986
+ const result = Object.assign({}, obj);
987
+ if (result.command === 'npx' && Array.isArray(result.args)) {
988
+ const argsStr = result.args.join(' ');
989
+ if (argsStr.includes('npm-global-exec@latest') && argsStr.includes('@cloudbase/cloudbase-mcp@latest')) {
990
+ result.command = 'cloudbase-mcp';
991
+ result.args = [];
992
+ modified = true;
993
+ log.debug(`修改配置文件 ${filePath}: npx -> cloudbase-mcp`);
994
+ }
995
+ }
996
+ for (const [key, value] of Object.entries(result)) {
997
+ result[key] = modifyCommands(value);
998
+ }
999
+ return result;
1000
+ };
1001
+ const modifiedConfig = modifyCommands(config);
1002
+ if (modified) {
1003
+ yield fs.writeJson(filePath, modifiedConfig, { spaces: 2 });
1004
+ log.debug(`✅ 已修改 ${filePath}`);
1005
+ }
1006
+ }
1007
+ catch (error) {
1008
+ log.warn(`⚠️ 修改配置文件 ${filePath} 失败: ${error.message}`);
1009
+ }
1010
+ });
1011
+ }
1012
+ modifyMCPTomlFile(filePath, log) {
1013
+ return __awaiter(this, void 0, void 0, function* () {
1014
+ const fs = yield Promise.resolve().then(() => __importStar(require('fs-extra')));
1015
+ const toml = require('toml');
1016
+ try {
1017
+ const content = yield fs.readFile(filePath, 'utf-8');
1018
+ const config = toml.parse(content);
1019
+ let modified = false;
1020
+ const modifyCommands = (obj) => {
1021
+ if (typeof obj !== 'object' || obj === null) {
1022
+ return obj;
1023
+ }
1024
+ if (Array.isArray(obj)) {
1025
+ return obj.map(item => modifyCommands(item));
1026
+ }
1027
+ const result = Object.assign({}, obj);
1028
+ if (result.command === 'npx' && Array.isArray(result.args)) {
1029
+ const argsStr = result.args.join(' ');
1030
+ if (argsStr.includes('@cloudbase/cloudbase-mcp@latest')) {
1031
+ result.command = 'cloudbase-mcp';
1032
+ result.args = [];
1033
+ modified = true;
1034
+ log.debug(`修改配置文件 ${filePath}: npx -> cloudbase-mcp`);
1035
+ }
1036
+ }
1037
+ for (const [key, value] of Object.entries(result)) {
1038
+ result[key] = modifyCommands(value);
1039
+ }
1040
+ return result;
1041
+ };
1042
+ const modifiedConfig = modifyCommands(config);
1043
+ if (modified) {
1044
+ const tomlString = this.objectToToml(modifiedConfig);
1045
+ yield fs.writeFile(filePath, tomlString, 'utf-8');
1046
+ log.debug(`✅ 已修改 ${filePath}`);
1047
+ }
1048
+ }
1049
+ catch (error) {
1050
+ log.warn(`⚠️ 修改配置文件 ${filePath} 失败: ${error.message}`);
1051
+ }
1052
+ });
1053
+ }
1054
+ objectToToml(obj, prefix = '') {
1055
+ const lines = [];
1056
+ for (const [key, value] of Object.entries(obj)) {
1057
+ const fullKey = prefix ? `${prefix}.${key}` : key;
1058
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
1059
+ lines.push(`[${fullKey}]`);
1060
+ lines.push(this.objectToToml(value, fullKey));
1061
+ }
1062
+ else if (Array.isArray(value)) {
1063
+ const arrayStr = value.map(item => {
1064
+ if (typeof item === 'string') {
1065
+ return `"${item}"`;
1066
+ }
1067
+ return item;
1068
+ }).join(', ');
1069
+ lines.push(`${key} = [${arrayStr}]`);
1070
+ }
1071
+ else if (typeof value === 'string') {
1072
+ lines.push(`${key} = "${value}"`);
1073
+ }
1074
+ else {
1075
+ lines.push(`${key} = ${value}`);
1076
+ }
1077
+ }
1078
+ return lines.join('\n');
1079
+ }
803
1080
  }
804
1081
  exports.AICommandRouter = AICommandRouter;
805
1082
  function safeParseJson(json) {