@cloudbase/cloudbase-mcp 2.0.6 → 2.2.0-alpha.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 (4) hide show
  1. package/dist/cli.cjs +837 -189
  2. package/dist/index.cjs +837 -189
  3. package/dist/index.js +426 -153
  4. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -102,6 +102,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
102
102
  Object.defineProperty(exports, "__esModule", ({ value: true }));
103
103
  exports.CloudRunService = void 0;
104
104
  exports.codeToZip = codeToZip;
105
+ exports.parseObjectToDiffConfigItem = parseObjectToDiffConfigItem;
105
106
  const archiver_1 = __importDefault(__webpack_require__(99133));
106
107
  const fs_extra_1 = __webpack_require__(21605);
107
108
  const path_1 = __importDefault(__webpack_require__(39902));
@@ -270,7 +271,7 @@ class CloudRunService {
270
271
  /**
271
272
  * 上传部署包
272
273
  */
273
- const zipFile = await codeToZip(targetPath, { installDependency: true });
274
+ const zipFile = await codeToZip(targetPath, { installDependency: (serverConfig === null || serverConfig === void 0 ? void 0 : serverConfig.InstallDependency) !== undefined ? serverConfig.InstallDependency : true });
274
275
  await (0, utils_1.upload)({
275
276
  url: uploadUrl,
276
277
  file: zipFile,
@@ -286,8 +287,14 @@ class CloudRunService {
286
287
  if (await this._checkFunctionExist(serverName)) {
287
288
  // 更新
288
289
  const serverDetail = await this.detail({ serverName });
289
- const _serverConfig = Object.assign(Object.assign(Object.assign({}, ((serverDetail === null || serverDetail === void 0 ? void 0 : serverDetail.ServerConfig) || {})), serverConfig), ((serverDetail === null || serverDetail === void 0 ? void 0 : serverDetail.ServerConfig.Tag) === 'function:' ? { Port: 3000 } : {}) // 函数型不能指定端口,需要固定为3000
290
+ const _serverConfig = Object.assign(Object.assign(Object.assign({}, serverConfig), { OpenAccessTypes: ['OA', 'PUBLIC', 'MINIAPP'] }), ((serverDetail === null || serverDetail === void 0 ? void 0 : serverDetail.ServerConfig.Tag) === 'function:' ? { Port: 3000 } : {}) // 函数型不能指定端口,需要固定为3000
290
291
  );
292
+ if ((serverDetail === null || serverDetail === void 0 ? void 0 : serverDetail.ServerConfig.Tag) === 'function:') {
293
+ deployInfo.BuildPacks = {
294
+ LanguageVersion: '20.18',
295
+ RepoLanguage: 'Node.js'
296
+ };
297
+ }
291
298
  deployInfo.ReleaseType = 'FULL';
292
299
  return this._upsertFunction(false, {
293
300
  name: serverName,
@@ -315,7 +322,13 @@ class CloudRunService {
315
322
  RepoLanguage: 'Node.js'
316
323
  };
317
324
  }
318
- const _serverConfig = Object.assign(Object.assign(Object.assign({ OpenAccessTypes: ['OA', 'PUBLIC'], Cpu: 0, Mem: 0, MinNum: 0, MaxNum: 0, PolicyDetails: [], EnvParams: JSON.stringify({}), InitialDelaySeconds: 0, CustomLogs: '', HasDockerfile: true, CreateTime: '', EnvId: envConfig.EnvId, ServerName: serverName, Port: type === 'container' ? 80 : 3000, Dockerfile: 'Dockerfile', BuildDir: '' }, serverConfig), (type === 'function' ? { Port: 3000 } : {})), { Tag: type === 'container' ? '' : 'function:' });
325
+ const _serverConfig = Object.assign(Object.assign(Object.assign({ OpenAccessTypes: ['OA', 'PUBLIC', 'MINIAPP'],
326
+ // Cpu: 0,
327
+ // Mem: 0,
328
+ MinNum: 0,
329
+ // MaxNum: 0,
330
+ // PolicyDetails: [],
331
+ EnvParams: JSON.stringify({}), InitialDelaySeconds: 0, CustomLogs: '', HasDockerfile: true, CreateTime: '', EnvId: envConfig.EnvId, ServerName: serverName, Port: type === 'container' ? 80 : 3000, Dockerfile: 'Dockerfile', BuildDir: '' }, serverConfig), (type === 'function' ? { Port: 3000 } : {})), { Tag: type === 'container' ? '' : 'function:' });
319
332
  return this._upsertFunction(true, {
320
333
  name: serverName,
321
334
  deployInfo,
@@ -349,11 +362,12 @@ class CloudRunService {
349
362
  _upsertFunction(isNew, data) {
350
363
  const { name, deployInfo, serverConfig } = data;
351
364
  const envConfig = this.environment.lazyEnvironmentConfig;
365
+ const Items = parseObjectToDiffConfigItem(serverConfig);
352
366
  return this.tcbrService.request(isNew ? 'CreateCloudRunServer' : 'UpdateCloudRunServer', {
353
367
  EnvId: envConfig.EnvId,
354
368
  ServerName: name,
355
369
  DeployInfo: deployInfo,
356
- ServerConfig: serverConfig
370
+ Items,
357
371
  });
358
372
  }
359
373
  }
@@ -426,6 +440,63 @@ async function codeToZip(cwd, options) {
426
440
  await archive.finalize();
427
441
  return bufferPromise;
428
442
  }
443
+ /**
444
+ * 提交参数变化映射
445
+ */
446
+ const SUBMIT_DIFF_MAP = {
447
+ Cpu: 'CpuSpecs',
448
+ Mem: 'MemSpecs',
449
+ OpenAccessTypes: 'AccessTypes',
450
+ EnvParams: 'EnvParam',
451
+ CustomLogs: 'LogPath'
452
+ };
453
+ /**
454
+ * 将 object 参数转为 [{key:"Port", IntValue:80}] 的格式,并且剔除空字符串
455
+ */
456
+ function parseObjectToDiffConfigItem(data) {
457
+ const kvs = Object.entries(data);
458
+ const Items = [];
459
+ kvs.forEach(([k, v]) => {
460
+ const Key = SUBMIT_DIFF_MAP[k] || k;
461
+ if ([
462
+ 'CustomLogs',
463
+ 'EnvParams',
464
+ 'CreateTime',
465
+ 'Dockerfile',
466
+ 'BuildDir',
467
+ 'LogType',
468
+ 'LogSetId',
469
+ 'LogTopicId',
470
+ 'LogParseType',
471
+ 'Tag',
472
+ 'InternalAccess',
473
+ 'InternalDomain',
474
+ 'OperationMode',
475
+ 'SessionAffinity'
476
+ ].includes(k)) {
477
+ !!v && Items.push({ Key, Value: v });
478
+ }
479
+ else if (['MinNum', 'MaxNum', 'InitialDelaySeconds', 'Port'].includes(k)) {
480
+ Items.push({ Key, IntValue: v });
481
+ }
482
+ else if (['HasDockerfile'].includes(k)) {
483
+ Items.push({ Key, BoolValue: v });
484
+ }
485
+ else if (['Cpu', 'Mem'].includes(k)) {
486
+ Items.push({ Key, FloatValue: v });
487
+ }
488
+ else if (['OpenAccessTypes', 'EntryPoint', 'Cmd'].includes(k)) {
489
+ Items.push({ Key, ArrayValue: v });
490
+ }
491
+ else if (['PolicyDetails'].includes(k)) {
492
+ Items.push({ Key, PolicyDetails: v });
493
+ }
494
+ else if (['TimerScale'].includes(k)) {
495
+ Items.push({ Key, TimerScale: v });
496
+ }
497
+ });
498
+ return Items;
499
+ }
429
500
 
430
501
 
431
502
  /***/ }),
@@ -23554,7 +23625,7 @@ async function getCloudBaseManager(options = {}) {
23554
23625
  secretKey,
23555
23626
  envId: finalEnvId || loginEnvId,
23556
23627
  token,
23557
- proxy: process.env.http_proxy
23628
+ proxy: process.env.http_proxy,
23558
23629
  });
23559
23630
  return manager;
23560
23631
  }
@@ -23571,13 +23642,8 @@ async function getCloudBaseManager(options = {}) {
23571
23642
  function createCloudBaseManagerWithOptions(cloudBaseOptions) {
23572
23643
  (0, logger_js_1.debug)('使用传入的 CloudBase 配置创建 manager:', cloudBaseOptions);
23573
23644
  const manager = new manager_node_1.default({
23574
- secretId: cloudBaseOptions.secretId,
23575
- secretKey: cloudBaseOptions.secretKey,
23576
- envId: cloudBaseOptions.envId,
23577
- token: cloudBaseOptions.token,
23645
+ ...cloudBaseOptions,
23578
23646
  proxy: cloudBaseOptions.proxy || process.env.http_proxy,
23579
- region: cloudBaseOptions.region,
23580
- envType: cloudBaseOptions.envType
23581
23647
  });
23582
23648
  return manager;
23583
23649
  }
@@ -38331,7 +38397,7 @@ function registerSQLDatabaseTools(server) {
38331
38397
  // executeReadOnlySQL
38332
38398
  server.registerTool?.("executeReadOnlySQL", {
38333
38399
  title: "Execute read-only SQL query",
38334
- description: "Execute a read-only SQL query on the SQL database. Note: For per-user ACL, each table should contain a fixed `_openid` column that represents the user and is used for access control.",
38400
+ description: "Execute a read-only SQL query on the SQL database. Note: For per-user ACL, each table should contain a fixed `_openid` column defined as `_openid VARCHAR(64) DEFAULT '' NOT NULL` that represents the user and is used for access control.",
38335
38401
  inputSchema: {
38336
38402
  sql: zod_1.z.string().describe("SQL query statement (SELECT queries only)"),
38337
38403
  },
@@ -38390,7 +38456,7 @@ function registerSQLDatabaseTools(server) {
38390
38456
  // executeWriteSQL
38391
38457
  server.registerTool?.("executeWriteSQL", {
38392
38458
  title: "Execute write SQL statement",
38393
- description: "Execute a write SQL statement on the SQL database (INSERT, UPDATE, DELETE, etc.). Whenever you create a new table, you **must** contain a fixed `_opeid` column that represents the user and is used for access control.",
38459
+ description: "Execute a write SQL statement on the SQL database (INSERT, UPDATE, DELETE, etc.). Whenever you create a new table, you **must** include a fixed `_openid` column defined as `_openid VARCHAR(64) DEFAULT '' NOT NULL` that represents the user and is used for access control.",
38394
38460
  inputSchema: {
38395
38461
  sql: zod_1.z
38396
38462
  .string()
@@ -48550,7 +48616,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
48550
48616
  exports.cloudBaseRequest = cloudBaseRequest;
48551
48617
  const auth_1 = __webpack_require__(23506);
48552
48618
  const http_request_1 = __webpack_require__(72088);
48553
- const SUPPORT_REGIONS = ['ap-shanghai', 'ap-guangzhou'];
48619
+ const SUPPORT_REGIONS = ['ap-shanghai', 'ap-guangzhou', 'ap-singapore'];
48554
48620
  async function cloudBaseRequest(options) {
48555
48621
  // const url = 'https://tcb-admin.tencentcloudapi.com/admin'
48556
48622
  const { config, params = {}, method = 'POST', headers = {} } = options;
@@ -48564,11 +48630,11 @@ async function cloudBaseRequest(options) {
48564
48630
  let internalRegionEndpoint = '';
48565
48631
  if (finalRegion) {
48566
48632
  if (SUPPORT_REGIONS.includes(finalRegion)) {
48567
- internetRegionEndpoint = `${finalRegion}.tcb-api.tencentcloudapi.com`;
48568
- internalRegionEndpoint = `internal.${finalRegion}.tcb-api.tencentcloudapi.com`;
48633
+ internetRegionEndpoint = `${envId}.${finalRegion}.tcb-api.tencentcloudapi.com`;
48634
+ internalRegionEndpoint = `${envId}.internal.${finalRegion}.tcb-api.tencentcloudapi.com`;
48569
48635
  }
48570
48636
  else {
48571
- console.warn('当前仅支持上海,广州地域,其他地域默认解析到固定域名(上海地域)');
48637
+ console.warn('当前仅支持上海,广州,新加坡地域,其他地域默认解析到固定域名(上海地域)');
48572
48638
  internetRegionEndpoint = `tcb-api.tencentcloudapi.com`;
48573
48639
  internalRegionEndpoint = `internal.tcb-api.tencentcloudapi.com`;
48574
48640
  }
@@ -90161,19 +90227,20 @@ class EnvService {
90161
90227
  });
90162
90228
  }
90163
90229
  getCos() {
90230
+ const internalEndpoint = this.environment.cloudBaseContext.isInternalEndpoint();
90164
90231
  const { secretId, secretKey, token } = this.environment.getAuthConfig();
90165
90232
  const cosConfig = {
90166
90233
  SecretId: secretId,
90167
90234
  SecretKey: secretKey,
90168
90235
  SecurityToken: token,
90169
- Domain: constant_1.USE_INTERNAL_ENDPOINT ? "{Bucket}.cos-internal.{Region}.tencentcos.cn" /* COS_ENDPOINT.INTERNAL */ : "{Bucket}.cos.{Region}.tencentcos.cn" /* COS_ENDPOINT.PUBLIC */,
90236
+ Domain: internalEndpoint ? "{Bucket}.cos-internal.{Region}.tencentcos.cn" /* COS_ENDPOINT.INTERNAL */ : "{Bucket}.cos.{Region}.tencentcos.cn" /* COS_ENDPOINT.PUBLIC */,
90170
90237
  };
90171
90238
  if (constant_1.COS_SDK_PROTOCOL) {
90172
90239
  cosConfig.Protocol = (constant_1.COS_SDK_PROTOCOL.endsWith(':')
90173
90240
  ? constant_1.COS_SDK_PROTOCOL.toLowerCase()
90174
90241
  : constant_1.COS_SDK_PROTOCOL.toLowerCase() + ':');
90175
90242
  }
90176
- if (constant_1.USE_INTERNAL_ENDPOINT) {
90243
+ if (internalEndpoint) {
90177
90244
  cosConfig.Protocol = 'http:';
90178
90245
  }
90179
90246
  return new cos_nodejs_sdk_v5_1.default(cosConfig);
@@ -100307,12 +100374,14 @@ const rag_js_1 = __webpack_require__(64215);
100307
100374
  const setup_js_1 = __webpack_require__(76556);
100308
100375
  const storage_js_1 = __webpack_require__(94848);
100309
100376
  // import { registerMiniprogramTools } from "./tools/miniprogram.js";
100377
+ const types_js_1 = __webpack_require__(1294);
100310
100378
  const cloudrun_js_1 = __webpack_require__(35023);
100311
100379
  const dataModel_js_1 = __webpack_require__(34052);
100312
100380
  const gateway_js_1 = __webpack_require__(84319);
100313
100381
  const invite_code_js_1 = __webpack_require__(44760);
100314
100382
  const security_rule_js_1 = __webpack_require__(7862);
100315
100383
  const cloud_mode_js_1 = __webpack_require__(89684);
100384
+ const logger_js_1 = __webpack_require__(13039);
100316
100385
  const tool_wrapper_js_1 = __webpack_require__(71363);
100317
100386
  // 默认插件列表
100318
100387
  const DEFAULT_PLUGINS = [
@@ -100413,6 +100482,13 @@ async function createCloudBaseMcpServer(options) {
100413
100482
  ...(ide === "CodeBuddy" ? { logging: {} } : {}),
100414
100483
  },
100415
100484
  });
100485
+ // Only set logging handler if logging capability is declared
100486
+ if (ide === "CodeBuddy") {
100487
+ server.server.setRequestHandler(types_js_1.SetLevelRequestSchema, (request, extra) => {
100488
+ (0, logger_js_1.info)(`--- Logging level: ${request.params.level}`);
100489
+ return {};
100490
+ });
100491
+ }
100416
100492
  // Store cloudBaseOptions in server instance for tools to access
100417
100493
  if (cloudBaseOptions) {
100418
100494
  server.cloudBaseOptions = cloudBaseOptions;
@@ -100443,10 +100519,10 @@ function getDefaultServer() {
100443
100519
  }
100444
100520
  var stdio_js_1 = __webpack_require__(6166);
100445
100521
  Object.defineProperty(exports, "StdioServerTransport", ({ enumerable: true, get: function () { return stdio_js_1.StdioServerTransport; } }));
100446
- var logger_js_1 = __webpack_require__(13039);
100447
- Object.defineProperty(exports, "error", ({ enumerable: true, get: function () { return logger_js_1.error; } }));
100448
- Object.defineProperty(exports, "info", ({ enumerable: true, get: function () { return logger_js_1.info; } }));
100449
- Object.defineProperty(exports, "warn", ({ enumerable: true, get: function () { return logger_js_1.warn; } }));
100522
+ var logger_js_2 = __webpack_require__(13039);
100523
+ Object.defineProperty(exports, "error", ({ enumerable: true, get: function () { return logger_js_2.error; } }));
100524
+ Object.defineProperty(exports, "info", ({ enumerable: true, get: function () { return logger_js_2.info; } }));
100525
+ Object.defineProperty(exports, "warn", ({ enumerable: true, get: function () { return logger_js_2.warn; } }));
100450
100526
  var telemetry_js_1 = __webpack_require__(45880);
100451
100527
  Object.defineProperty(exports, "reportToolCall", ({ enumerable: true, get: function () { return telemetry_js_1.reportToolCall; } }));
100452
100528
  Object.defineProperty(exports, "reportToolkitLifecycle", ({ enumerable: true, get: function () { return telemetry_js_1.reportToolkitLifecycle; } }));
@@ -101892,6 +101968,53 @@ class AsyncReader extends reader_1.default {
101892
101968
  exports["default"] = AsyncReader;
101893
101969
 
101894
101970
 
101971
+ /***/ }),
101972
+
101973
+ /***/ 32720:
101974
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
101975
+
101976
+ "use strict";
101977
+
101978
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
101979
+ exports.sendDeployNotification = sendDeployNotification;
101980
+ const logger_js_1 = __webpack_require__(13039);
101981
+ /**
101982
+ * Send deployment notification to CodeBuddy IDE
101983
+ * @param server ExtendedMcpServer instance
101984
+ * @param notificationData Deployment notification data
101985
+ */
101986
+ async function sendDeployNotification(server, notificationData) {
101987
+ // Check if current IDE is CodeBuddy (prefer server.ide, fallback to environment variable)
101988
+ const currentIde = server.ide || process.env.INTEGRATION_IDE;
101989
+ if (currentIde !== 'CodeBuddy' || !server.server) {
101990
+ // Not CodeBuddy IDE, skip notification
101991
+ return;
101992
+ }
101993
+ try {
101994
+ // Send notification using sendLoggingMessage
101995
+ server.server.sendLoggingMessage({
101996
+ level: "notice",
101997
+ data: {
101998
+ type: "tcb",
101999
+ event: "deploy",
102000
+ data: {
102001
+ type: notificationData.deployType, // "hosting" or "cloudrun"
102002
+ url: notificationData.url,
102003
+ projectId: notificationData.projectId,
102004
+ projectName: notificationData.projectName,
102005
+ consoleUrl: notificationData.consoleUrl
102006
+ }
102007
+ }
102008
+ });
102009
+ (0, logger_js_1.info)(`CodeBuddy IDE: 已发送部署通知 - ${notificationData.deployType} - ${notificationData.url}`);
102010
+ }
102011
+ catch (err) {
102012
+ // Log error but don't throw - notification failure should not affect deployment flow
102013
+ (0, logger_js_1.error)(`Failed to send deployment notification: ${err instanceof Error ? err.message : err}`, err);
102014
+ }
102015
+ }
102016
+
102017
+
101895
102018
  /***/ }),
101896
102019
 
101897
102020
  /***/ 32923:
@@ -110205,6 +110328,7 @@ const fs_1 = __importDefault(__webpack_require__(29021));
110205
110328
  const path_1 = __importDefault(__webpack_require__(39902));
110206
110329
  const zod_1 = __webpack_require__(21614);
110207
110330
  const cloudbase_manager_js_1 = __webpack_require__(3431);
110331
+ const notification_js_1 = __webpack_require__(32720);
110208
110332
  // CloudRun service types
110209
110333
  exports.CLOUDRUN_SERVICE_TYPES = ['function', 'container'];
110210
110334
  // CloudRun access types
@@ -110709,6 +110833,58 @@ for await (let x of res.textStream) {
110709
110833
  catch (error) {
110710
110834
  // Ignore cloudbaserc.json creation errors
110711
110835
  }
110836
+ // Send deployment notification to CodeBuddy IDE
110837
+ try {
110838
+ // Query service details to get access URL
110839
+ let serviceUrl = "";
110840
+ try {
110841
+ const serviceDetails = await cloudrunService.detail({ serverName: input.serverName });
110842
+ // Extract access URL from service details
110843
+ // Priority: DefaultDomainName > CustomDomainName > PublicDomain > InternalDomain
110844
+ const details = serviceDetails; // Use any to access dynamic properties
110845
+ if (details?.BaseInfo?.DefaultDomainName) {
110846
+ // DefaultDomainName is already a complete URL (e.g., https://...)
110847
+ serviceUrl = details.BaseInfo.DefaultDomainName;
110848
+ }
110849
+ else if (details?.BaseInfo?.CustomDomainName) {
110850
+ // CustomDomainName might be a domain without protocol
110851
+ const customDomain = details.BaseInfo.CustomDomainName;
110852
+ serviceUrl = customDomain.startsWith('http') ? customDomain : `https://${customDomain}`;
110853
+ }
110854
+ else if (details?.BaseInfo?.PublicDomain) {
110855
+ serviceUrl = `https://${details.BaseInfo.PublicDomain}`;
110856
+ }
110857
+ else if (details?.BaseInfo?.InternalDomain) {
110858
+ serviceUrl = `https://${details.BaseInfo.InternalDomain}`;
110859
+ }
110860
+ else if (details?.AccessInfo?.PublicDomain) {
110861
+ serviceUrl = `https://${details.AccessInfo.PublicDomain}`;
110862
+ }
110863
+ else {
110864
+ serviceUrl = ""; // URL not available
110865
+ }
110866
+ }
110867
+ catch (detailErr) {
110868
+ // If query fails, continue with empty URL
110869
+ serviceUrl = "";
110870
+ }
110871
+ // Extract project name from targetPath
110872
+ const projectName = path_1.default.basename(targetPath);
110873
+ // Build console URL
110874
+ const consoleUrl = `https://tcb.cloud.tencent.com/dev?envId=${currentEnvId}#/platform-run/service/detail?serverName=${input.serverName}&tabId=overview&envId=${currentEnvId}`;
110875
+ // Send notification
110876
+ await (0, notification_js_1.sendDeployNotification)(server, {
110877
+ deployType: 'cloudrun',
110878
+ url: serviceUrl,
110879
+ projectId: currentEnvId,
110880
+ projectName: projectName,
110881
+ consoleUrl: consoleUrl
110882
+ });
110883
+ }
110884
+ catch (notifyErr) {
110885
+ // Notification failure should not affect deployment flow
110886
+ // Error is already logged in sendDeployNotification
110887
+ }
110712
110888
  return {
110713
110889
  content: [
110714
110890
  {
@@ -114885,14 +115061,20 @@ module.exports = function (/*Buffer|null*/ inBuffer, /** object */ options) {
114885
115061
  /***/ }),
114886
115062
 
114887
115063
  /***/ 37279:
114888
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
115064
+ /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
114889
115065
 
114890
115066
  "use strict";
114891
115067
 
115068
+ var __importDefault = (this && this.__importDefault) || function (mod) {
115069
+ return (mod && mod.__esModule) ? mod : { "default": mod };
115070
+ };
114892
115071
  Object.defineProperty(exports, "__esModule", ({ value: true }));
114893
115072
  exports.registerHostingTools = registerHostingTools;
115073
+ const fs_1 = __importDefault(__webpack_require__(29021));
115074
+ const path_1 = __importDefault(__webpack_require__(39902));
114894
115075
  const zod_1 = __webpack_require__(21614);
114895
115076
  const cloudbase_manager_js_1 = __webpack_require__(3431);
115077
+ const notification_js_1 = __webpack_require__(32720);
114896
115078
  function registerHostingTools(server) {
114897
115079
  // 获取 cloudBaseOptions,如果没有则为 undefined
114898
115080
  const cloudBaseOptions = server.cloudBaseOptions;
@@ -114929,6 +115111,43 @@ function registerHostingTools(server) {
114929
115111
  // 获取环境信息
114930
115112
  const envInfo = await cloudbase.env.getEnvInfo();
114931
115113
  const staticDomain = envInfo.EnvInfo?.StaticStorages?.[0]?.StaticDomain;
115114
+ const accessUrl = staticDomain ? `https://${staticDomain}/${cloudPath || ''}` : "";
115115
+ // Send deployment notification to CodeBuddy IDE
115116
+ try {
115117
+ const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
115118
+ // Extract project name from localPath
115119
+ let projectName = "unknown";
115120
+ if (localPath) {
115121
+ try {
115122
+ // If localPath is a file, get parent directory name; if it's a directory, get directory name
115123
+ const stats = fs_1.default.statSync(localPath);
115124
+ if (stats.isFile()) {
115125
+ projectName = path_1.default.basename(path_1.default.dirname(localPath));
115126
+ }
115127
+ else {
115128
+ projectName = path_1.default.basename(localPath);
115129
+ }
115130
+ }
115131
+ catch (statErr) {
115132
+ // If stat fails, try to extract from path directly
115133
+ projectName = path_1.default.basename(localPath);
115134
+ }
115135
+ }
115136
+ // Build console URL
115137
+ const consoleUrl = `https://tcb.cloud.tencent.com/dev?envId=${envId}#/static-hosting`;
115138
+ // Send notification
115139
+ await (0, notification_js_1.sendDeployNotification)(server, {
115140
+ deployType: 'hosting',
115141
+ url: accessUrl,
115142
+ projectId: envId,
115143
+ projectName: projectName,
115144
+ consoleUrl: consoleUrl
115145
+ });
115146
+ }
115147
+ catch (notifyErr) {
115148
+ // Notification failure should not affect deployment flow
115149
+ // Error is already logged in sendDeployNotification
115150
+ }
114932
115151
  return {
114933
115152
  content: [
114934
115153
  {
@@ -114937,7 +115156,7 @@ function registerHostingTools(server) {
114937
115156
  ...result,
114938
115157
  staticDomain,
114939
115158
  message: "文件上传成功",
114940
- accessUrl: staticDomain ? `https://${staticDomain}/${cloudPath || ''}` : "请检查静态托管配置"
115159
+ accessUrl: accessUrl
114941
115160
  }, null, 2)
114942
115161
  }
114943
115162
  ]
@@ -134865,7 +135084,7 @@ class TelemetryReporter {
134865
135084
  const nodeVersion = process.version; // Node.js版本
134866
135085
  const arch = os_1.default.arch(); // 系统架构
134867
135086
  // 从构建时注入的版本号获取MCP版本信息
134868
- const mcpVersion = process.env.npm_package_version || "2.0.6" || 0;
135087
+ const mcpVersion = process.env.npm_package_version || "2.2.0-alpha.0" || 0;
134869
135088
  return {
134870
135089
  userAgent: `${osType} ${osRelease} ${arch} ${nodeVersion} CloudBase-MCP/${mcpVersion}`,
134871
135090
  deviceId: this.deviceId,
@@ -179463,6 +179682,7 @@ exports.sleep = sleep;
179463
179682
  exports.upperCaseStringFisrt = upperCaseStringFisrt;
179464
179683
  exports.upperCaseObjKey = upperCaseObjKey;
179465
179684
  exports.fetchTemplates = fetchTemplates;
179685
+ exports.successLog = successLog;
179466
179686
  const archiver_1 = __importDefault(__webpack_require__(99133));
179467
179687
  const crypto_1 = __importDefault(__webpack_require__(55511));
179468
179688
  const fs_extra_1 = __importDefault(__webpack_require__(21605));
@@ -179741,6 +179961,10 @@ const getCompleteTimeRange = (timeRange) => {
179741
179961
  };
179742
179962
  };
179743
179963
  exports.getCompleteTimeRange = getCompleteTimeRange;
179964
+ function successLog(msg) {
179965
+ // 空格,兼容中文字符编码长度问题
179966
+ console.log(`${msg}`);
179967
+ }
179744
179968
 
179745
179969
 
179746
179970
  /***/ }),
@@ -185531,6 +185755,7 @@ async function registerRagTools(server) {
185531
185755
  }
185532
185756
  });
185533
185757
  let skills = [];
185758
+ let openapis = [];
185534
185759
  // 知识库检索
185535
185760
  try {
185536
185761
  skills = await prepareKnowledgeBaseWebTemplate();
@@ -185540,22 +185765,40 @@ async function registerRagTools(server) {
185540
185765
  error,
185541
185766
  });
185542
185767
  }
185768
+ // OpenAPI 文档准备
185769
+ try {
185770
+ openapis = await prepareOpenAPIDocs();
185771
+ }
185772
+ catch (error) {
185773
+ (0, logger_js_1.warn)("[searchKnowledgeBase] Failed to prepare OpenAPI docs", {
185774
+ error,
185775
+ });
185776
+ }
185543
185777
  server.registerTool?.("searchKnowledgeBase", {
185544
185778
  title: "云开发知识库检索",
185545
- description: `云开发知识库智能检索工具,支持向量查询 (vector) 和固定文档 (doc) 查询。
185779
+ description: `云开发知识库智能检索工具,支持向量查询 (vector)、固定文档 (doc) 和 OpenAPI 文档 (openapi) 查询。
185546
185780
 
185547
- 强烈推荐始终优先使用固定文档 (doc) 模式进行检索,仅当固定文档无法覆盖你的问题时,再使用向量查询 (vector) 模式。
185781
+ 强烈推荐始终优先使用固定文档 (doc) 或 OpenAPI 文档 (openapi) 模式进行检索,仅当固定文档无法覆盖你的问题时,再使用向量查询 (vector) 模式。
185548
185782
 
185549
185783
  固定文档 (doc) 查询当前支持 ${skills.length} 个固定文档,分别是:
185550
185784
  ${skills
185551
185785
  .map((skill) => `文档名:${path.basename(path.dirname(skill.absolutePath))} 文档介绍:${skill.description}`)
185786
+ .join("\n")}
185787
+
185788
+ OpenAPI 文档 (openapi) 查询当前支持 ${openapis.length} 个 API 文档,分别是:
185789
+ ${openapis
185790
+ .map((api) => `API名:${api.name} API介绍:${api.description}`)
185552
185791
  .join("\n")}`,
185553
185792
  inputSchema: {
185554
- mode: zod_1.z.enum(["vector", "doc"]),
185793
+ mode: zod_1.z.enum(["vector", "doc", "openapi"]),
185555
185794
  docName: zod_1.z
185556
185795
  .enum(skills.map((skill) => path.basename(path.dirname(skill.absolutePath))))
185557
185796
  .optional()
185558
185797
  .describe("mode=doc 时指定。文档名称。"),
185798
+ apiName: zod_1.z
185799
+ .enum(openapis.map((api) => api.name))
185800
+ .optional()
185801
+ .describe("mode=openapi 时指定。API 名称。"),
185559
185802
  threshold: zod_1.z
185560
185803
  .number()
185561
185804
  .default(0.5)
@@ -185585,7 +185828,7 @@ async function registerRagTools(server) {
185585
185828
  openWorldHint: true,
185586
185829
  category: "rag",
185587
185830
  },
185588
- }, async ({ id, content, options: { chunkExpand = [3, 3] } = {}, limit = 5, threshold = 0.5, mode, docName, }) => {
185831
+ }, async ({ id, content, options: { chunkExpand = [3, 3] } = {}, limit = 5, threshold = 0.5, mode, docName, apiName, }) => {
185589
185832
  if (mode === "doc") {
185590
185833
  const absolutePath = skills.find((skill) => skill.absolutePath.includes(docName)).absolutePath;
185591
185834
  return {
@@ -185597,6 +185840,27 @@ async function registerRagTools(server) {
185597
185840
  ],
185598
185841
  };
185599
185842
  }
185843
+ if (mode === "openapi") {
185844
+ const api = openapis.find((api) => api.name === apiName);
185845
+ if (!api) {
185846
+ return {
185847
+ content: [
185848
+ {
185849
+ type: "text",
185850
+ text: `OpenAPI document "${apiName}" not found. Available APIs: ${openapis.map((a) => a.name).join(", ")}`,
185851
+ },
185852
+ ],
185853
+ };
185854
+ }
185855
+ return {
185856
+ content: [
185857
+ {
185858
+ type: "text",
185859
+ text: `OpenAPI document: ${api.name}\nDescription: ${api.description}\nPath: ${api.absolutePath}\n\n${(await fs.readFile(api.absolutePath)).toString()}`,
185860
+ },
185861
+ ],
185862
+ };
185863
+ }
185600
185864
  // 枚举到后端 id 映射
185601
185865
  const backendId = KnowledgeBaseIdMap[id] || id;
185602
185866
  const signInRes = await fetch("https://tcb-advanced-a656fc.api.tcloudbasegateway.com/auth/v1/signin/anonymously", {
@@ -185673,6 +185937,65 @@ function extractDescriptionFromFrontMatter(content) {
185673
185937
  .match(/^(?:decsription|description)\s*:\s*(.*)$/m);
185674
185938
  return match ? match[1].trim() : null;
185675
185939
  }
185940
+ // OpenAPI 文档 URL 列表
185941
+ const OPENAPI_SOURCES = [
185942
+ {
185943
+ name: "mysqldb",
185944
+ description: "MySQL RESTful API - 云开发 MySQL 数据库 HTTP API",
185945
+ url: "https://docs.cloudbase.net/openapi/mysqldb.v1.openapi.yaml",
185946
+ },
185947
+ {
185948
+ name: "functions",
185949
+ description: "Cloud Functions API - 云函数 HTTP API",
185950
+ url: "https://docs.cloudbase.net/openapi/functions.v1.openapi.yaml",
185951
+ },
185952
+ {
185953
+ name: "auth",
185954
+ description: "Authentication API - 身份认证 HTTP API",
185955
+ url: "https://docs.cloudbase.net/openapi/auth.v1.openapi.yaml",
185956
+ },
185957
+ {
185958
+ name: "cloudrun",
185959
+ description: "CloudRun API - 云托管服务 HTTP API",
185960
+ url: "https://docs.cloudbase.net/openapi/cloudrun.v1.openapi.yaml",
185961
+ },
185962
+ {
185963
+ name: "storage",
185964
+ description: "Storage API - 云存储 HTTP API",
185965
+ url: "https://docs.cloudbase.net/openapi/storage.v1.openapi.yaml",
185966
+ },
185967
+ ];
185968
+ // 下载并准备 OpenAPI 文档
185969
+ async function prepareOpenAPIDocs() {
185970
+ const baseDir = path.join(os.homedir(), ".cloudbase-mcp", "openapi");
185971
+ await fs.mkdir(baseDir, { recursive: true });
185972
+ const results = [];
185973
+ await Promise.all(OPENAPI_SOURCES.map(async (source) => {
185974
+ try {
185975
+ const response = await fetch(source.url);
185976
+ if (!response.ok) {
185977
+ (0, logger_js_1.warn)(`[prepareOpenAPIDocs] Failed to download ${source.name}`, {
185978
+ status: response.status,
185979
+ });
185980
+ return;
185981
+ }
185982
+ const content = await response.text();
185983
+ const filePath = path.join(baseDir, `${source.name}.openapi.yaml`);
185984
+ await fs.writeFile(filePath, content, "utf8");
185985
+ results.push({
185986
+ name: source.name,
185987
+ description: source.description,
185988
+ absolutePath: filePath,
185989
+ });
185990
+ }
185991
+ catch (error) {
185992
+ (0, logger_js_1.warn)(`[prepareOpenAPIDocs] Failed to download ${source.name}`, {
185993
+ error,
185994
+ });
185995
+ }
185996
+ }));
185997
+ return results;
185998
+ }
185676
185999
  async function collectSkillDescriptions(rootDir) {
185677
186000
  const result = [];
185678
186001
  async function walk(dir) {
@@ -190970,20 +191293,25 @@ function callSuccessCallback(callback, result) {
190970
191293
  /***/ }),
190971
191294
 
190972
191295
  /***/ 65607:
190973
- /***/ ((__unused_webpack_module, exports) => {
191296
+ /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
190974
191297
 
190975
191298
  "use strict";
190976
191299
 
190977
191300
  Object.defineProperty(exports, "__esModule", ({ value: true }));
190978
191301
  exports.CloudBaseContext = void 0;
191302
+ const constant_1 = __webpack_require__(40762);
190979
191303
  class CloudBaseContext {
190980
- constructor({ secretId = '', secretKey = '', token = '', proxy = '', region = '', envType = '' }) {
191304
+ constructor({ secretId = '', secretKey = '', token = '', proxy = '', region = '', envType = '', useInternalEndpoint = undefined }) {
190981
191305
  this.secretId = secretId;
190982
191306
  this.secretKey = secretKey;
190983
191307
  this.token = token;
190984
191308
  this.proxy = proxy;
190985
191309
  this.region = region;
190986
191310
  this.envType = envType;
191311
+ this.useInternalEndpoint = useInternalEndpoint;
191312
+ }
191313
+ isInternalEndpoint() {
191314
+ return this.useInternalEndpoint !== undefined ? this.useInternalEndpoint : constant_1.USE_INTERNAL_ENDPOINT;
190987
191315
  }
190988
191316
  }
190989
191317
  exports.CloudBaseContext = CloudBaseContext;
@@ -200510,7 +200838,7 @@ ${envIdSection}
200510
200838
  ## 环境信息
200511
200839
  - 操作系统: ${os_1.default.type()} ${os_1.default.release()}
200512
200840
  - Node.js版本: ${process.version}
200513
- - MCP 版本:${process.env.npm_package_version || "2.0.6" || 0}
200841
+ - MCP 版本:${process.env.npm_package_version || "2.2.0-alpha.0" || 0}
200514
200842
  - 系统架构: ${os_1.default.arch()}
200515
200843
  - 时间: ${new Date().toISOString()}
200516
200844
  - 请求ID: ${requestId}
@@ -203402,6 +203730,7 @@ class StorageService {
203402
203730
  * 获取 COS 配置
203403
203731
  */
203404
203732
  getCos(parallel = 20) {
203733
+ const internalEndpoint = this.environment.cloudBaseContext.isInternalEndpoint();
203405
203734
  const { secretId, secretKey, token, proxy } = this.environment.getAuthConfig();
203406
203735
  const cosProxy = process.env.TCB_COS_PROXY;
203407
203736
  const cosConfig = {
@@ -203410,14 +203739,14 @@ class StorageService {
203410
203739
  SecretKey: secretKey,
203411
203740
  Proxy: cosProxy || proxy,
203412
203741
  SecurityToken: token,
203413
- Domain: constant_1.USE_INTERNAL_ENDPOINT ? "{Bucket}.cos-internal.{Region}.tencentcos.cn" /* COS_ENDPOINT.INTERNAL */ : "{Bucket}.cos.{Region}.tencentcos.cn" /* COS_ENDPOINT.PUBLIC */,
203742
+ Domain: internalEndpoint ? "{Bucket}.cos-internal.{Region}.tencentcos.cn" /* COS_ENDPOINT.INTERNAL */ : "{Bucket}.cos.{Region}.tencentcos.cn" /* COS_ENDPOINT.PUBLIC */,
203414
203743
  };
203415
203744
  if (constant_1.COS_SDK_PROTOCOL) {
203416
203745
  cosConfig.Protocol = (constant_1.COS_SDK_PROTOCOL.endsWith(':')
203417
203746
  ? constant_1.COS_SDK_PROTOCOL.toLowerCase()
203418
203747
  : constant_1.COS_SDK_PROTOCOL.toLowerCase() + ':');
203419
203748
  }
203420
- if (constant_1.USE_INTERNAL_ENDPOINT) {
203749
+ if (internalEndpoint) {
203421
203750
  cosConfig.Protocol = 'http:';
203422
203751
  }
203423
203752
  // COSSDK 默认开启 KeepAlive,这里提供关闭的方式
@@ -214809,26 +215138,26 @@ const path = __importStar(__webpack_require__(39902));
214809
215138
  const zod_1 = __webpack_require__(21614);
214810
215139
  // CloudBase 模板配置
214811
215140
  const TEMPLATES = {
214812
- "react": {
215141
+ react: {
214813
215142
  description: "React + CloudBase 全栈应用模板",
214814
- url: "https://static.cloudbase.net/cloudbase-examples/web-cloudbase-react-template.zip"
215143
+ url: "https://static.cloudbase.net/cloudbase-examples/web-cloudbase-react-template.zip",
214815
215144
  },
214816
- "vue": {
215145
+ vue: {
214817
215146
  description: "Vue + CloudBase 全栈应用模板",
214818
- url: "https://static.cloudbase.net/cloudbase-examples/web-cloudbase-vue-template.zip"
215147
+ url: "https://static.cloudbase.net/cloudbase-examples/web-cloudbase-vue-template.zip",
214819
215148
  },
214820
- "miniprogram": {
215149
+ miniprogram: {
214821
215150
  description: "微信小程序 + 云开发模板",
214822
- url: "https://static.cloudbase.net/cloudbase-examples/miniprogram-cloudbase-miniprogram-template.zip"
215151
+ url: "https://static.cloudbase.net/cloudbase-examples/miniprogram-cloudbase-miniprogram-template.zip",
214823
215152
  },
214824
- "uniapp": {
215153
+ uniapp: {
214825
215154
  description: "UniApp + CloudBase 跨端应用模板",
214826
- url: "https://static.cloudbase.net/cloudbase-examples/universal-cloudbase-uniapp-template.zip"
215155
+ url: "https://static.cloudbase.net/cloudbase-examples/universal-cloudbase-uniapp-template.zip",
214827
215156
  },
214828
- "rules": {
215157
+ rules: {
214829
215158
  description: "AI编辑器配置模板(包含所有主流编辑器配置)",
214830
- url: "https://static.cloudbase.net/cloudbase-examples/web-cloudbase-project.zip"
214831
- }
215159
+ url: "https://static.cloudbase.net/cloudbase-examples/web-cloudbase-project.zip",
215160
+ },
214832
215161
  };
214833
215162
  // IDE类型枚举
214834
215163
  const IDE_TYPES = [
@@ -214848,22 +215177,13 @@ const IDE_TYPES = [
214848
215177
  "roocode", // RooCode AI编辑器
214849
215178
  "tongyi-lingma", // 通义灵码
214850
215179
  "trae", // Trae AI编辑器
214851
- "vscode" // Visual Studio Code
215180
+ "vscode", // Visual Studio Code
214852
215181
  ];
214853
215182
  // IDE到文件的映射关系
214854
215183
  const IDE_FILE_MAPPINGS = {
214855
- "cursor": [
214856
- ".cursor/rules/cloudbase-rules.mdc",
214857
- ".cursor/mcp.json"
214858
- ],
214859
- "windsurf": [
214860
- ".windsurf/rules/cloudbase-rules.md"
214861
- ],
214862
- "codebuddy": [
214863
- ".rules/cloudbase-rules.md",
214864
- "CODEBUDDY.md",
214865
- ".mcp.json"
214866
- ],
215184
+ cursor: [".cursor/rules/cloudbase-rules.mdc", ".cursor/mcp.json"],
215185
+ windsurf: [".windsurf/rules/cloudbase-rules.md"],
215186
+ codebuddy: [".rules/cloudbase-rules.md", "CODEBUDDY.md", ".mcp.json"],
214867
215187
  "claude-code": [
214868
215188
  "CLAUDE.md",
214869
215189
  ".mcp.json",
@@ -214872,49 +215192,22 @@ const IDE_FILE_MAPPINGS = {
214872
215192
  ".claude/commands/spec.md",
214873
215193
  ".claude/commands/no_spec.md",
214874
215194
  ],
214875
- "cline": [
214876
- ".clinerules/cloudbase-rules.mdc"
214877
- ],
214878
- "gemini-cli": [
214879
- ".gemini/GEMINI.md",
214880
- ".gemini/settings.json"
214881
- ],
214882
- "opencode": [
214883
- ".opencode.json"
214884
- ],
214885
- "qwen-code": [
214886
- ".qwen/QWEN.md",
214887
- ".qwen/settings.json"
214888
- ],
215195
+ cline: [".clinerules/cloudbase-rules.mdc"],
215196
+ "gemini-cli": [".gemini/GEMINI.md", ".gemini/settings.json"],
215197
+ opencode: [".opencode.json"],
215198
+ "qwen-code": [".qwen/QWEN.md", ".qwen/settings.json"],
214889
215199
  "baidu-comate": [
214890
215200
  ".comate/rules/cloudbase-rules.mdr",
214891
215201
  ".comate/rules/cloudbaase-rules.mdr",
214892
- ".comate/mcp.json"
214893
- ],
214894
- "openai-codex-cli": [
214895
- ".codex/config.toml",
214896
- "AGENTS.md",
215202
+ ".comate/mcp.json",
214897
215203
  ],
214898
- "augment-code": [
214899
- ".augment-guidelines"
214900
- ],
214901
- "github-copilot": [
214902
- ".github/copilot-instructions.md"
214903
- ],
214904
- "roocode": [
214905
- ".roo/rules/cloudbaase-rules.md",
214906
- ".roo/mcp.json"
214907
- ],
214908
- "tongyi-lingma": [
214909
- ".lingma/rules/cloudbaase-rules.md"
214910
- ],
214911
- "trae": [
214912
- ".trae/rules/cloudbase-rules.md"
214913
- ],
214914
- "vscode": [
214915
- ".vscode/mcp.json",
214916
- ".vscode/settings.json"
214917
- ]
215204
+ "openai-codex-cli": [".codex/config.toml", "AGENTS.md"],
215205
+ "augment-code": [".augment-guidelines"],
215206
+ "github-copilot": [".github/copilot-instructions.md"],
215207
+ roocode: [".roo/rules/cloudbaase-rules.md", ".roo/mcp.json"],
215208
+ "tongyi-lingma": [".lingma/rules/cloudbaase-rules.md"],
215209
+ trae: [".trae/rules/cloudbase-rules.md"],
215210
+ vscode: [".vscode/mcp.json", ".vscode/settings.json"],
214918
215211
  };
214919
215212
  // 所有IDE配置文件的完整列表 - 通过IDE_FILE_MAPPINGS计算得出
214920
215213
  const ALL_IDE_FILES = Array.from(new Set(Object.values(IDE_FILE_MAPPINGS).flat()));
@@ -214922,51 +215215,87 @@ const ALL_IDE_FILES = Array.from(new Set(Object.values(IDE_FILE_MAPPINGS).flat()
214922
215215
  IDE_FILE_MAPPINGS["all"] = ALL_IDE_FILES;
214923
215216
  // IDE描述映射
214924
215217
  const IDE_DESCRIPTIONS = {
214925
- "all": "所有IDE配置",
214926
- "cursor": "Cursor AI编辑器",
214927
- "windsurf": "WindSurf AI编辑器",
214928
- "codebuddy": "CodeBuddy AI编辑器",
215218
+ all: "所有IDE配置",
215219
+ cursor: "Cursor AI编辑器",
215220
+ windsurf: "WindSurf AI编辑器",
215221
+ codebuddy: "CodeBuddy AI编辑器",
214929
215222
  "claude-code": "Claude Code AI编辑器",
214930
- "cline": "Cline AI编辑器",
215223
+ cline: "Cline AI编辑器",
214931
215224
  "gemini-cli": "Gemini CLI",
214932
- "opencode": "OpenCode AI编辑器",
215225
+ opencode: "OpenCode AI编辑器",
214933
215226
  "qwen-code": "通义灵码",
214934
215227
  "baidu-comate": "百度Comate",
214935
215228
  "openai-codex-cli": "OpenAI Codex CLI",
214936
215229
  "augment-code": "Augment Code",
214937
215230
  "github-copilot": "GitHub Copilot",
214938
- "roocode": "RooCode AI编辑器",
215231
+ roocode: "RooCode AI编辑器",
214939
215232
  "tongyi-lingma": "通义灵码",
214940
- "trae": "Trae AI编辑器",
214941
- "vscode": "Visual Studio Code"
214942
- };
215233
+ trae: "Trae AI编辑器",
215234
+ vscode: "Visual Studio Code",
215235
+ };
215236
+ // INTEGRATION_IDE 环境变量值到 IDE 类型的映射
215237
+ const INTEGRATION_IDE_MAPPING = {
215238
+ Cursor: "cursor",
215239
+ WindSurf: "windsurf",
215240
+ CodeBuddy: "codebuddy",
215241
+ CodeBuddyManual: "codebuddy",
215242
+ CodeBuddyCode: "codebuddy",
215243
+ "Claude Code": "claude-code",
215244
+ CLINE: "cline",
215245
+ "Gemini CLI": "gemini-cli",
215246
+ OpenCode: "opencode",
215247
+ "Qwen Code": "qwen-code",
215248
+ "Baidu Comate": "baidu-comate",
215249
+ "OpenAI Codex CLI": "openai-codex-cli",
215250
+ "Augment Code": "augment-code",
215251
+ "GitHub Copilot": "github-copilot",
215252
+ RooCode: "roocode",
215253
+ "Tongyi Lingma": "tongyi-lingma",
215254
+ Trae: "trae",
215255
+ VSCode: "vscode",
215256
+ };
215257
+ // 根据 INTEGRATION_IDE 环境变量获取默认 IDE 类型
215258
+ function getDefaultIDEFromEnv() {
215259
+ const integrationIDE = process.env.INTEGRATION_IDE;
215260
+ if (integrationIDE) {
215261
+ const mappedIDE = INTEGRATION_IDE_MAPPING[integrationIDE];
215262
+ if (mappedIDE) {
215263
+ return mappedIDE;
215264
+ }
215265
+ }
215266
+ return "all";
215267
+ }
214943
215268
  // 下载文件到临时目录
214944
215269
  async function downloadFile(url, filePath) {
214945
215270
  return new Promise((resolve, reject) => {
214946
- const client = url.startsWith('https:') ? https : http;
214947
- client.get(url, (res) => {
215271
+ const client = url.startsWith("https:") ? https : http;
215272
+ client
215273
+ .get(url, (res) => {
214948
215274
  if (res.statusCode === 200) {
214949
215275
  const file = fs.createWriteStream(filePath);
214950
215276
  res.pipe(file);
214951
- file.on('finish', () => {
215277
+ file.on("finish", () => {
214952
215278
  file.close();
214953
215279
  resolve();
214954
215280
  });
214955
- file.on('error', reject);
215281
+ file.on("error", reject);
214956
215282
  }
214957
215283
  else if (res.statusCode === 302 || res.statusCode === 301) {
214958
215284
  // 处理重定向
214959
215285
  if (res.headers.location) {
214960
- downloadFile(res.headers.location, filePath).then(resolve).catch(reject);
215286
+ downloadFile(res.headers.location, filePath)
215287
+ .then(resolve)
215288
+ .catch(reject);
214961
215289
  }
214962
215290
  else {
214963
- reject(new Error('重定向但没有location header'));
215291
+ reject(new Error("重定向但没有location header"));
214964
215292
  }
214965
215293
  }
214966
215294
  else {
214967
215295
  reject(new Error(`下载失败,状态码: ${res.statusCode}`));
214968
215296
  }
214969
- }).on('error', reject);
215297
+ })
215298
+ .on("error", reject);
214970
215299
  });
214971
215300
  }
214972
215301
  // 解压ZIP文件
@@ -214979,7 +215308,7 @@ async function extractZip(zipPath, extractPath) {
214979
215308
  zip.extractAllTo(extractPath, true);
214980
215309
  }
214981
215310
  catch (error) {
214982
- throw new Error(`解压失败: ${error instanceof Error ? error.message : '未知错误'}`);
215311
+ throw new Error(`解压失败: ${error instanceof Error ? error.message : "未知错误"}`);
214983
215312
  }
214984
215313
  }
214985
215314
  // 获取目录下所有文件的相对路径列表
@@ -215003,7 +215332,7 @@ async function copyFileIfNotExists(src, dest) {
215003
215332
  try {
215004
215333
  // 检查目标文件是否存在
215005
215334
  if (fs.existsSync(dest)) {
215006
- return { copied: false, reason: '文件已存在' };
215335
+ return { copied: false, reason: "文件已存在" };
215007
215336
  }
215008
215337
  // 创建目标目录
215009
215338
  await fsPromises.mkdir(path.dirname(dest), { recursive: true });
@@ -215012,14 +215341,17 @@ async function copyFileIfNotExists(src, dest) {
215012
215341
  return { copied: true };
215013
215342
  }
215014
215343
  catch (error) {
215015
- return { copied: false, reason: `复制失败: ${error instanceof Error ? error.message : '未知错误'}` };
215344
+ return {
215345
+ copied: false,
215346
+ reason: `复制失败: ${error instanceof Error ? error.message : "未知错误"}`,
215347
+ };
215016
215348
  }
215017
215349
  }
215018
215350
  // 复制文件,支持覆盖模式
215019
215351
  // 判断是否应该跳过 README.md 文件
215020
215352
  function shouldSkipReadme(template, destPath, overwrite) {
215021
- const isReadme = path.basename(destPath).toLowerCase() === 'readme.md';
215022
- const isRulesTemplate = template === 'rules';
215353
+ const isReadme = path.basename(destPath).toLowerCase() === "readme.md";
215354
+ const isRulesTemplate = template === "rules";
215023
215355
  const exists = fs.existsSync(destPath);
215024
215356
  return isReadme && isRulesTemplate && exists && !overwrite;
215025
215357
  }
@@ -215028,11 +215360,15 @@ async function copyFile(src, dest, overwrite = false, template) {
215028
215360
  const destExists = fs.existsSync(dest);
215029
215361
  // 检查是否需要跳过 README.md 文件(仅对 rules 模板)
215030
215362
  if (template && shouldSkipReadme(template, dest, overwrite)) {
215031
- return { copied: false, reason: 'README.md 文件已存在,已保护', action: 'protected' };
215363
+ return {
215364
+ copied: false,
215365
+ reason: "README.md 文件已存在,已保护",
215366
+ action: "protected",
215367
+ };
215032
215368
  }
215033
215369
  // 如果目标文件存在且不允许覆盖
215034
215370
  if (destExists && !overwrite) {
215035
- return { copied: false, reason: '文件已存在', action: 'skipped' };
215371
+ return { copied: false, reason: "文件已存在", action: "skipped" };
215036
215372
  }
215037
215373
  // 创建目标目录
215038
215374
  await fsPromises.mkdir(path.dirname(dest), { recursive: true });
@@ -215040,11 +215376,14 @@ async function copyFile(src, dest, overwrite = false, template) {
215040
215376
  await fsPromises.copyFile(src, dest);
215041
215377
  return {
215042
215378
  copied: true,
215043
- action: destExists ? 'overwritten' : 'created'
215379
+ action: destExists ? "overwritten" : "created",
215044
215380
  };
215045
215381
  }
215046
215382
  catch (error) {
215047
- return { copied: false, reason: `复制失败: ${error instanceof Error ? error.message : '未知错误'}` };
215383
+ return {
215384
+ copied: false,
215385
+ reason: `复制失败: ${error instanceof Error ? error.message : "未知错误"}`,
215386
+ };
215048
215387
  }
215049
215388
  }
215050
215389
  // IDE验证函数
@@ -215052,13 +215391,13 @@ function validateIDE(ide) {
215052
215391
  if (ide === "all") {
215053
215392
  return { valid: true };
215054
215393
  }
215055
- const supportedIDEs = IDE_TYPES.filter(type => type !== "all");
215394
+ const supportedIDEs = IDE_TYPES.filter((type) => type !== "all");
215056
215395
  const isValid = supportedIDEs.includes(ide);
215057
215396
  if (!isValid) {
215058
215397
  return {
215059
215398
  valid: false,
215060
215399
  error: `不支持的IDE类型: ${ide}`,
215061
- supportedIDEs: supportedIDEs
215400
+ supportedIDEs: supportedIDEs,
215062
215401
  };
215063
215402
  }
215064
215403
  return { valid: true };
@@ -215073,9 +215412,9 @@ function filterFilesByIDE(files, ide) {
215073
215412
  return files; // 如果找不到映射,返回所有文件
215074
215413
  }
215075
215414
  // 计算需要排除的IDE文件(除了当前IDE需要的文件)
215076
- const filesToExclude = ALL_IDE_FILES.filter(file => !ideFiles.includes(file));
215415
+ const filesToExclude = ALL_IDE_FILES.filter((file) => !ideFiles.includes(file));
215077
215416
  // 排除不需要的IDE配置文件,保留其他所有文件
215078
- return files.filter(file => !filesToExclude.includes(file));
215417
+ return files.filter((file) => !filesToExclude.includes(file));
215079
215418
  }
215080
215419
  // 创建过滤后的目录结构
215081
215420
  async function createFilteredDirectory(extractDir, filteredFiles, ide) {
@@ -215083,7 +215422,7 @@ async function createFilteredDirectory(extractDir, filteredFiles, ide) {
215083
215422
  return extractDir; // 如果选择所有IDE,直接返回原目录
215084
215423
  }
215085
215424
  // 创建新的过滤后目录
215086
- const filteredDir = path.join(path.dirname(extractDir), 'filtered');
215425
+ const filteredDir = path.join(path.dirname(extractDir), "filtered");
215087
215426
  await fsPromises.mkdir(filteredDir, { recursive: true });
215088
215427
  // 只复制过滤后的文件到新目录
215089
215428
  for (const relativePath of filteredFiles) {
@@ -215102,32 +215441,42 @@ function registerSetupTools(server) {
215102
215441
  title: "下载项目模板",
215103
215442
  description: `自动下载并部署CloudBase项目模板。⚠️ **MANDATORY FOR NEW PROJECTS** ⚠️
215104
215443
 
215105
- **CRITICAL**: This tool MUST be called FIRST when starting a new project.\n\n支持的模板:\n- react: React + CloudBase 全栈应用模板\n- vue: Vue + CloudBase 全栈应用模板\n- miniprogram: 微信小程序 + 云开发模板 \n- uniapp: UniApp + CloudBase 跨端应用模板\n- rules: 只包含AI编辑器配置文件(包含Cursor、WindSurf、CodeBuddy等所有主流编辑器配置),适合在已有项目中补充AI编辑器配置\n\n支持的IDE类型:\n- all: 下载所有IDE配置(默认)\n- cursor: Cursor AI编辑器\n- windsurf: WindSurf AI编辑器\n- codebuddy: CodeBuddy AI编辑器\n- claude-code: Claude Code AI编辑器\n- cline: Cline AI编辑器\n- gemini-cli: Gemini CLI\n- opencode: OpenCode AI编辑器\n- qwen-code: 通义灵码\n- baidu-comate: 百度Comate\n- openai-codex-cli: OpenAI Codex CLI\n- augment-code: Augment Code\n- github-copilot: GitHub Copilot\n- roocode: RooCode AI编辑器\n- tongyi-lingma: 通义灵码\n- trae: Trae AI编辑器\n- vscode: Visual Studio Code\n\n特别说明:\n- rules 模板会自动包含当前 mcp 版本号信息(版本号:${ true ? "2.0.6" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
215444
+ **CRITICAL**: This tool MUST be called FIRST when starting a new project.\n\n支持的模板:\n- react: React + CloudBase 全栈应用模板\n- vue: Vue + CloudBase 全栈应用模板\n- miniprogram: 微信小程序 + 云开发模板 \n- uniapp: UniApp + CloudBase 跨端应用模板\n- rules: 只包含AI编辑器配置文件(包含Cursor、WindSurf、CodeBuddy等所有主流编辑器配置),适合在已有项目中补充AI编辑器配置\n\n支持的IDE类型:\n- all: 下载所有IDE配置(默认)\n- cursor: Cursor AI编辑器\n- windsurf: WindSurf AI编辑器\n- codebuddy: CodeBuddy AI编辑器\n- claude-code: Claude Code AI编辑器\n- cline: Cline AI编辑器\n- gemini-cli: Gemini CLI\n- opencode: OpenCode AI编辑器\n- qwen-code: 通义灵码\n- baidu-comate: 百度Comate\n- openai-codex-cli: OpenAI Codex CLI\n- augment-code: Augment Code\n- github-copilot: GitHub Copilot\n- roocode: RooCode AI编辑器\n- tongyi-lingma: 通义灵码\n- trae: Trae AI编辑器\n- vscode: Visual Studio Code\n\n特别说明:\n- rules 模板会自动包含当前 mcp 版本号信息(版本号:${ true ? "2.2.0-alpha.0" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
215106
215445
  inputSchema: {
215107
- template: zod_1.z.enum(["react", "vue", "miniprogram", "uniapp", "rules"]).describe("要下载的模板类型"),
215108
- ide: zod_1.z.enum(IDE_TYPES).optional().default("all").describe("指定要下载的IDE类型,默认为all(下载所有IDE配置)"),
215109
- overwrite: zod_1.z.boolean().optional().describe("是否覆盖已存在的文件,默认为false(不覆盖)")
215446
+ template: zod_1.z
215447
+ .enum(["react", "vue", "miniprogram", "uniapp", "rules"])
215448
+ .describe("要下载的模板类型"),
215449
+ ide: zod_1.z
215450
+ .enum(IDE_TYPES)
215451
+ .optional()
215452
+ .describe("指定要下载的IDE类型。如果未指定,会根据 INTEGRATION_IDE 环境变量自动选择对应的IDE配置;如果环境变量也未设置,则默认下载所有IDE配置"),
215453
+ overwrite: zod_1.z
215454
+ .boolean()
215455
+ .optional()
215456
+ .describe("是否覆盖已存在的文件,默认为false(不覆盖)"),
215110
215457
  },
215111
215458
  annotations: {
215112
215459
  readOnlyHint: false,
215113
215460
  destructiveHint: false,
215114
215461
  idempotentHint: false,
215115
215462
  openWorldHint: true,
215116
- category: "setup"
215117
- }
215118
- }, async ({ template, ide = "all", overwrite = false }) => {
215463
+ category: "setup",
215464
+ },
215465
+ }, async ({ template, ide, overwrite = false, }) => {
215119
215466
  try {
215467
+ // 如果没有传入 ide 参数,根据 INTEGRATION_IDE 环境变量获取默认值
215468
+ const resolvedIDE = ide ?? getDefaultIDEFromEnv();
215120
215469
  // 验证IDE类型
215121
- const ideValidation = validateIDE(ide);
215470
+ const ideValidation = validateIDE(resolvedIDE);
215122
215471
  if (!ideValidation.valid) {
215123
- const supportedIDEs = ideValidation.supportedIDEs?.join(', ') || '';
215472
+ const supportedIDEs = ideValidation.supportedIDEs?.join(", ") || "";
215124
215473
  return {
215125
215474
  content: [
215126
215475
  {
215127
215476
  type: "text",
215128
- text: `❌ ${ideValidation.error}\n\n支持的IDE类型: ${supportedIDEs}`
215129
- }
215130
- ]
215477
+ text: `❌ ${ideValidation.error}\n\n支持的IDE类型: ${supportedIDEs}`,
215478
+ },
215479
+ ],
215131
215480
  };
215132
215481
  }
215133
215482
  const templateConfig = TEMPLATES[template];
@@ -215136,23 +215485,23 @@ function registerSetupTools(server) {
215136
215485
  content: [
215137
215486
  {
215138
215487
  type: "text",
215139
- text: `❌ 不支持的模板类型: ${template}`
215140
- }
215141
- ]
215488
+ text: `❌ 不支持的模板类型: ${template}`,
215489
+ },
215490
+ ],
215142
215491
  };
215143
215492
  }
215144
215493
  // 创建临时目录
215145
- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'cloudbase-template-'));
215146
- const zipPath = path.join(tempDir, 'template.zip');
215147
- const extractDir = path.join(tempDir, 'extracted');
215494
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "cloudbase-template-"));
215495
+ const zipPath = path.join(tempDir, "template.zip");
215496
+ const extractDir = path.join(tempDir, "extracted");
215148
215497
  // 下载和解压
215149
215498
  await downloadFile(templateConfig.url, zipPath);
215150
215499
  await extractZip(zipPath, extractDir);
215151
215500
  const extractedFiles = await getAllFiles(extractDir);
215152
215501
  // 根据IDE类型过滤文件
215153
- const filteredFiles = filterFilesByIDE(extractedFiles, ide);
215502
+ const filteredFiles = filterFilesByIDE(extractedFiles, resolvedIDE);
215154
215503
  // 创建过滤后的目录结构(当选择特定IDE时)
215155
- const workingDir = await createFilteredDirectory(extractDir, filteredFiles, ide);
215504
+ const workingDir = await createFilteredDirectory(extractDir, filteredFiles, resolvedIDE);
215156
215505
  // 检查是否需要复制到项目目录
215157
215506
  const workspaceFolder = process.env.WORKSPACE_FOLDER_PATHS || process.cwd();
215158
215507
  let finalFiles = [];
@@ -215167,7 +215516,7 @@ function registerSetupTools(server) {
215167
215516
  const destPath = path.join(workspaceFolder, relativePath);
215168
215517
  const copyResult = await copyFile(srcPath, destPath, overwrite, template);
215169
215518
  if (copyResult.copied) {
215170
- if (copyResult.action === 'overwritten') {
215519
+ if (copyResult.action === "overwritten") {
215171
215520
  overwrittenCount++;
215172
215521
  }
215173
215522
  else {
@@ -215176,7 +215525,7 @@ function registerSetupTools(server) {
215176
215525
  finalFiles.push(destPath);
215177
215526
  }
215178
215527
  else {
215179
- if (copyResult.action === 'protected') {
215528
+ if (copyResult.action === "protected") {
215180
215529
  protectedCount++;
215181
215530
  }
215182
215531
  else {
@@ -215186,11 +215535,11 @@ function registerSetupTools(server) {
215186
215535
  }
215187
215536
  }
215188
215537
  // 添加IDE过滤信息
215189
- const ideInfo = IDE_DESCRIPTIONS[ide] || ide;
215538
+ const ideInfo = IDE_DESCRIPTIONS[resolvedIDE] || resolvedIDE;
215190
215539
  results.push(`✅ ${templateConfig.description} (${ideInfo}) 同步完成`);
215191
215540
  results.push(`📁 临时目录: ${workingDir}`);
215192
215541
  results.push(`🔍 文件过滤: ${extractedFiles.length} → ${filteredFiles.length} 个文件`);
215193
- if (ide !== "all") {
215542
+ if (resolvedIDE !== "all") {
215194
215543
  results.push(`✨ 已过滤IDE配置,仅保留 ${ideInfo} 相关文件`);
215195
215544
  }
215196
215545
  const stats = [];
@@ -215203,36 +215552,36 @@ function registerSetupTools(server) {
215203
215552
  if (skippedCount > 0)
215204
215553
  stats.push(`跳过 ${skippedCount} 个已存在文件`);
215205
215554
  if (stats.length > 0) {
215206
- results.push(`📊 ${stats.join('')}`);
215555
+ results.push(`📊 ${stats.join("")}`);
215207
215556
  }
215208
215557
  if (overwrite || overwrittenCount > 0 || skippedCount > 0) {
215209
- results.push(`🔄 覆盖模式: ${overwrite ? '启用' : '禁用'}`);
215558
+ results.push(`🔄 覆盖模式: ${overwrite ? "启用" : "禁用"}`);
215210
215559
  }
215211
215560
  }
215212
215561
  else {
215213
- finalFiles = filteredFiles.map(relativePath => path.join(workingDir, relativePath));
215214
- const ideInfo = IDE_DESCRIPTIONS[ide] || ide;
215562
+ finalFiles = filteredFiles.map((relativePath) => path.join(workingDir, relativePath));
215563
+ const ideInfo = IDE_DESCRIPTIONS[resolvedIDE] || resolvedIDE;
215215
215564
  results.push(`✅ ${templateConfig.description} (${ideInfo}) 下载完成`);
215216
215565
  results.push(`📁 保存在临时目录: ${workingDir}`);
215217
215566
  results.push(`🔍 文件过滤: ${extractedFiles.length} → ${filteredFiles.length} 个文件`);
215218
- if (ide !== "all") {
215567
+ if (resolvedIDE !== "all") {
215219
215568
  results.push(`✨ 已过滤IDE配置,仅保留 ${ideInfo} 相关文件`);
215220
215569
  }
215221
- results.push('💡 如需将模板(包括隐藏文件)复制到项目目录,请确保复制时包含所有隐藏文件。');
215570
+ results.push("💡 如需将模板(包括隐藏文件)复制到项目目录,请确保复制时包含所有隐藏文件。");
215222
215571
  }
215223
215572
  // 文件路径列表
215224
- results.push('');
215225
- results.push('📋 文件列表:');
215226
- finalFiles.forEach(filePath => {
215573
+ results.push("");
215574
+ results.push("📋 文件列表:");
215575
+ finalFiles.forEach((filePath) => {
215227
215576
  results.push(`${filePath}`);
215228
215577
  });
215229
215578
  return {
215230
215579
  content: [
215231
215580
  {
215232
215581
  type: "text",
215233
- text: results.join('\n')
215234
- }
215235
- ]
215582
+ text: results.join("\n"),
215583
+ },
215584
+ ],
215236
215585
  };
215237
215586
  }
215238
215587
  catch (error) {
@@ -215240,9 +215589,9 @@ function registerSetupTools(server) {
215240
215589
  content: [
215241
215590
  {
215242
215591
  type: "text",
215243
- text: `❌ 下载模板失败: ${error instanceof Error ? error.message : '未知错误'}`
215244
- }
215245
- ]
215592
+ text: `❌ 下载模板失败: ${error instanceof Error ? error.message : "未知错误"}`,
215593
+ },
215594
+ ],
215246
215595
  };
215247
215596
  }
215248
215597
  });
@@ -226148,6 +226497,7 @@ class CloudService {
226148
226497
  this.cloudBaseContext = context;
226149
226498
  }
226150
226499
  get baseUrl() {
226500
+ const internalEndpoint = this.cloudBaseContext.isInternalEndpoint();
226151
226501
  const tcb = process.env.TCB_BASE_URL || 'https://tcb.tencentcloudapi.com';
226152
226502
  const urlMap = {
226153
226503
  tcb,
@@ -226161,7 +226511,7 @@ class CloudService {
226161
226511
  const intranetUrlMap = Object.keys(urlMap).map((service) => ({
226162
226512
  [service]: `https://${service}.internal.tencentcloudapi.com`,
226163
226513
  })).reduce((acc, cur) => (Object.assign(Object.assign({}, acc), cur)), {});
226164
- if (constant_1.USE_INTERNAL_ENDPOINT) {
226514
+ if (internalEndpoint) {
226165
226515
  return intranetUrlMap[this.service];
226166
226516
  }
226167
226517
  if (urlMap[this.service]) {
@@ -269794,7 +270144,7 @@ class CloudBase {
269794
270144
  }
269795
270145
  constructor(config = {}) {
269796
270146
  this.cloudBaseConfig = {};
269797
- let { secretId, secretKey, token, envId, proxy, region, envType } = config;
270147
+ let { secretId, secretKey, token, envId, proxy, region, envType, useInternalEndpoint } = config;
269798
270148
  // config 中传入的 secretId secretkey 必须同时存在
269799
270149
  if ((secretId && !secretKey) || (!secretId && secretKey)) {
269800
270150
  throw new Error('secretId and secretKey must be a pair');
@@ -269806,7 +270156,8 @@ class CloudBase {
269806
270156
  envId,
269807
270157
  envType,
269808
270158
  proxy,
269809
- region
270159
+ region,
270160
+ useInternalEndpoint
269810
270161
  };
269811
270162
  // 初始化 context
269812
270163
  this.context = new context_1.CloudBaseContext(this.cloudBaseConfig);
@@ -269861,6 +270212,9 @@ class CloudBase {
269861
270212
  getManagerConfig() {
269862
270213
  return this.cloudBaseConfig;
269863
270214
  }
270215
+ get isInternalEndpoint() {
270216
+ return this.context.isInternalEndpoint();
270217
+ }
269864
270218
  }
269865
270219
  module.exports = CloudBase;
269866
270220
 
@@ -271939,6 +272293,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
271939
272293
  exports.FunctionService = void 0;
271940
272294
  const fs_1 = __importDefault(__webpack_require__(29021));
271941
272295
  const path_1 = __importDefault(__webpack_require__(39902));
272296
+ const lodash_1 = __importDefault(__webpack_require__(2543));
271942
272297
  const packer_1 = __webpack_require__(5147);
271943
272298
  const error_1 = __webpack_require__(40430);
271944
272299
  const utils_1 = __webpack_require__(62358);
@@ -272185,20 +272540,96 @@ class FunctionService {
272185
272540
  });
272186
272541
  return data;
272187
272542
  }
272543
+ /**
272544
+ * 列出所有函数
272545
+ * @param {IListFunctionOptions} options
272546
+ * @returns {Promise<Record<string, string>[]>}
272547
+ */
272548
+ async listAllFunctions(options) {
272549
+ const allFunctions = [];
272550
+ let currentOffset = 0;
272551
+ const pageSize = 20;
272552
+ const { envId } = options;
272553
+ while (true) {
272554
+ try {
272555
+ const res = await this.scfService.request('ListFunctions', {
272556
+ Namespace: envId,
272557
+ Limit: pageSize,
272558
+ Offset: currentOffset
272559
+ });
272560
+ const { Functions = [], TotalCount } = res;
272561
+ if (Functions.length === 0) {
272562
+ break;
272563
+ }
272564
+ allFunctions.push(...Functions);
272565
+ // 检查是否已获取所有函数
272566
+ if (allFunctions.length >= TotalCount || Functions.length < pageSize) {
272567
+ break;
272568
+ }
272569
+ currentOffset += pageSize;
272570
+ }
272571
+ catch (error) {
272572
+ throw new error_1.CloudBaseError(`获取函数列表失败: ${error.message}`);
272573
+ }
272574
+ }
272575
+ // 格式化数据
272576
+ const data = [];
272577
+ allFunctions.forEach(func => {
272578
+ const { FunctionId, FunctionName, Runtime, AddTime, ModTime, Status } = func;
272579
+ data.push({
272580
+ FunctionId,
272581
+ FunctionName,
272582
+ Runtime,
272583
+ AddTime,
272584
+ ModTime,
272585
+ Status
272586
+ });
272587
+ });
272588
+ return data;
272589
+ }
272188
272590
  /**
272189
272591
  * 删除云函数
272190
272592
  * @param {string} name 云函数名称
272191
272593
  * @param {string} qualifier 需要删除的版本号,不填默认删除函数下全部版本。
272192
272594
  * @returns {Promise<IResponseInfo>}
272193
272595
  */
272194
- async deleteFunction(name, qualifier) {
272596
+ async deleteFunction({ name }) {
272597
+ var _a;
272195
272598
  const { namespace } = this.getFunctionConfig();
272196
- return this.scfService.request('DeleteFunction', {
272599
+ // 检测是否绑定了 API 网关
272600
+ const accessService = this.environment.getAccessService();
272601
+ const res = await accessService.getAccessList({
272602
+ name
272603
+ });
272604
+ // 删除绑定的 API 网关
272605
+ if (((_a = res === null || res === void 0 ? void 0 : res.APISet) === null || _a === void 0 ? void 0 : _a.length) > 0) {
272606
+ await accessService.deleteAccess({
272607
+ name
272608
+ });
272609
+ }
272610
+ await this.scfService.request('DeleteFunction', {
272197
272611
  FunctionName: name,
272198
- Namespace: namespace,
272199
- Qualifier: qualifier
272612
+ Namespace: namespace
272200
272613
  });
272201
272614
  }
272615
+ /**
272616
+ * 批量删除云函数
272617
+ * @param {Object} options
272618
+ * @param {string[]} options.names 云函数名称列表
272619
+ * @returns {Promise<void>}
272620
+ */
272621
+ async batchDeleteFunctions({ names }) {
272622
+ const promises = names.map(name => (async () => {
272623
+ try {
272624
+ await this.deleteFunction({ name });
272625
+ (0, utils_1.successLog)(`[${name}] 函数删除成功!`);
272626
+ }
272627
+ catch (e) {
272628
+ throw new error_1.CloudBaseError(e.message);
272629
+ }
272630
+ })());
272631
+ await Promise.all(promises);
272632
+ }
272202
272633
  /**
272203
272634
  * 获取云函数详细信息
272204
272635
  * @param {string} name 云函数名称
@@ -272233,13 +272664,35 @@ class FunctionService {
272233
272664
  }
272234
272665
  catch (e) {
272235
272666
  data.VpcConfig = {
272236
- vpc: '',
272237
- subnet: ''
272667
+ vpc: 'VpcId',
272668
+ subnet: 'SubnetId'
272238
272669
  };
272239
272670
  }
272240
272671
  }
272241
272672
  return data;
272242
272673
  }
272674
+ /**
272675
+ * 批量获取云函数详细信息
272676
+ * @param {Object} options
272677
+ * @param {string[]} options.names 云函数名称列表
272678
+ * @param {string} options.envId 环境 ID
272679
+ * @param {string} options.codeSecret
272680
+ * @returns {Promise<IFunctionInfo[]>}
272681
+ */
272682
+ async batchGetFunctionsDetail({ names, envId, codeSecret }) {
272683
+ const data = [];
272684
+ const promises = names.map(name => (async () => {
272685
+ try {
272686
+ const info = await this.getFunctionDetail(name, codeSecret);
272687
+ data.push(info);
272688
+ }
272689
+ catch (e) {
272690
+ throw new error_1.CloudBaseError(`${name} 获取信息失败:${e.message}`);
272691
+ }
272692
+ })());
272693
+ await Promise.all(promises);
272694
+ return data;
272695
+ }
272243
272696
  /**
272244
272697
  * 获取函数日志
272245
272698
  * @deprecated 请使用 getFunctionLogsV2 代替
@@ -272336,6 +272789,33 @@ class FunctionService {
272336
272789
  const res = await this.tcbService.request('GetFunctionLogDetail', params);
272337
272790
  return res;
272338
272791
  }
272792
+ /**
272793
+ * 获取函数的完整调用日志
272794
+ * 该方法会自动完成两步操作:1. 获取日志请求ID列表。 2. 根据ID列表获取每条日志的详细内容。
272795
+ * @param {IFunctionLogOptionsV2} options - 查询选项
272796
+ * @returns {Promise<IFunctionLogDetailRes[]>} 返回包含完整日志详情的数组
272797
+ */
272798
+ async getCompleteFunctionLogs(options) {
272799
+ // 调用 getFunctionLogsV2 获取日志请求ID列表
272800
+ const { name } = options;
272801
+ const logs = await this.getFunctionLogsV2(options);
272802
+ // 如果没有日志,直接返回空数组
272803
+ if (logs.LogList.length === 0) {
272804
+ return [];
272805
+ }
272806
+ const detailPromises = logs.LogList.map(async (log) => {
272807
+ // 对每一个日志ID,调用 getFunctionLogDetail
272808
+ const res = await this.getFunctionLogDetail({
272809
+ logRequestId: log.RequestId,
272810
+ startTime: options.startTime,
272811
+ endTime: options.endTime
272812
+ });
272813
+ return Object.assign(Object.assign({}, res), { RetCode: log.RetCode, FunctionName: name });
272814
+ });
272815
+ // 并发执行所有详情查询,等待它们全部完成
272816
+ const detailedLogs = await Promise.all(detailPromises);
272817
+ return detailedLogs;
272818
+ }
272339
272819
  /**
272340
272820
  * 更新云函数配置
272341
272821
  * @param {ICloudFunction} func 云函数配置
@@ -272471,6 +272951,28 @@ class FunctionService {
272471
272951
  throw new error_1.CloudBaseError(`[${name}] 调用失败:\n${e.message}`);
272472
272952
  }
272473
272953
  }
272954
+ /**
272955
+ * 批量调用云函数
272956
+ * @param {IFunctionBatchOptions} options
272957
+ * @returns {Promise<IFunctionInvokeRes[]>}
272958
+ */
272959
+ async batchInvokeFunctions(options) {
272960
+ const { functions, envId, log = false } = options;
272961
+ const promises = functions.map(func => (async () => {
272962
+ try {
272963
+ const result = await this.invokeFunction(func.name, func.params);
272964
+ if (log) {
272965
+ (0, utils_1.successLog)(`[${func.name}] 调用成功\n响应结果:\n`);
272966
+ console.log(result);
272967
+ }
272968
+ return result;
272969
+ }
272970
+ catch (e) {
272971
+ throw new error_1.CloudBaseError(`${func.name} 函数调用失败:${e.message}`);
272972
+ }
272973
+ })());
272974
+ return Promise.all(promises);
272975
+ }
272474
272976
  /**
272475
272977
  * 复制云函数
272476
272978
  * @param {string} name 云函数名称
@@ -272513,12 +273015,34 @@ class FunctionService {
272513
273015
  TriggerDesc: item.config
272514
273016
  };
272515
273017
  });
272516
- return this.scfService.request('BatchCreateTrigger', {
272517
- FunctionName: name,
272518
- Namespace: namespace,
272519
- Triggers: JSON.stringify(parsedTriggers),
272520
- Count: parsedTriggers.length
272521
- });
273018
+ try {
273019
+ return await this.scfService.request('BatchCreateTrigger', {
273020
+ FunctionName: name,
273021
+ Namespace: namespace,
273022
+ Triggers: JSON.stringify(parsedTriggers),
273023
+ Count: parsedTriggers.length
273024
+ });
273025
+ }
273026
+ catch (e) {
273027
+ throw new error_1.CloudBaseError(`[${name}] 创建触发器失败:${e.message}`, {
273028
+ action: e.action,
273029
+ code: e.code
273030
+ });
273031
+ }
273032
+ }
273033
+ // 批量部署函数触发器
273034
+ async batchCreateTriggers(options) {
273035
+ const { functions, envId } = options;
273036
+ const promises = functions.map(func => (async () => {
273037
+ try {
273038
+ await this.createFunctionTriggers(func.name, func.triggers);
273039
+ (0, utils_1.successLog)(`[${func.name}] 创建云函数触发器成功!`);
273040
+ }
273041
+ catch (e) {
273042
+ throw new error_1.CloudBaseError(e.message);
273043
+ }
273044
+ })());
273045
+ await Promise.all(promises);
272522
273046
  }
272523
273047
  /**
272524
273048
  * 删除云函数触发器
@@ -272528,12 +273052,50 @@ class FunctionService {
272528
273052
  */
272529
273053
  async deleteFunctionTrigger(name, triggerName) {
272530
273054
  const { namespace } = this.getFunctionConfig();
272531
- return this.scfService.request('DeleteTrigger', {
272532
- FunctionName: name,
272533
- Namespace: namespace,
272534
- TriggerName: triggerName,
272535
- Type: 'timer'
273055
+ try {
273056
+ await this.scfService.request('DeleteTrigger', {
273057
+ FunctionName: name,
273058
+ Namespace: namespace,
273059
+ TriggerName: triggerName,
273060
+ Type: 'timer'
273061
+ });
273062
+ (0, utils_1.successLog)(`[${name}] 删除云函数触发器 ${triggerName} 成功!`);
273063
+ }
273064
+ catch (e) {
273065
+ throw new error_1.CloudBaseError(`[${name}] 删除触发器失败:${e.message}`);
273066
+ }
273067
+ }
273068
+ async batchDeleteTriggers(options) {
273069
+ const { functions, envId } = options;
273070
+ const promises = functions.map(func => (async () => {
273071
+ try {
273072
+ func.triggers.forEach(async (trigger) => {
273073
+ await this.deleteFunctionTrigger(func.name, trigger.name);
273074
+ });
273075
+ }
273076
+ catch (e) {
273077
+ throw new error_1.CloudBaseError(e.message);
273078
+ }
273079
+ })());
273080
+ await Promise.all(promises);
273081
+ }
273082
+ /**
273083
+ * 下载云函数代码
273084
+ * @param {IFunctionCodeOptions} options
273085
+ * @returns {Promise<void>}
273086
+ */
273087
+ async downloadFunctionCode(options) {
273088
+ const { destPath, envId, functionName, codeSecret } = options;
273089
+ // 检验路径是否存在
273090
+ (0, utils_1.checkFullAccess)(destPath, true);
273091
+ // 获取下载链接
273092
+ const { Url } = await this.scfService.request('GetFunctionAddress', {
273093
+ FunctionName: functionName,
273094
+ Namespace: envId,
273095
+ CodeSecret: codeSecret
272536
273096
  });
273097
+ // 下载文件
273098
+ return (0, utils_1.downloadAndExtractRemoteZip)(Url, destPath);
272537
273099
  }
272538
273100
  /**
272539
273101
  * 获取云函数代码下载 链接
@@ -272559,6 +273121,68 @@ class FunctionService {
272559
273121
  throw new error_1.CloudBaseError(`[${functionName}] 获取函数代码下载链接失败:\n${e.message}`);
272560
273122
  }
272561
273123
  }
273124
+ // 函数绑定文件层
273125
+ async attachLayer(options) {
273126
+ const { envId, functionName, layerName, layerVersion, codeSecret } = options;
273127
+ let { Layers = [] } = await this.getFunctionDetail(functionName, codeSecret);
273128
+ Layers = Layers.map(item => lodash_1.default.pick(item, ['LayerName', 'LayerVersion']));
273129
+ // 新加的文件层添加到最后
273130
+ Layers.push({
273131
+ LayerName: layerName,
273132
+ LayerVersion: layerVersion
273133
+ });
273134
+ const res = await this.scfService.request('UpdateFunctionConfiguration', {
273135
+ Layers,
273136
+ Namespace: envId,
273137
+ FunctionName: functionName
273138
+ });
273139
+ return res;
273140
+ }
273141
+ // 函数解绑文件层
273142
+ async unAttachLayer(options) {
273143
+ const { envId, functionName, layerName, layerVersion, codeSecret } = options;
273144
+ let { Layers } = await this.getFunctionDetail(functionName, codeSecret);
273145
+ Layers = Layers.map(item => lodash_1.default.pick(item, ['LayerName', 'LayerVersion']));
273146
+ const index = Layers.findIndex(item => item.LayerName === layerName && item.LayerVersion === layerVersion);
273147
+ if (index === -1) {
273148
+ throw new error_1.CloudBaseError('层不存在');
273149
+ }
273150
+ // 删除指定的层
273151
+ Layers.splice(index, 1);
273152
+ const apiParams = {
273153
+ Namespace: envId,
273154
+ FunctionName: functionName,
273155
+ Layers: Layers.length > 0 ? Layers : [{
273156
+ LayerName: '',
273157
+ LayerVersion: 0
273158
+ }]
273159
+ };
273160
+ return this.scfService.request('UpdateFunctionConfiguration', apiParams);
273161
+ }
273162
+ // 更新云函数层
273163
+ async updateFunctionLayer(options) {
273164
+ const { envId, functionName, layers } = options;
273165
+ return this.scfService.request('UpdateFunctionConfiguration', {
273166
+ Layers: layers,
273167
+ Namespace: envId,
273168
+ FunctionName: functionName
273169
+ });
273170
+ }
273171
+ // 下载文件层 ZIP 文件
273172
+ async downloadLayer(options) {
273173
+ const { name, version, destPath } = options;
273174
+ const res = await this.scfService.request('GetLayerVersion', {
273175
+ LayerName: name,
273176
+ LayerVersion: version
273177
+ });
273178
+ const url = res === null || res === void 0 ? void 0 : res.Location;
273179
+ const zipPath = path_1.default.join(destPath, `${name}-${version}.zip`);
273180
+ if ((0, utils_1.checkFullAccess)(zipPath)) {
273181
+ throw new error_1.CloudBaseError(`文件已存在:${zipPath}`);
273182
+ }
273183
+ // 下载文件
273184
+ return (0, utils_1.downloadAndExtractRemoteZip)(url, destPath);
273185
+ }
272562
273186
  // 创建文件层版本
272563
273187
  async createLayer(options) {
272564
273188
  const { env } = this.getFunctionConfig();
@@ -272631,7 +273255,7 @@ class FunctionService {
272631
273255
  Limit: limit,
272632
273256
  Offset: offset,
272633
273257
  SearchKey: searchKey,
272634
- SearchSrc: `TCB_${env}`
273258
+ // SearchSrc: `TCB_${env}`
272635
273259
  };
272636
273260
  if (runtime) {
272637
273261
  param.CompatibleRuntime = runtime;
@@ -272960,12 +273584,18 @@ __decorate([
272960
273584
  __decorate([
272961
273585
  (0, utils_1.preLazy)()
272962
273586
  ], FunctionService.prototype, "listFunctions", null);
273587
+ __decorate([
273588
+ (0, utils_1.preLazy)()
273589
+ ], FunctionService.prototype, "listAllFunctions", null);
272963
273590
  __decorate([
272964
273591
  (0, utils_1.preLazy)()
272965
273592
  ], FunctionService.prototype, "deleteFunction", null);
272966
273593
  __decorate([
272967
273594
  (0, utils_1.preLazy)()
272968
273595
  ], FunctionService.prototype, "getFunctionDetail", null);
273596
+ __decorate([
273597
+ (0, utils_1.preLazy)()
273598
+ ], FunctionService.prototype, "batchGetFunctionsDetail", null);
272969
273599
  __decorate([
272970
273600
  (0, utils_1.preLazy)()
272971
273601
  ], FunctionService.prototype, "getFunctionLogs", null);
@@ -272975,6 +273605,9 @@ __decorate([
272975
273605
  __decorate([
272976
273606
  (0, utils_1.preLazy)()
272977
273607
  ], FunctionService.prototype, "getFunctionLogDetail", null);
273608
+ __decorate([
273609
+ (0, utils_1.preLazy)()
273610
+ ], FunctionService.prototype, "getCompleteFunctionLogs", null);
272978
273611
  __decorate([
272979
273612
  (0, utils_1.preLazy)()
272980
273613
  ], FunctionService.prototype, "updateFunctionConfig", null);
@@ -272984,6 +273617,9 @@ __decorate([
272984
273617
  __decorate([
272985
273618
  (0, utils_1.preLazy)()
272986
273619
  ], FunctionService.prototype, "invokeFunction", null);
273620
+ __decorate([
273621
+ (0, utils_1.preLazy)()
273622
+ ], FunctionService.prototype, "batchInvokeFunctions", null);
272987
273623
  __decorate([
272988
273624
  (0, utils_1.preLazy)()
272989
273625
  ], FunctionService.prototype, "copyFunction", null);
@@ -272996,6 +273632,18 @@ __decorate([
272996
273632
  __decorate([
272997
273633
  (0, utils_1.preLazy)()
272998
273634
  ], FunctionService.prototype, "getFunctionDownloadUrl", null);
273635
+ __decorate([
273636
+ (0, utils_1.preLazy)()
273637
+ ], FunctionService.prototype, "attachLayer", null);
273638
+ __decorate([
273639
+ (0, utils_1.preLazy)()
273640
+ ], FunctionService.prototype, "unAttachLayer", null);
273641
+ __decorate([
273642
+ (0, utils_1.preLazy)()
273643
+ ], FunctionService.prototype, "updateFunctionLayer", null);
273644
+ __decorate([
273645
+ (0, utils_1.preLazy)()
273646
+ ], FunctionService.prototype, "downloadLayer", null);
272999
273647
  __decorate([
273000
273648
  (0, utils_1.preLazy)()
273001
273649
  ], FunctionService.prototype, "createLayer", null);