@cloudbase/cloudbase-mcp 2.23.11 → 2.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli.cjs +3 -3
- package/dist/index.cjs +402 -160
- package/dist/index.d.ts +9 -0
- package/dist/index.js +270 -50
- package/package.json +8 -2
package/dist/index.cjs
CHANGED
|
@@ -1761,6 +1761,8 @@ warn.forProperties(exports, 'deprecated', ['emitErrs', 'levelLength']);
|
|
|
1761
1761
|
"use strict";
|
|
1762
1762
|
|
|
1763
1763
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
1764
|
+
exports.DEFAULT_CREATE_ENV_RESOURCES = exports.CREATE_ENV_RESOURCE_VALUES = void 0;
|
|
1765
|
+
exports.resolveCreateEnvResources = resolveCreateEnvResources;
|
|
1764
1766
|
exports.simplifyEnvList = simplifyEnvList;
|
|
1765
1767
|
exports.registerEnvTools = registerEnvTools;
|
|
1766
1768
|
const toolbox_1 = __webpack_require__(25901);
|
|
@@ -1770,6 +1772,26 @@ const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
|
1770
1772
|
const logger_js_1 = __webpack_require__(13039);
|
|
1771
1773
|
const tool_result_js_1 = __webpack_require__(9835);
|
|
1772
1774
|
const env_setup_js_1 = __webpack_require__(6978);
|
|
1775
|
+
/**
|
|
1776
|
+
* Resources accepted by CreateEnv. Matches Cloud API / Manager SDK contract.
|
|
1777
|
+
* `postgresql` enables CloudBase PostgreSQL (PG mode) when supported by the package.
|
|
1778
|
+
*/
|
|
1779
|
+
exports.CREATE_ENV_RESOURCE_VALUES = [
|
|
1780
|
+
"flexdb",
|
|
1781
|
+
"storage",
|
|
1782
|
+
"function",
|
|
1783
|
+
"postgresql",
|
|
1784
|
+
];
|
|
1785
|
+
/** Default Resources when callers omit the field (schema promises "all four"). */
|
|
1786
|
+
exports.DEFAULT_CREATE_ENV_RESOURCES = [
|
|
1787
|
+
...exports.CREATE_ENV_RESOURCE_VALUES,
|
|
1788
|
+
];
|
|
1789
|
+
function resolveCreateEnvResources(resources) {
|
|
1790
|
+
if (Array.isArray(resources) && resources.length > 0) {
|
|
1791
|
+
return [...resources];
|
|
1792
|
+
}
|
|
1793
|
+
return [...exports.DEFAULT_CREATE_ENV_RESOURCES];
|
|
1794
|
+
}
|
|
1773
1795
|
/**
|
|
1774
1796
|
* Simplify environment list data by keeping only essential fields for AI assistant
|
|
1775
1797
|
* This reduces token consumption when returning environment lists via MCP tools
|
|
@@ -2535,7 +2557,13 @@ function resolveToolAuthOptions(server, overrides) {
|
|
|
2535
2557
|
function registerEnvTools(server) {
|
|
2536
2558
|
// 获取 cloudBaseOptions,如果没有则为 undefined
|
|
2537
2559
|
const cloudBaseOptions = server.cloudBaseOptions;
|
|
2538
|
-
|
|
2560
|
+
// Default: env-scoped tools need a bound envId (domains / domain management use SDK this.envId).
|
|
2561
|
+
// manageEnv create/listPackages are account-level — use requireEnvId: false there only.
|
|
2562
|
+
const getManager = (options) => (0, cloudbase_manager_js_1.getCloudBaseManager)({
|
|
2563
|
+
cloudBaseOptions,
|
|
2564
|
+
requireEnvId: options?.requireEnvId ?? true,
|
|
2565
|
+
mcpServer: server,
|
|
2566
|
+
});
|
|
2539
2567
|
const getManagerForEnvQuery = (targetEnvId, requireEnvId = true) => (0, cloudbase_manager_js_1.getCloudBaseManager)({
|
|
2540
2568
|
cloudBaseOptions: targetEnvId && targetEnvId !== cloudBaseOptions?.envId
|
|
2541
2569
|
? {
|
|
@@ -3416,14 +3444,10 @@ function registerEnvTools(server) {
|
|
|
3416
3444
|
.string()
|
|
3417
3445
|
.optional()
|
|
3418
3446
|
.describe("套餐 ID(action=create/modifyPlan 时必填)。可选值如 baas_personal(个人版)、baas_pf_standard(标准版)、baas_pf_enterprise(企业版)"),
|
|
3419
|
-
region: zod_1.z
|
|
3420
|
-
.string()
|
|
3421
|
-
.optional()
|
|
3422
|
-
.describe("环境地域(action=create 时可选)。默认 ap-shanghai,可选 ap-guangzhou、ap-beijing 等"),
|
|
3423
3447
|
resources: zod_1.z
|
|
3424
|
-
.array(zod_1.z.enum(
|
|
3448
|
+
.array(zod_1.z.enum(exports.CREATE_ENV_RESOURCE_VALUES))
|
|
3425
3449
|
.optional()
|
|
3426
|
-
.describe("启用的资源类型(action=create
|
|
3450
|
+
.describe("启用的资源类型(action=create 时可选)。省略时默认全部四项:flexdb(文档数据库)、storage(存储)、function(云函数)、postgresql(PostgreSQL)。CreateEnv 要求 Resources 非空,MCP 会始终下发该字段。"),
|
|
3427
3451
|
duration: zod_1.z
|
|
3428
3452
|
.number()
|
|
3429
3453
|
.int()
|
|
@@ -3451,17 +3475,19 @@ function registerEnvTools(server) {
|
|
|
3451
3475
|
const action = rawArgs.action ?? "";
|
|
3452
3476
|
const alias = normalizeOptionalToolString(rawArgs.alias);
|
|
3453
3477
|
const packageId = normalizeOptionalToolString(rawArgs.packageId);
|
|
3454
|
-
const
|
|
3455
|
-
const resources = rawArgs.resources;
|
|
3478
|
+
const resolvedResources = resolveCreateEnvResources(rawArgs.resources);
|
|
3456
3479
|
const duration = rawArgs.duration ?? 1;
|
|
3457
3480
|
const envId = normalizeOptionalToolString(rawArgs.envId);
|
|
3458
3481
|
const confirmed = rawArgs.confirm === "yes";
|
|
3459
3482
|
try {
|
|
3460
|
-
const cloudbase = await getManager();
|
|
3483
|
+
const cloudbase = await getManager({ requireEnvId: false });
|
|
3461
3484
|
switch (action) {
|
|
3462
3485
|
case "listPackages": {
|
|
3463
|
-
//
|
|
3464
|
-
const result = await cloudbase.env.describeBaasPackageList({
|
|
3486
|
+
// Query packages for new purchase. Source aligns with billing-side Baas package APIs.
|
|
3487
|
+
const result = await cloudbase.env.describeBaasPackageList({
|
|
3488
|
+
TargetAction: "new",
|
|
3489
|
+
Source: "qcloud",
|
|
3490
|
+
});
|
|
3465
3491
|
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
3466
3492
|
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
3467
3493
|
ok: true,
|
|
@@ -3471,12 +3497,13 @@ function registerEnvTools(server) {
|
|
|
3471
3497
|
});
|
|
3472
3498
|
}
|
|
3473
3499
|
case "create": {
|
|
3474
|
-
//
|
|
3500
|
+
// CreateEnv (Manager SDK / Cloud API) accepts Alias, PackageId, Resources, Period, etc.
|
|
3501
|
+
// It does NOT accept Region — region is determined by account/package, not this call.
|
|
3475
3502
|
if (!confirmed) {
|
|
3476
3503
|
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
3477
3504
|
ok: false,
|
|
3478
3505
|
code: "CONFIRM_REQUIRED",
|
|
3479
|
-
message: `创建环境需要您确认。请确认以下配置信息后传入 confirm="yes":\n别名: ${alias}\n套餐: ${packageId}\n
|
|
3506
|
+
message: `创建环境需要您确认。请确认以下配置信息后传入 confirm="yes":\n别名: ${alias}\n套餐: ${packageId}\n资源类型: ${resolvedResources.join(", ")}\n时长: ${duration} 个月\n说明: CreateEnv 不接受 Region;环境地域由账号与套餐侧决定。`,
|
|
3480
3507
|
next_step: {
|
|
3481
3508
|
tool: "manageEnv",
|
|
3482
3509
|
action: "create",
|
|
@@ -3493,12 +3520,9 @@ function registerEnvTools(server) {
|
|
|
3493
3520
|
const createParams = {
|
|
3494
3521
|
Alias: alias,
|
|
3495
3522
|
PackageId: packageId,
|
|
3496
|
-
|
|
3523
|
+
Resources: resolvedResources,
|
|
3497
3524
|
Period: duration,
|
|
3498
3525
|
};
|
|
3499
|
-
if (resources && resources.length > 0) {
|
|
3500
|
-
createParams.Resources = resources;
|
|
3501
|
-
}
|
|
3502
3526
|
const result = await cloudbase.env.createEnv(createParams);
|
|
3503
3527
|
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
3504
3528
|
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
@@ -3506,6 +3530,7 @@ function registerEnvTools(server) {
|
|
|
3506
3530
|
code: "ENV_CREATED",
|
|
3507
3531
|
message: `环境创建成功!新环境 ID: ${result.EnvId}。环境初始化可能需要几分钟,请通过 queryEnv(action="info", envId="${result.EnvId}") 轮询直到 Status 为正常。`,
|
|
3508
3532
|
envId: result.EnvId,
|
|
3533
|
+
resources: resolvedResources,
|
|
3509
3534
|
});
|
|
3510
3535
|
}
|
|
3511
3536
|
case "modifyPlan": {
|
|
@@ -3583,11 +3608,19 @@ function registerEnvTools(server) {
|
|
|
3583
3608
|
if (toolPayloadResult) {
|
|
3584
3609
|
return toolPayloadResult;
|
|
3585
3610
|
}
|
|
3611
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
3612
|
+
if (action === "listPackages" && /billTags/i.test(errorMessage)) {
|
|
3613
|
+
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
3614
|
+
ok: false,
|
|
3615
|
+
code: "PACKAGE_LIST_FAILED",
|
|
3616
|
+
message: `查询套餐列表失败(计费标签 BillTags):${errorMessage}。可改用控制台查看套餐,或直接使用已知 packageId(如 baas_personal)调用 manageEnv(action="create")。`,
|
|
3617
|
+
});
|
|
3618
|
+
}
|
|
3586
3619
|
return {
|
|
3587
3620
|
content: [
|
|
3588
3621
|
{
|
|
3589
3622
|
type: "text",
|
|
3590
|
-
text: `环境管理操作失败: ${
|
|
3623
|
+
text: `环境管理操作失败: ${errorMessage}`,
|
|
3591
3624
|
},
|
|
3592
3625
|
],
|
|
3593
3626
|
};
|
|
@@ -136828,6 +136861,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
136828
136861
|
};
|
|
136829
136862
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
136830
136863
|
exports.reportToolkitLifecycle = exports.reportToolCall = exports.telemetryReporter = void 0;
|
|
136864
|
+
exports.extractMcpClientInfo = extractMcpClientInfo;
|
|
136865
|
+
exports.readMcpClientInfoFromServer = readMcpClientInfoFromServer;
|
|
136831
136866
|
const crypto_1 = __importDefault(__webpack_require__(55511));
|
|
136832
136867
|
const http_1 = __importDefault(__webpack_require__(81630));
|
|
136833
136868
|
const https_1 = __importDefault(__webpack_require__(55591));
|
|
@@ -136879,7 +136914,7 @@ class TelemetryReporter {
|
|
|
136879
136914
|
const nodeVersion = process.version; // Node.js版本
|
|
136880
136915
|
const arch = os_1.default.arch(); // 系统架构
|
|
136881
136916
|
// 从构建时注入的版本号获取MCP版本信息
|
|
136882
|
-
const mcpVersion = process.env.npm_package_version || "2.
|
|
136917
|
+
const mcpVersion = process.env.npm_package_version || "2.24.1" || 0;
|
|
136883
136918
|
return {
|
|
136884
136919
|
userAgent: `${osType} ${osRelease} ${arch} ${nodeVersion} CloudBase-MCP/${mcpVersion}`,
|
|
136885
136920
|
deviceId: this.deviceId,
|
|
@@ -137061,6 +137096,49 @@ function resolveEnvId(cloudBaseOptions) {
|
|
|
137061
137096
|
}
|
|
137062
137097
|
return { envId, envIdSource };
|
|
137063
137098
|
}
|
|
137099
|
+
/**
|
|
137100
|
+
* Normalize SDK Implementation / clientInfo into telemetry-safe fields.
|
|
137101
|
+
*/
|
|
137102
|
+
function extractMcpClientInfo(clientVersion) {
|
|
137103
|
+
if (!clientVersion || typeof clientVersion !== "object") {
|
|
137104
|
+
return {};
|
|
137105
|
+
}
|
|
137106
|
+
const info = clientVersion;
|
|
137107
|
+
const name = typeof info.name === "string" ? info.name.trim() : "";
|
|
137108
|
+
const version = typeof info.version === "string" ? info.version.trim() : "";
|
|
137109
|
+
const title = typeof info.title === "string" ? info.title.trim() : "";
|
|
137110
|
+
return {
|
|
137111
|
+
...(name ? { name } : {}),
|
|
137112
|
+
...(version ? { version } : {}),
|
|
137113
|
+
...(title ? { title } : {}),
|
|
137114
|
+
};
|
|
137115
|
+
}
|
|
137116
|
+
/**
|
|
137117
|
+
* Read MCP clientInfo from an McpServer after initialize.
|
|
137118
|
+
* Returns empty object when handshake has not completed or the accessor is unavailable.
|
|
137119
|
+
*/
|
|
137120
|
+
function readMcpClientInfoFromServer(server) {
|
|
137121
|
+
try {
|
|
137122
|
+
return extractMcpClientInfo(server?.server?.getClientVersion?.());
|
|
137123
|
+
}
|
|
137124
|
+
catch {
|
|
137125
|
+
return {};
|
|
137126
|
+
}
|
|
137127
|
+
}
|
|
137128
|
+
function appendMcpClientInfoFields(eventData, clientInfo) {
|
|
137129
|
+
if (!clientInfo) {
|
|
137130
|
+
return;
|
|
137131
|
+
}
|
|
137132
|
+
if (clientInfo.name) {
|
|
137133
|
+
eventData.mcpClientName = clientInfo.name;
|
|
137134
|
+
}
|
|
137135
|
+
if (clientInfo.version) {
|
|
137136
|
+
eventData.mcpClientVersion = clientInfo.version;
|
|
137137
|
+
}
|
|
137138
|
+
if (clientInfo.title) {
|
|
137139
|
+
eventData.mcpClientTitle = clientInfo.title;
|
|
137140
|
+
}
|
|
137141
|
+
}
|
|
137064
137142
|
// 便捷方法
|
|
137065
137143
|
const reportToolCall = async (params) => {
|
|
137066
137144
|
const { nodeVersion, osType, osRelease, arch, mcpVersion } = exports.telemetryReporter.getUserAgent();
|
|
@@ -137105,6 +137183,7 @@ const reportToolCall = async (params) => {
|
|
|
137105
137183
|
if (params.ide) {
|
|
137106
137184
|
eventData.ide = params.ide;
|
|
137107
137185
|
}
|
|
137186
|
+
appendMcpClientInfoFields(eventData, params.mcpClientInfo);
|
|
137108
137187
|
// Debug: 打印最终上报参数
|
|
137109
137188
|
(0, logger_js_1.debug)('[telemetry] 工具调用上报参数', {
|
|
137110
137189
|
toolName: params.toolName,
|
|
@@ -137147,6 +137226,7 @@ const reportToolkitLifecycle = async (params) => {
|
|
|
137147
137226
|
if (params.ide) {
|
|
137148
137227
|
eventData.ide = params.ide;
|
|
137149
137228
|
}
|
|
137229
|
+
appendMcpClientInfoFields(eventData, params.mcpClientInfo);
|
|
137150
137230
|
// Debug: 打印最终上报参数
|
|
137151
137231
|
(0, logger_js_1.debug)('[telemetry] 生命周期事件上报参数', {
|
|
137152
137232
|
event: params.event,
|
|
@@ -160486,6 +160566,38 @@ function classifySqlRisk(sql) {
|
|
|
160486
160566
|
requiresConfirm: true,
|
|
160487
160567
|
};
|
|
160488
160568
|
}
|
|
160569
|
+
/**
|
|
160570
|
+
* Schema DDL that must go through applyMigration by default.
|
|
160571
|
+
* Includes CREATE/ALTER/COMMENT (schema_change) and DROP/TRUNCATE / destructive ALTER.
|
|
160572
|
+
* Excludes DML DELETE and security_change (GRANT/POLICY), which may still use execute.
|
|
160573
|
+
*/
|
|
160574
|
+
function isSchemaDdlRisk(risk, sql) {
|
|
160575
|
+
if (risk === "schema_change") {
|
|
160576
|
+
return true;
|
|
160577
|
+
}
|
|
160578
|
+
if (risk !== "destructive") {
|
|
160579
|
+
return false;
|
|
160580
|
+
}
|
|
160581
|
+
const verb = getSqlVerb(stripLeadingSqlComments(sql));
|
|
160582
|
+
return ["DROP", "TRUNCATE", "ALTER"].includes(verb);
|
|
160583
|
+
}
|
|
160584
|
+
function buildLocalMigrationFileHint(version, name) {
|
|
160585
|
+
return `migrations/${version}_${name}.sql`;
|
|
160586
|
+
}
|
|
160587
|
+
const MIGRATION_VERSION_REQUIRED_MESSAGE = "migrationVersion is required (14-digit UTC timestamp YYYYMMDDHHMMSS). " +
|
|
160588
|
+
"Decide the version first, write local file migrations/<version>_<migrationName>.sql, " +
|
|
160589
|
+
"then call planMigration/applyMigration with the same migrationVersion and migrationName.";
|
|
160590
|
+
function requireExplicitMigrationVersion(args, actionLabel) {
|
|
160591
|
+
const version = args.migrationVersion?.trim();
|
|
160592
|
+
if (!version) {
|
|
160593
|
+
return buildPgToolResult({
|
|
160594
|
+
success: false,
|
|
160595
|
+
errorCode: "MIGRATION_VERSION_REQUIRED",
|
|
160596
|
+
message: `Provide migrationVersion when action=${actionLabel}. ${MIGRATION_VERSION_REQUIRED_MESSAGE}`,
|
|
160597
|
+
});
|
|
160598
|
+
}
|
|
160599
|
+
return version;
|
|
160600
|
+
}
|
|
160489
160601
|
function quoteIdentifier(identifier) {
|
|
160490
160602
|
return `"${identifier.replace(/"/g, '""')}"`;
|
|
160491
160603
|
}
|
|
@@ -160850,12 +160962,6 @@ async function executeManagerPGSql(context, sql, cloudBaseOptions) {
|
|
|
160850
160962
|
}
|
|
160851
160963
|
throw new Error("Current @cloudbase/manager-node runtime does not expose database.executePGSql or commonService fallback. Upgrade to @cloudbase/manager-node >= 5.4.0.");
|
|
160852
160964
|
}
|
|
160853
|
-
/** Generate a 14-digit migration version (YYYYMMDDHHMMSS) from current time */
|
|
160854
|
-
function generateMigrationVersion() {
|
|
160855
|
-
const d = new Date();
|
|
160856
|
-
const p = (n) => String(n).padStart(2, "0");
|
|
160857
|
-
return `${d.getFullYear()}${p(d.getMonth() + 1)}${p(d.getDate())}${p(d.getHours())}${p(d.getMinutes())}${p(d.getSeconds())}`;
|
|
160858
|
-
}
|
|
160859
160965
|
/** Call a CloudBase PG migration API via commonService fallback */
|
|
160860
160966
|
async function callPgMigrationApi(context, action, params, cloudBaseOptions) {
|
|
160861
160967
|
const manager = await (0, cloudbase_manager_js_1.getCloudBaseManager)({
|
|
@@ -161098,6 +161204,34 @@ async function handleExecuteSql(args, context, deps) {
|
|
|
161098
161204
|
});
|
|
161099
161205
|
}
|
|
161100
161206
|
const classification = classifySqlRisk(args.sql);
|
|
161207
|
+
if (isSchemaDdlRisk(classification.risk, args.sql) && args.allowDdlViaExecute !== true) {
|
|
161208
|
+
return buildPgToolResult({
|
|
161209
|
+
success: false,
|
|
161210
|
+
errorCode: "DDL_USE_APPLY_MIGRATION",
|
|
161211
|
+
message: "Schema DDL (CREATE/ALTER/DROP/TRUNCATE/...) must use applyMigration with an explicit migrationVersion, " +
|
|
161212
|
+
"not execute. Write local migrations/<version>_<name>.sql first, then call applyMigration. " +
|
|
161213
|
+
"Set allowDdlViaExecute=true only for exceptional one-off ops that intentionally bypass migration history.",
|
|
161214
|
+
data: {
|
|
161215
|
+
classification,
|
|
161216
|
+
localFileHintPattern: "migrations/<migrationVersion>_<migrationName>.sql",
|
|
161217
|
+
},
|
|
161218
|
+
nextActions: [
|
|
161219
|
+
buildNextAction(MANAGE_PG_DATABASE, "planMigration", "Preview the schema change as a versioned migration (provide migrationVersion + migrationName).", {
|
|
161220
|
+
action: "planMigration",
|
|
161221
|
+
migrationName: "describe_your_change",
|
|
161222
|
+
migrationVersion: "YYYYMMDDHHMMSS",
|
|
161223
|
+
sql: args.sql,
|
|
161224
|
+
}),
|
|
161225
|
+
buildNextAction(MANAGE_PG_DATABASE, "applyMigration", "Apply the schema change via PushPGUserMigrations with the same explicit migrationVersion.", {
|
|
161226
|
+
action: "applyMigration",
|
|
161227
|
+
migrationName: "describe_your_change",
|
|
161228
|
+
migrationVersion: "YYYYMMDDHHMMSS",
|
|
161229
|
+
sql: args.sql,
|
|
161230
|
+
confirm: true,
|
|
161231
|
+
}),
|
|
161232
|
+
],
|
|
161233
|
+
});
|
|
161234
|
+
}
|
|
161101
161235
|
if (!classification.readOnly && !args.confirm) {
|
|
161102
161236
|
return buildPgToolResult({
|
|
161103
161237
|
success: false,
|
|
@@ -161107,7 +161241,12 @@ async function handleExecuteSql(args, context, deps) {
|
|
|
161107
161241
|
classification,
|
|
161108
161242
|
},
|
|
161109
161243
|
nextActions: [
|
|
161110
|
-
buildNextAction(MANAGE_PG_DATABASE, "execute", "Re-issue with confirm=true to actually run the SQL.", {
|
|
161244
|
+
buildNextAction(MANAGE_PG_DATABASE, "execute", "Re-issue with confirm=true to actually run the SQL.", {
|
|
161245
|
+
action: "execute",
|
|
161246
|
+
sql: args.sql,
|
|
161247
|
+
confirm: true,
|
|
161248
|
+
...(args.allowDdlViaExecute === true ? { allowDdlViaExecute: true } : {}),
|
|
161249
|
+
}),
|
|
161111
161250
|
buildNextAction(QUERY_PG_DATABASE, "metadata", "Inspect table size and shape before destructive changes.", { action: "metadata", limit: 20 }),
|
|
161112
161251
|
],
|
|
161113
161252
|
});
|
|
@@ -161124,8 +161263,15 @@ async function handleExecuteSql(args, context, deps) {
|
|
|
161124
161263
|
.slice(0, 5)
|
|
161125
161264
|
.map((row) => serializeValue(row)),
|
|
161126
161265
|
targetTable: targetTable ?? null,
|
|
161266
|
+
...(args.allowDdlViaExecute === true && isSchemaDdlRisk(classification.risk, args.sql)
|
|
161267
|
+
? {
|
|
161268
|
+
warning: "DDL executed via allowDdlViaExecute bypasses migration history. Prefer applyMigration for reproducible schema changes.",
|
|
161269
|
+
}
|
|
161270
|
+
: {}),
|
|
161127
161271
|
},
|
|
161128
|
-
message:
|
|
161272
|
+
message: args.allowDdlViaExecute === true && isSchemaDdlRisk(classification.risk, args.sql)
|
|
161273
|
+
? "Write SQL executed successfully (DDL via allowDdlViaExecute; migration history was bypassed)."
|
|
161274
|
+
: "Write SQL executed successfully.",
|
|
161129
161275
|
nextActions: classification.risk === "schema_change" && targetTable
|
|
161130
161276
|
? [
|
|
161131
161277
|
buildNextAction(QUERY_PG_DATABASE, "schema", "Inspect the table schema, columns, indexes, and RLS policies after schema changes.", {
|
|
@@ -161153,6 +161299,43 @@ async function handleDryRun(args) {
|
|
|
161153
161299
|
});
|
|
161154
161300
|
}
|
|
161155
161301
|
const classification = classifySqlRisk(args.sql);
|
|
161302
|
+
const schemaDdl = isSchemaDdlRisk(classification.risk, args.sql);
|
|
161303
|
+
if (classification.readOnly) {
|
|
161304
|
+
return buildPgToolResult({
|
|
161305
|
+
success: true,
|
|
161306
|
+
data: {
|
|
161307
|
+
classification,
|
|
161308
|
+
wouldExecute: false,
|
|
161309
|
+
sqlPreview: args.sql.trim().slice(0, 500),
|
|
161310
|
+
},
|
|
161311
|
+
message: "SQL dry run completed. This statement is read-only; use queryPgDatabase(action=sql) to execute it.",
|
|
161312
|
+
nextActions: [
|
|
161313
|
+
buildNextAction(QUERY_PG_DATABASE, "sql", "Execute the read-only SQL through queryPgDatabase.", { action: "sql", sql: args.sql, limit: 20 }),
|
|
161314
|
+
],
|
|
161315
|
+
});
|
|
161316
|
+
}
|
|
161317
|
+
if (schemaDdl) {
|
|
161318
|
+
return buildPgToolResult({
|
|
161319
|
+
success: true,
|
|
161320
|
+
data: {
|
|
161321
|
+
classification,
|
|
161322
|
+
wouldExecute: false,
|
|
161323
|
+
sqlPreview: args.sql.trim().slice(0, 500),
|
|
161324
|
+
preferredAction: "applyMigration",
|
|
161325
|
+
localFileHintPattern: "migrations/<migrationVersion>_<migrationName>.sql",
|
|
161326
|
+
},
|
|
161327
|
+
message: "SQL dry run completed. Schema DDL should use applyMigration with an explicit migrationVersion, not execute.",
|
|
161328
|
+
nextActions: [
|
|
161329
|
+
buildNextAction(MANAGE_PG_DATABASE, "applyMigration", "Apply schema DDL via versioned migration (provide migrationVersion + migrationName + confirm=true).", {
|
|
161330
|
+
action: "applyMigration",
|
|
161331
|
+
migrationName: "describe_your_change",
|
|
161332
|
+
migrationVersion: "YYYYMMDDHHMMSS",
|
|
161333
|
+
sql: args.sql,
|
|
161334
|
+
confirm: true,
|
|
161335
|
+
}),
|
|
161336
|
+
],
|
|
161337
|
+
});
|
|
161338
|
+
}
|
|
161156
161339
|
return buildPgToolResult({
|
|
161157
161340
|
success: true,
|
|
161158
161341
|
data: {
|
|
@@ -161160,15 +161343,9 @@ async function handleDryRun(args) {
|
|
|
161160
161343
|
wouldExecute: false,
|
|
161161
161344
|
sqlPreview: args.sql.trim().slice(0, 500),
|
|
161162
161345
|
},
|
|
161163
|
-
message:
|
|
161164
|
-
? "SQL dry run completed. This statement is read-only; use queryPgDatabase(action=sql) to execute it."
|
|
161165
|
-
: "SQL dry run completed. Write SQL requires managePgDatabase(action=execute, confirm=true).",
|
|
161346
|
+
message: "SQL dry run completed. Write SQL requires managePgDatabase(action=execute, confirm=true).",
|
|
161166
161347
|
nextActions: [
|
|
161167
|
-
buildNextAction(
|
|
161168
|
-
? "Execute the read-only SQL through queryPgDatabase."
|
|
161169
|
-
: "Execute the write SQL only after explicit confirmation.", classification.readOnly
|
|
161170
|
-
? { action: "sql", sql: args.sql, limit: 20 }
|
|
161171
|
-
: { action: "execute", sql: args.sql, confirm: true }),
|
|
161348
|
+
buildNextAction(MANAGE_PG_DATABASE, "execute", "Execute the write SQL only after explicit confirmation.", { action: "execute", sql: args.sql, confirm: true }),
|
|
161172
161349
|
],
|
|
161173
161350
|
});
|
|
161174
161351
|
}
|
|
@@ -161187,7 +161364,12 @@ async function handlePlanMigration(args, context, deps, cloudBaseOptions) {
|
|
|
161187
161364
|
message: "Provide migrationName (lowercase letters, digits and underscores, starting with a letter) when action=planMigration.",
|
|
161188
161365
|
});
|
|
161189
161366
|
}
|
|
161190
|
-
const
|
|
161367
|
+
const versionOrError = requireExplicitMigrationVersion(args, "planMigration");
|
|
161368
|
+
if (typeof versionOrError !== "string") {
|
|
161369
|
+
return versionOrError;
|
|
161370
|
+
}
|
|
161371
|
+
const version = versionOrError;
|
|
161372
|
+
const localFileHint = buildLocalMigrationFileHint(version, args.migrationName);
|
|
161191
161373
|
const migration = {
|
|
161192
161374
|
Version: version,
|
|
161193
161375
|
Name: args.migrationName,
|
|
@@ -161202,10 +161384,22 @@ async function handlePlanMigration(args, context, deps, cloudBaseOptions) {
|
|
|
161202
161384
|
}, cloudBaseOptions);
|
|
161203
161385
|
return buildPgToolResult({
|
|
161204
161386
|
success: true,
|
|
161205
|
-
data:
|
|
161206
|
-
|
|
161387
|
+
data: {
|
|
161388
|
+
migrationVersion: version,
|
|
161389
|
+
migrationName: args.migrationName,
|
|
161390
|
+
localFileHint,
|
|
161391
|
+
apiResult: result,
|
|
161392
|
+
},
|
|
161393
|
+
message: `Migration plan generated via PreviewPGUserMigrations. Reuse migrationVersion=${version} on applyMigration. Ensure local file ${localFileHint} exists and matches.`,
|
|
161207
161394
|
nextActions: [
|
|
161208
|
-
buildNextAction(MANAGE_PG_DATABASE, "applyMigration", "Review the plan above. If it looks correct, call applyMigration
|
|
161395
|
+
buildNextAction(MANAGE_PG_DATABASE, "applyMigration", "Review the plan above. If it looks correct, call applyMigration with the same migrationVersion.", {
|
|
161396
|
+
action: "applyMigration",
|
|
161397
|
+
migrationName: args.migrationName,
|
|
161398
|
+
migrationVersion: version,
|
|
161399
|
+
sql: args.sql,
|
|
161400
|
+
confirm: true,
|
|
161401
|
+
...(args.rollbackSql ? { rollbackSql: args.rollbackSql } : {}),
|
|
161402
|
+
}),
|
|
161209
161403
|
],
|
|
161210
161404
|
});
|
|
161211
161405
|
}
|
|
@@ -161239,7 +161433,12 @@ async function handleApplyMigration(args, context, deps, cloudBaseOptions) {
|
|
|
161239
161433
|
message: "PushPGUserMigrations requires confirm=true. Run with confirm=true to proceed.",
|
|
161240
161434
|
});
|
|
161241
161435
|
}
|
|
161242
|
-
const
|
|
161436
|
+
const versionOrError = requireExplicitMigrationVersion(args, "applyMigration");
|
|
161437
|
+
if (typeof versionOrError !== "string") {
|
|
161438
|
+
return versionOrError;
|
|
161439
|
+
}
|
|
161440
|
+
const version = versionOrError;
|
|
161441
|
+
const localFileHint = buildLocalMigrationFileHint(version, args.migrationName);
|
|
161243
161442
|
const migration = {
|
|
161244
161443
|
Version: version,
|
|
161245
161444
|
Name: args.migrationName,
|
|
@@ -161259,8 +161458,16 @@ async function handleApplyMigration(args, context, deps, cloudBaseOptions) {
|
|
|
161259
161458
|
const result = await callPgMigrationApi(context, "PushPGUserMigrations", params, cloudBaseOptions);
|
|
161260
161459
|
return buildPgToolResult({
|
|
161261
161460
|
success: true,
|
|
161262
|
-
data:
|
|
161263
|
-
|
|
161461
|
+
data: {
|
|
161462
|
+
migrationVersion: version,
|
|
161463
|
+
migrationName: args.migrationName,
|
|
161464
|
+
localFileHint,
|
|
161465
|
+
apiResult: result,
|
|
161466
|
+
},
|
|
161467
|
+
message: `Migrations applied via PushPGUserMigrations. Ensure local file ${localFileHint} exists and matches.`,
|
|
161468
|
+
nextActions: [
|
|
161469
|
+
buildNextAction(MANAGE_PG_DATABASE, "listMigrations", "Verify the remote migration history records the same migrationVersion.", { action: "listMigrations", limit: 20 }),
|
|
161470
|
+
],
|
|
161264
161471
|
});
|
|
161265
161472
|
}
|
|
161266
161473
|
catch (error) {
|
|
@@ -161535,11 +161742,11 @@ function registerPGDatabaseTools(server, providedDeps) {
|
|
|
161535
161742
|
});
|
|
161536
161743
|
server.registerTool?.(MANAGE_PG_DATABASE, {
|
|
161537
161744
|
title: "管理 PostgreSQL 上下文或执行写入 SQL",
|
|
161538
|
-
description: "管理 CloudBase PostgreSQL:执行已确认的写入 SQL
|
|
161745
|
+
description: "管理 CloudBase PostgreSQL:执行已确认的写入 SQL、SQL 风险预检、迁移管理。建表/ALTER/DROP 等 schema 变更必须使用 applyMigration(显式 migrationVersion + 本地 migrations/ 留档),不要默认用 execute。execute 主要用于 DML 与 GRANT/RLS 等运维 SQL。",
|
|
161539
161746
|
inputSchema: {
|
|
161540
161747
|
action: zod_1.z
|
|
161541
161748
|
.enum(MANAGE_ACTIONS)
|
|
161542
|
-
.describe("操作类型:execute=执行已确认的写入 SQL
|
|
161749
|
+
.describe("操作类型:execute=执行已确认的写入 SQL(DML/GRANT/RLS;schema DDL 默认拒绝,需 allowDdlViaExecute=true);dryRun=只分析 SQL 风险不执行;planMigration=预览迁移计划(需 migrationName + migrationVersion + sql);applyMigration=应用迁移,建表/改 schema 首选(需 migrationName + migrationVersion + sql + confirm=true);listMigrations=查询已应用的 Migration 列表(可传 limit/offset 分页);migrationDetail=查看单条 Migration 详情(需 migrationVersion);rollbackMigration=回滚最近 N 条 Migration(需 lastN + confirm=true);repairMigration=修复 Migration 历史记录(需 migrationVersion + migrationName + repairStatus + repairReason)"),
|
|
161543
161750
|
sql: zod_1.z
|
|
161544
161751
|
.string()
|
|
161545
161752
|
.optional()
|
|
@@ -161577,7 +161784,7 @@ function registerPGDatabaseTools(server, providedDeps) {
|
|
|
161577
161784
|
.string()
|
|
161578
161785
|
.regex(/^\d{14}$/)
|
|
161579
161786
|
.optional()
|
|
161580
|
-
.describe("14 位时间戳 YYYYMMDDHHMMSS。detail/repair
|
|
161787
|
+
.describe("14 位时间戳 YYYYMMDDHHMMSS。plan/apply/detail/repair 必填;禁止由服务端静默生成,避免与本地 migrations/<version>_<name>.sql 分叉。"),
|
|
161581
161788
|
rollbackSql: zod_1.z
|
|
161582
161789
|
.string()
|
|
161583
161790
|
.optional()
|
|
@@ -161619,6 +161826,10 @@ function registerPGDatabaseTools(server, providedDeps) {
|
|
|
161619
161826
|
.string()
|
|
161620
161827
|
.optional()
|
|
161621
161828
|
.describe("repair 必填:修复原因。"),
|
|
161829
|
+
allowDdlViaExecute: zod_1.z
|
|
161830
|
+
.boolean()
|
|
161831
|
+
.optional()
|
|
161832
|
+
.describe("可选,默认 false。仅当需要故意绕过 migration history 时设为 true,才允许 schema DDL 走 execute;正常建表/改 schema 必须用 applyMigration。"),
|
|
161622
161833
|
},
|
|
161623
161834
|
annotations: {
|
|
161624
161835
|
readOnlyHint: false,
|
|
@@ -161632,6 +161843,14 @@ function registerPGDatabaseTools(server, providedDeps) {
|
|
|
161632
161843
|
const cbOpts = server.cloudBaseOptions;
|
|
161633
161844
|
switch (args.action) {
|
|
161634
161845
|
case "execute": {
|
|
161846
|
+
// Soft-block schema DDL before readiness probe so agents get migration guidance immediately.
|
|
161847
|
+
if (args.sql?.trim()) {
|
|
161848
|
+
const classification = classifySqlRisk(args.sql);
|
|
161849
|
+
if (isSchemaDdlRisk(classification.risk, args.sql) &&
|
|
161850
|
+
args.allowDdlViaExecute !== true) {
|
|
161851
|
+
return handleExecuteSql(args, context, deps);
|
|
161852
|
+
}
|
|
161853
|
+
}
|
|
161635
161854
|
try {
|
|
161636
161855
|
await ensurePgReadyOnce(cbOpts, deps);
|
|
161637
161856
|
}
|
|
@@ -194065,10 +194284,13 @@ function parseCommaParts(str) {
|
|
|
194065
194284
|
return parts;
|
|
194066
194285
|
}
|
|
194067
194286
|
|
|
194068
|
-
function expandTop(str) {
|
|
194287
|
+
function expandTop(str, options) {
|
|
194069
194288
|
if (!str)
|
|
194070
194289
|
return [];
|
|
194071
194290
|
|
|
194291
|
+
options = options || {};
|
|
194292
|
+
var max = options.max == null ? Infinity : options.max;
|
|
194293
|
+
|
|
194072
194294
|
// I don't know why Bash 4.3 does this, but it does.
|
|
194073
194295
|
// Anything starting with {} will have the first two bytes preserved
|
|
194074
194296
|
// but *only* at the top level, so {},a}b will not expand to anything,
|
|
@@ -194079,7 +194301,7 @@ function expandTop(str) {
|
|
|
194079
194301
|
str = '\\{\\}' + str.substr(2);
|
|
194080
194302
|
}
|
|
194081
194303
|
|
|
194082
|
-
return expand(escapeBraces(str), true).map(unescapeBraces);
|
|
194304
|
+
return expand(escapeBraces(str), max, true).map(unescapeBraces);
|
|
194083
194305
|
}
|
|
194084
194306
|
|
|
194085
194307
|
function identity(e) {
|
|
@@ -194100,110 +194322,115 @@ function gte(i, y) {
|
|
|
194100
194322
|
return i >= y;
|
|
194101
194323
|
}
|
|
194102
194324
|
|
|
194103
|
-
function expand(str, isTop) {
|
|
194325
|
+
function expand(str, max, isTop) {
|
|
194104
194326
|
var expansions = [];
|
|
194105
194327
|
|
|
194106
|
-
|
|
194107
|
-
|
|
194328
|
+
// The `{a},b}` rewrite below restarts expansion on a rewritten string with
|
|
194329
|
+
// the same `max` and `isTop = true`. Loop instead of recursing so a long run
|
|
194330
|
+
// of non-expanding `{}` groups can't exhaust the call stack.
|
|
194331
|
+
for (;;) {
|
|
194332
|
+
var m = balanced('{', '}', str);
|
|
194333
|
+
if (!m || /\$$/.test(m.pre)) return [str];
|
|
194108
194334
|
|
|
194109
|
-
|
|
194110
|
-
|
|
194111
|
-
|
|
194112
|
-
|
|
194113
|
-
|
|
194114
|
-
|
|
194115
|
-
|
|
194116
|
-
|
|
194117
|
-
|
|
194335
|
+
var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
|
|
194336
|
+
var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
|
|
194337
|
+
var isSequence = isNumericSequence || isAlphaSequence;
|
|
194338
|
+
var isOptions = m.body.indexOf(',') >= 0;
|
|
194339
|
+
if (!isSequence && !isOptions) {
|
|
194340
|
+
// {a},b}
|
|
194341
|
+
if (m.post.match(/,(?!,).*\}/)) {
|
|
194342
|
+
str = m.pre + '{' + m.body + escClose + m.post;
|
|
194343
|
+
isTop = true
|
|
194344
|
+
continue
|
|
194345
|
+
}
|
|
194346
|
+
return [str];
|
|
194118
194347
|
}
|
|
194119
|
-
return [str];
|
|
194120
|
-
}
|
|
194121
194348
|
|
|
194122
|
-
|
|
194123
|
-
|
|
194124
|
-
|
|
194125
|
-
|
|
194126
|
-
|
|
194127
|
-
if (n.length === 1) {
|
|
194128
|
-
// x{{a,b}}y ==> x{a}y x{b}y
|
|
194129
|
-
n = expand(n[0], false).map(embrace);
|
|
194349
|
+
var n;
|
|
194350
|
+
if (isSequence) {
|
|
194351
|
+
n = m.body.split(/\.\./);
|
|
194352
|
+
} else {
|
|
194353
|
+
n = parseCommaParts(m.body);
|
|
194130
194354
|
if (n.length === 1) {
|
|
194131
|
-
|
|
194132
|
-
|
|
194133
|
-
|
|
194134
|
-
|
|
194135
|
-
|
|
194136
|
-
|
|
194355
|
+
// x{{a,b}}y ==> x{a}y x{b}y
|
|
194356
|
+
n = expand(n[0], max, false).map(embrace);
|
|
194357
|
+
if (n.length === 1) {
|
|
194358
|
+
var post = m.post.length
|
|
194359
|
+
? expand(m.post, max, false)
|
|
194360
|
+
: [''];
|
|
194361
|
+
return post.map(function(p) {
|
|
194362
|
+
return m.pre + n[0] + p;
|
|
194363
|
+
});
|
|
194364
|
+
}
|
|
194137
194365
|
}
|
|
194138
194366
|
}
|
|
194139
|
-
}
|
|
194140
194367
|
|
|
194141
|
-
|
|
194142
|
-
|
|
194368
|
+
// at this point, n is the parts, and we know it's not a comma set
|
|
194369
|
+
// with a single entry.
|
|
194143
194370
|
|
|
194144
|
-
|
|
194145
|
-
|
|
194146
|
-
|
|
194147
|
-
|
|
194148
|
-
|
|
194149
|
-
|
|
194150
|
-
|
|
194151
|
-
|
|
194152
|
-
|
|
194153
|
-
|
|
194154
|
-
|
|
194155
|
-
|
|
194156
|
-
|
|
194157
|
-
|
|
194158
|
-
|
|
194159
|
-
|
|
194160
|
-
|
|
194161
|
-
|
|
194162
|
-
|
|
194163
|
-
|
|
194164
|
-
|
|
194165
|
-
|
|
194166
|
-
|
|
194167
|
-
|
|
194168
|
-
|
|
194169
|
-
|
|
194170
|
-
|
|
194171
|
-
|
|
194172
|
-
|
|
194173
|
-
|
|
194174
|
-
|
|
194175
|
-
|
|
194176
|
-
|
|
194177
|
-
|
|
194178
|
-
|
|
194179
|
-
|
|
194180
|
-
|
|
194181
|
-
|
|
194182
|
-
|
|
194183
|
-
|
|
194184
|
-
|
|
194371
|
+
// no need to expand pre, since it is guaranteed to be free of brace-sets
|
|
194372
|
+
var pre = m.pre;
|
|
194373
|
+
var post = m.post.length
|
|
194374
|
+
? expand(m.post, max, false)
|
|
194375
|
+
: [''];
|
|
194376
|
+
|
|
194377
|
+
var N;
|
|
194378
|
+
|
|
194379
|
+
if (isSequence) {
|
|
194380
|
+
var x = numeric(n[0]);
|
|
194381
|
+
var y = numeric(n[1]);
|
|
194382
|
+
var width = Math.max(n[0].length, n[1].length)
|
|
194383
|
+
var incr = n.length == 3
|
|
194384
|
+
? Math.max(Math.abs(numeric(n[2])), 1)
|
|
194385
|
+
: 1;
|
|
194386
|
+
var test = lte;
|
|
194387
|
+
var reverse = y < x;
|
|
194388
|
+
if (reverse) {
|
|
194389
|
+
incr *= -1;
|
|
194390
|
+
test = gte;
|
|
194391
|
+
}
|
|
194392
|
+
var pad = n.some(isPadded);
|
|
194393
|
+
|
|
194394
|
+
N = [];
|
|
194395
|
+
|
|
194396
|
+
for (var i = x; test(i, y) && N.length < max; i += incr) {
|
|
194397
|
+
var c;
|
|
194398
|
+
if (isAlphaSequence) {
|
|
194399
|
+
c = String.fromCharCode(i);
|
|
194400
|
+
if (c === '\\')
|
|
194401
|
+
c = '';
|
|
194402
|
+
} else {
|
|
194403
|
+
c = String(i);
|
|
194404
|
+
if (pad) {
|
|
194405
|
+
var need = width - c.length;
|
|
194406
|
+
if (need > 0) {
|
|
194407
|
+
var z = new Array(need + 1).join('0');
|
|
194408
|
+
if (i < 0)
|
|
194409
|
+
c = '-' + z + c.slice(1);
|
|
194410
|
+
else
|
|
194411
|
+
c = z + c;
|
|
194412
|
+
}
|
|
194185
194413
|
}
|
|
194186
194414
|
}
|
|
194415
|
+
N.push(c);
|
|
194187
194416
|
}
|
|
194188
|
-
|
|
194417
|
+
} else {
|
|
194418
|
+
N = concatMap(n, function(el) { return expand(el, max, false) });
|
|
194189
194419
|
}
|
|
194190
|
-
} else {
|
|
194191
|
-
N = concatMap(n, function(el) { return expand(el, false) });
|
|
194192
|
-
}
|
|
194193
194420
|
|
|
194194
|
-
|
|
194195
|
-
|
|
194196
|
-
|
|
194197
|
-
|
|
194198
|
-
|
|
194421
|
+
for (var j = 0; j < N.length; j++) {
|
|
194422
|
+
for (var k = 0; k < post.length && expansions.length < max; k++) {
|
|
194423
|
+
var expansion = pre + N[j] + post[k];
|
|
194424
|
+
if (!isTop || isSequence || expansion)
|
|
194425
|
+
expansions.push(expansion);
|
|
194426
|
+
}
|
|
194199
194427
|
}
|
|
194200
|
-
}
|
|
194201
194428
|
|
|
194202
|
-
|
|
194429
|
+
return expansions;
|
|
194430
|
+
}
|
|
194203
194431
|
}
|
|
194204
194432
|
|
|
194205
194433
|
|
|
194206
|
-
|
|
194207
194434
|
/***/ }),
|
|
194208
194435
|
|
|
194209
194436
|
/***/ 69027:
|
|
@@ -196778,7 +197005,7 @@ ${envIdSection}
|
|
|
196778
197005
|
## 环境信息
|
|
196779
197006
|
- 操作系统: ${os_1.default.type()} ${os_1.default.release()}
|
|
196780
197007
|
- Node.js版本: ${process.version}
|
|
196781
|
-
- MCP 版本:${process.env.npm_package_version || "2.
|
|
197008
|
+
- MCP 版本:${process.env.npm_package_version || "2.24.1" || 0}
|
|
196782
197009
|
- 系统架构: ${os_1.default.arch()}
|
|
196783
197010
|
- 时间: ${new Date().toISOString()}
|
|
196784
197011
|
- 请求ID: ${requestId}
|
|
@@ -196859,7 +197086,7 @@ function createWrappedHandler(name, handler, server) {
|
|
|
196859
197086
|
requestId: (typeof error === 'object' && error && 'requestId' in error) ? error.requestId : '',
|
|
196860
197087
|
ide: server.ide || process.env.INTEGRATION_IDE || ''
|
|
196861
197088
|
});
|
|
196862
|
-
const mcpVersion = true ? "2.
|
|
197089
|
+
const mcpVersion = true ? "2.24.1" : 0;
|
|
196863
197090
|
const requestIdSuffix = requestId ? `\n🆔 RequestId: ${requestId}` : '';
|
|
196864
197091
|
const enhancedErrorMessage = `${errorMessage}${requestIdSuffix}\n\n📦 CloudBase MCP v${mcpVersion}\n🔗 遇到问题?请复制以下链接到浏览器打开\n即可自动携带错误详情快速创建 GitHub Issue:\n${issueLink}`;
|
|
196865
197092
|
// 创建新的错误对象,保持原有的错误类型但更新消息
|
|
@@ -196896,7 +197123,8 @@ function createWrappedHandler(name, handler, server) {
|
|
|
196896
197123
|
error: errorMessage,
|
|
196897
197124
|
inputParams: sanitizeArgs(args), // 添加入参上报
|
|
196898
197125
|
cloudBaseOptions: cloudBaseOptions, // 传递 CloudBase 配置(可能已更新)
|
|
196899
|
-
ide: server.ide || process.env.INTEGRATION_IDE // 传递集成IDE信息
|
|
197126
|
+
ide: server.ide || process.env.INTEGRATION_IDE, // 传递集成IDE信息
|
|
197127
|
+
mcpClientInfo: (0, telemetry_js_1.readMcpClientInfoFromServer)(server),
|
|
196900
197128
|
}).catch(err => {
|
|
196901
197129
|
// 静默处理上报错误,不影响主要功能
|
|
196902
197130
|
(0, logger_js_1.debug)('遥测上报失败', { toolName: name, error: err instanceof Error ? err.message : String(err) });
|
|
@@ -212872,7 +213100,7 @@ function registerSetupTools(server) {
|
|
|
212872
213100
|
server.registerTool("downloadTemplate", {
|
|
212873
213101
|
title: "下载项目模板",
|
|
212874
213102
|
description: `自动下载并部署CloudBase项目模板。
|
|
212875
|
-
**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.
|
|
213103
|
+
**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.24.1" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
|
|
212876
213104
|
inputSchema: {
|
|
212877
213105
|
template: zod_1.z
|
|
212878
213106
|
.enum(["react", "vue", "miniprogram", "uniapp", "rules"])
|
|
@@ -231086,10 +231314,13 @@ function parseCommaParts(str) {
|
|
|
231086
231314
|
return parts;
|
|
231087
231315
|
}
|
|
231088
231316
|
|
|
231089
|
-
function expandTop(str) {
|
|
231317
|
+
function expandTop(str, options) {
|
|
231090
231318
|
if (!str)
|
|
231091
231319
|
return [];
|
|
231092
231320
|
|
|
231321
|
+
options = options || {};
|
|
231322
|
+
var max = options.max == null ? Infinity : options.max;
|
|
231323
|
+
|
|
231093
231324
|
// I don't know why Bash 4.3 does this, but it does.
|
|
231094
231325
|
// Anything starting with {} will have the first two bytes preserved
|
|
231095
231326
|
// but *only* at the top level, so {},a}b will not expand to anything,
|
|
@@ -231100,7 +231331,7 @@ function expandTop(str) {
|
|
|
231100
231331
|
str = '\\{\\}' + str.substr(2);
|
|
231101
231332
|
}
|
|
231102
231333
|
|
|
231103
|
-
return expand(escapeBraces(str), true).map(unescapeBraces);
|
|
231334
|
+
return expand(escapeBraces(str), max, true).map(unescapeBraces);
|
|
231104
231335
|
}
|
|
231105
231336
|
|
|
231106
231337
|
function embrace(str) {
|
|
@@ -231117,24 +231348,29 @@ function gte(i, y) {
|
|
|
231117
231348
|
return i >= y;
|
|
231118
231349
|
}
|
|
231119
231350
|
|
|
231120
|
-
function expand(str, isTop) {
|
|
231351
|
+
function expand(str, max, isTop) {
|
|
231121
231352
|
var expansions = [];
|
|
231122
231353
|
|
|
231123
|
-
|
|
231124
|
-
|
|
231354
|
+
// The `{a},b}` rewrite below restarts expansion on a rewritten string with
|
|
231355
|
+
// the same `max` and `isTop = true`. Loop instead of recursing so a long run
|
|
231356
|
+
// of non-expanding `{}` groups can't exhaust the call stack.
|
|
231357
|
+
for (;;) {
|
|
231358
|
+
const m = balanced('{', '}', str)
|
|
231359
|
+
if (!m) return [str]
|
|
231125
231360
|
|
|
231126
|
-
|
|
231127
|
-
|
|
231128
|
-
var post = m.post.length
|
|
231129
|
-
? expand(m.post, false)
|
|
231130
|
-
: [''];
|
|
231361
|
+
// no need to expand pre, since it is guaranteed to be free of brace-sets
|
|
231362
|
+
const pre = m.pre
|
|
231131
231363
|
|
|
231132
|
-
|
|
231133
|
-
|
|
231134
|
-
|
|
231135
|
-
|
|
231364
|
+
if (/\$$/.test(m.pre)) {
|
|
231365
|
+
const post =
|
|
231366
|
+
m.post.length ? expand(m.post, max, false) : ['']
|
|
231367
|
+
for (let k = 0; k < post.length && k < max; k++) {
|
|
231368
|
+
const expansion = pre + '{' + m.body + '}' + post[k]
|
|
231369
|
+
expansions.push(expansion)
|
|
231370
|
+
}
|
|
231371
|
+
return expansions
|
|
231136
231372
|
}
|
|
231137
|
-
|
|
231373
|
+
|
|
231138
231374
|
var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
|
|
231139
231375
|
var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
|
|
231140
231376
|
var isSequence = isNumericSequence || isAlphaSequence;
|
|
@@ -231143,11 +231379,18 @@ function expand(str, isTop) {
|
|
|
231143
231379
|
// {a},b}
|
|
231144
231380
|
if (m.post.match(/,(?!,).*\}/)) {
|
|
231145
231381
|
str = m.pre + '{' + m.body + escClose + m.post;
|
|
231146
|
-
|
|
231382
|
+
isTop = true;
|
|
231383
|
+
continue;
|
|
231147
231384
|
}
|
|
231148
231385
|
return [str];
|
|
231149
231386
|
}
|
|
231150
231387
|
|
|
231388
|
+
// Only expand post once we know this brace set actually expands. Computing
|
|
231389
|
+
// it before the early returns above expanded post a second time on every
|
|
231390
|
+
// non-expanding `{}`, which is what made inputs like `a{},{},{}...` blow up
|
|
231391
|
+
// exponentially.
|
|
231392
|
+
const post =
|
|
231393
|
+
m.post.length ? expand(m.post, max, false) : ['']
|
|
231151
231394
|
var n;
|
|
231152
231395
|
if (isSequence) {
|
|
231153
231396
|
n = m.body.split(/\.\./);
|
|
@@ -231155,7 +231398,7 @@ function expand(str, isTop) {
|
|
|
231155
231398
|
n = parseCommaParts(m.body);
|
|
231156
231399
|
if (n.length === 1) {
|
|
231157
231400
|
// x{{a,b}}y ==> x{a}y x{b}y
|
|
231158
|
-
n = expand(n[0], false).map(embrace);
|
|
231401
|
+
n = expand(n[0], max, false).map(embrace);
|
|
231159
231402
|
if (n.length === 1) {
|
|
231160
231403
|
return post.map(function(p) {
|
|
231161
231404
|
return m.pre + n[0] + p;
|
|
@@ -231173,7 +231416,7 @@ function expand(str, isTop) {
|
|
|
231173
231416
|
var y = numeric(n[1]);
|
|
231174
231417
|
var width = Math.max(n[0].length, n[1].length)
|
|
231175
231418
|
var incr = n.length == 3
|
|
231176
|
-
? Math.abs(numeric(n[2]))
|
|
231419
|
+
? Math.max(Math.abs(numeric(n[2])), 1)
|
|
231177
231420
|
: 1;
|
|
231178
231421
|
var test = lte;
|
|
231179
231422
|
var reverse = y < x;
|
|
@@ -231185,7 +231428,7 @@ function expand(str, isTop) {
|
|
|
231185
231428
|
|
|
231186
231429
|
N = [];
|
|
231187
231430
|
|
|
231188
|
-
for (var i = x; test(i, y); i += incr) {
|
|
231431
|
+
for (var i = x; test(i, y) && N.length < max; i += incr) {
|
|
231189
231432
|
var c;
|
|
231190
231433
|
if (isAlphaSequence) {
|
|
231191
231434
|
c = String.fromCharCode(i);
|
|
@@ -231210,24 +231453,23 @@ function expand(str, isTop) {
|
|
|
231210
231453
|
N = [];
|
|
231211
231454
|
|
|
231212
231455
|
for (var j = 0; j < n.length; j++) {
|
|
231213
|
-
N.push.apply(N, expand(n[j], false));
|
|
231456
|
+
N.push.apply(N, expand(n[j], max, false));
|
|
231214
231457
|
}
|
|
231215
231458
|
}
|
|
231216
231459
|
|
|
231217
231460
|
for (var j = 0; j < N.length; j++) {
|
|
231218
|
-
for (var k = 0; k < post.length; k++) {
|
|
231461
|
+
for (var k = 0; k < post.length && expansions.length < max; k++) {
|
|
231219
231462
|
var expansion = pre + N[j] + post[k];
|
|
231220
231463
|
if (!isTop || isSequence || expansion)
|
|
231221
231464
|
expansions.push(expansion);
|
|
231222
231465
|
}
|
|
231223
231466
|
}
|
|
231224
|
-
}
|
|
231225
231467
|
|
|
231226
|
-
|
|
231468
|
+
return expansions;
|
|
231469
|
+
}
|
|
231227
231470
|
}
|
|
231228
231471
|
|
|
231229
231472
|
|
|
231230
|
-
|
|
231231
231473
|
/***/ }),
|
|
231232
231474
|
|
|
231233
231475
|
/***/ 85014:
|