@cloudbase/cloudbase-mcp 2.13.0 → 2.14.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 +3 -3
- package/dist/index.cjs +1770 -461
- package/dist/index.d.ts +409 -13
- package/dist/index.js +1447 -321
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -32,11 +32,12 @@ import * as __WEBPACK_EXTERNAL_MODULE_winston__ from "winston";
|
|
|
32
32
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
33
33
|
exports.simplifyEnvList = simplifyEnvList;
|
|
34
34
|
exports.registerEnvTools = registerEnvTools;
|
|
35
|
+
const toolbox_1 = __webpack_require__(2090);
|
|
35
36
|
const zod_1 = __webpack_require__(2971);
|
|
36
37
|
const auth_js_1 = __webpack_require__(7291);
|
|
37
38
|
const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
38
39
|
const logger_js_1 = __webpack_require__(3039);
|
|
39
|
-
const
|
|
40
|
+
const tool_result_js_1 = __webpack_require__(9835);
|
|
40
41
|
const rag_js_1 = __webpack_require__(4215);
|
|
41
42
|
/**
|
|
42
43
|
* Simplify environment list data by keeping only essential fields for AI assistant
|
|
@@ -68,17 +69,119 @@ function simplifyEnvList(envList) {
|
|
|
68
69
|
return simplified;
|
|
69
70
|
});
|
|
70
71
|
}
|
|
72
|
+
function formatDeviceAuthHint(deviceAuthInfo) {
|
|
73
|
+
if (!deviceAuthInfo) {
|
|
74
|
+
return "";
|
|
75
|
+
}
|
|
76
|
+
const lines = [
|
|
77
|
+
"",
|
|
78
|
+
"### Device Flow 授权信息",
|
|
79
|
+
`- user_code: ${deviceAuthInfo.user_code}`,
|
|
80
|
+
];
|
|
81
|
+
if (deviceAuthInfo.verification_uri) {
|
|
82
|
+
lines.push(`- verification_uri: ${deviceAuthInfo.verification_uri}`);
|
|
83
|
+
}
|
|
84
|
+
lines.push(`- expires_in: ${deviceAuthInfo.expires_in}s`);
|
|
85
|
+
lines.push("", "请在另一台可用浏览器设备打开 `verification_uri` 并输入 `user_code` 完成授权。");
|
|
86
|
+
return lines.join("\n");
|
|
87
|
+
}
|
|
88
|
+
function emitDeviceAuthNotice(server, deviceAuthInfo) {
|
|
89
|
+
// Temporarily disabled: avoid sending logging notifications for device auth
|
|
90
|
+
}
|
|
91
|
+
async function fetchAvailableEnvCandidates(cloudBaseOptions, server) {
|
|
92
|
+
try {
|
|
93
|
+
return await (0, cloudbase_manager_js_1.listAvailableEnvCandidates)({
|
|
94
|
+
cloudBaseOptions,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return [];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const CODEBUDDY_AUTH_ACTIONS = ["status", "set_env"];
|
|
102
|
+
const DEFAULT_AUTH_ACTIONS = [
|
|
103
|
+
"status",
|
|
104
|
+
"start_auth",
|
|
105
|
+
"set_env",
|
|
106
|
+
"logout",
|
|
107
|
+
];
|
|
108
|
+
function getCurrentIde(server) {
|
|
109
|
+
return server.ide || process.env.INTEGRATION_IDE || "";
|
|
110
|
+
}
|
|
111
|
+
function isCodeBuddyIde(server) {
|
|
112
|
+
return getCurrentIde(server) === "CodeBuddy";
|
|
113
|
+
}
|
|
114
|
+
function getSupportedAuthActions(server) {
|
|
115
|
+
return isCodeBuddyIde(server) ? CODEBUDDY_AUTH_ACTIONS : DEFAULT_AUTH_ACTIONS;
|
|
116
|
+
}
|
|
117
|
+
function buildAuthRequiredNextStep(server) {
|
|
118
|
+
if (isCodeBuddyIde(server)) {
|
|
119
|
+
return (0, tool_result_js_1.buildAuthNextStep)("status", {
|
|
120
|
+
suggestedArgs: { action: "status" },
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
return (0, tool_result_js_1.buildAuthNextStep)("start_auth", {
|
|
124
|
+
suggestedArgs: { action: "start_auth", authMode: "device" },
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
function buildSetEnvNextStep(envCandidates) {
|
|
128
|
+
const singleEnvId = envCandidates.length === 1 ? envCandidates[0].envId : undefined;
|
|
129
|
+
return (0, tool_result_js_1.buildAuthNextStep)("set_env", {
|
|
130
|
+
requiredParams: singleEnvId ? undefined : ["envId"],
|
|
131
|
+
suggestedArgs: singleEnvId
|
|
132
|
+
? { action: "set_env", envId: singleEnvId }
|
|
133
|
+
: { action: "set_env" },
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
async function getGuidePrompt(server) {
|
|
137
|
+
if (getCurrentIde(server) === "CodeBuddy" ||
|
|
138
|
+
process.env.CLOUDBASE_GUIDE_PROMPT === "false") {
|
|
139
|
+
return "";
|
|
140
|
+
}
|
|
141
|
+
try {
|
|
142
|
+
return await (0, rag_js_1.getClaudePrompt)();
|
|
143
|
+
}
|
|
144
|
+
catch (promptError) {
|
|
145
|
+
(0, logger_js_1.debug)("Failed to get CLAUDE prompt", { error: promptError });
|
|
146
|
+
return "";
|
|
147
|
+
}
|
|
148
|
+
}
|
|
71
149
|
function registerEnvTools(server) {
|
|
72
150
|
// 获取 cloudBaseOptions,如果没有则为 undefined
|
|
73
151
|
const cloudBaseOptions = server.cloudBaseOptions;
|
|
74
152
|
const getManager = () => (0, cloudbase_manager_js_1.getCloudBaseManager)({ cloudBaseOptions, mcpServer: server });
|
|
75
153
|
const hasEnvId = typeof cloudBaseOptions?.envId === 'string' && cloudBaseOptions?.envId.length > 0;
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
154
|
+
const supportedAuthActions = getSupportedAuthActions(server);
|
|
155
|
+
const authActionEnum = [...supportedAuthActions];
|
|
156
|
+
// auth - CloudBase (云开发) 开发阶段登录与环境绑定
|
|
157
|
+
server.registerTool?.("auth", {
|
|
158
|
+
title: "CloudBase 开发阶段登录与环境",
|
|
159
|
+
description: "CloudBase(腾讯云开发)开发阶段登录与环境绑定。登录后即可访问云资源;环境(env)是云函数、数据库、静态托管等资源的隔离单元,绑定环境后其他 MCP 工具才能操作该环境。支持:查询状态、发起登录、绑定环境(set_env)、退出登录。",
|
|
80
160
|
inputSchema: {
|
|
81
|
-
|
|
161
|
+
action: zod_1.z
|
|
162
|
+
.enum(authActionEnum)
|
|
163
|
+
.optional()
|
|
164
|
+
.describe("动作:status=查询状态,start_auth=发起登录,set_env=绑定环境(传envId),logout=退出登录"),
|
|
165
|
+
...(supportedAuthActions.includes("start_auth")
|
|
166
|
+
? {
|
|
167
|
+
authMode: zod_1.z
|
|
168
|
+
.enum(["device", "web"])
|
|
169
|
+
.optional()
|
|
170
|
+
.describe("认证模式:device=设备码授权,web=浏览器回调授权"),
|
|
171
|
+
}
|
|
172
|
+
: {}),
|
|
173
|
+
envId: zod_1.z
|
|
174
|
+
.string()
|
|
175
|
+
.optional()
|
|
176
|
+
.describe("环境ID(CloudBase 环境唯一标识),绑定后工具将操作该环境。action=set_env 时必填"),
|
|
177
|
+
...(supportedAuthActions.includes("logout")
|
|
178
|
+
? {
|
|
179
|
+
confirm: zod_1.z
|
|
180
|
+
.literal("yes")
|
|
181
|
+
.optional()
|
|
182
|
+
.describe("action=logout 时确认操作,传 yes"),
|
|
183
|
+
}
|
|
184
|
+
: {}),
|
|
82
185
|
},
|
|
83
186
|
annotations: {
|
|
84
187
|
readOnlyHint: false,
|
|
@@ -87,135 +190,326 @@ function registerEnvTools(server) {
|
|
|
87
190
|
openWorldHint: true,
|
|
88
191
|
category: "env",
|
|
89
192
|
},
|
|
90
|
-
}, async (
|
|
91
|
-
|
|
193
|
+
}, async (rawArgs) => {
|
|
194
|
+
const action = rawArgs.action ?? "status";
|
|
195
|
+
const authMode = rawArgs.authMode === "device" || rawArgs.authMode === "web"
|
|
196
|
+
? rawArgs.authMode
|
|
197
|
+
: undefined;
|
|
198
|
+
const envId = rawArgs.envId;
|
|
199
|
+
const confirm = rawArgs.confirm === "yes" ? "yes" : undefined;
|
|
200
|
+
let deviceAuthInfo;
|
|
201
|
+
const onDeviceCode = (info) => {
|
|
202
|
+
deviceAuthInfo = info;
|
|
203
|
+
(0, auth_js_1.setPendingAuthProgressState)(info, "device");
|
|
204
|
+
// emitDeviceAuthNotice(server, info);
|
|
205
|
+
};
|
|
206
|
+
const authChallenge = () => deviceAuthInfo
|
|
207
|
+
? {
|
|
208
|
+
user_code: deviceAuthInfo.user_code,
|
|
209
|
+
verification_uri: deviceAuthInfo.verification_uri,
|
|
210
|
+
expires_in: deviceAuthInfo.expires_in,
|
|
211
|
+
}
|
|
212
|
+
: undefined;
|
|
92
213
|
try {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
serverIde: server?.ide
|
|
102
|
-
});
|
|
103
|
-
const { selectedEnvId, cancelled, error, noEnvs, switch: switchAccount, } = await (0, interactive_js_1._promptAndSetEnvironmentId)(forceUpdate, {
|
|
104
|
-
server, // Pass ExtendedMcpServer instance
|
|
105
|
-
loginFromCloudBaseLoginPage: isSwitching,
|
|
106
|
-
// When switching account, ignore environment variables to force Web login
|
|
107
|
-
ignoreEnvVars: isSwitching,
|
|
214
|
+
if (!supportedAuthActions.includes(action)) {
|
|
215
|
+
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
216
|
+
ok: false,
|
|
217
|
+
code: "NOT_SUPPORTED",
|
|
218
|
+
message: `当前 IDE 不支持 auth(action="${action}")。`,
|
|
219
|
+
next_step: (0, tool_result_js_1.buildAuthNextStep)("status", {
|
|
220
|
+
suggestedArgs: { action: "status" },
|
|
221
|
+
}),
|
|
108
222
|
});
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
223
|
+
}
|
|
224
|
+
if (action === "status") {
|
|
225
|
+
const loginState = await (0, auth_js_1.peekLoginState)();
|
|
226
|
+
const authFlowState = await (0, auth_js_1.getAuthProgressState)();
|
|
227
|
+
const envId = (0, cloudbase_manager_js_1.getCachedEnvId)() ||
|
|
228
|
+
process.env.CLOUDBASE_ENV_ID ||
|
|
229
|
+
(typeof loginState?.envId === "string" ? loginState.envId : undefined);
|
|
230
|
+
const authStatus = loginState
|
|
231
|
+
? "READY"
|
|
232
|
+
: authFlowState.status === "PENDING"
|
|
233
|
+
? "PENDING"
|
|
234
|
+
: "REQUIRED";
|
|
235
|
+
const envCandidates = await fetchAvailableEnvCandidates(cloudBaseOptions, server);
|
|
236
|
+
const envStatus = envId
|
|
237
|
+
? "READY"
|
|
238
|
+
: envCandidates.length > 1
|
|
239
|
+
? "MULTIPLE"
|
|
240
|
+
: envCandidates.length === 1
|
|
241
|
+
? "READY"
|
|
242
|
+
: "NONE";
|
|
243
|
+
const message = authStatus === "READY"
|
|
244
|
+
? `当前已登录${envId ? `,环境: ${envId}` : ",但未绑定环境"}`
|
|
245
|
+
: authStatus === "PENDING"
|
|
246
|
+
? "设备码授权进行中,请完成浏览器授权后再次调用 auth(action=\"status\")"
|
|
247
|
+
: isCodeBuddyIde(server)
|
|
248
|
+
? "当前未登录。CodeBuddy 暂不支持在 tool 内发起认证,请在外部完成认证后再次调用 auth(action=\"status\")。"
|
|
249
|
+
: "当前未登录,请先执行 auth(action=\"start_auth\")";
|
|
250
|
+
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
251
|
+
ok: true,
|
|
252
|
+
code: "STATUS",
|
|
253
|
+
auth_status: authStatus,
|
|
254
|
+
env_status: envStatus,
|
|
255
|
+
current_env_id: envId || null,
|
|
256
|
+
env_candidates: envCandidates,
|
|
257
|
+
auth_challenge: authFlowState.status === "PENDING" && authFlowState.authChallenge
|
|
258
|
+
? {
|
|
259
|
+
user_code: authFlowState.authChallenge.user_code,
|
|
260
|
+
verification_uri: authFlowState.authChallenge.verification_uri,
|
|
261
|
+
expires_in: authFlowState.authChallenge.expires_in,
|
|
262
|
+
}
|
|
263
|
+
: undefined,
|
|
264
|
+
message,
|
|
265
|
+
next_step: authStatus === "REQUIRED"
|
|
266
|
+
? buildAuthRequiredNextStep(server)
|
|
267
|
+
: authStatus === "PENDING"
|
|
268
|
+
? (0, tool_result_js_1.buildAuthNextStep)("status", {
|
|
269
|
+
suggestedArgs: { action: "status" },
|
|
270
|
+
})
|
|
271
|
+
: !envId
|
|
272
|
+
? buildSetEnvNextStep(envCandidates)
|
|
273
|
+
: (0, tool_result_js_1.buildAuthNextStep)("status", {
|
|
274
|
+
suggestedArgs: { action: "status" },
|
|
275
|
+
}),
|
|
116
276
|
});
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
277
|
+
}
|
|
278
|
+
if (action === "start_auth") {
|
|
279
|
+
const region = server.cloudBaseOptions?.region || process.env.TCB_REGION;
|
|
280
|
+
const auth = toolbox_1.AuthSupervisor.getInstance({});
|
|
281
|
+
const authFlowState = await (0, auth_js_1.getAuthProgressState)();
|
|
282
|
+
if (authFlowState.status === "PENDING" && authFlowState.authChallenge) {
|
|
283
|
+
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
284
|
+
ok: true,
|
|
285
|
+
code: "AUTH_PENDING",
|
|
286
|
+
message: "设备码授权进行中,请在浏览器中打开 verification_uri 并输入 user_code 完成授权。",
|
|
287
|
+
auth_challenge: {
|
|
288
|
+
user_code: authFlowState.authChallenge.user_code,
|
|
289
|
+
verification_uri: authFlowState.authChallenge.verification_uri,
|
|
290
|
+
expires_in: authFlowState.authChallenge.expires_in,
|
|
291
|
+
},
|
|
292
|
+
next_step: (0, tool_result_js_1.buildAuthNextStep)("status", {
|
|
293
|
+
suggestedArgs: { action: "status" },
|
|
294
|
+
}),
|
|
295
|
+
});
|
|
122
296
|
}
|
|
123
|
-
//
|
|
124
|
-
|
|
125
|
-
(0,
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
297
|
+
// 1. 如果已经有登录态,直接返回 AUTH_READY
|
|
298
|
+
try {
|
|
299
|
+
const existingLoginState = await (0, auth_js_1.peekLoginState)();
|
|
300
|
+
if (existingLoginState) {
|
|
301
|
+
const envId = typeof existingLoginState.envId === "string" ? existingLoginState.envId : null;
|
|
302
|
+
const envCandidates = envId
|
|
303
|
+
? []
|
|
304
|
+
: await fetchAvailableEnvCandidates(cloudBaseOptions, server);
|
|
305
|
+
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
306
|
+
ok: true,
|
|
307
|
+
code: "AUTH_READY",
|
|
308
|
+
message: envId
|
|
309
|
+
? `认证成功,当前登录态 envId: ${envId}`
|
|
310
|
+
: "认证成功",
|
|
311
|
+
auth_challenge: authChallenge(),
|
|
312
|
+
env_candidates: envCandidates,
|
|
313
|
+
next_step: envId
|
|
314
|
+
? (0, tool_result_js_1.buildAuthNextStep)("status", {
|
|
315
|
+
suggestedArgs: { action: "status" },
|
|
316
|
+
})
|
|
317
|
+
: buildSetEnvNextStep(envCandidates),
|
|
318
|
+
});
|
|
139
319
|
}
|
|
140
320
|
}
|
|
141
|
-
|
|
142
|
-
//
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
321
|
+
catch {
|
|
322
|
+
// 忽略 getLoginState 错误,继续尝试发起登录
|
|
323
|
+
}
|
|
324
|
+
// 2. 设备码模式:监听到 device code 即返回 AUTH_PENDING,后续由 toolbox 异步轮询并更新本地 credential
|
|
325
|
+
const effectiveMode = authMode && (authMode === "device" || authMode === "web")
|
|
326
|
+
? authMode
|
|
327
|
+
: process.env.TCB_AUTH_MODE === "web"
|
|
328
|
+
? "web"
|
|
329
|
+
: "device";
|
|
330
|
+
if (effectiveMode === "device") {
|
|
331
|
+
let resolveCode;
|
|
332
|
+
let rejectCode;
|
|
333
|
+
const codeReady = new Promise((resolve, reject) => {
|
|
334
|
+
resolveCode = resolve;
|
|
335
|
+
rejectCode = reject;
|
|
336
|
+
});
|
|
337
|
+
const deviceOnCode = (info) => {
|
|
338
|
+
onDeviceCode(info);
|
|
339
|
+
if (resolveCode) {
|
|
340
|
+
resolveCode();
|
|
148
341
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
342
|
+
};
|
|
343
|
+
try {
|
|
344
|
+
// 启动 Device Flow,全流程由 toolbox 负责轮询和写入 credential,这里不等待完成
|
|
345
|
+
auth
|
|
346
|
+
.loginByWebAuth({
|
|
347
|
+
flow: "device",
|
|
348
|
+
onDeviceCode: deviceOnCode,
|
|
349
|
+
})
|
|
350
|
+
.then(() => {
|
|
351
|
+
(0, auth_js_1.resolveAuthProgressState)();
|
|
352
|
+
})
|
|
353
|
+
.catch((err) => {
|
|
354
|
+
(0, auth_js_1.rejectAuthProgressState)(err);
|
|
355
|
+
// 如果在拿到 device code 之前就失败,则唤醒当前调用并返回错误
|
|
356
|
+
if (!deviceAuthInfo && rejectCode) {
|
|
357
|
+
rejectCode(err);
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
catch (err) {
|
|
362
|
+
if (rejectCode) {
|
|
363
|
+
rejectCode(err);
|
|
152
364
|
}
|
|
153
365
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
366
|
+
try {
|
|
367
|
+
await codeReady;
|
|
368
|
+
}
|
|
369
|
+
catch (err) {
|
|
370
|
+
const message = err instanceof Error ? err.message : String(err ?? "unknown error");
|
|
371
|
+
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
372
|
+
ok: false,
|
|
373
|
+
code: "AUTH_REQUIRED",
|
|
374
|
+
message: `设备码登录初始化失败: ${message}`,
|
|
375
|
+
next_step: (0, tool_result_js_1.buildAuthNextStep)("start_auth", {
|
|
376
|
+
suggestedArgs: { action: "start_auth", authMode: "device" },
|
|
377
|
+
}),
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
if (!deviceAuthInfo) {
|
|
381
|
+
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
382
|
+
ok: false,
|
|
383
|
+
code: "AUTH_REQUIRED",
|
|
384
|
+
message: "未获取到设备码信息,请重试设备码登录",
|
|
385
|
+
next_step: (0, tool_result_js_1.buildAuthNextStep)("start_auth", {
|
|
386
|
+
suggestedArgs: { action: "start_auth", authMode: "device" },
|
|
387
|
+
}),
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
const envCandidates = await fetchAvailableEnvCandidates(cloudBaseOptions, server);
|
|
391
|
+
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
392
|
+
ok: true,
|
|
393
|
+
code: "AUTH_PENDING",
|
|
394
|
+
message: "已发起设备码登录,请在浏览器中打开 verification_uri 并输入 user_code 完成授权。授权完成后请再次调用 auth(action=\"status\")。",
|
|
395
|
+
auth_challenge: authChallenge(),
|
|
396
|
+
env_candidates: envCandidates,
|
|
397
|
+
next_step: (0, tool_result_js_1.buildAuthNextStep)("status", {
|
|
398
|
+
suggestedArgs: { action: "status" },
|
|
399
|
+
}),
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
// 3. 非 Device Flow(显式 web 模式)仍然使用 getLoginState 阻塞等待
|
|
403
|
+
const loginState = await (0, auth_js_1.ensureLogin)({
|
|
404
|
+
region,
|
|
405
|
+
authMode: effectiveMode,
|
|
406
|
+
});
|
|
407
|
+
if (!loginState) {
|
|
408
|
+
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
409
|
+
ok: false,
|
|
410
|
+
code: "AUTH_REQUIRED",
|
|
411
|
+
message: "未获取到登录态,请先完成认证",
|
|
412
|
+
next_step: (0, tool_result_js_1.buildAuthNextStep)("start_auth", {
|
|
413
|
+
suggestedArgs: { action: "start_auth", authMode: effectiveMode },
|
|
414
|
+
}),
|
|
415
|
+
});
|
|
166
416
|
}
|
|
167
|
-
|
|
417
|
+
const envId = typeof loginState.envId === "string" ? loginState.envId : null;
|
|
418
|
+
const envCandidates = envId
|
|
419
|
+
? []
|
|
420
|
+
: await fetchAvailableEnvCandidates(cloudBaseOptions, server);
|
|
421
|
+
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
422
|
+
ok: true,
|
|
423
|
+
code: "AUTH_READY",
|
|
424
|
+
message: envId ? `认证成功,当前登录态 envId: ${envId}` : "认证成功",
|
|
425
|
+
auth_challenge: authChallenge(),
|
|
426
|
+
env_candidates: envCandidates,
|
|
427
|
+
next_step: envId
|
|
428
|
+
? (0, tool_result_js_1.buildAuthNextStep)("status", {
|
|
429
|
+
suggestedArgs: { action: "status" },
|
|
430
|
+
})
|
|
431
|
+
: buildSetEnvNextStep(envCandidates),
|
|
432
|
+
});
|
|
168
433
|
}
|
|
434
|
+
if (action === "set_env") {
|
|
435
|
+
const loginState = await (0, auth_js_1.peekLoginState)();
|
|
436
|
+
if (!loginState) {
|
|
437
|
+
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
438
|
+
ok: false,
|
|
439
|
+
code: "AUTH_REQUIRED",
|
|
440
|
+
message: isCodeBuddyIde(server)
|
|
441
|
+
? "当前未登录。CodeBuddy 暂不支持在 tool 内发起认证,请在外部完成认证后再次调用 auth(action=\"status\")。"
|
|
442
|
+
: "当前未登录,请先执行 auth(action=\"start_auth\")。",
|
|
443
|
+
next_step: buildAuthRequiredNextStep(server),
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
const envCandidates = await fetchAvailableEnvCandidates(cloudBaseOptions, server);
|
|
447
|
+
if (!envId) {
|
|
448
|
+
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
449
|
+
ok: false,
|
|
450
|
+
code: "INVALID_ARGS",
|
|
451
|
+
message: "action=set_env 时必须提供 envId",
|
|
452
|
+
env_candidates: envCandidates,
|
|
453
|
+
next_step: buildSetEnvNextStep(envCandidates),
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
const target = envCandidates.find((item) => item.envId === envId);
|
|
457
|
+
if (envCandidates.length > 0 && !target) {
|
|
458
|
+
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
459
|
+
ok: false,
|
|
460
|
+
code: "INVALID_ARGS",
|
|
461
|
+
message: `未找到环境: ${envId}`,
|
|
462
|
+
env_candidates: envCandidates,
|
|
463
|
+
next_step: buildSetEnvNextStep(envCandidates),
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
await cloudbase_manager_js_1.envManager.setEnvId(envId);
|
|
467
|
+
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
468
|
+
ok: true,
|
|
469
|
+
code: "ENV_READY",
|
|
470
|
+
message: `环境设置成功,当前环境: ${envId}`,
|
|
471
|
+
current_env_id: envId,
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
if (action === "logout") {
|
|
475
|
+
if (confirm !== "yes") {
|
|
476
|
+
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
477
|
+
ok: false,
|
|
478
|
+
code: "INVALID_ARGS",
|
|
479
|
+
message: "action=logout 时必须传 confirm=\"yes\"",
|
|
480
|
+
next_step: (0, tool_result_js_1.buildAuthNextStep)("logout", {
|
|
481
|
+
suggestedArgs: { action: "logout", confirm: "yes" },
|
|
482
|
+
}),
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
await (0, auth_js_1.logout)();
|
|
486
|
+
(0, cloudbase_manager_js_1.resetCloudBaseManagerCache)();
|
|
487
|
+
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
488
|
+
ok: true,
|
|
489
|
+
code: "LOGGED_OUT",
|
|
490
|
+
message: "✅ 已退出登录",
|
|
491
|
+
});
|
|
492
|
+
}
|
|
493
|
+
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
494
|
+
ok: false,
|
|
495
|
+
code: "NOT_SUPPORTED",
|
|
496
|
+
message: `不支持的 auth action: ${action}`,
|
|
497
|
+
next_step: (0, tool_result_js_1.buildAuthNextStep)("status", {
|
|
498
|
+
suggestedArgs: { action: "status" },
|
|
499
|
+
}),
|
|
500
|
+
});
|
|
169
501
|
}
|
|
170
502
|
catch (error) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
// logout - 退出云开发环境
|
|
182
|
-
server.registerTool?.("logout", {
|
|
183
|
-
title: "退出登录",
|
|
184
|
-
description: "退出云开发环境",
|
|
185
|
-
inputSchema: {
|
|
186
|
-
confirm: zod_1.z.literal("yes").describe("确认操作,默认传 yes"),
|
|
187
|
-
},
|
|
188
|
-
annotations: {
|
|
189
|
-
readOnlyHint: false,
|
|
190
|
-
destructiveHint: false,
|
|
191
|
-
idempotentHint: true,
|
|
192
|
-
openWorldHint: false,
|
|
193
|
-
category: "env",
|
|
194
|
-
},
|
|
195
|
-
}, async () => {
|
|
196
|
-
try {
|
|
197
|
-
// 登出账户
|
|
198
|
-
await (0, auth_js_1.logout)();
|
|
199
|
-
// 清理环境ID缓存
|
|
200
|
-
(0, cloudbase_manager_js_1.resetCloudBaseManagerCache)();
|
|
201
|
-
return {
|
|
202
|
-
content: [
|
|
203
|
-
{
|
|
204
|
-
type: "text",
|
|
205
|
-
text: "✅ 已退出登录",
|
|
206
|
-
},
|
|
207
|
-
],
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
catch (error) {
|
|
211
|
-
return {
|
|
212
|
-
content: [
|
|
213
|
-
{
|
|
214
|
-
type: "text",
|
|
215
|
-
text: `退出失败: ${error instanceof Error ? error.message : String(error)}`,
|
|
216
|
-
},
|
|
217
|
-
],
|
|
218
|
-
};
|
|
503
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
504
|
+
return (0, tool_result_js_1.buildJsonToolResult)({
|
|
505
|
+
ok: false,
|
|
506
|
+
code: "INTERNAL_ERROR",
|
|
507
|
+
message: `auth 执行失败: ${message}`,
|
|
508
|
+
auth_challenge: authChallenge(),
|
|
509
|
+
next_step: (0, tool_result_js_1.buildAuthNextStep)("status", {
|
|
510
|
+
suggestedArgs: { action: "status" },
|
|
511
|
+
}),
|
|
512
|
+
});
|
|
219
513
|
}
|
|
220
514
|
});
|
|
221
515
|
// envQuery - 环境查询(合并 listEnvs + getEnvInfo + getEnvAuthDomains + getWebsiteConfig)
|
|
@@ -289,6 +583,10 @@ function registerEnvTools(server) {
|
|
|
289
583
|
}
|
|
290
584
|
}
|
|
291
585
|
catch (fallbackError) {
|
|
586
|
+
const toolPayloadResult = (0, tool_result_js_1.toolPayloadErrorToResult)(fallbackError);
|
|
587
|
+
if (toolPayloadResult) {
|
|
588
|
+
return toolPayloadResult;
|
|
589
|
+
}
|
|
292
590
|
(0, logger_js_1.debug)("降级到 listEnvs() 也失败:", fallbackError instanceof Error ? fallbackError : new Error(String(fallbackError)));
|
|
293
591
|
return {
|
|
294
592
|
content: [
|
|
@@ -352,6 +650,10 @@ function registerEnvTools(server) {
|
|
|
352
650
|
};
|
|
353
651
|
}
|
|
354
652
|
catch (error) {
|
|
653
|
+
const toolPayloadResult = (0, tool_result_js_1.toolPayloadErrorToResult)(error);
|
|
654
|
+
if (toolPayloadResult) {
|
|
655
|
+
return toolPayloadResult;
|
|
656
|
+
}
|
|
355
657
|
return {
|
|
356
658
|
content: [
|
|
357
659
|
{
|
|
@@ -405,6 +707,10 @@ function registerEnvTools(server) {
|
|
|
405
707
|
};
|
|
406
708
|
}
|
|
407
709
|
catch (error) {
|
|
710
|
+
const toolPayloadResult = (0, tool_result_js_1.toolPayloadErrorToResult)(error);
|
|
711
|
+
if (toolPayloadResult) {
|
|
712
|
+
return toolPayloadResult;
|
|
713
|
+
}
|
|
408
714
|
return {
|
|
409
715
|
content: [
|
|
410
716
|
{
|
|
@@ -480,7 +786,20 @@ function registerCapiTools(server) {
|
|
|
480
786
|
throw new Error(`${service}/${action} Cloud API is not exposed or does not exist. Please use another API.`);
|
|
481
787
|
}
|
|
482
788
|
if (service === 'tcb') {
|
|
483
|
-
const tcbCapiForbidList = [
|
|
789
|
+
const tcbCapiForbidList = [
|
|
790
|
+
// 未明确对外的云API
|
|
791
|
+
'DescribeStorageACL', 'ModifyStorageACL', 'DescribeSecurityRule',
|
|
792
|
+
// 要下线的云API
|
|
793
|
+
"ListTables",
|
|
794
|
+
"DescribeCloudBaseGWAPI",
|
|
795
|
+
"DescribeCloudBaseGWService",
|
|
796
|
+
"CreateCloudBaseGWAPI",
|
|
797
|
+
"DeleteCloudBaseGWAPI",
|
|
798
|
+
"ModifyCloudBaseGWAPI",
|
|
799
|
+
"DeleteCloudBaseGWDomain",
|
|
800
|
+
"BindCloudBaseGWDomain",
|
|
801
|
+
"BindCloudBaseAccessDomain"
|
|
802
|
+
];
|
|
484
803
|
if (tcbCapiForbidList.includes(action)) {
|
|
485
804
|
throw new Error(`${service}/${action} Cloud API is not exposed or does not exist. Please use another API.`);
|
|
486
805
|
}
|
|
@@ -526,6 +845,7 @@ const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
|
526
845
|
const cloud_mode_js_1 = __webpack_require__(9684);
|
|
527
846
|
const logger_js_1 = __webpack_require__(3039);
|
|
528
847
|
const telemetry_js_1 = __webpack_require__(5880);
|
|
848
|
+
const tool_result_js_1 = __webpack_require__(9835);
|
|
529
849
|
/**
|
|
530
850
|
* 生成 GitHub Issue 创建链接
|
|
531
851
|
* @param toolName 工具名称
|
|
@@ -573,7 +893,7 @@ ${envIdSection}
|
|
|
573
893
|
## 环境信息
|
|
574
894
|
- 操作系统: ${os_1.default.type()} ${os_1.default.release()}
|
|
575
895
|
- Node.js版本: ${process.version}
|
|
576
|
-
- MCP 版本:${process.env.npm_package_version || "2.
|
|
896
|
+
- MCP 版本:${process.env.npm_package_version || "2.14.2" || 0}
|
|
577
897
|
- 系统架构: ${os_1.default.arch()}
|
|
578
898
|
- 时间: ${new Date().toISOString()}
|
|
579
899
|
- 请求ID: ${requestId}
|
|
@@ -638,6 +958,11 @@ function createWrappedHandler(name, handler, server) {
|
|
|
638
958
|
if (!isTestEnvironment) {
|
|
639
959
|
server.logger?.({ type: 'errorToolCall', toolName: name, args: sanitizeArgs(args), message: errorMessage, duration: Date.now() - startTime });
|
|
640
960
|
}
|
|
961
|
+
// Preserve structured tool guidance such as next_step.
|
|
962
|
+
// These errors are expected control flow and should be serialized by the outer server wrapper.
|
|
963
|
+
if ((0, tool_result_js_1.isToolPayloadError)(error)) {
|
|
964
|
+
throw error;
|
|
965
|
+
}
|
|
641
966
|
// In tests, avoid any extra work that may block (envId lookup, issue link generation, etc.)
|
|
642
967
|
if (isTestEnvironment) {
|
|
643
968
|
throw error instanceof Error ? error : new Error(String(error));
|
|
@@ -784,6 +1109,7 @@ const security_rule_js_1 = __webpack_require__(7862);
|
|
|
784
1109
|
const cloud_mode_js_1 = __webpack_require__(9684);
|
|
785
1110
|
const logger_js_1 = __webpack_require__(3039);
|
|
786
1111
|
const tencet_cloud_js_1 = __webpack_require__(5018);
|
|
1112
|
+
const tool_result_js_1 = __webpack_require__(9835);
|
|
787
1113
|
const tool_wrapper_js_1 = __webpack_require__(1363);
|
|
788
1114
|
// 默认插件列表
|
|
789
1115
|
const DEFAULT_PLUGINS = [
|
|
@@ -898,6 +1224,18 @@ async function createCloudBaseMcpServer(options) {
|
|
|
898
1224
|
...(ide === "CodeBuddy" ? { logging: {} } : {}),
|
|
899
1225
|
},
|
|
900
1226
|
});
|
|
1227
|
+
const originalRegisterTool = server.registerTool.bind(server);
|
|
1228
|
+
server.registerTool = ((name, meta, handler) => originalRegisterTool(name, meta, async (args) => {
|
|
1229
|
+
try {
|
|
1230
|
+
return await handler(args);
|
|
1231
|
+
}
|
|
1232
|
+
catch (error) {
|
|
1233
|
+
if ((0, tool_result_js_1.isToolPayloadError)(error)) {
|
|
1234
|
+
return (0, tool_result_js_1.buildJsonToolResult)(error.payload);
|
|
1235
|
+
}
|
|
1236
|
+
throw error;
|
|
1237
|
+
}
|
|
1238
|
+
}));
|
|
901
1239
|
// Only set logging handler if logging capability is declared
|
|
902
1240
|
if (ide === "CodeBuddy") {
|
|
903
1241
|
server.server.setRequestHandler(types_js_1.SetLevelRequestSchema, (request, extra) => {
|
|
@@ -4087,6 +4425,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4087
4425
|
};
|
|
4088
4426
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
4089
4427
|
exports.envManager = void 0;
|
|
4428
|
+
exports.listAvailableEnvCandidates = listAvailableEnvCandidates;
|
|
4090
4429
|
exports.getEnvId = getEnvId;
|
|
4091
4430
|
exports.resetCloudBaseManagerCache = resetCloudBaseManagerCache;
|
|
4092
4431
|
exports.getCachedEnvId = getCachedEnvId;
|
|
@@ -4096,9 +4435,134 @@ exports.extractRequestId = extractRequestId;
|
|
|
4096
4435
|
exports.logCloudBaseResult = logCloudBaseResult;
|
|
4097
4436
|
const manager_node_1 = __importDefault(__webpack_require__(6665));
|
|
4098
4437
|
const auth_js_1 = __webpack_require__(7291);
|
|
4099
|
-
const interactive_js_1 = __webpack_require__(3461);
|
|
4100
4438
|
const logger_js_1 = __webpack_require__(3039);
|
|
4101
|
-
const
|
|
4439
|
+
const tool_result_js_1 = __webpack_require__(9835);
|
|
4440
|
+
// Timeout for envId auto-resolution flow.
|
|
4441
|
+
// 10 minutes (600 seconds) - matches InteractiveServer timeout
|
|
4442
|
+
const ENV_ID_TIMEOUT = 600000;
|
|
4443
|
+
function toEnvCandidates(envList) {
|
|
4444
|
+
if (!Array.isArray(envList)) {
|
|
4445
|
+
return [];
|
|
4446
|
+
}
|
|
4447
|
+
return envList
|
|
4448
|
+
.filter((item) => item?.EnvId)
|
|
4449
|
+
.map((item) => ({
|
|
4450
|
+
envId: item.EnvId,
|
|
4451
|
+
alias: item.Alias,
|
|
4452
|
+
region: item.Region,
|
|
4453
|
+
status: item.Status,
|
|
4454
|
+
env_type: item.EnvType,
|
|
4455
|
+
}));
|
|
4456
|
+
}
|
|
4457
|
+
function createManagerFromLoginState(loginState, region) {
|
|
4458
|
+
return new manager_node_1.default({
|
|
4459
|
+
secretId: loginState.secretId,
|
|
4460
|
+
secretKey: loginState.secretKey,
|
|
4461
|
+
envId: loginState.envId,
|
|
4462
|
+
token: loginState.token,
|
|
4463
|
+
proxy: process.env.http_proxy,
|
|
4464
|
+
region,
|
|
4465
|
+
});
|
|
4466
|
+
}
|
|
4467
|
+
async function listAvailableEnvCandidates(options) {
|
|
4468
|
+
const { cloudBaseOptions, loginState: providedLoginState } = options ?? {};
|
|
4469
|
+
if (cloudBaseOptions?.envId) {
|
|
4470
|
+
return [{
|
|
4471
|
+
envId: cloudBaseOptions.envId,
|
|
4472
|
+
}];
|
|
4473
|
+
}
|
|
4474
|
+
let cloudbase;
|
|
4475
|
+
if (cloudBaseOptions?.secretId && cloudBaseOptions?.secretKey) {
|
|
4476
|
+
cloudbase = createCloudBaseManagerWithOptions(cloudBaseOptions);
|
|
4477
|
+
}
|
|
4478
|
+
else {
|
|
4479
|
+
const loginState = providedLoginState ?? await (0, auth_js_1.peekLoginState)();
|
|
4480
|
+
if (!loginState?.secretId || !loginState?.secretKey) {
|
|
4481
|
+
return [];
|
|
4482
|
+
}
|
|
4483
|
+
const region = cloudBaseOptions?.region ?? process.env.TCB_REGION ?? undefined;
|
|
4484
|
+
cloudbase = createManagerFromLoginState(loginState, region);
|
|
4485
|
+
}
|
|
4486
|
+
try {
|
|
4487
|
+
const result = await cloudbase.commonService("tcb", "2018-06-08").call({
|
|
4488
|
+
Action: "DescribeEnvs",
|
|
4489
|
+
Param: {
|
|
4490
|
+
EnvTypes: ["weda", "baas"],
|
|
4491
|
+
IsVisible: false,
|
|
4492
|
+
Channels: ["dcloud", "iotenable", "tem", "scene_module"],
|
|
4493
|
+
},
|
|
4494
|
+
});
|
|
4495
|
+
const envList = result?.EnvList || result?.Data?.EnvList || [];
|
|
4496
|
+
return toEnvCandidates(envList);
|
|
4497
|
+
}
|
|
4498
|
+
catch {
|
|
4499
|
+
try {
|
|
4500
|
+
const fallback = await cloudbase.env.listEnvs();
|
|
4501
|
+
return toEnvCandidates(fallback?.EnvList || []);
|
|
4502
|
+
}
|
|
4503
|
+
catch {
|
|
4504
|
+
return [];
|
|
4505
|
+
}
|
|
4506
|
+
}
|
|
4507
|
+
}
|
|
4508
|
+
function throwAuthRequiredError() {
|
|
4509
|
+
(0, tool_result_js_1.throwToolPayloadError)({
|
|
4510
|
+
ok: false,
|
|
4511
|
+
code: "AUTH_REQUIRED",
|
|
4512
|
+
message: "当前未登录,请先调用 auth 工具完成认证。",
|
|
4513
|
+
next_step: (0, tool_result_js_1.buildAuthNextStep)("start_auth", {
|
|
4514
|
+
suggestedArgs: {
|
|
4515
|
+
action: "start_auth",
|
|
4516
|
+
authMode: "device",
|
|
4517
|
+
},
|
|
4518
|
+
}),
|
|
4519
|
+
});
|
|
4520
|
+
}
|
|
4521
|
+
async function throwPendingAuthError() {
|
|
4522
|
+
const authState = await (0, auth_js_1.getAuthProgressState)();
|
|
4523
|
+
(0, tool_result_js_1.throwToolPayloadError)({
|
|
4524
|
+
ok: false,
|
|
4525
|
+
code: "AUTH_PENDING",
|
|
4526
|
+
message: authState.lastError || "设备码授权进行中,请先完成登录后再重试当前工具。",
|
|
4527
|
+
auth_challenge: authState.authChallenge
|
|
4528
|
+
? {
|
|
4529
|
+
user_code: authState.authChallenge.user_code,
|
|
4530
|
+
verification_uri: authState.authChallenge.verification_uri,
|
|
4531
|
+
expires_in: authState.authChallenge.expires_in,
|
|
4532
|
+
}
|
|
4533
|
+
: undefined,
|
|
4534
|
+
next_step: (0, tool_result_js_1.buildAuthNextStep)("status", {
|
|
4535
|
+
suggestedArgs: {
|
|
4536
|
+
action: "status",
|
|
4537
|
+
},
|
|
4538
|
+
}),
|
|
4539
|
+
});
|
|
4540
|
+
}
|
|
4541
|
+
async function throwEnvRequiredError(options) {
|
|
4542
|
+
const envCandidates = options?.envCandidates ?? (await listAvailableEnvCandidates(options));
|
|
4543
|
+
const singleEnvId = envCandidates.length === 1 ? envCandidates[0].envId : undefined;
|
|
4544
|
+
(0, tool_result_js_1.throwToolPayloadError)({
|
|
4545
|
+
ok: false,
|
|
4546
|
+
code: "ENV_REQUIRED",
|
|
4547
|
+
message: envCandidates.length === 0
|
|
4548
|
+
? "当前已登录,但还没有可用环境,请先调用 auth 工具完成环境选择或创建环境。"
|
|
4549
|
+
: envCandidates.length === 1
|
|
4550
|
+
? `当前已登录,但尚未绑定环境。可直接选择环境 ${singleEnvId}。`
|
|
4551
|
+
: "当前已登录,但尚未绑定环境,请先调用 auth 工具选择环境。",
|
|
4552
|
+
env_candidates: envCandidates,
|
|
4553
|
+
next_step: (0, tool_result_js_1.buildAuthNextStep)("set_env", {
|
|
4554
|
+
requiredParams: singleEnvId ? undefined : ["envId"],
|
|
4555
|
+
suggestedArgs: singleEnvId
|
|
4556
|
+
? {
|
|
4557
|
+
action: "set_env",
|
|
4558
|
+
envId: singleEnvId,
|
|
4559
|
+
}
|
|
4560
|
+
: {
|
|
4561
|
+
action: "set_env",
|
|
4562
|
+
},
|
|
4563
|
+
}),
|
|
4564
|
+
});
|
|
4565
|
+
}
|
|
4102
4566
|
// 统一的环境ID管理类
|
|
4103
4567
|
class EnvironmentManager {
|
|
4104
4568
|
cachedEnvId = null;
|
|
@@ -4110,7 +4574,7 @@ class EnvironmentManager {
|
|
|
4110
4574
|
delete process.env.CLOUDBASE_ENV_ID;
|
|
4111
4575
|
}
|
|
4112
4576
|
// 获取环境ID的核心逻辑
|
|
4113
|
-
async getEnvId(
|
|
4577
|
+
async getEnvId() {
|
|
4114
4578
|
// 1. 优先使用内存缓存
|
|
4115
4579
|
if (this.cachedEnvId) {
|
|
4116
4580
|
(0, logger_js_1.debug)('使用内存缓存的环境ID:', { envId: this.cachedEnvId });
|
|
@@ -4120,17 +4584,10 @@ class EnvironmentManager {
|
|
|
4120
4584
|
if (this.envIdPromise) {
|
|
4121
4585
|
return this.envIdPromise;
|
|
4122
4586
|
}
|
|
4123
|
-
// 3. 开始获取环境ID
|
|
4124
|
-
this.envIdPromise = this._fetchEnvId(
|
|
4125
|
-
// 增加超时保护
|
|
4126
|
-
const timeoutPromise = new Promise((_, reject) => {
|
|
4127
|
-
const id = setTimeout(() => {
|
|
4128
|
-
clearTimeout(id);
|
|
4129
|
-
reject(new Error(`EnvId 获取超时(${ENV_ID_TIMEOUT / 1000}秒)`));
|
|
4130
|
-
}, ENV_ID_TIMEOUT);
|
|
4131
|
-
});
|
|
4587
|
+
// 3. 开始获取环境ID
|
|
4588
|
+
this.envIdPromise = this._fetchEnvId();
|
|
4132
4589
|
try {
|
|
4133
|
-
const result = await
|
|
4590
|
+
const result = await this.envIdPromise;
|
|
4134
4591
|
return result;
|
|
4135
4592
|
}
|
|
4136
4593
|
catch (err) {
|
|
@@ -4138,7 +4595,7 @@ class EnvironmentManager {
|
|
|
4138
4595
|
throw err;
|
|
4139
4596
|
}
|
|
4140
4597
|
}
|
|
4141
|
-
async _fetchEnvId(
|
|
4598
|
+
async _fetchEnvId() {
|
|
4142
4599
|
try {
|
|
4143
4600
|
// 1. 检查进程环境变量
|
|
4144
4601
|
if (process.env.CLOUDBASE_ENV_ID) {
|
|
@@ -4146,48 +4603,23 @@ class EnvironmentManager {
|
|
|
4146
4603
|
this.cachedEnvId = process.env.CLOUDBASE_ENV_ID;
|
|
4147
4604
|
return this.cachedEnvId;
|
|
4148
4605
|
}
|
|
4149
|
-
// 2.
|
|
4150
|
-
(0,
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
|
|
4162
|
-
|
|
4163
|
-
// Re-throw with enhanced context
|
|
4164
|
-
const enhancedError = new Error(`自动设置环境ID失败: ${errorObj.message}`);
|
|
4165
|
-
enhancedError.originalError = errorObj;
|
|
4166
|
-
enhancedError.failureInfo = {
|
|
4167
|
-
reason: 'unknown_error',
|
|
4168
|
-
error: errorObj.message,
|
|
4169
|
-
errorCode: 'SETUP_EXCEPTION',
|
|
4170
|
-
};
|
|
4171
|
-
throw enhancedError;
|
|
4172
|
-
}
|
|
4173
|
-
const autoEnvId = setupResult.selectedEnvId;
|
|
4174
|
-
if (!autoEnvId) {
|
|
4175
|
-
// Build detailed error message from failure info
|
|
4176
|
-
const errorMessage = this._buildDetailedErrorMessage(setupResult.failureInfo);
|
|
4177
|
-
(0, logger_js_1.error)('自动设置环境ID失败:', {
|
|
4178
|
-
reason: setupResult.failureInfo?.reason,
|
|
4179
|
-
errorCode: setupResult.failureInfo?.errorCode,
|
|
4180
|
-
error: setupResult.failureInfo?.error,
|
|
4181
|
-
details: setupResult.failureInfo?.details,
|
|
4182
|
-
});
|
|
4183
|
-
// Create error with detailed information
|
|
4184
|
-
const detailedError = new Error(errorMessage);
|
|
4185
|
-
detailedError.failureInfo = setupResult.failureInfo;
|
|
4186
|
-
throw detailedError;
|
|
4606
|
+
// 2. 如果登录态里已有 envId,直接复用
|
|
4607
|
+
const loginState = await (0, auth_js_1.peekLoginState)();
|
|
4608
|
+
if (typeof loginState?.envId === 'string' && loginState.envId.length > 0) {
|
|
4609
|
+
(0, logger_js_1.debug)('使用登录态中的环境ID:', { envId: loginState.envId });
|
|
4610
|
+
this._setCachedEnvId(loginState.envId);
|
|
4611
|
+
return loginState.envId;
|
|
4612
|
+
}
|
|
4613
|
+
// 3. 单环境自动绑定;多环境时返回结构化引导,不再触发交互弹窗
|
|
4614
|
+
const envCandidates = await listAvailableEnvCandidates({ loginState });
|
|
4615
|
+
if (envCandidates.length === 1) {
|
|
4616
|
+
const singleEnvId = envCandidates[0].envId;
|
|
4617
|
+
(0, logger_js_1.debug)('自动绑定唯一环境:', { envId: singleEnvId });
|
|
4618
|
+
this._setCachedEnvId(singleEnvId);
|
|
4619
|
+
return singleEnvId;
|
|
4187
4620
|
}
|
|
4188
|
-
|
|
4189
|
-
|
|
4190
|
-
return autoEnvId;
|
|
4621
|
+
await throwEnvRequiredError({ loginState, envCandidates });
|
|
4622
|
+
throw new Error('Unreachable after throwEnvRequiredError');
|
|
4191
4623
|
}
|
|
4192
4624
|
catch (err) {
|
|
4193
4625
|
// Log the error with full context before re-throwing
|
|
@@ -4211,65 +4643,6 @@ class EnvironmentManager {
|
|
|
4211
4643
|
process.env.CLOUDBASE_ENV_ID = envId;
|
|
4212
4644
|
(0, logger_js_1.debug)('已更新环境ID缓存:', { envId });
|
|
4213
4645
|
}
|
|
4214
|
-
// Build detailed error message from failure info
|
|
4215
|
-
_buildDetailedErrorMessage(failureInfo) {
|
|
4216
|
-
if (!failureInfo) {
|
|
4217
|
-
return "CloudBase Environment ID not found after auto setup. Please set CLOUDBASE_ENV_ID or run setupEnvironmentId tool.";
|
|
4218
|
-
}
|
|
4219
|
-
const { reason, error: errorMsg, errorCode, helpUrl, details } = failureInfo;
|
|
4220
|
-
let message = "CloudBase Environment ID not found after auto setup.\n\n";
|
|
4221
|
-
message += `原因: ${this._getReasonDescription(reason)}\n`;
|
|
4222
|
-
if (errorMsg) {
|
|
4223
|
-
message += `错误: ${errorMsg}\n`;
|
|
4224
|
-
}
|
|
4225
|
-
if (errorCode) {
|
|
4226
|
-
message += `错误代码: ${errorCode}\n`;
|
|
4227
|
-
}
|
|
4228
|
-
// Add specific details based on failure reason
|
|
4229
|
-
if (reason === 'tcb_init_failed' && details?.initTcbError) {
|
|
4230
|
-
const initError = details.initTcbError;
|
|
4231
|
-
if (initError.needRealNameAuth) {
|
|
4232
|
-
message += "\n需要完成实名认证才能使用 CloudBase 服务。\n";
|
|
4233
|
-
}
|
|
4234
|
-
if (initError.needCamAuth) {
|
|
4235
|
-
message += "\n需要 CAM 权限才能使用 CloudBase 服务。\n";
|
|
4236
|
-
}
|
|
4237
|
-
}
|
|
4238
|
-
if (reason === 'env_creation_failed' && details?.createEnvError) {
|
|
4239
|
-
const createError = details.createEnvError;
|
|
4240
|
-
message += `\n环境创建失败: ${createError.message || '未知错误'}\n`;
|
|
4241
|
-
}
|
|
4242
|
-
if (reason === 'env_query_failed' && details?.queryEnvError) {
|
|
4243
|
-
message += `\n环境查询失败: ${details.queryEnvError}\n`;
|
|
4244
|
-
}
|
|
4245
|
-
if (reason === 'timeout' && details?.timeoutDuration) {
|
|
4246
|
-
message += `\n超时时间: ${details.timeoutDuration / 1000} 秒\n`;
|
|
4247
|
-
message += "提示: 请确保浏览器窗口已打开,并在规定时间内完成环境选择。\n";
|
|
4248
|
-
}
|
|
4249
|
-
message += "\n解决方案:\n";
|
|
4250
|
-
message += "1. 手动设置环境ID: 设置环境变量 CLOUDBASE_ENV_ID\n";
|
|
4251
|
-
message += "2. 使用工具设置: 运行 setupEnvironmentId 工具\n";
|
|
4252
|
-
if (helpUrl) {
|
|
4253
|
-
message += `3. 查看帮助文档: ${helpUrl}\n`;
|
|
4254
|
-
}
|
|
4255
|
-
else {
|
|
4256
|
-
message += "3. 查看帮助文档: https://docs.cloudbase.net/cli-v1/env\n";
|
|
4257
|
-
}
|
|
4258
|
-
return message;
|
|
4259
|
-
}
|
|
4260
|
-
_getReasonDescription(reason) {
|
|
4261
|
-
const descriptions = {
|
|
4262
|
-
'timeout': '环境选择超时',
|
|
4263
|
-
'cancelled': '用户取消了环境选择',
|
|
4264
|
-
'no_environments': '没有可用环境',
|
|
4265
|
-
'login_failed': '登录失败',
|
|
4266
|
-
'tcb_init_failed': 'CloudBase 服务初始化失败',
|
|
4267
|
-
'env_query_failed': '环境列表查询失败',
|
|
4268
|
-
'env_creation_failed': '环境创建失败',
|
|
4269
|
-
'unknown_error': '未知错误',
|
|
4270
|
-
};
|
|
4271
|
-
return descriptions[reason] || '未知原因';
|
|
4272
|
-
}
|
|
4273
4646
|
// 手动设置环境ID(用于外部调用)
|
|
4274
4647
|
async setEnvId(envId) {
|
|
4275
4648
|
this._setCachedEnvId(envId);
|
|
@@ -4290,6 +4663,16 @@ async function getEnvId(cloudBaseOptions) {
|
|
|
4290
4663
|
(0, logger_js_1.debug)('使用传入的 envId:', { envId: cloudBaseOptions.envId });
|
|
4291
4664
|
return cloudBaseOptions.envId;
|
|
4292
4665
|
}
|
|
4666
|
+
const cachedEnvId = envManager.getCachedEnvId() || process.env.CLOUDBASE_ENV_ID;
|
|
4667
|
+
if (cachedEnvId) {
|
|
4668
|
+
(0, logger_js_1.debug)('使用缓存中的 envId:', { envId: cachedEnvId });
|
|
4669
|
+
return cachedEnvId;
|
|
4670
|
+
}
|
|
4671
|
+
const loginState = await (0, auth_js_1.peekLoginState)();
|
|
4672
|
+
if (typeof loginState?.envId === 'string' && loginState.envId.length > 0) {
|
|
4673
|
+
(0, logger_js_1.debug)('使用登录态中的 envId:', { envId: loginState.envId });
|
|
4674
|
+
return loginState.envId;
|
|
4675
|
+
}
|
|
4293
4676
|
// 否则使用默认逻辑
|
|
4294
4677
|
return envManager.getEnvId();
|
|
4295
4678
|
}
|
|
@@ -4305,37 +4688,89 @@ function getCachedEnvId() {
|
|
|
4305
4688
|
* 每次都实时获取最新的 token/secretId/secretKey
|
|
4306
4689
|
*/
|
|
4307
4690
|
async function getCloudBaseManager(options = {}) {
|
|
4308
|
-
const { requireEnvId = true, cloudBaseOptions,
|
|
4309
|
-
|
|
4310
|
-
|
|
4691
|
+
const { requireEnvId = true, cloudBaseOptions, authStrategy = 'fail_fast', } = options;
|
|
4692
|
+
const hasDirectCredentials = !!(cloudBaseOptions?.secretId && cloudBaseOptions?.secretKey);
|
|
4693
|
+
// 如果传入了完整凭据,优先使用显式 CloudBase 配置
|
|
4694
|
+
if (cloudBaseOptions && hasDirectCredentials) {
|
|
4695
|
+
let resolvedEnvId = cloudBaseOptions.envId;
|
|
4696
|
+
if (requireEnvId && !resolvedEnvId) {
|
|
4697
|
+
const envCandidates = await listAvailableEnvCandidates({ cloudBaseOptions });
|
|
4698
|
+
if (envCandidates.length === 1) {
|
|
4699
|
+
const singleEnvId = envCandidates[0].envId;
|
|
4700
|
+
cloudBaseOptions.envId = singleEnvId;
|
|
4701
|
+
resolvedEnvId = singleEnvId;
|
|
4702
|
+
(0, logger_js_1.debug)('自动绑定唯一环境(显式配置):', { envId: singleEnvId });
|
|
4703
|
+
}
|
|
4704
|
+
else if (authStrategy === 'fail_fast') {
|
|
4705
|
+
await throwEnvRequiredError({ cloudBaseOptions, envCandidates });
|
|
4706
|
+
}
|
|
4707
|
+
else {
|
|
4708
|
+
(0, tool_result_js_1.throwToolPayloadError)({
|
|
4709
|
+
ok: false,
|
|
4710
|
+
code: "ENV_REQUIRED",
|
|
4711
|
+
message: "当前显式 CloudBase 凭据未绑定环境,请补充 envId 或先选择环境。",
|
|
4712
|
+
env_candidates: envCandidates,
|
|
4713
|
+
next_step: (0, tool_result_js_1.buildAuthNextStep)("set_env", {
|
|
4714
|
+
suggestedArgs: { action: "set_env" },
|
|
4715
|
+
requiredParams: ["envId"],
|
|
4716
|
+
}),
|
|
4717
|
+
});
|
|
4718
|
+
}
|
|
4719
|
+
}
|
|
4311
4720
|
(0, logger_js_1.debug)('使用传入的 CloudBase 配置');
|
|
4312
|
-
return createCloudBaseManagerWithOptions(
|
|
4721
|
+
return createCloudBaseManagerWithOptions({
|
|
4722
|
+
...cloudBaseOptions,
|
|
4723
|
+
envId: resolvedEnvId,
|
|
4724
|
+
});
|
|
4313
4725
|
}
|
|
4314
4726
|
try {
|
|
4315
4727
|
// Get region from environment variable for auth URL
|
|
4316
|
-
|
|
4317
|
-
const
|
|
4318
|
-
|
|
4728
|
+
const region = cloudBaseOptions?.region ?? process.env.TCB_REGION;
|
|
4729
|
+
const loginState = authStrategy === 'ensure'
|
|
4730
|
+
? await (0, auth_js_1.getLoginState)({ region })
|
|
4731
|
+
: await (0, auth_js_1.peekLoginState)();
|
|
4732
|
+
if (!loginState) {
|
|
4733
|
+
const authState = await (0, auth_js_1.getAuthProgressState)();
|
|
4734
|
+
if (authState.status === 'PENDING') {
|
|
4735
|
+
await throwPendingAuthError();
|
|
4736
|
+
}
|
|
4737
|
+
throwAuthRequiredError();
|
|
4738
|
+
}
|
|
4319
4739
|
const { envId: loginEnvId, secretId, secretKey, token } = loginState;
|
|
4320
|
-
let finalEnvId;
|
|
4740
|
+
let finalEnvId = cloudBaseOptions?.envId;
|
|
4321
4741
|
if (requireEnvId) {
|
|
4322
|
-
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
(
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
|
|
4334
|
-
|
|
4335
|
-
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4742
|
+
if (!finalEnvId) {
|
|
4743
|
+
// Optimize: Check if envManager has cached envId first (fast path)
|
|
4744
|
+
// If cached, use it directly; otherwise check loginEnvId before calling getEnvId()
|
|
4745
|
+
// This avoids unnecessary async calls when we have a valid envId available
|
|
4746
|
+
const cachedEnvId = envManager.getCachedEnvId() || process.env.CLOUDBASE_ENV_ID;
|
|
4747
|
+
if (cachedEnvId) {
|
|
4748
|
+
(0, logger_js_1.debug)('使用 envManager 缓存的环境ID:', { cachedEnvId });
|
|
4749
|
+
finalEnvId = cachedEnvId;
|
|
4750
|
+
}
|
|
4751
|
+
else if (loginEnvId) {
|
|
4752
|
+
// If no cache but loginState has envId, use it directly
|
|
4753
|
+
(0, logger_js_1.debug)('使用 loginState 中的环境ID:', { loginEnvId });
|
|
4754
|
+
finalEnvId = loginEnvId;
|
|
4755
|
+
}
|
|
4756
|
+
else {
|
|
4757
|
+
if (authStrategy === 'fail_fast') {
|
|
4758
|
+
const envCandidates = await listAvailableEnvCandidates({ loginState });
|
|
4759
|
+
if (envCandidates.length === 1) {
|
|
4760
|
+
const singleEnvId = envCandidates[0].envId;
|
|
4761
|
+
await envManager.setEnvId(singleEnvId);
|
|
4762
|
+
finalEnvId = singleEnvId;
|
|
4763
|
+
(0, logger_js_1.debug)('自动绑定唯一环境:', { envId: singleEnvId });
|
|
4764
|
+
}
|
|
4765
|
+
else {
|
|
4766
|
+
await throwEnvRequiredError({ loginState, envCandidates });
|
|
4767
|
+
}
|
|
4768
|
+
}
|
|
4769
|
+
else {
|
|
4770
|
+
// ensure 模式下也保持非交互:单环境自动绑定,多环境返回 ENV_REQUIRED
|
|
4771
|
+
finalEnvId = await envManager.getEnvId();
|
|
4772
|
+
}
|
|
4773
|
+
}
|
|
4339
4774
|
}
|
|
4340
4775
|
}
|
|
4341
4776
|
// envId priority: envManager.cachedEnvId > envManager.getEnvId() > loginState.envId > undefined
|
|
@@ -4572,6 +5007,7 @@ async function _promptAndSetEnvironmentId(autoSelectSingle, options) {
|
|
|
4572
5007
|
hasServerServer: !!server?.server,
|
|
4573
5008
|
hasServerIde: !!server?.ide,
|
|
4574
5009
|
ignoreEnvVars: options?.ignoreEnvVars,
|
|
5010
|
+
authMode: options?.authMode,
|
|
4575
5011
|
optionsKeys: options ? Object.keys(options).join(', ') : 'null',
|
|
4576
5012
|
});
|
|
4577
5013
|
if (!server) {
|
|
@@ -4588,6 +5024,9 @@ async function _promptAndSetEnvironmentId(autoSelectSingle, options) {
|
|
|
4588
5024
|
fromCloudBaseLoginPage: options?.loginFromCloudBaseLoginPage,
|
|
4589
5025
|
ignoreEnvVars: options?.ignoreEnvVars,
|
|
4590
5026
|
region,
|
|
5027
|
+
authMode: options?.authMode,
|
|
5028
|
+
clientId: options?.clientId,
|
|
5029
|
+
onDeviceCode: options?.onDeviceCode,
|
|
4591
5030
|
});
|
|
4592
5031
|
(0, logger_js_1.debug)("[interactive] Login state:", {
|
|
4593
5032
|
hasLoginState: !!loginState,
|
|
@@ -7299,6 +7738,15 @@ async function registerRagTools(server) {
|
|
|
7299
7738
|
],
|
|
7300
7739
|
};
|
|
7301
7740
|
}
|
|
7741
|
+
// 向量检索模式下必须提供 id 和 content,避免后端报「知识库名称不能为空」
|
|
7742
|
+
if (mode === "vector") {
|
|
7743
|
+
if (!id) {
|
|
7744
|
+
throw new Error("知识库名称不能为空: please provide `id` when mode=vector (cloudbase / scf / miniprogram).");
|
|
7745
|
+
}
|
|
7746
|
+
if (!content || !content.trim()) {
|
|
7747
|
+
throw new Error("检索内容不能为空: please provide non-empty `content` when mode=vector.");
|
|
7748
|
+
}
|
|
7749
|
+
}
|
|
7302
7750
|
// 枚举到后端 id 映射
|
|
7303
7751
|
const backendId = KnowledgeBaseIdMap[id] || id;
|
|
7304
7752
|
const signInRes = await fetch("https://tcb-advanced-a656fc.api.tcloudbasegateway.com/auth/v1/signin/anonymously", {
|
|
@@ -8703,7 +9151,7 @@ class TelemetryReporter {
|
|
|
8703
9151
|
const nodeVersion = process.version; // Node.js版本
|
|
8704
9152
|
const arch = os_1.default.arch(); // 系统架构
|
|
8705
9153
|
// 从构建时注入的版本号获取MCP版本信息
|
|
8706
|
-
const mcpVersion = process.env.npm_package_version || "2.
|
|
9154
|
+
const mcpVersion = process.env.npm_package_version || "2.14.2" || 0;
|
|
8707
9155
|
return {
|
|
8708
9156
|
userAgent: `${osType} ${osRelease} ${arch} ${nodeVersion} CloudBase-MCP/${mcpVersion}`,
|
|
8709
9157
|
deviceId: this.deviceId,
|
|
@@ -9015,23 +9463,71 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
9015
9463
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9016
9464
|
};
|
|
9017
9465
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
9018
|
-
exports.TRIGGER_CONFIG_EXAMPLES = exports.SUPPORTED_TRIGGER_TYPES = exports.DEFAULT_NODEJS_RUNTIME = exports.SUPPORTED_NODEJS_RUNTIMES = void 0;
|
|
9466
|
+
exports.WRITE_FUNCTION_LAYER_ACTIONS = exports.READ_FUNCTION_LAYER_ACTIONS = exports.TRIGGER_CONFIG_EXAMPLES = exports.SUPPORTED_TRIGGER_TYPES = exports.DEFAULT_NODEJS_RUNTIME = exports.SUPPORTED_NODEJS_RUNTIMES = exports.RECOMMENDED_RUNTIMES = exports.DEFAULT_RUNTIME = exports.ALL_SUPPORTED_RUNTIMES = exports.SUPPORTED_RUNTIMES = void 0;
|
|
9467
|
+
exports.formatRuntimeList = formatRuntimeList;
|
|
9019
9468
|
exports.registerFunctionTools = registerFunctionTools;
|
|
9020
9469
|
const zod_1 = __webpack_require__(2971);
|
|
9021
9470
|
const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
9022
9471
|
const logger_js_1 = __webpack_require__(3039);
|
|
9023
9472
|
const path_1 = __importDefault(__webpack_require__(2521));
|
|
9024
|
-
//
|
|
9025
|
-
exports.
|
|
9026
|
-
|
|
9027
|
-
|
|
9028
|
-
|
|
9029
|
-
|
|
9030
|
-
|
|
9031
|
-
|
|
9032
|
-
|
|
9033
|
-
|
|
9034
|
-
|
|
9473
|
+
// 所有支持的运行时环境(按语言分类)
|
|
9474
|
+
exports.SUPPORTED_RUNTIMES = {
|
|
9475
|
+
nodejs: [
|
|
9476
|
+
"Nodejs20.19",
|
|
9477
|
+
"Nodejs18.15",
|
|
9478
|
+
"Nodejs16.13",
|
|
9479
|
+
"Nodejs14.18",
|
|
9480
|
+
"Nodejs12.16",
|
|
9481
|
+
"Nodejs10.15",
|
|
9482
|
+
"Nodejs8.9",
|
|
9483
|
+
],
|
|
9484
|
+
python: [
|
|
9485
|
+
"Python3.10",
|
|
9486
|
+
"Python3.9",
|
|
9487
|
+
"Python3.7",
|
|
9488
|
+
"Python3.6",
|
|
9489
|
+
"Python2.7",
|
|
9490
|
+
],
|
|
9491
|
+
php: [
|
|
9492
|
+
"Php8.0",
|
|
9493
|
+
"Php7.4",
|
|
9494
|
+
"Php7.2",
|
|
9495
|
+
],
|
|
9496
|
+
java: [
|
|
9497
|
+
"Java8",
|
|
9498
|
+
"Java11",
|
|
9499
|
+
],
|
|
9500
|
+
golang: [
|
|
9501
|
+
"Golang1",
|
|
9502
|
+
],
|
|
9503
|
+
};
|
|
9504
|
+
// 所有支持的运行时(扁平化数组,用于验证)
|
|
9505
|
+
exports.ALL_SUPPORTED_RUNTIMES = Object.values(exports.SUPPORTED_RUNTIMES).flat();
|
|
9506
|
+
// 默认运行时
|
|
9507
|
+
exports.DEFAULT_RUNTIME = "Nodejs18.15";
|
|
9508
|
+
// 推荐运行时(用于文档和提示)
|
|
9509
|
+
exports.RECOMMENDED_RUNTIMES = {
|
|
9510
|
+
nodejs: "Nodejs18.15",
|
|
9511
|
+
python: "Python3.9",
|
|
9512
|
+
php: "Php7.4",
|
|
9513
|
+
java: "Java11",
|
|
9514
|
+
golang: "Golang1",
|
|
9515
|
+
};
|
|
9516
|
+
// 保留向后兼容
|
|
9517
|
+
exports.SUPPORTED_NODEJS_RUNTIMES = exports.SUPPORTED_RUNTIMES.nodejs;
|
|
9518
|
+
exports.DEFAULT_NODEJS_RUNTIME = exports.DEFAULT_RUNTIME;
|
|
9519
|
+
/**
|
|
9520
|
+
* 格式化运行时列表(按语言分类)
|
|
9521
|
+
* 用于错误提示和用户引导
|
|
9522
|
+
*/
|
|
9523
|
+
function formatRuntimeList() {
|
|
9524
|
+
return Object.entries(exports.SUPPORTED_RUNTIMES)
|
|
9525
|
+
.map(([lang, runtimes]) => {
|
|
9526
|
+
const capitalizedLang = lang.charAt(0).toUpperCase() + lang.slice(1);
|
|
9527
|
+
return ` ${capitalizedLang}: ${runtimes.join(', ')}`;
|
|
9528
|
+
})
|
|
9529
|
+
.join('\n');
|
|
9530
|
+
}
|
|
9035
9531
|
// Supported trigger types
|
|
9036
9532
|
exports.SUPPORTED_TRIGGER_TYPES = [
|
|
9037
9533
|
"timer", // Timer trigger
|
|
@@ -9048,6 +9544,41 @@ exports.TRIGGER_CONFIG_EXAMPLES = {
|
|
|
9048
9544
|
],
|
|
9049
9545
|
},
|
|
9050
9546
|
};
|
|
9547
|
+
exports.READ_FUNCTION_LAYER_ACTIONS = [
|
|
9548
|
+
"listLayers",
|
|
9549
|
+
"listLayerVersions",
|
|
9550
|
+
"getLayerVersion",
|
|
9551
|
+
"getFunctionLayers",
|
|
9552
|
+
];
|
|
9553
|
+
exports.WRITE_FUNCTION_LAYER_ACTIONS = [
|
|
9554
|
+
"createLayerVersion",
|
|
9555
|
+
"deleteLayerVersion",
|
|
9556
|
+
"attachLayer",
|
|
9557
|
+
"detachLayer",
|
|
9558
|
+
"updateFunctionLayers",
|
|
9559
|
+
];
|
|
9560
|
+
function jsonContent(body) {
|
|
9561
|
+
return {
|
|
9562
|
+
content: [
|
|
9563
|
+
{
|
|
9564
|
+
type: "text",
|
|
9565
|
+
text: JSON.stringify(body, null, 2),
|
|
9566
|
+
},
|
|
9567
|
+
],
|
|
9568
|
+
};
|
|
9569
|
+
}
|
|
9570
|
+
function normalizeFunctionLayers(layers) {
|
|
9571
|
+
if (!Array.isArray(layers)) {
|
|
9572
|
+
return [];
|
|
9573
|
+
}
|
|
9574
|
+
return layers
|
|
9575
|
+
.filter((layer) => Boolean(layer))
|
|
9576
|
+
.map((layer) => ({
|
|
9577
|
+
LayerName: String(layer.LayerName ?? ""),
|
|
9578
|
+
LayerVersion: Number(layer.LayerVersion ?? 0),
|
|
9579
|
+
}))
|
|
9580
|
+
.filter((layer) => Boolean(layer.LayerName) && Number.isFinite(layer.LayerVersion));
|
|
9581
|
+
}
|
|
9051
9582
|
/**
|
|
9052
9583
|
* 处理函数根目录路径,确保不包含函数名
|
|
9053
9584
|
* @param functionRootPath 用户输入的路径
|
|
@@ -9075,12 +9606,12 @@ function registerFunctionTools(server) {
|
|
|
9075
9606
|
// getFunctionList - 获取云函数列表或详情(推荐)
|
|
9076
9607
|
server.registerTool?.("getFunctionList", {
|
|
9077
9608
|
title: "查询云函数列表或详情",
|
|
9078
|
-
description: "获取云函数列表或单个函数详情。通过 action 参数区分操作类型:list=获取函数列表(默认,无需额外参数),detail=获取函数详情(需要提供 name
|
|
9609
|
+
description: "获取云函数列表或单个函数详情。通过 action 参数区分操作类型:list=获取函数列表(默认,无需额外参数),detail=获取函数详情(需要提供 name 参数指定函数名称,返回结果中包含函数当前绑定的 Layers 信息)",
|
|
9079
9610
|
inputSchema: {
|
|
9080
9611
|
action: zod_1.z
|
|
9081
9612
|
.enum(["list", "detail"])
|
|
9082
9613
|
.optional()
|
|
9083
|
-
.describe("操作类型:list=获取函数列表(默认,无需额外参数),detail=获取函数详情(需要提供 name
|
|
9614
|
+
.describe("操作类型:list=获取函数列表(默认,无需额外参数),detail=获取函数详情(需要提供 name 参数,返回结果中包含当前绑定的 Layers)"),
|
|
9084
9615
|
limit: zod_1.z.number().optional().describe("范围(list 操作时使用)"),
|
|
9085
9616
|
offset: zod_1.z.number().optional().describe("偏移(list 操作时使用)"),
|
|
9086
9617
|
name: zod_1.z
|
|
@@ -9134,7 +9665,11 @@ function registerFunctionTools(server) {
|
|
|
9134
9665
|
// createFunction - 创建云函数 (cloud-incompatible)
|
|
9135
9666
|
server.registerTool("createFunction", {
|
|
9136
9667
|
title: "创建云函数",
|
|
9137
|
-
description: "
|
|
9668
|
+
description: "创建云函数。云函数分为事件型云函数(Event)和 HTTP 云函数。\n\n" +
|
|
9669
|
+
"支持的运行时:\n" +
|
|
9670
|
+
"- Event 函数: Node.js, Python, PHP, Java, Go\n" +
|
|
9671
|
+
"- HTTP 函数: 所有语言(通过 scf_bootstrap 启动脚本)\n\n" +
|
|
9672
|
+
"注意: 运行时创建后不可修改,请谨慎选择。",
|
|
9138
9673
|
inputSchema: {
|
|
9139
9674
|
func: zod_1.z
|
|
9140
9675
|
.object({
|
|
@@ -9177,8 +9712,18 @@ function registerFunctionTools(server) {
|
|
|
9177
9712
|
runtime: zod_1.z
|
|
9178
9713
|
.string()
|
|
9179
9714
|
.optional()
|
|
9180
|
-
.describe("
|
|
9181
|
-
|
|
9715
|
+
.describe("运行时环境。Event 函数支持多种运行时:\n" +
|
|
9716
|
+
formatRuntimeList() + "\n\n" +
|
|
9717
|
+
"推荐运行时:\n" +
|
|
9718
|
+
` Node.js: ${exports.RECOMMENDED_RUNTIMES.nodejs}\n` +
|
|
9719
|
+
` Python: ${exports.RECOMMENDED_RUNTIMES.python}\n` +
|
|
9720
|
+
` PHP: ${exports.RECOMMENDED_RUNTIMES.php}\n` +
|
|
9721
|
+
` Java: ${exports.RECOMMENDED_RUNTIMES.java}\n` +
|
|
9722
|
+
` Go: ${exports.RECOMMENDED_RUNTIMES.golang}\n\n` +
|
|
9723
|
+
"注意:\n" +
|
|
9724
|
+
"- HTTP 函数已支持所有语言(通过 scf_bootstrap 启动脚本)\n" +
|
|
9725
|
+
"- Node.js 函数会自动安装依赖\n" +
|
|
9726
|
+
"- Python/PHP/Java/Go 函数需要预先打包依赖到函数目录"),
|
|
9182
9727
|
triggers: zod_1.z
|
|
9183
9728
|
.array(zod_1.z.object({
|
|
9184
9729
|
name: zod_1.z.string().describe("Trigger name"),
|
|
@@ -9226,12 +9771,14 @@ function registerFunctionTools(server) {
|
|
|
9226
9771
|
if (!isHttpFunction) {
|
|
9227
9772
|
// 自动填充默认 runtime
|
|
9228
9773
|
if (!func.runtime) {
|
|
9229
|
-
func.runtime = exports.
|
|
9774
|
+
func.runtime = exports.DEFAULT_RUNTIME;
|
|
9775
|
+
console.log(`未指定 runtime,使用默认值: ${exports.DEFAULT_RUNTIME}\n` +
|
|
9776
|
+
`可选运行时:\n${formatRuntimeList()}`);
|
|
9230
9777
|
}
|
|
9231
9778
|
else {
|
|
9232
9779
|
// 验证 runtime 格式,防止常见的空格问题
|
|
9233
9780
|
const normalizedRuntime = func.runtime.replace(/\s+/g, "");
|
|
9234
|
-
if (exports.
|
|
9781
|
+
if (exports.ALL_SUPPORTED_RUNTIMES.includes(normalizedRuntime)) {
|
|
9235
9782
|
func.runtime = normalizedRuntime;
|
|
9236
9783
|
}
|
|
9237
9784
|
else if (func.runtime.includes(" ")) {
|
|
@@ -9240,8 +9787,13 @@ function registerFunctionTools(server) {
|
|
|
9240
9787
|
}
|
|
9241
9788
|
}
|
|
9242
9789
|
// 验证 runtime 是否有效
|
|
9243
|
-
if (!exports.
|
|
9244
|
-
throw new Error(`不支持的运行时环境: "${func.runtime}"
|
|
9790
|
+
if (!exports.ALL_SUPPORTED_RUNTIMES.includes(func.runtime)) {
|
|
9791
|
+
throw new Error(`不支持的运行时环境: "${func.runtime}"\n\n` +
|
|
9792
|
+
`支持的运行时:\n${formatRuntimeList()}\n\n` +
|
|
9793
|
+
`提示:\n` +
|
|
9794
|
+
`- Node.js 函数会自动安装依赖\n` +
|
|
9795
|
+
`- Python/PHP/Java/Go 函数需要预先打包依赖到函数目录\n` +
|
|
9796
|
+
`- 详细信息请参考文档: https://docs.cloudbase.net/api-reference/manager/node/function#createfunction`);
|
|
9245
9797
|
}
|
|
9246
9798
|
}
|
|
9247
9799
|
// 强制设置 installDependency 为 true(不暴露给AI)
|
|
@@ -9594,6 +10146,379 @@ function registerFunctionTools(server) {
|
|
|
9594
10146
|
throw new Error(`不支持的操作类型: ${action}`);
|
|
9595
10147
|
}
|
|
9596
10148
|
});
|
|
10149
|
+
server.registerTool?.("readFunctionLayers", {
|
|
10150
|
+
title: "查询云函数层信息",
|
|
10151
|
+
description: "查询云函数层及函数层配置。通过 action 区分操作:listLayers=查询层列表,listLayerVersions=查询指定层的版本列表,getLayerVersion=查询层版本详情(含下载地址/元信息),getFunctionLayers=查询指定函数当前绑定的层。返回格式:JSON 包含 success、data(含 action 与对应结果字段)、message;data.layers 或 data.layerVersions 为数组,getFunctionLayers 的 data.layers 每项为 { LayerName, LayerVersion }。",
|
|
10152
|
+
inputSchema: {
|
|
10153
|
+
action: zod_1.z
|
|
10154
|
+
.enum(exports.READ_FUNCTION_LAYER_ACTIONS)
|
|
10155
|
+
.describe("操作类型:listLayers=查询层列表,listLayerVersions=查询指定层的版本列表,getLayerVersion=查询层版本详情,getFunctionLayers=查询指定函数当前绑定的层"),
|
|
10156
|
+
name: zod_1.z
|
|
10157
|
+
.string()
|
|
10158
|
+
.optional()
|
|
10159
|
+
.describe("层名称。listLayerVersions 和 getLayerVersion 操作时必填"),
|
|
10160
|
+
version: zod_1.z
|
|
10161
|
+
.number()
|
|
10162
|
+
.optional()
|
|
10163
|
+
.describe("层版本号。getLayerVersion 操作时必填"),
|
|
10164
|
+
runtime: zod_1.z
|
|
10165
|
+
.string()
|
|
10166
|
+
.optional()
|
|
10167
|
+
.describe("运行时筛选。listLayers 操作时可选"),
|
|
10168
|
+
searchKey: zod_1.z
|
|
10169
|
+
.string()
|
|
10170
|
+
.optional()
|
|
10171
|
+
.describe("层名称搜索关键字。listLayers 操作时可选"),
|
|
10172
|
+
offset: zod_1.z.number().optional().describe("分页偏移。listLayers 操作时可选"),
|
|
10173
|
+
limit: zod_1.z.number().optional().describe("分页数量。listLayers 操作时可选"),
|
|
10174
|
+
functionName: zod_1.z
|
|
10175
|
+
.string()
|
|
10176
|
+
.optional()
|
|
10177
|
+
.describe("函数名称。getFunctionLayers 操作时必填"),
|
|
10178
|
+
codeSecret: zod_1.z
|
|
10179
|
+
.string()
|
|
10180
|
+
.optional()
|
|
10181
|
+
.describe("代码保护密钥。getFunctionLayers 操作时可选"),
|
|
10182
|
+
},
|
|
10183
|
+
annotations: {
|
|
10184
|
+
readOnlyHint: true,
|
|
10185
|
+
openWorldHint: true,
|
|
10186
|
+
category: "functions",
|
|
10187
|
+
},
|
|
10188
|
+
}, async ({ action, name, version, runtime, searchKey, offset, limit, functionName, codeSecret, }) => {
|
|
10189
|
+
if (action === "listLayers") {
|
|
10190
|
+
const cloudbase = await getManager();
|
|
10191
|
+
const result = await cloudbase.functions.listLayers({
|
|
10192
|
+
offset,
|
|
10193
|
+
limit,
|
|
10194
|
+
runtime,
|
|
10195
|
+
searchKey,
|
|
10196
|
+
});
|
|
10197
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10198
|
+
return jsonContent({
|
|
10199
|
+
success: true,
|
|
10200
|
+
data: {
|
|
10201
|
+
action,
|
|
10202
|
+
layers: result.Layers || [],
|
|
10203
|
+
totalCount: result.TotalCount || 0,
|
|
10204
|
+
requestId: result.RequestId,
|
|
10205
|
+
},
|
|
10206
|
+
message: `Successfully retrieved ${result.Layers?.length || 0} layer entries`,
|
|
10207
|
+
nextActions: [
|
|
10208
|
+
{ tool: "readFunctionLayers", action: "listLayerVersions", reason: "List versions of a layer" },
|
|
10209
|
+
{ tool: "writeFunctionLayers", action: "createLayerVersion", reason: "Create a new layer version" },
|
|
10210
|
+
],
|
|
10211
|
+
});
|
|
10212
|
+
}
|
|
10213
|
+
if (action === "listLayerVersions") {
|
|
10214
|
+
if (!name) {
|
|
10215
|
+
throw new Error("查询层版本列表时,name 参数是必需的");
|
|
10216
|
+
}
|
|
10217
|
+
const cloudbase = await getManager();
|
|
10218
|
+
const result = await cloudbase.functions.listLayerVersions({ name });
|
|
10219
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10220
|
+
return jsonContent({
|
|
10221
|
+
success: true,
|
|
10222
|
+
data: {
|
|
10223
|
+
action,
|
|
10224
|
+
name,
|
|
10225
|
+
layerVersions: result.LayerVersions || [],
|
|
10226
|
+
requestId: result.RequestId,
|
|
10227
|
+
},
|
|
10228
|
+
message: `Successfully retrieved ${result.LayerVersions?.length || 0} versions for layer '${name}'`,
|
|
10229
|
+
nextActions: [
|
|
10230
|
+
{ tool: "readFunctionLayers", action: "getLayerVersion", reason: "Get version details and download info" },
|
|
10231
|
+
{ tool: "writeFunctionLayers", action: "attachLayer", reason: "Bind this layer to a function" },
|
|
10232
|
+
],
|
|
10233
|
+
});
|
|
10234
|
+
}
|
|
10235
|
+
if (action === "getLayerVersion") {
|
|
10236
|
+
if (!name) {
|
|
10237
|
+
throw new Error("查询层版本详情时,name 参数是必需的");
|
|
10238
|
+
}
|
|
10239
|
+
if (typeof version !== "number") {
|
|
10240
|
+
throw new Error("查询层版本详情时,version 参数是必需的");
|
|
10241
|
+
}
|
|
10242
|
+
const cloudbase = await getManager();
|
|
10243
|
+
const result = await cloudbase.functions.getLayerVersion({
|
|
10244
|
+
name,
|
|
10245
|
+
version,
|
|
10246
|
+
});
|
|
10247
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10248
|
+
return jsonContent({
|
|
10249
|
+
success: true,
|
|
10250
|
+
data: {
|
|
10251
|
+
action,
|
|
10252
|
+
name,
|
|
10253
|
+
version,
|
|
10254
|
+
layerVersion: result,
|
|
10255
|
+
downloadInfo: {
|
|
10256
|
+
location: result.Location,
|
|
10257
|
+
codeSha256: result.CodeSha256,
|
|
10258
|
+
},
|
|
10259
|
+
requestId: result.RequestId,
|
|
10260
|
+
},
|
|
10261
|
+
message: `Successfully retrieved details for layer '${name}' version ${version}`,
|
|
10262
|
+
nextActions: [
|
|
10263
|
+
{ tool: "writeFunctionLayers", action: "attachLayer", reason: "Bind this layer version to a function" },
|
|
10264
|
+
{ tool: "writeFunctionLayers", action: "deleteLayerVersion", reason: "Delete this layer version" },
|
|
10265
|
+
],
|
|
10266
|
+
});
|
|
10267
|
+
}
|
|
10268
|
+
if (!functionName) {
|
|
10269
|
+
throw new Error("查询函数层配置时,functionName 参数是必需的");
|
|
10270
|
+
}
|
|
10271
|
+
const cloudbase = await getManager();
|
|
10272
|
+
const result = await cloudbase.functions.getFunctionDetail(functionName, codeSecret);
|
|
10273
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10274
|
+
const layers = normalizeFunctionLayers(result.Layers);
|
|
10275
|
+
return jsonContent({
|
|
10276
|
+
success: true,
|
|
10277
|
+
data: {
|
|
10278
|
+
action,
|
|
10279
|
+
functionName,
|
|
10280
|
+
layers,
|
|
10281
|
+
count: layers.length,
|
|
10282
|
+
requestId: result.RequestId,
|
|
10283
|
+
},
|
|
10284
|
+
message: `Successfully retrieved ${layers.length} bound layers for function '${functionName}'`,
|
|
10285
|
+
nextActions: [
|
|
10286
|
+
{ tool: "writeFunctionLayers", action: "attachLayer", reason: "Add a layer to this function" },
|
|
10287
|
+
{ tool: "writeFunctionLayers", action: "detachLayer", reason: "Remove a layer from this function" },
|
|
10288
|
+
{ tool: "writeFunctionLayers", action: "updateFunctionLayers", reason: "Replace or reorder bound layers" },
|
|
10289
|
+
],
|
|
10290
|
+
});
|
|
10291
|
+
});
|
|
10292
|
+
server.registerTool?.("writeFunctionLayers", {
|
|
10293
|
+
title: "管理云函数层",
|
|
10294
|
+
description: "管理云函数层和函数层绑定。通过 action 区分操作:createLayerVersion=创建层版本,deleteLayerVersion=删除层版本,attachLayer=给函数追加绑定层,detachLayer=解绑函数层,updateFunctionLayers=整体更新函数层数组以调整顺序或批量更新。返回格式:JSON 包含 success、data(含 action 与结果字段,如 layerVersion、layers)、message、nextActions(建议的后续操作)。",
|
|
10295
|
+
inputSchema: {
|
|
10296
|
+
action: zod_1.z
|
|
10297
|
+
.enum(exports.WRITE_FUNCTION_LAYER_ACTIONS)
|
|
10298
|
+
.describe("操作类型:createLayerVersion=创建层版本,deleteLayerVersion=删除层版本,attachLayer=追加绑定层,detachLayer=解绑层,updateFunctionLayers=整体更新函数层数组"),
|
|
10299
|
+
name: zod_1.z
|
|
10300
|
+
.string()
|
|
10301
|
+
.optional()
|
|
10302
|
+
.describe("层名称。createLayerVersion 和 deleteLayerVersion 操作时必填"),
|
|
10303
|
+
version: zod_1.z
|
|
10304
|
+
.number()
|
|
10305
|
+
.optional()
|
|
10306
|
+
.describe("层版本号。deleteLayerVersion 操作时必填"),
|
|
10307
|
+
contentPath: zod_1.z
|
|
10308
|
+
.string()
|
|
10309
|
+
.optional()
|
|
10310
|
+
.describe("层内容路径,可以是目录或 ZIP 文件路径。createLayerVersion 操作时与 base64Content 二选一"),
|
|
10311
|
+
base64Content: zod_1.z
|
|
10312
|
+
.string()
|
|
10313
|
+
.optional()
|
|
10314
|
+
.describe("层内容的 base64 编码。createLayerVersion 操作时与 contentPath 二选一"),
|
|
10315
|
+
runtimes: zod_1.z
|
|
10316
|
+
.array(zod_1.z.string())
|
|
10317
|
+
.optional()
|
|
10318
|
+
.describe("层适用的运行时列表。createLayerVersion 操作时必填"),
|
|
10319
|
+
description: zod_1.z
|
|
10320
|
+
.string()
|
|
10321
|
+
.optional()
|
|
10322
|
+
.describe("层版本描述。createLayerVersion 操作时可选"),
|
|
10323
|
+
licenseInfo: zod_1.z
|
|
10324
|
+
.string()
|
|
10325
|
+
.optional()
|
|
10326
|
+
.describe("许可证信息。createLayerVersion 操作时可选"),
|
|
10327
|
+
functionName: zod_1.z
|
|
10328
|
+
.string()
|
|
10329
|
+
.optional()
|
|
10330
|
+
.describe("函数名称。attachLayer、detachLayer、updateFunctionLayers 操作时必填"),
|
|
10331
|
+
layerName: zod_1.z
|
|
10332
|
+
.string()
|
|
10333
|
+
.optional()
|
|
10334
|
+
.describe("要绑定或解绑的层名称。attachLayer 和 detachLayer 操作时必填"),
|
|
10335
|
+
layerVersion: zod_1.z
|
|
10336
|
+
.number()
|
|
10337
|
+
.optional()
|
|
10338
|
+
.describe("要绑定或解绑的层版本号。attachLayer 和 detachLayer 操作时必填"),
|
|
10339
|
+
layers: zod_1.z
|
|
10340
|
+
.array(zod_1.z.object({
|
|
10341
|
+
LayerName: zod_1.z.string().describe("层名称"),
|
|
10342
|
+
LayerVersion: zod_1.z.number().describe("层版本号"),
|
|
10343
|
+
}))
|
|
10344
|
+
.optional()
|
|
10345
|
+
.describe("目标函数层数组。updateFunctionLayers 操作时必填,顺序即最终顺序"),
|
|
10346
|
+
codeSecret: zod_1.z
|
|
10347
|
+
.string()
|
|
10348
|
+
.optional()
|
|
10349
|
+
.describe("代码保护密钥。attachLayer 和 detachLayer 操作时可选"),
|
|
10350
|
+
},
|
|
10351
|
+
annotations: {
|
|
10352
|
+
readOnlyHint: false,
|
|
10353
|
+
destructiveHint: true,
|
|
10354
|
+
idempotentHint: false,
|
|
10355
|
+
openWorldHint: true,
|
|
10356
|
+
category: "functions",
|
|
10357
|
+
},
|
|
10358
|
+
}, async ({ action, name, version, contentPath, base64Content, runtimes, description, licenseInfo, functionName, layerName, layerVersion, layers, codeSecret, }) => {
|
|
10359
|
+
if (action === "createLayerVersion") {
|
|
10360
|
+
if (!name) {
|
|
10361
|
+
throw new Error("创建层版本时,name 参数是必需的");
|
|
10362
|
+
}
|
|
10363
|
+
if (!runtimes || runtimes.length === 0) {
|
|
10364
|
+
throw new Error("创建层版本时,runtimes 参数是必需的");
|
|
10365
|
+
}
|
|
10366
|
+
if (!contentPath && !base64Content) {
|
|
10367
|
+
throw new Error("创建层版本时,contentPath 和 base64Content 至少需要提供一个");
|
|
10368
|
+
}
|
|
10369
|
+
const cloudbase = await getManager();
|
|
10370
|
+
const result = await cloudbase.functions.createLayer({
|
|
10371
|
+
name,
|
|
10372
|
+
contentPath,
|
|
10373
|
+
base64Content,
|
|
10374
|
+
runtimes,
|
|
10375
|
+
description,
|
|
10376
|
+
licenseInfo,
|
|
10377
|
+
});
|
|
10378
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10379
|
+
return jsonContent({
|
|
10380
|
+
success: true,
|
|
10381
|
+
data: {
|
|
10382
|
+
action,
|
|
10383
|
+
name,
|
|
10384
|
+
layerVersion: result.LayerVersion,
|
|
10385
|
+
requestId: result.RequestId,
|
|
10386
|
+
},
|
|
10387
|
+
message: `Successfully created a new version for layer '${name}'`,
|
|
10388
|
+
nextActions: [
|
|
10389
|
+
{ tool: "readFunctionLayers", action: "listLayerVersions", reason: "List all versions of this layer" },
|
|
10390
|
+
{ tool: "writeFunctionLayers", action: "attachLayer", reason: "Bind this version to a function" },
|
|
10391
|
+
],
|
|
10392
|
+
});
|
|
10393
|
+
}
|
|
10394
|
+
if (action === "deleteLayerVersion") {
|
|
10395
|
+
if (!name) {
|
|
10396
|
+
throw new Error("删除层版本时,name 参数是必需的");
|
|
10397
|
+
}
|
|
10398
|
+
if (typeof version !== "number") {
|
|
10399
|
+
throw new Error("删除层版本时,version 参数是必需的");
|
|
10400
|
+
}
|
|
10401
|
+
const cloudbase = await getManager();
|
|
10402
|
+
const result = await cloudbase.functions.deleteLayerVersion({
|
|
10403
|
+
name,
|
|
10404
|
+
version,
|
|
10405
|
+
});
|
|
10406
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10407
|
+
return jsonContent({
|
|
10408
|
+
success: true,
|
|
10409
|
+
data: {
|
|
10410
|
+
action,
|
|
10411
|
+
name,
|
|
10412
|
+
version,
|
|
10413
|
+
requestId: result.RequestId,
|
|
10414
|
+
},
|
|
10415
|
+
message: `Successfully deleted layer '${name}' version ${version}`,
|
|
10416
|
+
nextActions: [
|
|
10417
|
+
{ tool: "readFunctionLayers", action: "listLayers", reason: "List remaining layers" },
|
|
10418
|
+
],
|
|
10419
|
+
});
|
|
10420
|
+
}
|
|
10421
|
+
if (action === "attachLayer" ||
|
|
10422
|
+
action === "detachLayer" ||
|
|
10423
|
+
action === "updateFunctionLayers") {
|
|
10424
|
+
if (!functionName) {
|
|
10425
|
+
throw new Error(`${action} 操作时,functionName 参数是必需的`);
|
|
10426
|
+
}
|
|
10427
|
+
}
|
|
10428
|
+
const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
10429
|
+
const cloudbase = await getManager();
|
|
10430
|
+
if (action === "attachLayer") {
|
|
10431
|
+
if (!layerName) {
|
|
10432
|
+
throw new Error("attachLayer 操作时,layerName 参数是必需的");
|
|
10433
|
+
}
|
|
10434
|
+
if (typeof layerVersion !== "number") {
|
|
10435
|
+
throw new Error("attachLayer 操作时,layerVersion 参数是必需的");
|
|
10436
|
+
}
|
|
10437
|
+
const result = await cloudbase.functions.attachLayer({
|
|
10438
|
+
envId,
|
|
10439
|
+
functionName: functionName,
|
|
10440
|
+
layerName,
|
|
10441
|
+
layerVersion,
|
|
10442
|
+
codeSecret,
|
|
10443
|
+
});
|
|
10444
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10445
|
+
const detail = await cloudbase.functions.getFunctionDetail(functionName, codeSecret);
|
|
10446
|
+
const boundLayers = normalizeFunctionLayers(detail.Layers);
|
|
10447
|
+
return jsonContent({
|
|
10448
|
+
success: true,
|
|
10449
|
+
data: {
|
|
10450
|
+
action,
|
|
10451
|
+
functionName,
|
|
10452
|
+
layers: boundLayers,
|
|
10453
|
+
requestId: result.RequestId,
|
|
10454
|
+
},
|
|
10455
|
+
message: `Successfully attached layer '${layerName}' version ${layerVersion} to function '${functionName}'`,
|
|
10456
|
+
nextActions: [
|
|
10457
|
+
{ tool: "readFunctionLayers", action: "getFunctionLayers", reason: "Verify bound layers" },
|
|
10458
|
+
{ tool: "writeFunctionLayers", action: "detachLayer", reason: "Remove this layer from function" },
|
|
10459
|
+
],
|
|
10460
|
+
});
|
|
10461
|
+
}
|
|
10462
|
+
if (action === "detachLayer") {
|
|
10463
|
+
if (!layerName) {
|
|
10464
|
+
throw new Error("detachLayer 操作时,layerName 参数是必需的");
|
|
10465
|
+
}
|
|
10466
|
+
if (typeof layerVersion !== "number") {
|
|
10467
|
+
throw new Error("detachLayer 操作时,layerVersion 参数是必需的");
|
|
10468
|
+
}
|
|
10469
|
+
const result = await cloudbase.functions.unAttachLayer({
|
|
10470
|
+
envId,
|
|
10471
|
+
functionName: functionName,
|
|
10472
|
+
layerName,
|
|
10473
|
+
layerVersion,
|
|
10474
|
+
codeSecret,
|
|
10475
|
+
});
|
|
10476
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10477
|
+
const detail = await cloudbase.functions.getFunctionDetail(functionName, codeSecret);
|
|
10478
|
+
const boundLayers = normalizeFunctionLayers(detail.Layers);
|
|
10479
|
+
return jsonContent({
|
|
10480
|
+
success: true,
|
|
10481
|
+
data: {
|
|
10482
|
+
action,
|
|
10483
|
+
functionName,
|
|
10484
|
+
layers: boundLayers,
|
|
10485
|
+
requestId: result.RequestId,
|
|
10486
|
+
},
|
|
10487
|
+
message: `Successfully detached layer '${layerName}' version ${layerVersion} from function '${functionName}'`,
|
|
10488
|
+
nextActions: [
|
|
10489
|
+
{ tool: "readFunctionLayers", action: "getFunctionLayers", reason: "Verify current bound layers" },
|
|
10490
|
+
],
|
|
10491
|
+
});
|
|
10492
|
+
}
|
|
10493
|
+
if (!layers || layers.length === 0) {
|
|
10494
|
+
throw new Error("updateFunctionLayers 操作时,layers 参数是必需的");
|
|
10495
|
+
}
|
|
10496
|
+
const normalizedLayers = normalizeFunctionLayers(layers);
|
|
10497
|
+
if (normalizedLayers.length === 0) {
|
|
10498
|
+
throw new Error("updateFunctionLayers 操作时,layers 参数必须包含有效的 LayerName 和 LayerVersion");
|
|
10499
|
+
}
|
|
10500
|
+
const result = await cloudbase.functions.updateFunctionLayer({
|
|
10501
|
+
envId,
|
|
10502
|
+
functionName: functionName,
|
|
10503
|
+
layers: normalizedLayers,
|
|
10504
|
+
});
|
|
10505
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
10506
|
+
const detail = await cloudbase.functions.getFunctionDetail(functionName);
|
|
10507
|
+
const boundLayers = normalizeFunctionLayers(detail.Layers);
|
|
10508
|
+
return jsonContent({
|
|
10509
|
+
success: true,
|
|
10510
|
+
data: {
|
|
10511
|
+
action,
|
|
10512
|
+
functionName,
|
|
10513
|
+
layers: boundLayers,
|
|
10514
|
+
requestId: result.RequestId,
|
|
10515
|
+
},
|
|
10516
|
+
message: `Successfully updated bound layers for function '${functionName}'`,
|
|
10517
|
+
nextActions: [
|
|
10518
|
+
{ tool: "readFunctionLayers", action: "getFunctionLayers", reason: "Verify updated layer order" },
|
|
10519
|
+
],
|
|
10520
|
+
});
|
|
10521
|
+
});
|
|
9597
10522
|
// // Layer相关功能
|
|
9598
10523
|
// // createLayer - 创建Layer
|
|
9599
10524
|
// server.tool(
|
|
@@ -9992,6 +10917,7 @@ const INTEGRATION_IDE_MAPPING = {
|
|
|
9992
10917
|
CodeBuddy: "codebuddy",
|
|
9993
10918
|
CodeBuddyManual: "codebuddy",
|
|
9994
10919
|
CodeBuddyCode: "codebuddy",
|
|
10920
|
+
CodeBuddyPlugin: "codebuddy",
|
|
9995
10921
|
"Claude Code": "claude-code",
|
|
9996
10922
|
CLINE: "cline",
|
|
9997
10923
|
"Gemini CLI": "gemini-cli",
|
|
@@ -10250,7 +11176,7 @@ function registerSetupTools(server) {
|
|
|
10250
11176
|
title: "下载项目模板",
|
|
10251
11177
|
description: `自动下载并部署CloudBase项目模板。⚠️ **MANDATORY FOR NEW PROJECTS** ⚠️
|
|
10252
11178
|
|
|
10253
|
-
**CRITICAL**: This tool MUST be called FIRST when starting a new project.\n\n支持的模板:\n- react: React + CloudBase 全栈应用模板\n- vue: Vue + CloudBase 全栈应用模板\n- miniprogram: 微信小程序 + 云开发模板 \n- uniapp: UniApp + CloudBase 跨端应用模板\n- rules: 只包含AI编辑器配置文件(包含Cursor、WindSurf、CodeBuddy等所有主流编辑器配置),适合在已有项目中补充AI编辑器配置\n\n支持的IDE类型:\n- all: 下载所有IDE配置\n- cursor: Cursor AI编辑器\n- 其他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.
|
|
11179
|
+
**CRITICAL**: This tool MUST be called FIRST when starting a new project.\n\n支持的模板:\n- react: React + CloudBase 全栈应用模板\n- vue: Vue + CloudBase 全栈应用模板\n- miniprogram: 微信小程序 + 云开发模板 \n- uniapp: UniApp + CloudBase 跨端应用模板\n- rules: 只包含AI编辑器配置文件(包含Cursor、WindSurf、CodeBuddy等所有主流编辑器配置),适合在已有项目中补充AI编辑器配置\n\n支持的IDE类型:\n- all: 下载所有IDE配置\n- cursor: Cursor AI编辑器\n- 其他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.14.2" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
|
|
10254
11180
|
inputSchema: {
|
|
10255
11181
|
template: zod_1.z
|
|
10256
11182
|
.enum(["react", "vue", "miniprogram", "uniapp", "rules"])
|
|
@@ -11578,7 +12504,13 @@ async function getUinForTelemetry() {
|
|
|
11578
12504
|
const loginState = await (0, auth_js_1.getLoginState)({ region });
|
|
11579
12505
|
// Try to extract UIN from loginState
|
|
11580
12506
|
// Note: actual field name may vary, adjust based on actual response
|
|
11581
|
-
|
|
12507
|
+
if (loginState &&
|
|
12508
|
+
typeof loginState === "object" &&
|
|
12509
|
+
"uin" in loginState &&
|
|
12510
|
+
typeof loginState.uin !== "undefined") {
|
|
12511
|
+
return String(loginState.uin);
|
|
12512
|
+
}
|
|
12513
|
+
return undefined;
|
|
11582
12514
|
}
|
|
11583
12515
|
catch (err) {
|
|
11584
12516
|
(0, logger_js_1.debug)('Failed to get UIN for telemetry', { error: err instanceof Error ? err.message : String(err) });
|
|
@@ -11887,10 +12819,10 @@ function registerHostingTools(server) {
|
|
|
11887
12819
|
// uploadFiles - 上传文件到静态网站托管 (cloud-incompatible)
|
|
11888
12820
|
server.registerTool("uploadFiles", {
|
|
11889
12821
|
title: "上传静态文件",
|
|
11890
|
-
description: "
|
|
12822
|
+
description: "上传文件到静态网站托管。部署前请先完成构建;如果站点会部署到子路径,请检查构建配置中的 publicPath、base、assetPrefix 等是否使用相对路径,避免静态资源加载失败。",
|
|
11891
12823
|
inputSchema: {
|
|
11892
|
-
localPath: zod_1.z.string().optional().describe("本地文件或文件夹路径,需要是绝对路径,例如 /tmp/files/data.txt"),
|
|
11893
|
-
cloudPath: zod_1.z.string().optional().describe("云端文件或文件夹路径,例如files/data.txt"),
|
|
12824
|
+
localPath: zod_1.z.string().optional().describe("本地文件或文件夹路径,需要是绝对路径,例如 /tmp/files/data.txt。"),
|
|
12825
|
+
cloudPath: zod_1.z.string().optional().describe("云端文件或文件夹路径,例如 files/data.txt。若部署到子路径,请同时检查构建配置中的 publicPath、base、assetPrefix 等是否为相对路径。"),
|
|
11894
12826
|
files: zod_1.z.array(zod_1.z.object({
|
|
11895
12827
|
localPath: zod_1.z.string(),
|
|
11896
12828
|
cloudPath: zod_1.z.string()
|
|
@@ -12139,56 +13071,181 @@ function registerHostingTools(server) {
|
|
|
12139
13071
|
|
|
12140
13072
|
|
|
12141
13073
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
13074
|
+
exports.getAuthProgressStateSync = getAuthProgressStateSync;
|
|
13075
|
+
exports.getAuthProgressState = getAuthProgressState;
|
|
13076
|
+
exports.setPendingAuthProgressState = setPendingAuthProgressState;
|
|
13077
|
+
exports.resolveAuthProgressState = resolveAuthProgressState;
|
|
13078
|
+
exports.rejectAuthProgressState = rejectAuthProgressState;
|
|
13079
|
+
exports.resetAuthProgressState = resetAuthProgressState;
|
|
13080
|
+
exports.peekLoginState = peekLoginState;
|
|
13081
|
+
exports.ensureLogin = ensureLogin;
|
|
12142
13082
|
exports.getLoginState = getLoginState;
|
|
12143
13083
|
exports.logout = logout;
|
|
12144
13084
|
const toolbox_1 = __webpack_require__(2090);
|
|
12145
13085
|
const logger_js_1 = __webpack_require__(3039);
|
|
12146
13086
|
const tencet_cloud_js_1 = __webpack_require__(5018);
|
|
12147
|
-
const auth = toolbox_1.
|
|
12148
|
-
|
|
13087
|
+
const auth = toolbox_1.AuthSupervisor.getInstance({});
|
|
13088
|
+
const authProgressState = {
|
|
13089
|
+
status: "IDLE",
|
|
13090
|
+
updatedAt: Date.now(),
|
|
13091
|
+
};
|
|
13092
|
+
function updateAuthProgressState(partial) {
|
|
13093
|
+
Object.assign(authProgressState, partial, {
|
|
13094
|
+
updatedAt: Date.now(),
|
|
13095
|
+
});
|
|
13096
|
+
return getAuthProgressStateSync();
|
|
13097
|
+
}
|
|
13098
|
+
function normalizeLoginStateFromEnvVars(options) {
|
|
12149
13099
|
const { TENCENTCLOUD_SECRETID, TENCENTCLOUD_SECRETKEY, TENCENTCLOUD_SESSIONTOKEN, } = process.env;
|
|
12150
|
-
(0, logger_js_1.debug)("TENCENTCLOUD_SECRETID", { secretId: TENCENTCLOUD_SECRETID });
|
|
12151
|
-
// If ignoreEnvVars is true (e.g., when switching account), skip environment variables
|
|
12152
|
-
// and force Web authentication to allow account switching
|
|
12153
13100
|
if (!options?.ignoreEnvVars && TENCENTCLOUD_SECRETID && TENCENTCLOUD_SECRETKEY) {
|
|
12154
|
-
(0, logger_js_1.debug)("loginByApiSecret");
|
|
12155
13101
|
return {
|
|
12156
13102
|
secretId: TENCENTCLOUD_SECRETID,
|
|
12157
13103
|
secretKey: TENCENTCLOUD_SECRETKEY,
|
|
12158
13104
|
token: TENCENTCLOUD_SESSIONTOKEN,
|
|
13105
|
+
envId: process.env.CLOUDBASE_ENV_ID,
|
|
12159
13106
|
};
|
|
12160
|
-
// await auth.loginByApiSecret(TENCENTCLOUD_SECRETID, TENCENTCLOUD_SECRETKEY, TENCENTCLOUD_SESSIONTOKEN)
|
|
12161
13107
|
}
|
|
12162
|
-
|
|
13108
|
+
return null;
|
|
13109
|
+
}
|
|
13110
|
+
function mapAuthErrorStatus(error) {
|
|
13111
|
+
const message = error instanceof Error ? error.message : String(error ?? "");
|
|
13112
|
+
if (message.includes("拒绝") || message.includes("denied")) {
|
|
13113
|
+
return "DENIED";
|
|
13114
|
+
}
|
|
13115
|
+
if (message.includes("过期") || message.includes("expired")) {
|
|
13116
|
+
return "EXPIRED";
|
|
13117
|
+
}
|
|
13118
|
+
return "ERROR";
|
|
13119
|
+
}
|
|
13120
|
+
function getAuthProgressStateSync() {
|
|
13121
|
+
return {
|
|
13122
|
+
...authProgressState,
|
|
13123
|
+
authChallenge: authProgressState.authChallenge
|
|
13124
|
+
? { ...authProgressState.authChallenge }
|
|
13125
|
+
: undefined,
|
|
13126
|
+
};
|
|
13127
|
+
}
|
|
13128
|
+
async function getAuthProgressState() {
|
|
13129
|
+
const loginState = await peekLoginState();
|
|
13130
|
+
if (loginState && authProgressState.status === "PENDING") {
|
|
13131
|
+
updateAuthProgressState({
|
|
13132
|
+
status: "READY",
|
|
13133
|
+
lastError: undefined,
|
|
13134
|
+
});
|
|
13135
|
+
}
|
|
13136
|
+
if (authProgressState.status === "PENDING" &&
|
|
13137
|
+
authProgressState.authChallenge?.expires_in) {
|
|
13138
|
+
const issuedAt = authProgressState.updatedAt;
|
|
13139
|
+
const expiresAt = issuedAt + authProgressState.authChallenge.expires_in * 1000;
|
|
13140
|
+
if (Date.now() > expiresAt) {
|
|
13141
|
+
updateAuthProgressState({
|
|
13142
|
+
status: "EXPIRED",
|
|
13143
|
+
lastError: "设备码已过期,请重新发起授权",
|
|
13144
|
+
});
|
|
13145
|
+
}
|
|
13146
|
+
}
|
|
13147
|
+
return getAuthProgressStateSync();
|
|
13148
|
+
}
|
|
13149
|
+
function setPendingAuthProgressState(challenge, authMode = "device") {
|
|
13150
|
+
return updateAuthProgressState({
|
|
13151
|
+
status: "PENDING",
|
|
13152
|
+
authMode,
|
|
13153
|
+
authChallenge: challenge,
|
|
13154
|
+
lastError: undefined,
|
|
13155
|
+
});
|
|
13156
|
+
}
|
|
13157
|
+
function resolveAuthProgressState() {
|
|
13158
|
+
return updateAuthProgressState({
|
|
13159
|
+
status: "READY",
|
|
13160
|
+
lastError: undefined,
|
|
13161
|
+
});
|
|
13162
|
+
}
|
|
13163
|
+
function rejectAuthProgressState(error) {
|
|
13164
|
+
const message = error instanceof Error ? error.message : String(error ?? "unknown error");
|
|
13165
|
+
return updateAuthProgressState({
|
|
13166
|
+
status: mapAuthErrorStatus(error),
|
|
13167
|
+
lastError: message,
|
|
13168
|
+
});
|
|
13169
|
+
}
|
|
13170
|
+
function resetAuthProgressState() {
|
|
13171
|
+
return updateAuthProgressState({
|
|
13172
|
+
status: "IDLE",
|
|
13173
|
+
authMode: undefined,
|
|
13174
|
+
authChallenge: undefined,
|
|
13175
|
+
lastError: undefined,
|
|
13176
|
+
});
|
|
13177
|
+
}
|
|
13178
|
+
async function peekLoginState(options) {
|
|
13179
|
+
const envVarLoginState = normalizeLoginStateFromEnvVars(options);
|
|
13180
|
+
if (envVarLoginState) {
|
|
13181
|
+
(0, logger_js_1.debug)("loginByApiSecret");
|
|
13182
|
+
return envVarLoginState;
|
|
13183
|
+
}
|
|
13184
|
+
return auth.getLoginState();
|
|
13185
|
+
}
|
|
13186
|
+
async function ensureLogin(options) {
|
|
13187
|
+
(0, logger_js_1.debug)("TENCENTCLOUD_SECRETID", { secretId: process.env.TENCENTCLOUD_SECRETID });
|
|
13188
|
+
const loginState = await peekLoginState({
|
|
13189
|
+
ignoreEnvVars: options?.ignoreEnvVars,
|
|
13190
|
+
});
|
|
12163
13191
|
if (!loginState) {
|
|
12164
|
-
|
|
12165
|
-
|
|
12166
|
-
|
|
12167
|
-
|
|
12168
|
-
|
|
12169
|
-
|
|
12170
|
-
|
|
12171
|
-
|
|
12172
|
-
|
|
12173
|
-
|
|
12174
|
-
|
|
12175
|
-
if ((0, tencet_cloud_js_1.isInternationalRegion)(options?.region)) {
|
|
12176
|
-
url = url.replace('cloud.tencent.com', 'tencentcloud.com');
|
|
13192
|
+
const envMode = process.env.TCB_AUTH_MODE;
|
|
13193
|
+
const normalizedEnvMode = envMode === "web" || envMode === "device" ? envMode : undefined;
|
|
13194
|
+
const mode = options?.authMode || normalizedEnvMode || "device";
|
|
13195
|
+
const loginOptions = { flow: mode };
|
|
13196
|
+
if (mode === "web") {
|
|
13197
|
+
loginOptions.getAuthUrl =
|
|
13198
|
+
options?.fromCloudBaseLoginPage && !(0, tencet_cloud_js_1.isInternationalRegion)(options?.region)
|
|
13199
|
+
? (url) => {
|
|
13200
|
+
const separator = url.includes("?") ? "&" : "?";
|
|
13201
|
+
const urlWithParam = `${url}${separator}allowNoEnv=true`;
|
|
13202
|
+
return `https://tcb.cloud.tencent.com/login?_redirect_uri=${encodeURIComponent(urlWithParam)}`;
|
|
12177
13203
|
}
|
|
12178
|
-
|
|
12179
|
-
|
|
12180
|
-
|
|
12181
|
-
|
|
12182
|
-
|
|
12183
|
-
|
|
13204
|
+
: (url) => {
|
|
13205
|
+
if ((0, tencet_cloud_js_1.isInternationalRegion)(options?.region)) {
|
|
13206
|
+
url = url.replace("cloud.tencent.com", "tencentcloud.com");
|
|
13207
|
+
}
|
|
13208
|
+
const separator = url.includes("?") ? "&" : "?";
|
|
13209
|
+
return `${url}${separator}allowNoEnv=true`;
|
|
13210
|
+
};
|
|
13211
|
+
}
|
|
13212
|
+
else {
|
|
13213
|
+
if (options?.clientId) {
|
|
13214
|
+
loginOptions.client_id = options.clientId;
|
|
13215
|
+
}
|
|
13216
|
+
if (options?.onDeviceCode) {
|
|
13217
|
+
loginOptions.onDeviceCode = (info) => {
|
|
13218
|
+
setPendingAuthProgressState(info, mode);
|
|
13219
|
+
options.onDeviceCode?.(info);
|
|
13220
|
+
};
|
|
13221
|
+
}
|
|
13222
|
+
}
|
|
13223
|
+
(0, logger_js_1.debug)("beforeloginByWebAuth", { loginOptions });
|
|
13224
|
+
try {
|
|
13225
|
+
await auth.loginByWebAuth(loginOptions);
|
|
13226
|
+
resolveAuthProgressState();
|
|
13227
|
+
}
|
|
13228
|
+
catch (error) {
|
|
13229
|
+
rejectAuthProgressState(error);
|
|
13230
|
+
throw error;
|
|
13231
|
+
}
|
|
13232
|
+
const loginState = await peekLoginState({
|
|
13233
|
+
ignoreEnvVars: options?.ignoreEnvVars,
|
|
13234
|
+
});
|
|
13235
|
+
(0, logger_js_1.debug)("loginByWebAuth", { mode, hasLoginState: !!loginState });
|
|
12184
13236
|
return loginState;
|
|
12185
13237
|
}
|
|
12186
13238
|
else {
|
|
13239
|
+
resolveAuthProgressState();
|
|
12187
13240
|
return loginState;
|
|
12188
13241
|
}
|
|
12189
13242
|
}
|
|
13243
|
+
async function getLoginState(options) {
|
|
13244
|
+
return ensureLogin(options);
|
|
13245
|
+
}
|
|
12190
13246
|
async function logout() {
|
|
12191
13247
|
const result = await auth.logout();
|
|
13248
|
+
resetAuthProgressState();
|
|
12192
13249
|
return result;
|
|
12193
13250
|
}
|
|
12194
13251
|
|
|
@@ -13616,8 +14673,7 @@ function shouldRegisterTool(toolName) {
|
|
|
13616
14673
|
// Cloud-incompatible tools that involve local file operations
|
|
13617
14674
|
const cloudIncompatibleTools = [
|
|
13618
14675
|
// Auth tools - local file uploads
|
|
13619
|
-
'
|
|
13620
|
-
'logout',
|
|
14676
|
+
'auth',
|
|
13621
14677
|
// Storage tools - local file uploads
|
|
13622
14678
|
'uploadFile',
|
|
13623
14679
|
// Hosting tools - local file uploads
|
|
@@ -13757,6 +14813,60 @@ function registerSQLDatabaseTools(server) {
|
|
|
13757
14813
|
}
|
|
13758
14814
|
|
|
13759
14815
|
|
|
14816
|
+
/***/ }),
|
|
14817
|
+
|
|
14818
|
+
/***/ 9835:
|
|
14819
|
+
/***/ ((__unused_webpack_module, exports) => {
|
|
14820
|
+
|
|
14821
|
+
|
|
14822
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
14823
|
+
exports.ToolPayloadError = void 0;
|
|
14824
|
+
exports.buildJsonToolResult = buildJsonToolResult;
|
|
14825
|
+
exports.isToolPayloadError = isToolPayloadError;
|
|
14826
|
+
exports.toolPayloadErrorToResult = toolPayloadErrorToResult;
|
|
14827
|
+
exports.buildAuthNextStep = buildAuthNextStep;
|
|
14828
|
+
exports.throwToolPayloadError = throwToolPayloadError;
|
|
14829
|
+
function buildJsonToolResult(payload) {
|
|
14830
|
+
return {
|
|
14831
|
+
content: [
|
|
14832
|
+
{
|
|
14833
|
+
type: "text",
|
|
14834
|
+
text: JSON.stringify(payload, null, 2),
|
|
14835
|
+
},
|
|
14836
|
+
],
|
|
14837
|
+
};
|
|
14838
|
+
}
|
|
14839
|
+
class ToolPayloadError extends Error {
|
|
14840
|
+
payload;
|
|
14841
|
+
constructor(payload) {
|
|
14842
|
+
super(typeof payload.message === "string" ? payload.message : "Tool payload error");
|
|
14843
|
+
this.name = "ToolPayloadError";
|
|
14844
|
+
this.payload = payload;
|
|
14845
|
+
}
|
|
14846
|
+
}
|
|
14847
|
+
exports.ToolPayloadError = ToolPayloadError;
|
|
14848
|
+
function isToolPayloadError(error) {
|
|
14849
|
+
return error instanceof ToolPayloadError;
|
|
14850
|
+
}
|
|
14851
|
+
function toolPayloadErrorToResult(error) {
|
|
14852
|
+
if (!isToolPayloadError(error)) {
|
|
14853
|
+
return null;
|
|
14854
|
+
}
|
|
14855
|
+
return buildJsonToolResult(error.payload);
|
|
14856
|
+
}
|
|
14857
|
+
function buildAuthNextStep(action, options) {
|
|
14858
|
+
return {
|
|
14859
|
+
tool: "auth",
|
|
14860
|
+
action,
|
|
14861
|
+
required_params: options?.requiredParams,
|
|
14862
|
+
suggested_args: options?.suggestedArgs ?? { action },
|
|
14863
|
+
};
|
|
14864
|
+
}
|
|
14865
|
+
function throwToolPayloadError(payload) {
|
|
14866
|
+
throw new ToolPayloadError(payload);
|
|
14867
|
+
}
|
|
14868
|
+
|
|
14869
|
+
|
|
13760
14870
|
/***/ })
|
|
13761
14871
|
|
|
13762
14872
|
/******/ });
|
|
@@ -13851,7 +14961,7 @@ var __webpack_exports__ = {};
|
|
|
13851
14961
|
var exports = __webpack_exports__;
|
|
13852
14962
|
|
|
13853
14963
|
Object.defineProperty(exports, "BJ", ({ value: true }));
|
|
13854
|
-
exports.pk = exports.ZS = exports.vY = exports.q8 = exports.bM = exports.fW = exports._k = exports.T$ = exports.$n = exports.S = exports.bT = exports.ri = exports.BS = exports.R8 = exports.z3 = exports.pq = exports.R4 = exports.ps = exports.v7 = exports.S7 = exports.dD = exports.Gh = void 0;
|
|
14964
|
+
exports.j8 = exports.fO = exports.gk = exports.Yh = exports.JA = exports.xz = exports.RX = exports.pk = exports.ZS = exports.vY = exports.q8 = exports.bM = exports.fW = exports._k = exports.T$ = exports.$n = exports.S = exports.bT = exports.ri = exports.BS = exports.R8 = exports.z3 = exports.pq = exports.R4 = exports.ps = exports.v7 = exports.S7 = exports.dD = exports.Gh = void 0;
|
|
13855
14965
|
exports.SJ = getInteractiveServerAsync;
|
|
13856
14966
|
// CloudBase MCP Server Library
|
|
13857
14967
|
var server_js_1 = __webpack_require__(1422);
|
|
@@ -13882,6 +14992,15 @@ var env_js_1 = __webpack_require__(622);
|
|
|
13882
14992
|
Object.defineProperty(exports, "ZS", ({ enumerable: true, get: function () { return env_js_1.simplifyEnvList; } }));
|
|
13883
14993
|
var setup_js_1 = __webpack_require__(6556);
|
|
13884
14994
|
Object.defineProperty(exports, "pk", ({ enumerable: true, get: function () { return setup_js_1.RAW_IDE_FILE_MAPPINGS; } }));
|
|
14995
|
+
// Export runtime constants for multi-language support
|
|
14996
|
+
var functions_js_1 = __webpack_require__(5936);
|
|
14997
|
+
Object.defineProperty(exports, "RX", ({ enumerable: true, get: function () { return functions_js_1.SUPPORTED_RUNTIMES; } }));
|
|
14998
|
+
Object.defineProperty(exports, "xz", ({ enumerable: true, get: function () { return functions_js_1.ALL_SUPPORTED_RUNTIMES; } }));
|
|
14999
|
+
Object.defineProperty(exports, "JA", ({ enumerable: true, get: function () { return functions_js_1.DEFAULT_RUNTIME; } }));
|
|
15000
|
+
Object.defineProperty(exports, "Yh", ({ enumerable: true, get: function () { return functions_js_1.RECOMMENDED_RUNTIMES; } }));
|
|
15001
|
+
Object.defineProperty(exports, "gk", ({ enumerable: true, get: function () { return functions_js_1.formatRuntimeList; } }));
|
|
15002
|
+
Object.defineProperty(exports, "fO", ({ enumerable: true, get: function () { return functions_js_1.SUPPORTED_NODEJS_RUNTIMES; } }));
|
|
15003
|
+
Object.defineProperty(exports, "j8", ({ enumerable: true, get: function () { return functions_js_1.DEFAULT_NODEJS_RUNTIME; } }));
|
|
13885
15004
|
/**
|
|
13886
15005
|
* Get interactive server instance (CommonJS compatible)
|
|
13887
15006
|
*/
|
|
@@ -13894,7 +15013,13 @@ async function getInteractiveServerAsync() {
|
|
|
13894
15013
|
|
|
13895
15014
|
})();
|
|
13896
15015
|
|
|
15016
|
+
const __webpack_exports__ALL_SUPPORTED_RUNTIMES = __webpack_exports__.xz;
|
|
15017
|
+
const __webpack_exports__DEFAULT_NODEJS_RUNTIME = __webpack_exports__.j8;
|
|
15018
|
+
const __webpack_exports__DEFAULT_RUNTIME = __webpack_exports__.JA;
|
|
13897
15019
|
const __webpack_exports__RAW_IDE_FILE_MAPPINGS = __webpack_exports__.pk;
|
|
15020
|
+
const __webpack_exports__RECOMMENDED_RUNTIMES = __webpack_exports__.Yh;
|
|
15021
|
+
const __webpack_exports__SUPPORTED_NODEJS_RUNTIMES = __webpack_exports__.fO;
|
|
15022
|
+
const __webpack_exports__SUPPORTED_RUNTIMES = __webpack_exports__.RX;
|
|
13898
15023
|
const __webpack_exports__StdioServerTransport = __webpack_exports__.S7;
|
|
13899
15024
|
const __webpack_exports___esModule = __webpack_exports__.BJ;
|
|
13900
15025
|
const __webpack_exports__createCloudBaseManagerWithOptions = __webpack_exports__.q8;
|
|
@@ -13902,6 +15027,7 @@ const __webpack_exports__createCloudBaseMcpServer = __webpack_exports__.Gh;
|
|
|
13902
15027
|
const __webpack_exports__enableCloudMode = __webpack_exports__.S;
|
|
13903
15028
|
const __webpack_exports__envManager = __webpack_exports__.vY;
|
|
13904
15029
|
const __webpack_exports__error = __webpack_exports__.z3;
|
|
15030
|
+
const __webpack_exports__formatRuntimeList = __webpack_exports__.gk;
|
|
13905
15031
|
const __webpack_exports__getCloudBaseManager = __webpack_exports__._k;
|
|
13906
15032
|
const __webpack_exports__getCloudModeStatus = __webpack_exports__.$n;
|
|
13907
15033
|
const __webpack_exports__getDefaultServer = __webpack_exports__.dD;
|
|
@@ -13918,4 +15044,4 @@ const __webpack_exports__shouldRegisterTool = __webpack_exports__.T$;
|
|
|
13918
15044
|
const __webpack_exports__simplifyEnvList = __webpack_exports__.ZS;
|
|
13919
15045
|
const __webpack_exports__telemetryReporter = __webpack_exports__.v7;
|
|
13920
15046
|
const __webpack_exports__warn = __webpack_exports__.R8;
|
|
13921
|
-
export { __webpack_exports__RAW_IDE_FILE_MAPPINGS as RAW_IDE_FILE_MAPPINGS, __webpack_exports__StdioServerTransport as StdioServerTransport, __webpack_exports___esModule as __esModule, __webpack_exports__createCloudBaseManagerWithOptions as createCloudBaseManagerWithOptions, __webpack_exports__createCloudBaseMcpServer as createCloudBaseMcpServer, __webpack_exports__enableCloudMode as enableCloudMode, __webpack_exports__envManager as envManager, __webpack_exports__error as error, __webpack_exports__getCloudBaseManager as getCloudBaseManager, __webpack_exports__getCloudModeStatus as getCloudModeStatus, __webpack_exports__getDefaultServer as getDefaultServer, __webpack_exports__getEnvId as getEnvId, __webpack_exports__getInteractiveServerAsync as getInteractiveServerAsync, __webpack_exports__getLoginState as getLoginState, __webpack_exports__info as info, __webpack_exports__isCloudMode as isCloudMode, __webpack_exports__logout as logout, __webpack_exports__reportToolCall as reportToolCall, __webpack_exports__reportToolkitLifecycle as reportToolkitLifecycle, __webpack_exports__resetCloudBaseManagerCache as resetCloudBaseManagerCache, __webpack_exports__shouldRegisterTool as shouldRegisterTool, __webpack_exports__simplifyEnvList as simplifyEnvList, __webpack_exports__telemetryReporter as telemetryReporter, __webpack_exports__warn as warn };
|
|
15047
|
+
export { __webpack_exports__ALL_SUPPORTED_RUNTIMES as ALL_SUPPORTED_RUNTIMES, __webpack_exports__DEFAULT_NODEJS_RUNTIME as DEFAULT_NODEJS_RUNTIME, __webpack_exports__DEFAULT_RUNTIME as DEFAULT_RUNTIME, __webpack_exports__RAW_IDE_FILE_MAPPINGS as RAW_IDE_FILE_MAPPINGS, __webpack_exports__RECOMMENDED_RUNTIMES as RECOMMENDED_RUNTIMES, __webpack_exports__SUPPORTED_NODEJS_RUNTIMES as SUPPORTED_NODEJS_RUNTIMES, __webpack_exports__SUPPORTED_RUNTIMES as SUPPORTED_RUNTIMES, __webpack_exports__StdioServerTransport as StdioServerTransport, __webpack_exports___esModule as __esModule, __webpack_exports__createCloudBaseManagerWithOptions as createCloudBaseManagerWithOptions, __webpack_exports__createCloudBaseMcpServer as createCloudBaseMcpServer, __webpack_exports__enableCloudMode as enableCloudMode, __webpack_exports__envManager as envManager, __webpack_exports__error as error, __webpack_exports__formatRuntimeList as formatRuntimeList, __webpack_exports__getCloudBaseManager as getCloudBaseManager, __webpack_exports__getCloudModeStatus as getCloudModeStatus, __webpack_exports__getDefaultServer as getDefaultServer, __webpack_exports__getEnvId as getEnvId, __webpack_exports__getInteractiveServerAsync as getInteractiveServerAsync, __webpack_exports__getLoginState as getLoginState, __webpack_exports__info as info, __webpack_exports__isCloudMode as isCloudMode, __webpack_exports__logout as logout, __webpack_exports__reportToolCall as reportToolCall, __webpack_exports__reportToolkitLifecycle as reportToolkitLifecycle, __webpack_exports__resetCloudBaseManagerCache as resetCloudBaseManagerCache, __webpack_exports__shouldRegisterTool as shouldRegisterTool, __webpack_exports__simplifyEnvList as simplifyEnvList, __webpack_exports__telemetryReporter as telemetryReporter, __webpack_exports__warn as warn };
|