@cloudbase/cloudbase-mcp 2.25.1 → 2.25.2
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/dist/cli.cjs +2 -2
- package/dist/index.cjs +783 -58
- package/dist/index.js +781 -58
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -84648,6 +84648,154 @@ exports.colors = {
|
|
|
84648
84648
|
})));
|
|
84649
84649
|
|
|
84650
84650
|
|
|
84651
|
+
/***/ }),
|
|
84652
|
+
|
|
84653
|
+
/***/ 22435:
|
|
84654
|
+
/***/ ((__unused_webpack_module, exports) => {
|
|
84655
|
+
|
|
84656
|
+
"use strict";
|
|
84657
|
+
|
|
84658
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
84659
|
+
exports.rankGatewayAccessUrls = rankGatewayAccessUrls;
|
|
84660
|
+
exports.flattenHttpServiceRoutes = flattenHttpServiceRoutes;
|
|
84661
|
+
exports.filterRoutesByUpstream = filterRoutesByUpstream;
|
|
84662
|
+
exports.toAccessUrlEnvelope = toAccessUrlEnvelope;
|
|
84663
|
+
exports.resolveGatewayAccessUrls = resolveGatewayAccessUrls;
|
|
84664
|
+
exports.preferGatewayOrFallback = preferGatewayOrFallback;
|
|
84665
|
+
function normalizeAccessPath(path) {
|
|
84666
|
+
if (!path) {
|
|
84667
|
+
return "/";
|
|
84668
|
+
}
|
|
84669
|
+
return path.startsWith("/") ? path : `/${path}`;
|
|
84670
|
+
}
|
|
84671
|
+
function buildHttpsUrl(domain, path) {
|
|
84672
|
+
return `https://${domain}${normalizeAccessPath(path)}`;
|
|
84673
|
+
}
|
|
84674
|
+
/**
|
|
84675
|
+
* Rank gateway route URLs: custom domains (IsDefault !== true) before default domain.
|
|
84676
|
+
* Stable within each group; dedupe by full URL.
|
|
84677
|
+
*/
|
|
84678
|
+
function rankGatewayAccessUrls(routes) {
|
|
84679
|
+
const mapped = routes
|
|
84680
|
+
.filter((route) => Boolean(route.Domain))
|
|
84681
|
+
.map((route) => {
|
|
84682
|
+
const path = normalizeAccessPath(route.Path);
|
|
84683
|
+
const isDefault = route.IsDefault === true;
|
|
84684
|
+
return {
|
|
84685
|
+
url: buildHttpsUrl(route.Domain, path),
|
|
84686
|
+
domain: route.Domain,
|
|
84687
|
+
path,
|
|
84688
|
+
isDefault,
|
|
84689
|
+
source: (isDefault
|
|
84690
|
+
? "gateway.default"
|
|
84691
|
+
: "gateway.custom"),
|
|
84692
|
+
};
|
|
84693
|
+
});
|
|
84694
|
+
mapped.sort((a, b) => {
|
|
84695
|
+
if (a.isDefault === b.isDefault) {
|
|
84696
|
+
return 0;
|
|
84697
|
+
}
|
|
84698
|
+
return a.isDefault ? 1 : -1;
|
|
84699
|
+
});
|
|
84700
|
+
const seen = new Set();
|
|
84701
|
+
const deduped = [];
|
|
84702
|
+
for (const item of mapped) {
|
|
84703
|
+
if (seen.has(item.url)) {
|
|
84704
|
+
continue;
|
|
84705
|
+
}
|
|
84706
|
+
seen.add(item.url);
|
|
84707
|
+
deduped.push(item);
|
|
84708
|
+
}
|
|
84709
|
+
return deduped;
|
|
84710
|
+
}
|
|
84711
|
+
function flattenHttpServiceRoutes(result) {
|
|
84712
|
+
return (result.Domains ?? []).flatMap((domainItem) => (domainItem.Routes ?? []).map((route) => ({
|
|
84713
|
+
Domain: domainItem.Domain ?? "",
|
|
84714
|
+
IsDefault: domainItem.IsDefault,
|
|
84715
|
+
Path: typeof route.Path === "string" ? route.Path : undefined,
|
|
84716
|
+
UpstreamResourceType: typeof route.UpstreamResourceType === "string"
|
|
84717
|
+
? route.UpstreamResourceType
|
|
84718
|
+
: undefined,
|
|
84719
|
+
UpstreamResourceName: typeof route.UpstreamResourceName === "string"
|
|
84720
|
+
? route.UpstreamResourceName
|
|
84721
|
+
: undefined,
|
|
84722
|
+
})));
|
|
84723
|
+
}
|
|
84724
|
+
function filterRoutesByUpstream(routes, input) {
|
|
84725
|
+
const name = input.upstreamResourceName;
|
|
84726
|
+
const types = input.upstreamResourceTypes?.map((t) => String(t));
|
|
84727
|
+
return routes.filter((route) => {
|
|
84728
|
+
if (route.UpstreamResourceName !== name) {
|
|
84729
|
+
return false;
|
|
84730
|
+
}
|
|
84731
|
+
if (!types || types.length === 0) {
|
|
84732
|
+
return true;
|
|
84733
|
+
}
|
|
84734
|
+
return Boolean(route.UpstreamResourceType &&
|
|
84735
|
+
types.includes(String(route.UpstreamResourceType)));
|
|
84736
|
+
});
|
|
84737
|
+
}
|
|
84738
|
+
function toAccessUrlEnvelope(ranked) {
|
|
84739
|
+
if (ranked.length === 0) {
|
|
84740
|
+
return { accessUrls: [], routes: [] };
|
|
84741
|
+
}
|
|
84742
|
+
return {
|
|
84743
|
+
accessUrl: ranked[0].url,
|
|
84744
|
+
accessUrls: ranked.map((item) => item.url),
|
|
84745
|
+
accessUrlSource: ranked[0].source,
|
|
84746
|
+
routes: ranked,
|
|
84747
|
+
};
|
|
84748
|
+
}
|
|
84749
|
+
/**
|
|
84750
|
+
* Best-effort lookup of gateway access URLs for an upstream resource.
|
|
84751
|
+
* Never throws — returns empty lists on failure.
|
|
84752
|
+
*/
|
|
84753
|
+
async function resolveGatewayAccessUrls(input) {
|
|
84754
|
+
try {
|
|
84755
|
+
const manager = await input.getManager();
|
|
84756
|
+
const result = await manager.env.describeHttpServiceRoute({
|
|
84757
|
+
EnvId: input.envId,
|
|
84758
|
+
Limit: 1000,
|
|
84759
|
+
});
|
|
84760
|
+
const flattened = flattenHttpServiceRoutes(result);
|
|
84761
|
+
const matched = filterRoutesByUpstream(flattened, {
|
|
84762
|
+
upstreamResourceName: input.upstreamResourceName,
|
|
84763
|
+
upstreamResourceTypes: input.upstreamResourceTypes,
|
|
84764
|
+
});
|
|
84765
|
+
return toAccessUrlEnvelope(rankGatewayAccessUrls(matched));
|
|
84766
|
+
}
|
|
84767
|
+
catch {
|
|
84768
|
+
return { accessUrls: [], routes: [] };
|
|
84769
|
+
}
|
|
84770
|
+
}
|
|
84771
|
+
/**
|
|
84772
|
+
* Merge ranked gateway URLs with a resource-native fallback URL.
|
|
84773
|
+
* Gateway custom/default always win over the fallback when present.
|
|
84774
|
+
*/
|
|
84775
|
+
function preferGatewayOrFallback(input) {
|
|
84776
|
+
if (input.gateway.accessUrl) {
|
|
84777
|
+
const urls = [...input.gateway.accessUrls];
|
|
84778
|
+
if (input.fallbackUrl &&
|
|
84779
|
+
!urls.includes(input.fallbackUrl)) {
|
|
84780
|
+
urls.push(input.fallbackUrl);
|
|
84781
|
+
}
|
|
84782
|
+
return {
|
|
84783
|
+
accessUrl: input.gateway.accessUrl,
|
|
84784
|
+
accessUrls: urls,
|
|
84785
|
+
accessUrlSource: input.gateway.accessUrlSource,
|
|
84786
|
+
};
|
|
84787
|
+
}
|
|
84788
|
+
if (input.fallbackUrl) {
|
|
84789
|
+
return {
|
|
84790
|
+
accessUrl: input.fallbackUrl,
|
|
84791
|
+
accessUrls: [input.fallbackUrl],
|
|
84792
|
+
accessUrlSource: input.fallbackSource,
|
|
84793
|
+
};
|
|
84794
|
+
}
|
|
84795
|
+
return { accessUrls: [] };
|
|
84796
|
+
}
|
|
84797
|
+
|
|
84798
|
+
|
|
84651
84799
|
/***/ }),
|
|
84652
84800
|
|
|
84653
84801
|
/***/ 22573:
|
|
@@ -90059,6 +90207,7 @@ exports.registerFunctionTools = registerFunctionTools;
|
|
|
90059
90207
|
const zod_1 = __webpack_require__(21614);
|
|
90060
90208
|
const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
90061
90209
|
const cloud_mode_js_1 = __webpack_require__(89684);
|
|
90210
|
+
const gateway_access_urls_js_1 = __webpack_require__(22435);
|
|
90062
90211
|
const json_content_js_1 = __webpack_require__(4365);
|
|
90063
90212
|
const logger_js_1 = __webpack_require__(13039);
|
|
90064
90213
|
const fs_1 = __webpack_require__(29021);
|
|
@@ -90903,9 +91052,33 @@ function registerFunctionTools(server) {
|
|
|
90903
91052
|
const message = func.type === "HTTP"
|
|
90904
91053
|
? `已创建 HTTP 函数 ${functionName}。如果后续需要通过 URL 访问,请显式调用 manageGateway(action="createRoute"),并把 upstreamResourceType="WEB_SCF" 一起传入,再按实际路径和鉴权需求创建访问入口。评测或其他外部调用方可能会以匿名身份访问,而且失败后不一定会把 EXCEED_AUTHORITY 再反馈给 AI;交付前请主动确认访问路径和函数安全规则,若已出现 EXCEED_AUTHORITY,请先调用 queryPermissions(action="getResourcePermission", resourceType="function", resourceId="${functionName}") 查看当前规则,再按需要使用 managePermissions(action="updateResourcePermission") 调整权限。`
|
|
90905
91054
|
: `已创建函数 ${functionName}`;
|
|
91055
|
+
let accessUrl;
|
|
91056
|
+
let accessUrls = [];
|
|
91057
|
+
let accessUrlSource;
|
|
91058
|
+
if (func.type === "HTTP") {
|
|
91059
|
+
const envId = cloudBaseOptions?.envId ?? await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
91060
|
+
const gateway = await (0, gateway_access_urls_js_1.resolveGatewayAccessUrls)({
|
|
91061
|
+
envId,
|
|
91062
|
+
upstreamResourceName: functionName,
|
|
91063
|
+
upstreamResourceTypes: ["WEB_SCF", "SCF"],
|
|
91064
|
+
getManager: async () => {
|
|
91065
|
+
const manager = await getManager();
|
|
91066
|
+
if (!manager) {
|
|
91067
|
+
throw new Error("cloudbase manager unavailable");
|
|
91068
|
+
}
|
|
91069
|
+
return manager;
|
|
91070
|
+
},
|
|
91071
|
+
});
|
|
91072
|
+
accessUrl = gateway.accessUrl;
|
|
91073
|
+
accessUrls = gateway.accessUrls;
|
|
91074
|
+
accessUrlSource = gateway.accessUrlSource;
|
|
91075
|
+
}
|
|
90906
91076
|
return buildEnvelope({
|
|
90907
91077
|
action: input.action,
|
|
90908
91078
|
functionName,
|
|
91079
|
+
...(accessUrl ? { accessUrl } : {}),
|
|
91080
|
+
...(accessUrls.length > 0 ? { accessUrls } : {}),
|
|
91081
|
+
...(accessUrlSource ? { accessUrlSource } : {}),
|
|
90909
91082
|
raw: result,
|
|
90910
91083
|
}, message, nextActions);
|
|
90911
91084
|
}
|
|
@@ -90944,11 +91117,33 @@ function registerFunctionTools(server) {
|
|
|
90944
91117
|
throw wrapFunctionOperationError("updateFunctionCode", input.functionName, undefined, error);
|
|
90945
91118
|
}
|
|
90946
91119
|
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, imageResult);
|
|
91120
|
+
const envId = cloudBaseOptions?.envId ?? await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
91121
|
+
const imageGatewayAccess = await (0, gateway_access_urls_js_1.resolveGatewayAccessUrls)({
|
|
91122
|
+
envId,
|
|
91123
|
+
upstreamResourceName: input.functionName,
|
|
91124
|
+
upstreamResourceTypes: ["WEB_SCF", "SCF"],
|
|
91125
|
+
getManager: async () => {
|
|
91126
|
+
const manager = await getManager();
|
|
91127
|
+
if (!manager) {
|
|
91128
|
+
throw new Error("cloudbase manager unavailable");
|
|
91129
|
+
}
|
|
91130
|
+
return manager;
|
|
91131
|
+
},
|
|
91132
|
+
});
|
|
90947
91133
|
return buildEnvelope({
|
|
90948
91134
|
action: input.action,
|
|
90949
91135
|
functionName: input.functionName,
|
|
90950
91136
|
deployMode: "image",
|
|
90951
91137
|
imageUri: updateImageConfig.imageUri,
|
|
91138
|
+
...(imageGatewayAccess.accessUrl
|
|
91139
|
+
? { accessUrl: imageGatewayAccess.accessUrl }
|
|
91140
|
+
: {}),
|
|
91141
|
+
...(imageGatewayAccess.accessUrls.length > 0
|
|
91142
|
+
? { accessUrls: imageGatewayAccess.accessUrls }
|
|
91143
|
+
: {}),
|
|
91144
|
+
...(imageGatewayAccess.accessUrlSource
|
|
91145
|
+
? { accessUrlSource: imageGatewayAccess.accessUrlSource }
|
|
91146
|
+
: {}),
|
|
90952
91147
|
raw: imageResult,
|
|
90953
91148
|
}, `已将函数 ${input.functionName} 的镜像更新为 ${updateImageConfig.imageUri}。` +
|
|
90954
91149
|
`部署后可用 queryFunctions(action="getFunctionDetail") 确认函数已就绪(Active)。`, [
|
|
@@ -90979,9 +91174,29 @@ function registerFunctionTools(server) {
|
|
|
90979
91174
|
throw wrapFunctionOperationError("updateFunctionCode", input.functionName, processedRootPath, error);
|
|
90980
91175
|
}
|
|
90981
91176
|
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
91177
|
+
const envId = cloudBaseOptions?.envId ?? await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
91178
|
+
const gatewayAccess = await (0, gateway_access_urls_js_1.resolveGatewayAccessUrls)({
|
|
91179
|
+
envId,
|
|
91180
|
+
upstreamResourceName: input.functionName,
|
|
91181
|
+
upstreamResourceTypes: ["WEB_SCF", "SCF"],
|
|
91182
|
+
getManager: async () => {
|
|
91183
|
+
const manager = await getManager();
|
|
91184
|
+
if (!manager) {
|
|
91185
|
+
throw new Error("cloudbase manager unavailable");
|
|
91186
|
+
}
|
|
91187
|
+
return manager;
|
|
91188
|
+
},
|
|
91189
|
+
});
|
|
90982
91190
|
return buildEnvelope({
|
|
90983
91191
|
action: input.action,
|
|
90984
91192
|
functionName: input.functionName,
|
|
91193
|
+
...(gatewayAccess.accessUrl ? { accessUrl: gatewayAccess.accessUrl } : {}),
|
|
91194
|
+
...(gatewayAccess.accessUrls.length > 0
|
|
91195
|
+
? { accessUrls: gatewayAccess.accessUrls }
|
|
91196
|
+
: {}),
|
|
91197
|
+
...(gatewayAccess.accessUrlSource
|
|
91198
|
+
? { accessUrlSource: gatewayAccess.accessUrlSource }
|
|
91199
|
+
: {}),
|
|
90985
91200
|
raw: result,
|
|
90986
91201
|
}, `已更新函数 ${input.functionName} 的代码`, [
|
|
90987
91202
|
{
|
|
@@ -114238,7 +114453,9 @@ const path_1 = __importDefault(__webpack_require__(39902));
|
|
|
114238
114453
|
const zod_1 = __webpack_require__(21614);
|
|
114239
114454
|
const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
114240
114455
|
const logger_js_1 = __webpack_require__(13039);
|
|
114456
|
+
const gateway_access_urls_js_1 = __webpack_require__(22435);
|
|
114241
114457
|
const notification_js_1 = __webpack_require__(32720);
|
|
114458
|
+
const cloudrun_config_js_1 = __webpack_require__(48266);
|
|
114242
114459
|
// CloudRun service types
|
|
114243
114460
|
exports.CLOUDRUN_SERVICE_TYPES = ['function', 'container'];
|
|
114244
114461
|
// CloudRun access types
|
|
@@ -114257,10 +114474,11 @@ const queryCloudRunInputSchema = {
|
|
|
114257
114474
|
};
|
|
114258
114475
|
// Input schema for manageCloudRun tool
|
|
114259
114476
|
const ManageCloudRunInputSchema = {
|
|
114260
|
-
action: zod_1.z.enum(['init', 'download', 'run', 'deploy', 'delete', 'createAgent']).describe('云托管服务管理操作类型:init=从模板初始化新的云托管项目代码(在targetPath目录下创建以serverName命名的子目录,支持多种语言和框架模板),download=从云端下载现有服务的代码到本地进行开发,run=在本地运行函数型云托管服务(用于开发和调试,仅支持函数型服务),deploy
|
|
114477
|
+
action: zod_1.z.enum(['init', 'download', 'run', 'deploy', 'delete', 'createAgent', 'updateConfig']).describe('云托管服务管理操作类型:init=从模板初始化新的云托管项目代码(在targetPath目录下创建以serverName命名的子目录,支持多种语言和框架模板),download=从云端下载现有服务的代码到本地进行开发,run=在本地运行函数型云托管服务(用于开发和调试,仅支持函数型服务),deploy=将本地代码部署到云端云托管服务(支持函数型和容器型;已存在服务会 Read-Merge-Write 保留远程 VpcConf/EnvParams/OpenAccessTypes),updateConfig=仅更新服务配置不重新上传代码(对齐控制台服务设置,走 SubmitServerConfigChangeDiff;不需要 targetPath),delete=删除指定的云托管服务(不可恢复,需要确认),createAgent=创建函数型Agent(基于函数型云托管开发AI智能体)'),
|
|
114261
114478
|
serverName: zod_1.z.string().describe('云托管服务名称,用于标识和管理服务。命名规则:支持大小写字母、数字、连字符和下划线,必须以字母开头,长度3-45个字符。在init操作中会作为在targetPath下创建的子目录名,在其他操作中作为目标服务名'),
|
|
114262
114479
|
// Deploy operation parameters
|
|
114263
|
-
targetPath: zod_1.z.string().optional().describe('本地代码路径,必须是绝对路径。在deploy操作中指定要部署的代码目录,在download操作中指定下载目标目录,在init操作中指定云托管服务的上级目录(会在该目录下创建以serverName
|
|
114480
|
+
targetPath: zod_1.z.string().optional().describe('本地代码路径,必须是绝对路径。在deploy操作中指定要部署的代码目录,在download操作中指定下载目标目录,在init操作中指定云托管服务的上级目录(会在该目录下创建以serverName命名的子目录)。updateConfig 不需要此参数。建议约定:项目根目录下的cloudrun/目录,例如:/Users/username/projects/my-project/cloudrun'),
|
|
114481
|
+
envParamsReplaceAll: zod_1.z.boolean().optional().default(false).describe('EnvParams 合并策略(deploy / updateConfig):false(默认)= 与远程按 key 合并(输入覆盖同名 key,远程其余 key 保留);true= 用输入 EnvParams 整包替换远程。仅当显式传入 EnvParams 时生效'),
|
|
114264
114482
|
serverConfig: zod_1.z.object({
|
|
114265
114483
|
OpenAccessTypes: zod_1.z.array(zod_1.z.enum(exports.CLOUDRUN_ACCESS_TYPES)).optional().describe('公网访问类型配置,控制服务的访问权限:OA=办公网访问,PUBLIC=公网访问(默认,可通过HTTPS域名访问),MINIAPP=小程序访问,VPC=VPC访问(仅同VPC内可访问)。可配置多个类型'),
|
|
114266
114484
|
Cpu: zod_1.z.number().positive().optional().describe('CPU规格配置,单位为核。可选值:0.25、0.5、1、2、4、8等。注意:内存规格必须是CPU规格的2倍(如CPU=0.25时内存=0.5,CPU=1时内存=2)。影响服务性能和计费'),
|
|
@@ -114299,7 +114517,7 @@ const ManageCloudRunInputSchema = {
|
|
|
114299
114517
|
VpcConf: zod_1.z.object({
|
|
114300
114518
|
VpcId: zod_1.z.string().describe('VPC网络ID,格式如 vpc-xxxxxxxx。必须与目标数据库/Redis 处于同一地域,并优先选择同一 VPC。禁止猜测或使用占位符;须来自数据库控制台、已有资源详情、callCloudApi 或用户确认。建议首次创建即配置;已存在服务也可在 deploy 时传入,部署后必须用 queryCloudRun detail 复核是否生效'),
|
|
114301
114519
|
SubnetId: zod_1.z.string().describe('子网ID,格式如 subnet-xxxxxxxx。云托管实例将占用该子网 IP,需确保有足够可用 IP'),
|
|
114302
|
-
}).optional().describe('VPC网络配置(实例出网/私有网络)。用于让云托管实例接入指定 VPC,从而内网访问 MySQL/PostgreSQL/Redis/CVM 等资源。与 OpenAccessTypes(外部如何访问本服务)是不同概念。TCP 连库场景必须配置。禁止猜测 VpcId/SubnetId,须来自数据库控制台、已有资源详情、callCloudApi
|
|
114520
|
+
}).optional().describe('VPC网络配置(实例出网/私有网络)。用于让云托管实例接入指定 VPC,从而内网访问 MySQL/PostgreSQL/Redis/CVM 等资源。与 OpenAccessTypes(外部如何访问本服务)是不同概念。TCP 连库场景必须配置。禁止猜测 VpcId/SubnetId,须来自数据库控制台、已有资源详情、callCloudApi 或用户确认。创建时映射为 SDK vpcInfo(CreateType=2);已存在服务可用 updateConfig 或 deploy(RMW 会保留未传入的远程 VpcConf)。部署/更新后必须用 queryCloudRun detail 复核 ServerConfig.VpcConf'),
|
|
114303
114521
|
VolumesConf: zod_1.z.array(zod_1.z.object({
|
|
114304
114522
|
VolumeName: zod_1.z.string().describe('存储卷名称'),
|
|
114305
114523
|
VolumeType: zod_1.z.string().describe('存储卷类型,如CFS表示云文件存储'),
|
|
@@ -114309,7 +114527,7 @@ const ManageCloudRunInputSchema = {
|
|
|
114309
114527
|
PublicAccess: zod_1.z.boolean().optional().describe('是否开启公网访问,true=开启公网访问,false=关闭公网访问'),
|
|
114310
114528
|
PublicAccessPath: zod_1.z.string().optional().describe('公网访问路径配置')
|
|
114311
114529
|
}).optional().describe('公网访问配置,用于控制服务的公网访问策略。可配置是否开启公网访问及访问路径'),
|
|
114312
|
-
}).optional().describe('
|
|
114530
|
+
}).optional().describe('服务配置项,用于 deploy / updateConfig。包括资源规格、访问权限、环境变量、日志、网络等。deploy 未提供时对已存在服务仍会从远程合并保留 VpcConf/EnvParams/OpenAccessTypes;updateConfig 至少需要一个配置字段'),
|
|
114313
114531
|
// Init operation parameters
|
|
114314
114532
|
template: zod_1.z.string().optional().default('helloworld').describe('项目模板标识符,用于指定初始化项目时使用的模板。可通过queryCloudRun的templates操作获取可用模板列表。常用模板:helloworld=Hello World示例,nodejs=Node.js项目模板,python=Python项目模板等'),
|
|
114315
114533
|
// Run operation parameters (function services only)
|
|
@@ -114493,6 +114711,30 @@ function normalizeProcessLogText(logs) {
|
|
|
114493
114711
|
})
|
|
114494
114712
|
.join("\n");
|
|
114495
114713
|
}
|
|
114714
|
+
function normalizeCloudRunDomainUrl(input) {
|
|
114715
|
+
if (typeof input !== "string" || !input.trim())
|
|
114716
|
+
return undefined;
|
|
114717
|
+
const raw = input.trim();
|
|
114718
|
+
return raw.startsWith("http://") || raw.startsWith("https://")
|
|
114719
|
+
? raw
|
|
114720
|
+
: `https://${raw}`;
|
|
114721
|
+
}
|
|
114722
|
+
function resolveCloudRunFallbackAccess(details) {
|
|
114723
|
+
const custom = normalizeCloudRunDomainUrl(details?.BaseInfo?.CustomDomainName);
|
|
114724
|
+
if (custom)
|
|
114725
|
+
return { url: custom, source: "cloudrun.customDomain" };
|
|
114726
|
+
const defaultDomain = normalizeCloudRunDomainUrl(details?.BaseInfo?.DefaultDomainName);
|
|
114727
|
+
if (defaultDomain)
|
|
114728
|
+
return { url: defaultDomain, source: "cloudrun.defaultDomain" };
|
|
114729
|
+
const publicDomain = normalizeCloudRunDomainUrl(details?.BaseInfo?.PublicDomain) ??
|
|
114730
|
+
normalizeCloudRunDomainUrl(details?.AccessInfo?.PublicDomain);
|
|
114731
|
+
if (publicDomain)
|
|
114732
|
+
return { url: publicDomain, source: "cloudrun.publicDomain" };
|
|
114733
|
+
const internal = normalizeCloudRunDomainUrl(details?.BaseInfo?.InternalDomain);
|
|
114734
|
+
if (internal)
|
|
114735
|
+
return { url: internal, source: "cloudrun.internalDomain" };
|
|
114736
|
+
return {};
|
|
114737
|
+
}
|
|
114496
114738
|
/**
|
|
114497
114739
|
* Format CloudRun service info for display
|
|
114498
114740
|
*/
|
|
@@ -114726,7 +114968,7 @@ function registerCloudRunTools(server) {
|
|
|
114726
114968
|
// Tool 2: Manage CloudRun services (write operations)
|
|
114727
114969
|
server.registerTool("manageCloudRun", {
|
|
114728
114970
|
title: "管理 CloudRun 服务",
|
|
114729
|
-
description: "管理云托管服务,按开发顺序支持:初始化项目(可从模板开始,模板列表可通过 queryCloudRun
|
|
114971
|
+
description: "管理云托管服务,按开发顺序支持:初始化项目(可从模板开始,模板列表可通过 queryCloudRun 查询)、下载服务代码、本地运行(仅函数型服务)、部署代码、仅更新配置(updateConfig,无需重新上传代码)、删除服务。deploy 对已存在服务会先读取远程配置再合并(保留 VpcConf/EnvParams/OpenAccessTypes)。updateConfig 对齐控制台服务设置页。删除操作需要确认,建议设置force=true。",
|
|
114730
114972
|
inputSchema: ManageCloudRunInputSchema,
|
|
114731
114973
|
annotations: {
|
|
114732
114974
|
readOnlyHint: false,
|
|
@@ -114917,6 +115159,8 @@ for await (let x of res.textStream) {
|
|
|
114917
115159
|
}
|
|
114918
115160
|
// Determine service type - use input.serverType if provided, otherwise auto-detect
|
|
114919
115161
|
let serverType;
|
|
115162
|
+
let remoteServerConfig = null;
|
|
115163
|
+
let existingService = false;
|
|
114920
115164
|
if (input.serverType) {
|
|
114921
115165
|
serverType = input.serverType;
|
|
114922
115166
|
}
|
|
@@ -114925,6 +115169,8 @@ for await (let x of res.textStream) {
|
|
|
114925
115169
|
// First try to get existing service details
|
|
114926
115170
|
const details = await cloudrunService.detail({ serverName: input.serverName });
|
|
114927
115171
|
serverType = details.BaseInfo?.ServerType || 'container';
|
|
115172
|
+
remoteServerConfig = (details.ServerConfig || null);
|
|
115173
|
+
existingService = true;
|
|
114928
115174
|
}
|
|
114929
115175
|
catch (e) {
|
|
114930
115176
|
// If service doesn't exist, determine by project structure
|
|
@@ -114958,20 +115204,40 @@ for await (let x of res.textStream) {
|
|
|
114958
115204
|
}
|
|
114959
115205
|
}
|
|
114960
115206
|
}
|
|
115207
|
+
// When serverType was provided explicitly, still try to load remote config for RMW.
|
|
115208
|
+
if (!existingService) {
|
|
115209
|
+
try {
|
|
115210
|
+
const details = await cloudrunService.detail({ serverName: input.serverName });
|
|
115211
|
+
remoteServerConfig = (details.ServerConfig || null);
|
|
115212
|
+
existingService = true;
|
|
115213
|
+
}
|
|
115214
|
+
catch {
|
|
115215
|
+
// New service create path
|
|
115216
|
+
}
|
|
115217
|
+
}
|
|
115218
|
+
let mergedFromRemote = [];
|
|
115219
|
+
let effectiveServerConfig = input.serverConfig;
|
|
115220
|
+
if (existingService) {
|
|
115221
|
+
const mergedResult = (0, cloudrun_config_js_1.mergeCloudRunServerConfig)({
|
|
115222
|
+
remote: remoteServerConfig,
|
|
115223
|
+
input: input.serverConfig || {},
|
|
115224
|
+
envParamsReplaceAll: Boolean(input.envParamsReplaceAll),
|
|
115225
|
+
});
|
|
115226
|
+
effectiveServerConfig = mergedResult.merged;
|
|
115227
|
+
mergedFromRemote = mergedResult.mergedFromRemote;
|
|
115228
|
+
}
|
|
114961
115229
|
const deployParams = {
|
|
114962
115230
|
serverName: input.serverName,
|
|
114963
115231
|
targetPath: targetPath,
|
|
114964
115232
|
force: input.force,
|
|
114965
115233
|
serverType: serverType,
|
|
114966
115234
|
};
|
|
114967
|
-
|
|
114968
|
-
|
|
114969
|
-
deployParams.serverConfig = input.serverConfig;
|
|
115235
|
+
if (effectiveServerConfig && Object.keys(effectiveServerConfig).length > 0) {
|
|
115236
|
+
deployParams.serverConfig = effectiveServerConfig;
|
|
114970
115237
|
}
|
|
114971
115238
|
// Manager SDK create path prefers top-level vpcInfo (CreateCloudRunServer.VpcInfo).
|
|
114972
115239
|
// Map serverConfig.VpcConf → vpcInfo so first-time create actually binds VPC.
|
|
114973
|
-
|
|
114974
|
-
const vpcConf = input.serverConfig?.VpcConf;
|
|
115240
|
+
const vpcConf = effectiveServerConfig?.VpcConf;
|
|
114975
115241
|
if (vpcConf?.VpcId?.trim() && vpcConf?.SubnetId?.trim()) {
|
|
114976
115242
|
deployParams.vpcInfo = {
|
|
114977
115243
|
VpcId: vpcConf.VpcId.trim(),
|
|
@@ -115002,47 +115268,46 @@ for await (let x of res.textStream) {
|
|
|
115002
115268
|
catch (error) {
|
|
115003
115269
|
(0, logger_js_1.debug)('cloudbaserc.json creation skipped:', error instanceof Error ? error : new Error(String(error)));
|
|
115004
115270
|
}
|
|
115271
|
+
let preferredAccessUrl;
|
|
115272
|
+
let preferredAccessUrls = [];
|
|
115273
|
+
let preferredAccessSource;
|
|
115274
|
+
let verifiedConfigSnapshot;
|
|
115275
|
+
try {
|
|
115276
|
+
const serviceDetails = await cloudrunService.detail({
|
|
115277
|
+
serverName: input.serverName,
|
|
115278
|
+
});
|
|
115279
|
+
verifiedConfigSnapshot = (0, cloudrun_config_js_1.summarizeConfigSnapshot)(serviceDetails?.ServerConfig);
|
|
115280
|
+
const fallback = resolveCloudRunFallbackAccess(serviceDetails);
|
|
115281
|
+
const gateway = await (0, gateway_access_urls_js_1.resolveGatewayAccessUrls)({
|
|
115282
|
+
envId: currentEnvId,
|
|
115283
|
+
upstreamResourceName: input.serverName,
|
|
115284
|
+
upstreamResourceTypes: ["CBR"],
|
|
115285
|
+
getManager: async () => {
|
|
115286
|
+
const manager = await getManager();
|
|
115287
|
+
if (!manager) {
|
|
115288
|
+
throw new Error("cloudbase manager unavailable");
|
|
115289
|
+
}
|
|
115290
|
+
return manager;
|
|
115291
|
+
},
|
|
115292
|
+
});
|
|
115293
|
+
const preferred = (0, gateway_access_urls_js_1.preferGatewayOrFallback)({
|
|
115294
|
+
gateway,
|
|
115295
|
+
fallbackUrl: fallback.url,
|
|
115296
|
+
fallbackSource: fallback.source,
|
|
115297
|
+
});
|
|
115298
|
+
preferredAccessUrl = preferred.accessUrl;
|
|
115299
|
+
preferredAccessUrls = preferred.accessUrls;
|
|
115300
|
+
preferredAccessSource = preferred.accessUrlSource;
|
|
115301
|
+
}
|
|
115302
|
+
catch {
|
|
115303
|
+
// best-effort URL enrichment only
|
|
115304
|
+
}
|
|
115005
115305
|
// Send deployment notification to CodeBuddy IDE
|
|
115006
115306
|
try {
|
|
115007
|
-
// Query service details to get access URL
|
|
115008
|
-
let serviceUrl = "";
|
|
115009
|
-
try {
|
|
115010
|
-
const serviceDetails = await cloudrunService.detail({ serverName: input.serverName });
|
|
115011
|
-
// Extract access URL from service details
|
|
115012
|
-
// Priority: DefaultDomainName > CustomDomainName > PublicDomain > InternalDomain
|
|
115013
|
-
const details = serviceDetails; // Use any to access dynamic properties
|
|
115014
|
-
if (details?.BaseInfo?.DefaultDomainName) {
|
|
115015
|
-
// DefaultDomainName is already a complete URL (e.g., https://...)
|
|
115016
|
-
serviceUrl = details.BaseInfo.DefaultDomainName;
|
|
115017
|
-
}
|
|
115018
|
-
else if (details?.BaseInfo?.CustomDomainName) {
|
|
115019
|
-
// CustomDomainName might be a domain without protocol
|
|
115020
|
-
const customDomain = details.BaseInfo.CustomDomainName;
|
|
115021
|
-
serviceUrl = customDomain.startsWith('http') ? customDomain : `https://${customDomain}`;
|
|
115022
|
-
}
|
|
115023
|
-
else if (details?.BaseInfo?.PublicDomain) {
|
|
115024
|
-
serviceUrl = `https://${details.BaseInfo.PublicDomain}`;
|
|
115025
|
-
}
|
|
115026
|
-
else if (details?.BaseInfo?.InternalDomain) {
|
|
115027
|
-
serviceUrl = `https://${details.BaseInfo.InternalDomain}`;
|
|
115028
|
-
}
|
|
115029
|
-
else if (details?.AccessInfo?.PublicDomain) {
|
|
115030
|
-
serviceUrl = `https://${details.AccessInfo.PublicDomain}`;
|
|
115031
|
-
}
|
|
115032
|
-
else {
|
|
115033
|
-
serviceUrl = ""; // URL not available
|
|
115034
|
-
}
|
|
115035
|
-
}
|
|
115036
|
-
catch (detailErr) {
|
|
115037
|
-
// If query fails, continue with empty URL
|
|
115038
|
-
serviceUrl = "";
|
|
115039
|
-
}
|
|
115040
|
-
// Extract project name from targetPath
|
|
115041
115307
|
const projectName = path_1.default.basename(targetPath);
|
|
115042
|
-
// Send notification
|
|
115043
115308
|
await (0, notification_js_1.sendDeployNotification)(server, {
|
|
115044
115309
|
deployType: 'cloudrun',
|
|
115045
|
-
url:
|
|
115310
|
+
url: preferredAccessUrl ?? "",
|
|
115046
115311
|
projectId: currentEnvId,
|
|
115047
115312
|
projectName: projectName,
|
|
115048
115313
|
consoleUrl: consoleUrl
|
|
@@ -115053,8 +115318,8 @@ for await (let x of res.textStream) {
|
|
|
115053
115318
|
// Error is already logged in sendDeployNotification
|
|
115054
115319
|
}
|
|
115055
115320
|
const dbNetworkRisk = detectCloudRunDbNetworkRisk({
|
|
115056
|
-
envParams:
|
|
115057
|
-
vpcConf:
|
|
115321
|
+
envParams: effectiveServerConfig?.EnvParams,
|
|
115322
|
+
vpcConf: effectiveServerConfig?.VpcConf,
|
|
115058
115323
|
});
|
|
115059
115324
|
const warnings = dbNetworkRisk ? [dbNetworkRisk] : [];
|
|
115060
115325
|
const warningSuffix = dbNetworkRisk
|
|
@@ -115073,6 +115338,25 @@ for await (let x of res.textStream) {
|
|
|
115073
115338
|
serverType: serverType,
|
|
115074
115339
|
cloudbasercGenerated: true,
|
|
115075
115340
|
consoleUrl,
|
|
115341
|
+
...(existingService
|
|
115342
|
+
? {
|
|
115343
|
+
configMerge: {
|
|
115344
|
+
existingService: true,
|
|
115345
|
+
mergedFromRemote,
|
|
115346
|
+
appliedConfig: (0, cloudrun_config_js_1.summarizeConfigSnapshot)(effectiveServerConfig),
|
|
115347
|
+
...(verifiedConfigSnapshot
|
|
115348
|
+
? { verifiedAfterDeploy: verifiedConfigSnapshot }
|
|
115349
|
+
: {}),
|
|
115350
|
+
},
|
|
115351
|
+
}
|
|
115352
|
+
: {}),
|
|
115353
|
+
...(preferredAccessUrl ? { accessUrl: preferredAccessUrl } : {}),
|
|
115354
|
+
...(preferredAccessUrls.length > 0
|
|
115355
|
+
? { accessUrls: preferredAccessUrls }
|
|
115356
|
+
: {}),
|
|
115357
|
+
...(preferredAccessSource
|
|
115358
|
+
? { accessUrlSource: preferredAccessSource }
|
|
115359
|
+
: {}),
|
|
115076
115360
|
...(warnings.length > 0 ? { warnings } : {}),
|
|
115077
115361
|
},
|
|
115078
115362
|
message: `Triggered deployment for ${serverType} service '${input.serverName}' from ${targetPath}. You can follow the progress in ${consoleUrl}.${warningSuffix}`
|
|
@@ -115081,6 +115365,125 @@ for await (let x of res.textStream) {
|
|
|
115081
115365
|
]
|
|
115082
115366
|
};
|
|
115083
115367
|
}
|
|
115368
|
+
case 'updateConfig': {
|
|
115369
|
+
if (!input.serverConfig || Object.keys(input.serverConfig).length === 0) {
|
|
115370
|
+
throw new Error("serverConfig with at least one field is required for updateConfig");
|
|
115371
|
+
}
|
|
115372
|
+
let remoteServerConfig = {};
|
|
115373
|
+
try {
|
|
115374
|
+
const details = await cloudrunService.detail({
|
|
115375
|
+
serverName: input.serverName,
|
|
115376
|
+
});
|
|
115377
|
+
remoteServerConfig = (details.ServerConfig ||
|
|
115378
|
+
{});
|
|
115379
|
+
}
|
|
115380
|
+
catch (error) {
|
|
115381
|
+
throw new Error(buildManageCloudRunErrorMessage("updateConfig", input.serverName, error));
|
|
115382
|
+
}
|
|
115383
|
+
// EnvParams on Diff replaces the whole blob — merge keys unless replaceAll.
|
|
115384
|
+
const dirty = { ...input.serverConfig };
|
|
115385
|
+
if (Object.prototype.hasOwnProperty.call(input.serverConfig, "EnvParams")) {
|
|
115386
|
+
const { merged } = (0, cloudrun_config_js_1.mergeCloudRunServerConfig)({
|
|
115387
|
+
remote: { EnvParams: remoteServerConfig.EnvParams },
|
|
115388
|
+
input: { EnvParams: input.serverConfig.EnvParams },
|
|
115389
|
+
envParamsReplaceAll: Boolean(input.envParamsReplaceAll),
|
|
115390
|
+
});
|
|
115391
|
+
if (merged.EnvParams !== undefined) {
|
|
115392
|
+
dirty.EnvParams = merged.EnvParams;
|
|
115393
|
+
}
|
|
115394
|
+
}
|
|
115395
|
+
let Items;
|
|
115396
|
+
try {
|
|
115397
|
+
Items = (0, cloudrun_config_js_1.parseServerConfigToDiffItems)(dirty);
|
|
115398
|
+
}
|
|
115399
|
+
catch (error) {
|
|
115400
|
+
throw new Error(buildManageCloudRunErrorMessage("updateConfig", input.serverName, error));
|
|
115401
|
+
}
|
|
115402
|
+
if (Items.length === 0) {
|
|
115403
|
+
return {
|
|
115404
|
+
content: [
|
|
115405
|
+
{
|
|
115406
|
+
type: "text",
|
|
115407
|
+
text: JSON.stringify({
|
|
115408
|
+
success: true,
|
|
115409
|
+
data: {
|
|
115410
|
+
serviceName: input.serverName,
|
|
115411
|
+
status: "noop",
|
|
115412
|
+
itemsCount: 0,
|
|
115413
|
+
appliedConfig: (0, cloudrun_config_js_1.summarizeConfigSnapshot)(dirty),
|
|
115414
|
+
verifiedConfig: (0, cloudrun_config_js_1.summarizeConfigSnapshot)(remoteServerConfig),
|
|
115415
|
+
},
|
|
115416
|
+
message: `No effective config changes for '${input.serverName}'.`,
|
|
115417
|
+
}, null, 2),
|
|
115418
|
+
},
|
|
115419
|
+
],
|
|
115420
|
+
};
|
|
115421
|
+
}
|
|
115422
|
+
const currentEnvId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
115423
|
+
if (!manager.commonService) {
|
|
115424
|
+
throw new Error("Current CloudBase Manager does not support commonService; cannot call SubmitServerConfigChangeDiff.");
|
|
115425
|
+
}
|
|
115426
|
+
let diffResult;
|
|
115427
|
+
try {
|
|
115428
|
+
diffResult = await manager
|
|
115429
|
+
.commonService("tcbr", "2022-02-17")
|
|
115430
|
+
.call({
|
|
115431
|
+
Action: "SubmitServerConfigChangeDiff",
|
|
115432
|
+
Param: {
|
|
115433
|
+
EnvId: currentEnvId,
|
|
115434
|
+
ServerName: input.serverName,
|
|
115435
|
+
Items,
|
|
115436
|
+
},
|
|
115437
|
+
});
|
|
115438
|
+
}
|
|
115439
|
+
catch (error) {
|
|
115440
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
115441
|
+
if (/ResourceInUse|task|running|进行中/i.test(msg)) {
|
|
115442
|
+
throw new Error(buildManageCloudRunErrorMessage("updateConfig", input.serverName, new Error(`${msg} A deploy or config task may still be running. Wait, then retry; or use queryCloudRun(action="getDeployLog").`)));
|
|
115443
|
+
}
|
|
115444
|
+
throw new Error(buildManageCloudRunErrorMessage("updateConfig", input.serverName, error));
|
|
115445
|
+
}
|
|
115446
|
+
let verifiedConfig = (0, cloudrun_config_js_1.summarizeConfigSnapshot)(remoteServerConfig);
|
|
115447
|
+
try {
|
|
115448
|
+
const after = await cloudrunService.detail({
|
|
115449
|
+
serverName: input.serverName,
|
|
115450
|
+
});
|
|
115451
|
+
verifiedConfig = (0, cloudrun_config_js_1.summarizeConfigSnapshot)(after?.ServerConfig);
|
|
115452
|
+
}
|
|
115453
|
+
catch {
|
|
115454
|
+
// best-effort verify
|
|
115455
|
+
}
|
|
115456
|
+
const likelyRedeploy = (0, cloudrun_config_js_1.listLikelyRedeployFields)(dirty);
|
|
115457
|
+
const consoleUrl = `https://tcb.cloud.tencent.com/dev?envId=${currentEnvId}#/platform-run/service/detail?serverName=${input.serverName}&tabId=overview&envId=${currentEnvId}`;
|
|
115458
|
+
const taskId = diffResult?.TaskId ??
|
|
115459
|
+
diffResult?.Response?.TaskId ??
|
|
115460
|
+
diffResult?.taskId;
|
|
115461
|
+
const redeployHint = likelyRedeploy.length > 0
|
|
115462
|
+
? ` Fields that often trigger redeploy-with-online-image: ${likelyRedeploy.join(", ")}.`
|
|
115463
|
+
: " Change may apply as a hot update (e.g. MinNum/MaxNum/AccessTypes).";
|
|
115464
|
+
return {
|
|
115465
|
+
content: [
|
|
115466
|
+
{
|
|
115467
|
+
type: "text",
|
|
115468
|
+
text: JSON.stringify({
|
|
115469
|
+
success: true,
|
|
115470
|
+
data: {
|
|
115471
|
+
serviceName: input.serverName,
|
|
115472
|
+
status: "configUpdating",
|
|
115473
|
+
itemsCount: Items.length,
|
|
115474
|
+
itemsKeys: Items.map((i) => i.Key),
|
|
115475
|
+
...(taskId ? { taskId } : {}),
|
|
115476
|
+
appliedConfig: (0, cloudrun_config_js_1.summarizeConfigSnapshot)(dirty),
|
|
115477
|
+
verifiedConfig,
|
|
115478
|
+
likelyRedeployFields: likelyRedeploy,
|
|
115479
|
+
consoleUrl,
|
|
115480
|
+
},
|
|
115481
|
+
message: `Submitted config change for '${input.serverName}'.${redeployHint} Verify with queryCloudRun(action="detail"). Console: ${consoleUrl}`,
|
|
115482
|
+
}, null, 2),
|
|
115483
|
+
},
|
|
115484
|
+
],
|
|
115485
|
+
};
|
|
115486
|
+
}
|
|
115084
115487
|
case 'run': {
|
|
115085
115488
|
if (!targetPath) {
|
|
115086
115489
|
throw new Error("targetPath is required for run operation");
|
|
@@ -117768,6 +118171,7 @@ const zod_1 = __webpack_require__(21614);
|
|
|
117768
118171
|
const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
117769
118172
|
const json_content_js_1 = __webpack_require__(4365);
|
|
117770
118173
|
const cloud_mode_js_1 = __webpack_require__(89684);
|
|
118174
|
+
const gateway_access_urls_js_1 = __webpack_require__(22435);
|
|
117771
118175
|
const QUERY_APP_ACTIONS = ["listApps", "getApp", "listAppVersions", "getAppVersion", "getBuildLog"];
|
|
117772
118176
|
const MANAGE_APP_ACTIONS = ["deployApp", "getUploadUrl", "deleteApp", "deleteAppVersion"];
|
|
117773
118177
|
const APP_FRAMEWORKS = ["vue", "react", "next", "nuxt", "vite", "angular", "static"];
|
|
@@ -118144,6 +118548,8 @@ function registerAppTools(server) {
|
|
|
118144
118548
|
let appInfo;
|
|
118145
118549
|
let domain;
|
|
118146
118550
|
let accessUrl;
|
|
118551
|
+
let accessUrls = [];
|
|
118552
|
+
let accessUrlSource;
|
|
118147
118553
|
let accessUrlLookupWarning;
|
|
118148
118554
|
try {
|
|
118149
118555
|
appInfo = await appService.describeAppInfo({
|
|
@@ -118152,9 +118558,34 @@ function registerAppTools(server) {
|
|
|
118152
118558
|
});
|
|
118153
118559
|
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, appInfo);
|
|
118154
118560
|
({ domain, accessUrl } = normalizeAccessUrlFromDomain(appInfo?.Domain));
|
|
118561
|
+
const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
118562
|
+
const gateway = await (0, gateway_access_urls_js_1.resolveGatewayAccessUrls)({
|
|
118563
|
+
envId,
|
|
118564
|
+
upstreamResourceName: serviceName,
|
|
118565
|
+
upstreamResourceTypes: ["STATIC_STORE"],
|
|
118566
|
+
getManager: async () => {
|
|
118567
|
+
const manager = await getManager();
|
|
118568
|
+
if (!manager) {
|
|
118569
|
+
throw new Error("cloudbase manager unavailable");
|
|
118570
|
+
}
|
|
118571
|
+
return manager;
|
|
118572
|
+
},
|
|
118573
|
+
});
|
|
118574
|
+
const preferred = (0, gateway_access_urls_js_1.preferGatewayOrFallback)({
|
|
118575
|
+
gateway,
|
|
118576
|
+
fallbackUrl: accessUrl,
|
|
118577
|
+
fallbackSource: "describeAppInfo.Domain",
|
|
118578
|
+
});
|
|
118579
|
+
accessUrl = preferred.accessUrl;
|
|
118580
|
+
accessUrls = preferred.accessUrls;
|
|
118581
|
+
accessUrlSource = preferred.accessUrlSource;
|
|
118155
118582
|
}
|
|
118156
118583
|
catch (error) {
|
|
118157
118584
|
accessUrlLookupWarning = error instanceof Error ? error.message : String(error);
|
|
118585
|
+
if (accessUrl) {
|
|
118586
|
+
accessUrls = [accessUrl];
|
|
118587
|
+
accessUrlSource = "describeAppInfo.Domain";
|
|
118588
|
+
}
|
|
118158
118589
|
}
|
|
118159
118590
|
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
118160
118591
|
action,
|
|
@@ -118163,7 +118594,8 @@ function registerAppTools(server) {
|
|
|
118163
118594
|
buildId: BuildId,
|
|
118164
118595
|
domain,
|
|
118165
118596
|
accessUrl,
|
|
118166
|
-
|
|
118597
|
+
accessUrls: accessUrls.length > 0 ? accessUrls : undefined,
|
|
118598
|
+
accessUrlSource,
|
|
118167
118599
|
accessUrlLookupWarning,
|
|
118168
118600
|
app: appInfo,
|
|
118169
118601
|
upload: { cosTimestamp: cosTs },
|
|
@@ -119537,6 +119969,7 @@ const path_1 = __importDefault(__webpack_require__(39902));
|
|
|
119537
119969
|
const zod_1 = __webpack_require__(21614);
|
|
119538
119970
|
const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
119539
119971
|
const cloud_mode_js_1 = __webpack_require__(89684);
|
|
119972
|
+
const gateway_access_urls_js_1 = __webpack_require__(22435);
|
|
119540
119973
|
const notification_js_1 = __webpack_require__(32720);
|
|
119541
119974
|
const tool_result_js_1 = __webpack_require__(9835);
|
|
119542
119975
|
const HOSTING_CDN_SWITCH_VALUES = ['on', 'off'];
|
|
@@ -120072,9 +120505,48 @@ function registerHostingTools(server) {
|
|
|
120072
120505
|
// StaticDomain there but not in DescribeStaticStore.
|
|
120073
120506
|
const cdnFromStore = (store.CdnDomain ?? store.StaticDomain);
|
|
120074
120507
|
const staticDomain = cdnFromStore || await resolveHostingStaticDomain(cloudbase, server.logger);
|
|
120075
|
-
const
|
|
120508
|
+
const fallbackAccessUrl = buildHostingAccessUrl(staticDomain, input.cloudPath, input.localPath);
|
|
120509
|
+
const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
120510
|
+
const gatewayCandidates = Array.from(new Set([
|
|
120511
|
+
store.StaticStoreName,
|
|
120512
|
+
store.Name,
|
|
120513
|
+
store.StoreName,
|
|
120514
|
+
store.Bucket,
|
|
120515
|
+
"staticstore",
|
|
120516
|
+
]
|
|
120517
|
+
.map((item) => (typeof item === "string" ? item.trim() : ""))
|
|
120518
|
+
.filter(Boolean)));
|
|
120519
|
+
let accessUrl = fallbackAccessUrl;
|
|
120520
|
+
let accessUrls = accessUrl ? [accessUrl] : [];
|
|
120521
|
+
let accessUrlSource = accessUrl
|
|
120522
|
+
? "hosting.staticDomain"
|
|
120523
|
+
: undefined;
|
|
120524
|
+
for (const upstreamName of gatewayCandidates) {
|
|
120525
|
+
const gateway = await (0, gateway_access_urls_js_1.resolveGatewayAccessUrls)({
|
|
120526
|
+
envId,
|
|
120527
|
+
upstreamResourceName: upstreamName,
|
|
120528
|
+
upstreamResourceTypes: ["STATIC_STORE"],
|
|
120529
|
+
getManager: async () => {
|
|
120530
|
+
const manager = await getManager();
|
|
120531
|
+
if (!manager) {
|
|
120532
|
+
throw new Error("cloudbase manager unavailable");
|
|
120533
|
+
}
|
|
120534
|
+
return manager;
|
|
120535
|
+
},
|
|
120536
|
+
});
|
|
120537
|
+
const preferred = (0, gateway_access_urls_js_1.preferGatewayOrFallback)({
|
|
120538
|
+
gateway,
|
|
120539
|
+
fallbackUrl: fallbackAccessUrl || undefined,
|
|
120540
|
+
fallbackSource: "hosting.staticDomain",
|
|
120541
|
+
});
|
|
120542
|
+
if (preferred.accessUrl) {
|
|
120543
|
+
accessUrl = preferred.accessUrl;
|
|
120544
|
+
accessUrls = preferred.accessUrls;
|
|
120545
|
+
accessUrlSource = preferred.accessUrlSource;
|
|
120546
|
+
break;
|
|
120547
|
+
}
|
|
120548
|
+
}
|
|
120076
120549
|
try {
|
|
120077
|
-
const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
120078
120550
|
let projectName = 'unknown';
|
|
120079
120551
|
if (input.localPath) {
|
|
120080
120552
|
try {
|
|
@@ -120109,6 +120581,8 @@ function registerHostingTools(server) {
|
|
|
120109
120581
|
ignore: input.ignore,
|
|
120110
120582
|
staticDomain,
|
|
120111
120583
|
accessUrl,
|
|
120584
|
+
accessUrls,
|
|
120585
|
+
accessUrlSource,
|
|
120112
120586
|
result,
|
|
120113
120587
|
nextActions: uploadPrefix ? [buildFindFilesNextStep(uploadPrefix.replace(/^\/+/, ''))] : undefined,
|
|
120114
120588
|
},
|
|
@@ -137205,7 +137679,7 @@ class TelemetryReporter {
|
|
|
137205
137679
|
const nodeVersion = process.version; // Node.js版本
|
|
137206
137680
|
const arch = os_1.default.arch(); // 系统架构
|
|
137207
137681
|
// 从构建时注入的版本号获取MCP版本信息
|
|
137208
|
-
const mcpVersion = process.env.npm_package_version || "2.25.
|
|
137682
|
+
const mcpVersion = process.env.npm_package_version || "2.25.2" || 0;
|
|
137209
137683
|
return {
|
|
137210
137684
|
userAgent: `${osType} ${osRelease} ${arch} ${nodeVersion} CloudBase-MCP/${mcpVersion}`,
|
|
137211
137685
|
deviceId: this.deviceId,
|
|
@@ -148174,6 +148648,220 @@ function compileAsync(schema, meta, callback) {
|
|
|
148174
148648
|
}
|
|
148175
148649
|
|
|
148176
148650
|
|
|
148651
|
+
/***/ }),
|
|
148652
|
+
|
|
148653
|
+
/***/ 48266:
|
|
148654
|
+
/***/ ((__unused_webpack_module, exports) => {
|
|
148655
|
+
|
|
148656
|
+
"use strict";
|
|
148657
|
+
|
|
148658
|
+
/**
|
|
148659
|
+
* CloudRun serverConfig merge (RMW) and DiffConfigItem helpers.
|
|
148660
|
+
* Aligns with console SubmitServerConfigChangeDiff field mapping.
|
|
148661
|
+
*/
|
|
148662
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
148663
|
+
exports.CONFIG_FIELDS_LIKELY_REDEPLOY = void 0;
|
|
148664
|
+
exports.mergeCloudRunServerConfig = mergeCloudRunServerConfig;
|
|
148665
|
+
exports.assertCpuMemPair = assertCpuMemPair;
|
|
148666
|
+
exports.parseServerConfigToDiffItems = parseServerConfigToDiffItems;
|
|
148667
|
+
exports.summarizeConfigSnapshot = summarizeConfigSnapshot;
|
|
148668
|
+
exports.listLikelyRedeployFields = listLikelyRedeployFields;
|
|
148669
|
+
const SUBMIT_DIFF_MAP = {
|
|
148670
|
+
Cpu: "CpuSpecs",
|
|
148671
|
+
Mem: "MemSpecs",
|
|
148672
|
+
OpenAccessTypes: "AccessTypes",
|
|
148673
|
+
EnvParams: "EnvParam",
|
|
148674
|
+
CustomLogs: "LogPath",
|
|
148675
|
+
};
|
|
148676
|
+
const STRING_KEYS = new Set([
|
|
148677
|
+
"CustomLogs",
|
|
148678
|
+
"EnvParams",
|
|
148679
|
+
"CreateTime",
|
|
148680
|
+
"Dockerfile",
|
|
148681
|
+
"BuildDir",
|
|
148682
|
+
"LogType",
|
|
148683
|
+
"LogSetId",
|
|
148684
|
+
"LogTopicId",
|
|
148685
|
+
"LogParseType",
|
|
148686
|
+
"Tag",
|
|
148687
|
+
"InternalAccess",
|
|
148688
|
+
"InternalDomain",
|
|
148689
|
+
"OperationMode",
|
|
148690
|
+
"SessionAffinity",
|
|
148691
|
+
]);
|
|
148692
|
+
const INT_KEYS = new Set(["MinNum", "MaxNum", "InitialDelaySeconds", "Port"]);
|
|
148693
|
+
const BOOL_KEYS = new Set(["HasDockerfile"]);
|
|
148694
|
+
const FLOAT_KEYS = new Set(["Cpu", "Mem"]);
|
|
148695
|
+
const ARRAY_KEYS = new Set(["OpenAccessTypes", "EntryPoint", "Cmd"]);
|
|
148696
|
+
function parseEnvParamsObject(raw) {
|
|
148697
|
+
if (!raw || !String(raw).trim()) {
|
|
148698
|
+
return {};
|
|
148699
|
+
}
|
|
148700
|
+
try {
|
|
148701
|
+
const value = JSON.parse(String(raw));
|
|
148702
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
148703
|
+
return {};
|
|
148704
|
+
}
|
|
148705
|
+
const out = {};
|
|
148706
|
+
for (const [k, v] of Object.entries(value)) {
|
|
148707
|
+
if (v === undefined || v === null)
|
|
148708
|
+
continue;
|
|
148709
|
+
out[k] = typeof v === "string" ? v : String(v);
|
|
148710
|
+
}
|
|
148711
|
+
return out;
|
|
148712
|
+
}
|
|
148713
|
+
catch {
|
|
148714
|
+
return {};
|
|
148715
|
+
}
|
|
148716
|
+
}
|
|
148717
|
+
function stringifyEnvParams(obj) {
|
|
148718
|
+
return JSON.stringify(obj);
|
|
148719
|
+
}
|
|
148720
|
+
function isCompleteVpcConf(vpc) {
|
|
148721
|
+
return Boolean(vpc?.VpcId?.trim() && vpc?.SubnetId?.trim());
|
|
148722
|
+
}
|
|
148723
|
+
/**
|
|
148724
|
+
* Merge remote ServerConfig with deploy/update input.
|
|
148725
|
+
* Explicit input wins for provided fields; EnvParams merges by key unless replaceAll.
|
|
148726
|
+
*/
|
|
148727
|
+
function mergeCloudRunServerConfig(options) {
|
|
148728
|
+
const remote = options.remote || {};
|
|
148729
|
+
const input = options.input || {};
|
|
148730
|
+
const mergedFromRemote = [];
|
|
148731
|
+
const merged = { ...input };
|
|
148732
|
+
if (isCompleteVpcConf(input.VpcConf)) {
|
|
148733
|
+
merged.VpcConf = {
|
|
148734
|
+
VpcId: input.VpcConf.VpcId.trim(),
|
|
148735
|
+
SubnetId: input.VpcConf.SubnetId.trim(),
|
|
148736
|
+
...(input.VpcConf.VpcCIDR ? { VpcCIDR: input.VpcConf.VpcCIDR } : {}),
|
|
148737
|
+
...(input.VpcConf.SubnetCIDR ? { SubnetCIDR: input.VpcConf.SubnetCIDR } : {}),
|
|
148738
|
+
};
|
|
148739
|
+
}
|
|
148740
|
+
else if (isCompleteVpcConf(remote.VpcConf)) {
|
|
148741
|
+
merged.VpcConf = {
|
|
148742
|
+
VpcId: remote.VpcConf.VpcId.trim(),
|
|
148743
|
+
SubnetId: remote.VpcConf.SubnetId.trim(),
|
|
148744
|
+
...(remote.VpcConf.VpcCIDR ? { VpcCIDR: remote.VpcConf.VpcCIDR } : {}),
|
|
148745
|
+
...(remote.VpcConf.SubnetCIDR ? { SubnetCIDR: remote.VpcConf.SubnetCIDR } : {}),
|
|
148746
|
+
};
|
|
148747
|
+
mergedFromRemote.push("VpcConf");
|
|
148748
|
+
}
|
|
148749
|
+
else {
|
|
148750
|
+
delete merged.VpcConf;
|
|
148751
|
+
}
|
|
148752
|
+
const inputHasEnv = Object.prototype.hasOwnProperty.call(input, "EnvParams");
|
|
148753
|
+
const remoteEnv = parseEnvParamsObject(remote.EnvParams);
|
|
148754
|
+
const inputEnv = parseEnvParamsObject(input.EnvParams);
|
|
148755
|
+
if (options.envParamsReplaceAll && inputHasEnv) {
|
|
148756
|
+
merged.EnvParams = stringifyEnvParams(inputEnv);
|
|
148757
|
+
}
|
|
148758
|
+
else if (inputHasEnv || Object.keys(remoteEnv).length > 0) {
|
|
148759
|
+
const combined = options.envParamsReplaceAll
|
|
148760
|
+
? { ...inputEnv }
|
|
148761
|
+
: { ...remoteEnv, ...inputEnv };
|
|
148762
|
+
if (Object.keys(remoteEnv).length > 0 && !options.envParamsReplaceAll) {
|
|
148763
|
+
const preserved = Object.keys(remoteEnv).filter((k) => !(k in inputEnv));
|
|
148764
|
+
if (preserved.length > 0) {
|
|
148765
|
+
mergedFromRemote.push("EnvParams");
|
|
148766
|
+
}
|
|
148767
|
+
}
|
|
148768
|
+
if (Object.keys(combined).length > 0 || inputHasEnv) {
|
|
148769
|
+
merged.EnvParams = stringifyEnvParams(combined);
|
|
148770
|
+
}
|
|
148771
|
+
}
|
|
148772
|
+
// Must be explicit so Manager SDK update path cannot wipe with OA/PUBLIC/MINIAPP defaults.
|
|
148773
|
+
if (Array.isArray(input.OpenAccessTypes) && input.OpenAccessTypes.length > 0) {
|
|
148774
|
+
merged.OpenAccessTypes = [...input.OpenAccessTypes];
|
|
148775
|
+
}
|
|
148776
|
+
else if (Array.isArray(remote.OpenAccessTypes) && remote.OpenAccessTypes.length > 0) {
|
|
148777
|
+
merged.OpenAccessTypes = [...remote.OpenAccessTypes];
|
|
148778
|
+
mergedFromRemote.push("OpenAccessTypes");
|
|
148779
|
+
}
|
|
148780
|
+
return { merged, mergedFromRemote };
|
|
148781
|
+
}
|
|
148782
|
+
function assertCpuMemPair(config) {
|
|
148783
|
+
const hasCpu = config.Cpu !== undefined && config.Cpu !== null;
|
|
148784
|
+
const hasMem = config.Mem !== undefined && config.Mem !== null;
|
|
148785
|
+
if (hasCpu !== hasMem) {
|
|
148786
|
+
throw new Error("Cpu and Mem must be provided together when updating CloudRun config (platform requires the pair).");
|
|
148787
|
+
}
|
|
148788
|
+
}
|
|
148789
|
+
/**
|
|
148790
|
+
* Convert serverConfig object to DiffConfigItem[] for SubmitServerConfigChangeDiff.
|
|
148791
|
+
*/
|
|
148792
|
+
function parseServerConfigToDiffItems(data) {
|
|
148793
|
+
assertCpuMemPair(data);
|
|
148794
|
+
const Items = [];
|
|
148795
|
+
for (const [k, v] of Object.entries(data)) {
|
|
148796
|
+
if (v === undefined || v === null)
|
|
148797
|
+
continue;
|
|
148798
|
+
const Key = SUBMIT_DIFF_MAP[k] || k;
|
|
148799
|
+
if (STRING_KEYS.has(k)) {
|
|
148800
|
+
if (v !== "") {
|
|
148801
|
+
Items.push({ Key, Value: String(v) });
|
|
148802
|
+
}
|
|
148803
|
+
}
|
|
148804
|
+
else if (INT_KEYS.has(k)) {
|
|
148805
|
+
Items.push({ Key, IntValue: Number(v) });
|
|
148806
|
+
}
|
|
148807
|
+
else if (BOOL_KEYS.has(k)) {
|
|
148808
|
+
Items.push({ Key, BoolValue: Boolean(v) });
|
|
148809
|
+
}
|
|
148810
|
+
else if (FLOAT_KEYS.has(k)) {
|
|
148811
|
+
Items.push({ Key, FloatValue: Number(v) });
|
|
148812
|
+
}
|
|
148813
|
+
else if (ARRAY_KEYS.has(k)) {
|
|
148814
|
+
Items.push({ Key, ArrayValue: v });
|
|
148815
|
+
}
|
|
148816
|
+
else if (k === "PolicyDetails") {
|
|
148817
|
+
Items.push({ Key, PolicyDetails: v });
|
|
148818
|
+
}
|
|
148819
|
+
else if (k === "TimerScale") {
|
|
148820
|
+
Items.push({ Key, TimerScale: v });
|
|
148821
|
+
}
|
|
148822
|
+
else if (k === "VpcConf") {
|
|
148823
|
+
Items.push({ Key, VpcConf: v });
|
|
148824
|
+
}
|
|
148825
|
+
else if (k === "VolumesConf") {
|
|
148826
|
+
Items.push({ Key, VolumesConf: v });
|
|
148827
|
+
}
|
|
148828
|
+
else if (k === "PublicNetConf") {
|
|
148829
|
+
Items.push({ Key, PublicNetConf: v });
|
|
148830
|
+
}
|
|
148831
|
+
}
|
|
148832
|
+
return Items;
|
|
148833
|
+
}
|
|
148834
|
+
function summarizeConfigSnapshot(config) {
|
|
148835
|
+
const vpc = config?.VpcConf;
|
|
148836
|
+
const envKeys = Object.keys(parseEnvParamsObject(config?.EnvParams));
|
|
148837
|
+
return {
|
|
148838
|
+
hasVpcConf: isCompleteVpcConf(vpc),
|
|
148839
|
+
...(vpc?.VpcId ? { vpcId: vpc.VpcId } : {}),
|
|
148840
|
+
...(vpc?.SubnetId ? { subnetId: vpc.SubnetId } : {}),
|
|
148841
|
+
...(Array.isArray(config?.OpenAccessTypes)
|
|
148842
|
+
? { openAccessTypes: config.OpenAccessTypes }
|
|
148843
|
+
: {}),
|
|
148844
|
+
envParamKeys: envKeys,
|
|
148845
|
+
};
|
|
148846
|
+
}
|
|
148847
|
+
exports.CONFIG_FIELDS_LIKELY_REDEPLOY = [
|
|
148848
|
+
"VpcConf",
|
|
148849
|
+
"EnvParams",
|
|
148850
|
+
"Cpu",
|
|
148851
|
+
"Mem",
|
|
148852
|
+
"Port",
|
|
148853
|
+
"Dockerfile",
|
|
148854
|
+
"BuildDir",
|
|
148855
|
+
"VolumesConf",
|
|
148856
|
+
"LogType",
|
|
148857
|
+
"LogSetId",
|
|
148858
|
+
"LogTopicId",
|
|
148859
|
+
];
|
|
148860
|
+
function listLikelyRedeployFields(config) {
|
|
148861
|
+
return exports.CONFIG_FIELDS_LIKELY_REDEPLOY.filter((k) => Object.prototype.hasOwnProperty.call(config, k));
|
|
148862
|
+
}
|
|
148863
|
+
|
|
148864
|
+
|
|
148177
148865
|
/***/ }),
|
|
148178
148866
|
|
|
148179
148867
|
/***/ 48303:
|
|
@@ -197301,7 +197989,7 @@ ${envIdSection}
|
|
|
197301
197989
|
## 环境信息
|
|
197302
197990
|
- 操作系统: ${os_1.default.type()} ${os_1.default.release()}
|
|
197303
197991
|
- Node.js版本: ${process.version}
|
|
197304
|
-
- MCP 版本:${process.env.npm_package_version || "2.25.
|
|
197992
|
+
- MCP 版本:${process.env.npm_package_version || "2.25.2" || 0}
|
|
197305
197993
|
- 系统架构: ${os_1.default.arch()}
|
|
197306
197994
|
- 时间: ${new Date().toISOString()}
|
|
197307
197995
|
- 请求ID: ${requestId}
|
|
@@ -197382,7 +198070,7 @@ function createWrappedHandler(name, handler, server) {
|
|
|
197382
198070
|
requestId: (typeof error === 'object' && error && 'requestId' in error) ? error.requestId : '',
|
|
197383
198071
|
ide: server.ide || process.env.INTEGRATION_IDE || ''
|
|
197384
198072
|
});
|
|
197385
|
-
const mcpVersion = true ? "2.25.
|
|
198073
|
+
const mcpVersion = true ? "2.25.2" : 0;
|
|
197386
198074
|
const requestIdSuffix = requestId ? `\n🆔 RequestId: ${requestId}` : '';
|
|
197387
198075
|
const enhancedErrorMessage = `${errorMessage}${requestIdSuffix}\n\n📦 CloudBase MCP v${mcpVersion}\n🔗 遇到问题?请复制以下链接到浏览器打开\n即可自动携带错误详情快速创建 GitHub Issue:\n${issueLink}`;
|
|
197388
198076
|
// 创建新的错误对象,保持原有的错误类型但更新消息
|
|
@@ -213970,7 +214658,7 @@ function registerSetupTools(server) {
|
|
|
213970
214658
|
server.registerTool("downloadTemplate", {
|
|
213971
214659
|
title: "下载项目模板",
|
|
213972
214660
|
description: `自动下载并部署CloudBase项目模板。
|
|
213973
|
-
**Note**: Call this tool when the user requests to create a new project using a CloudBase template.\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- 其他IDE类型见下方列表\n\n注意:如果未传入 ide 参数且无法从环境变量检测到 IDE,将提示错误并要求传入 ide 参数\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- qoder: Qoder AI编辑器\n- antigravity: Google Antigravity AI编辑器\n- vscode: Visual Studio Code\n- kiro: Kiro AI编辑器\n- aider: Aider AI编辑器\n\n特别说明:\n- rules 模板会自动包含当前 mcp 版本号信息(版本号:${ true ? "2.25.
|
|
214661
|
+
**Note**: Call this tool when the user requests to create a new project using a CloudBase template.\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- 其他IDE类型见下方列表\n\n注意:如果未传入 ide 参数且无法从环境变量检测到 IDE,将提示错误并要求传入 ide 参数\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- qoder: Qoder AI编辑器\n- antigravity: Google Antigravity AI编辑器\n- vscode: Visual Studio Code\n- kiro: Kiro AI编辑器\n- aider: Aider AI编辑器\n\n特别说明:\n- rules 模板会自动包含当前 mcp 版本号信息(版本号:${ true ? "2.25.2" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
|
|
213974
214662
|
inputSchema: {
|
|
213975
214663
|
template: zod_1.z
|
|
213976
214664
|
.enum(["react", "vue", "miniprogram", "uniapp", "rules"])
|
|
@@ -231068,6 +231756,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
|
231068
231756
|
exports.registerGatewayTools = registerGatewayTools;
|
|
231069
231757
|
const zod_1 = __webpack_require__(21614);
|
|
231070
231758
|
const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
231759
|
+
const gateway_access_urls_js_1 = __webpack_require__(22435);
|
|
231071
231760
|
const json_content_js_1 = __webpack_require__(4365);
|
|
231072
231761
|
const QUERY_GATEWAY_ACTIONS = [
|
|
231073
231762
|
"listRoutes",
|
|
@@ -231143,9 +231832,33 @@ function registerGatewayTools(server) {
|
|
|
231143
231832
|
IsDefault: domainItem.IsDefault,
|
|
231144
231833
|
...route,
|
|
231145
231834
|
})));
|
|
231146
|
-
const buildRouteUrls = (routes) =>
|
|
231147
|
-
.
|
|
231148
|
-
|
|
231835
|
+
const buildRouteUrls = (routes) => {
|
|
231836
|
+
const candidates = routes.map((route) => ({
|
|
231837
|
+
Domain: route.Domain,
|
|
231838
|
+
Path: route.Path,
|
|
231839
|
+
IsDefault: route.IsDefault,
|
|
231840
|
+
UpstreamResourceType: route.UpstreamResourceType,
|
|
231841
|
+
UpstreamResourceName: route.UpstreamResourceName,
|
|
231842
|
+
}));
|
|
231843
|
+
return (0, gateway_access_urls_js_1.rankGatewayAccessUrls)(candidates).map((item) => item.url);
|
|
231844
|
+
};
|
|
231845
|
+
const buildAccessUrlFields = (routes) => {
|
|
231846
|
+
const candidates = routes.map((route) => ({
|
|
231847
|
+
Domain: route.Domain,
|
|
231848
|
+
Path: route.Path,
|
|
231849
|
+
IsDefault: route.IsDefault,
|
|
231850
|
+
UpstreamResourceType: route.UpstreamResourceType,
|
|
231851
|
+
UpstreamResourceName: route.UpstreamResourceName,
|
|
231852
|
+
}));
|
|
231853
|
+
const envelope = (0, gateway_access_urls_js_1.toAccessUrlEnvelope)((0, gateway_access_urls_js_1.rankGatewayAccessUrls)(candidates));
|
|
231854
|
+
return {
|
|
231855
|
+
...(envelope.accessUrl ? { accessUrl: envelope.accessUrl } : {}),
|
|
231856
|
+
accessUrls: envelope.accessUrls,
|
|
231857
|
+
...(envelope.accessUrlSource
|
|
231858
|
+
? { accessUrlSource: envelope.accessUrlSource }
|
|
231859
|
+
: {}),
|
|
231860
|
+
};
|
|
231861
|
+
};
|
|
231149
231862
|
const resolveDefaultHttpDomain = async () => {
|
|
231150
231863
|
const routeInfo = await listHttpServiceRoutes();
|
|
231151
231864
|
const domains = routeInfo.Domains ?? [];
|
|
@@ -231256,6 +231969,7 @@ function registerGatewayTools(server) {
|
|
|
231256
231969
|
action: input.action,
|
|
231257
231970
|
routes,
|
|
231258
231971
|
urls: buildRouteUrls(routes),
|
|
231972
|
+
...buildAccessUrlFields(routes),
|
|
231259
231973
|
total: result.TotalCount ?? routes.length,
|
|
231260
231974
|
raw: result,
|
|
231261
231975
|
}, `已获取 ${result.TotalCount ?? routes.length} 条 HTTP 路由`);
|
|
@@ -231297,6 +232011,7 @@ function registerGatewayTools(server) {
|
|
|
231297
232011
|
routes: matches,
|
|
231298
232012
|
total: matches.length,
|
|
231299
232013
|
urls,
|
|
232014
|
+
...buildAccessUrlFields(matches),
|
|
231300
232015
|
raw: result,
|
|
231301
232016
|
}, matches.length === 0
|
|
231302
232017
|
? "未找到对应路由"
|
|
@@ -231350,6 +232065,11 @@ function registerGatewayTools(server) {
|
|
|
231350
232065
|
upstreamResourceName: payload.resolved.upstreamResourceName,
|
|
231351
232066
|
auth: payload.resolved.enableAuth ?? null,
|
|
231352
232067
|
enablePathTransmission: payload.resolved.enablePathTransmission ?? null,
|
|
232068
|
+
accessUrl: `https://${payload.resolved.domain}${payload.resolved.path}`,
|
|
232069
|
+
accessUrls: [`https://${payload.resolved.domain}${payload.resolved.path}`],
|
|
232070
|
+
accessUrlSource: input.domain && input.domain === payload.resolved.domain
|
|
232071
|
+
? "gateway.custom"
|
|
232072
|
+
: "gateway.default",
|
|
231353
232073
|
raw: result,
|
|
231354
232074
|
}, `已为目标 ${payload.resolved.upstreamResourceName} 在域名 ${payload.resolved.domain} 创建路由 ${payload.resolved.path}(${payload.resolved.upstreamResourceType})` +
|
|
231355
232075
|
(payload.resolved.enablePathTransmission === true
|
|
@@ -231376,6 +232096,11 @@ function registerGatewayTools(server) {
|
|
|
231376
232096
|
upstreamResourceName: payload.resolved.upstreamResourceName,
|
|
231377
232097
|
auth: payload.resolved.enableAuth ?? null,
|
|
231378
232098
|
enablePathTransmission: payload.resolved.enablePathTransmission ?? null,
|
|
232099
|
+
accessUrl: `https://${payload.resolved.domain}${payload.resolved.path}`,
|
|
232100
|
+
accessUrls: [`https://${payload.resolved.domain}${payload.resolved.path}`],
|
|
232101
|
+
accessUrlSource: input.domain && input.domain === payload.resolved.domain
|
|
232102
|
+
? "gateway.custom"
|
|
232103
|
+
: "gateway.default",
|
|
231379
232104
|
raw: result,
|
|
231380
232105
|
}, `HTTP 路由更新成功(${payload.resolved.domain}${payload.resolved.path}` +
|
|
231381
232106
|
(payload.resolved.enablePathTransmission === true
|