@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/index.cjs CHANGED
@@ -1763,11 +1763,12 @@ warn.forProperties(exports, 'deprecated', ['emitErrs', 'levelLength']);
1763
1763
  Object.defineProperty(exports, "__esModule", ({ value: true }));
1764
1764
  exports.simplifyEnvList = simplifyEnvList;
1765
1765
  exports.registerEnvTools = registerEnvTools;
1766
+ const toolbox_1 = __webpack_require__(25901);
1766
1767
  const zod_1 = __webpack_require__(21614);
1767
1768
  const auth_js_1 = __webpack_require__(77291);
1768
1769
  const cloudbase_manager_js_1 = __webpack_require__(3431);
1769
1770
  const logger_js_1 = __webpack_require__(13039);
1770
- const interactive_js_1 = __webpack_require__(3461);
1771
+ const tool_result_js_1 = __webpack_require__(9835);
1771
1772
  const rag_js_1 = __webpack_require__(64215);
1772
1773
  /**
1773
1774
  * Simplify environment list data by keeping only essential fields for AI assistant
@@ -1799,17 +1800,119 @@ function simplifyEnvList(envList) {
1799
1800
  return simplified;
1800
1801
  });
1801
1802
  }
1803
+ function formatDeviceAuthHint(deviceAuthInfo) {
1804
+ if (!deviceAuthInfo) {
1805
+ return "";
1806
+ }
1807
+ const lines = [
1808
+ "",
1809
+ "### Device Flow 授权信息",
1810
+ `- user_code: ${deviceAuthInfo.user_code}`,
1811
+ ];
1812
+ if (deviceAuthInfo.verification_uri) {
1813
+ lines.push(`- verification_uri: ${deviceAuthInfo.verification_uri}`);
1814
+ }
1815
+ lines.push(`- expires_in: ${deviceAuthInfo.expires_in}s`);
1816
+ lines.push("", "请在另一台可用浏览器设备打开 `verification_uri` 并输入 `user_code` 完成授权。");
1817
+ return lines.join("\n");
1818
+ }
1819
+ function emitDeviceAuthNotice(server, deviceAuthInfo) {
1820
+ // Temporarily disabled: avoid sending logging notifications for device auth
1821
+ }
1822
+ async function fetchAvailableEnvCandidates(cloudBaseOptions, server) {
1823
+ try {
1824
+ return await (0, cloudbase_manager_js_1.listAvailableEnvCandidates)({
1825
+ cloudBaseOptions,
1826
+ });
1827
+ }
1828
+ catch {
1829
+ return [];
1830
+ }
1831
+ }
1832
+ const CODEBUDDY_AUTH_ACTIONS = ["status", "set_env"];
1833
+ const DEFAULT_AUTH_ACTIONS = [
1834
+ "status",
1835
+ "start_auth",
1836
+ "set_env",
1837
+ "logout",
1838
+ ];
1839
+ function getCurrentIde(server) {
1840
+ return server.ide || process.env.INTEGRATION_IDE || "";
1841
+ }
1842
+ function isCodeBuddyIde(server) {
1843
+ return getCurrentIde(server) === "CodeBuddy";
1844
+ }
1845
+ function getSupportedAuthActions(server) {
1846
+ return isCodeBuddyIde(server) ? CODEBUDDY_AUTH_ACTIONS : DEFAULT_AUTH_ACTIONS;
1847
+ }
1848
+ function buildAuthRequiredNextStep(server) {
1849
+ if (isCodeBuddyIde(server)) {
1850
+ return (0, tool_result_js_1.buildAuthNextStep)("status", {
1851
+ suggestedArgs: { action: "status" },
1852
+ });
1853
+ }
1854
+ return (0, tool_result_js_1.buildAuthNextStep)("start_auth", {
1855
+ suggestedArgs: { action: "start_auth", authMode: "device" },
1856
+ });
1857
+ }
1858
+ function buildSetEnvNextStep(envCandidates) {
1859
+ const singleEnvId = envCandidates.length === 1 ? envCandidates[0].envId : undefined;
1860
+ return (0, tool_result_js_1.buildAuthNextStep)("set_env", {
1861
+ requiredParams: singleEnvId ? undefined : ["envId"],
1862
+ suggestedArgs: singleEnvId
1863
+ ? { action: "set_env", envId: singleEnvId }
1864
+ : { action: "set_env" },
1865
+ });
1866
+ }
1867
+ async function getGuidePrompt(server) {
1868
+ if (getCurrentIde(server) === "CodeBuddy" ||
1869
+ process.env.CLOUDBASE_GUIDE_PROMPT === "false") {
1870
+ return "";
1871
+ }
1872
+ try {
1873
+ return await (0, rag_js_1.getClaudePrompt)();
1874
+ }
1875
+ catch (promptError) {
1876
+ (0, logger_js_1.debug)("Failed to get CLAUDE prompt", { error: promptError });
1877
+ return "";
1878
+ }
1879
+ }
1802
1880
  function registerEnvTools(server) {
1803
1881
  // 获取 cloudBaseOptions,如果没有则为 undefined
1804
1882
  const cloudBaseOptions = server.cloudBaseOptions;
1805
1883
  const getManager = () => (0, cloudbase_manager_js_1.getCloudBaseManager)({ cloudBaseOptions, mcpServer: server });
1806
1884
  const hasEnvId = typeof cloudBaseOptions?.envId === 'string' && cloudBaseOptions?.envId.length > 0;
1807
- // login - 登录云开发环境
1808
- server.registerTool?.("login", {
1809
- title: "登录云开发",
1810
- description: "登录云开发环境,在生成包含云开发 CloudBase 相关功能前**必须**先调用此工具进行登录。登录云开发环境并选择要使用的环境。",
1885
+ const supportedAuthActions = getSupportedAuthActions(server);
1886
+ const authActionEnum = [...supportedAuthActions];
1887
+ // auth - CloudBase (云开发) 开发阶段登录与环境绑定
1888
+ server.registerTool?.("auth", {
1889
+ title: "CloudBase 开发阶段登录与环境",
1890
+ description: "CloudBase(腾讯云开发)开发阶段登录与环境绑定。登录后即可访问云资源;环境(env)是云函数、数据库、静态托管等资源的隔离单元,绑定环境后其他 MCP 工具才能操作该环境。支持:查询状态、发起登录、绑定环境(set_env)、退出登录。",
1811
1891
  inputSchema: {
1812
- forceUpdate: zod_1.z.boolean().optional().describe("是否强制重新选择环境"),
1892
+ action: zod_1.z
1893
+ .enum(authActionEnum)
1894
+ .optional()
1895
+ .describe("动作:status=查询状态,start_auth=发起登录,set_env=绑定环境(传envId),logout=退出登录"),
1896
+ ...(supportedAuthActions.includes("start_auth")
1897
+ ? {
1898
+ authMode: zod_1.z
1899
+ .enum(["device", "web"])
1900
+ .optional()
1901
+ .describe("认证模式:device=设备码授权,web=浏览器回调授权"),
1902
+ }
1903
+ : {}),
1904
+ envId: zod_1.z
1905
+ .string()
1906
+ .optional()
1907
+ .describe("环境ID(CloudBase 环境唯一标识),绑定后工具将操作该环境。action=set_env 时必填"),
1908
+ ...(supportedAuthActions.includes("logout")
1909
+ ? {
1910
+ confirm: zod_1.z
1911
+ .literal("yes")
1912
+ .optional()
1913
+ .describe("action=logout 时确认操作,传 yes"),
1914
+ }
1915
+ : {}),
1813
1916
  },
1814
1917
  annotations: {
1815
1918
  readOnlyHint: false,
@@ -1818,135 +1921,326 @@ function registerEnvTools(server) {
1818
1921
  openWorldHint: true,
1819
1922
  category: "env",
1820
1923
  },
1821
- }, async ({ forceUpdate = false }) => {
1822
- let isSwitching = false;
1924
+ }, async (rawArgs) => {
1925
+ const action = rawArgs.action ?? "status";
1926
+ const authMode = rawArgs.authMode === "device" || rawArgs.authMode === "web"
1927
+ ? rawArgs.authMode
1928
+ : undefined;
1929
+ const envId = rawArgs.envId;
1930
+ const confirm = rawArgs.confirm === "yes" ? "yes" : undefined;
1931
+ let deviceAuthInfo;
1932
+ const onDeviceCode = (info) => {
1933
+ deviceAuthInfo = info;
1934
+ (0, auth_js_1.setPendingAuthProgressState)(info, "device");
1935
+ // emitDeviceAuthNotice(server, info);
1936
+ };
1937
+ const authChallenge = () => deviceAuthInfo
1938
+ ? {
1939
+ user_code: deviceAuthInfo.user_code,
1940
+ verification_uri: deviceAuthInfo.verification_uri,
1941
+ expires_in: deviceAuthInfo.expires_in,
1942
+ }
1943
+ : undefined;
1823
1944
  try {
1824
- // 使用 while 循环处理用户切换账号的情况
1825
- while (true) {
1826
- // CRITICAL: Ensure server is passed correctly
1827
- (0, logger_js_1.debug)("[env] Calling _promptAndSetEnvironmentId with server:", {
1828
- hasServer: !!server,
1829
- serverType: typeof server,
1830
- hasServerServer: !!server?.server,
1831
- hasServerIde: !!server?.ide,
1832
- serverIde: server?.ide
1833
- });
1834
- const { selectedEnvId, cancelled, error, noEnvs, switch: switchAccount, } = await (0, interactive_js_1._promptAndSetEnvironmentId)(forceUpdate, {
1835
- server, // Pass ExtendedMcpServer instance
1836
- loginFromCloudBaseLoginPage: isSwitching,
1837
- // When switching account, ignore environment variables to force Web login
1838
- ignoreEnvVars: isSwitching,
1945
+ if (!supportedAuthActions.includes(action)) {
1946
+ return (0, tool_result_js_1.buildJsonToolResult)({
1947
+ ok: false,
1948
+ code: "NOT_SUPPORTED",
1949
+ message: `当前 IDE 不支持 auth(action="${action}")。`,
1950
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("status", {
1951
+ suggestedArgs: { action: "status" },
1952
+ }),
1839
1953
  });
1840
- isSwitching = Boolean(switchAccount);
1841
- (0, logger_js_1.debug)("login", {
1842
- selectedEnvId,
1843
- cancelled,
1844
- error,
1845
- noEnvs,
1846
- switchAccount,
1954
+ }
1955
+ if (action === "status") {
1956
+ const loginState = await (0, auth_js_1.peekLoginState)();
1957
+ const authFlowState = await (0, auth_js_1.getAuthProgressState)();
1958
+ const envId = (0, cloudbase_manager_js_1.getCachedEnvId)() ||
1959
+ process.env.CLOUDBASE_ENV_ID ||
1960
+ (typeof loginState?.envId === "string" ? loginState.envId : undefined);
1961
+ const authStatus = loginState
1962
+ ? "READY"
1963
+ : authFlowState.status === "PENDING"
1964
+ ? "PENDING"
1965
+ : "REQUIRED";
1966
+ const envCandidates = await fetchAvailableEnvCandidates(cloudBaseOptions, server);
1967
+ const envStatus = envId
1968
+ ? "READY"
1969
+ : envCandidates.length > 1
1970
+ ? "MULTIPLE"
1971
+ : envCandidates.length === 1
1972
+ ? "READY"
1973
+ : "NONE";
1974
+ const message = authStatus === "READY"
1975
+ ? `当前已登录${envId ? `,环境: ${envId}` : ",但未绑定环境"}`
1976
+ : authStatus === "PENDING"
1977
+ ? "设备码授权进行中,请完成浏览器授权后再次调用 auth(action=\"status\")"
1978
+ : isCodeBuddyIde(server)
1979
+ ? "当前未登录。CodeBuddy 暂不支持在 tool 内发起认证,请在外部完成认证后再次调用 auth(action=\"status\")。"
1980
+ : "当前未登录,请先执行 auth(action=\"start_auth\")";
1981
+ return (0, tool_result_js_1.buildJsonToolResult)({
1982
+ ok: true,
1983
+ code: "STATUS",
1984
+ auth_status: authStatus,
1985
+ env_status: envStatus,
1986
+ current_env_id: envId || null,
1987
+ env_candidates: envCandidates,
1988
+ auth_challenge: authFlowState.status === "PENDING" && authFlowState.authChallenge
1989
+ ? {
1990
+ user_code: authFlowState.authChallenge.user_code,
1991
+ verification_uri: authFlowState.authChallenge.verification_uri,
1992
+ expires_in: authFlowState.authChallenge.expires_in,
1993
+ }
1994
+ : undefined,
1995
+ message,
1996
+ next_step: authStatus === "REQUIRED"
1997
+ ? buildAuthRequiredNextStep(server)
1998
+ : authStatus === "PENDING"
1999
+ ? (0, tool_result_js_1.buildAuthNextStep)("status", {
2000
+ suggestedArgs: { action: "status" },
2001
+ })
2002
+ : !envId
2003
+ ? buildSetEnvNextStep(envCandidates)
2004
+ : (0, tool_result_js_1.buildAuthNextStep)("status", {
2005
+ suggestedArgs: { action: "status" },
2006
+ }),
1847
2007
  });
1848
- if (error) {
1849
- return { content: [{ type: "text", text: error }] };
1850
- }
1851
- if (cancelled) {
1852
- return { content: [{ type: "text", text: "用户取消了登录" }] };
2008
+ }
2009
+ if (action === "start_auth") {
2010
+ const region = server.cloudBaseOptions?.region || process.env.TCB_REGION;
2011
+ const auth = toolbox_1.AuthSupervisor.getInstance({});
2012
+ const authFlowState = await (0, auth_js_1.getAuthProgressState)();
2013
+ if (authFlowState.status === "PENDING" && authFlowState.authChallenge) {
2014
+ return (0, tool_result_js_1.buildJsonToolResult)({
2015
+ ok: true,
2016
+ code: "AUTH_PENDING",
2017
+ message: "设备码授权进行中,请在浏览器中打开 verification_uri 并输入 user_code 完成授权。",
2018
+ auth_challenge: {
2019
+ user_code: authFlowState.authChallenge.user_code,
2020
+ verification_uri: authFlowState.authChallenge.verification_uri,
2021
+ expires_in: authFlowState.authChallenge.expires_in,
2022
+ },
2023
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("status", {
2024
+ suggestedArgs: { action: "status" },
2025
+ }),
2026
+ });
1853
2027
  }
1854
- // 用户选择切换账号,先 logout 再重新登录
1855
- if (switchAccount) {
1856
- (0, logger_js_1.debug)("User requested switch account, logging out...");
1857
- try {
1858
- await (0, auth_js_1.logout)();
1859
- (0, cloudbase_manager_js_1.resetCloudBaseManagerCache)();
1860
- (0, logger_js_1.debug)("Logged out successfully, restarting login flow...");
1861
- // Set isSwitching to true so next iteration will ignore env vars
1862
- // and force Web authentication to allow account switching
1863
- isSwitching = true;
1864
- // 继续循环,重新显示登录界面
1865
- continue;
1866
- }
1867
- catch (logoutError) {
1868
- (0, logger_js_1.debug)("Logout failed during switch", { error: logoutError });
1869
- continue;
2028
+ // 1. 如果已经有登录态,直接返回 AUTH_READY
2029
+ try {
2030
+ const existingLoginState = await (0, auth_js_1.peekLoginState)();
2031
+ if (existingLoginState) {
2032
+ const envId = typeof existingLoginState.envId === "string" ? existingLoginState.envId : null;
2033
+ const envCandidates = envId
2034
+ ? []
2035
+ : await fetchAvailableEnvCandidates(cloudBaseOptions, server);
2036
+ return (0, tool_result_js_1.buildJsonToolResult)({
2037
+ ok: true,
2038
+ code: "AUTH_READY",
2039
+ message: envId
2040
+ ? `认证成功,当前登录态 envId: ${envId}`
2041
+ : "认证成功",
2042
+ auth_challenge: authChallenge(),
2043
+ env_candidates: envCandidates,
2044
+ next_step: envId
2045
+ ? (0, tool_result_js_1.buildAuthNextStep)("status", {
2046
+ suggestedArgs: { action: "status" },
2047
+ })
2048
+ : buildSetEnvNextStep(envCandidates),
2049
+ });
1870
2050
  }
1871
2051
  }
1872
- if (selectedEnvId) {
1873
- // Get CLAUDE.md prompt content (skip for CodeBuddy IDE)
1874
- let promptContent = "";
1875
- const currentIde = server.ide || process.env.INTEGRATION_IDE;
1876
- if (currentIde !== "CodeBuddy" && process.env.CLOUDBASE_GUIDE_PROMPT !== "false") {
1877
- try {
1878
- promptContent = await (0, rag_js_1.getClaudePrompt)();
2052
+ catch {
2053
+ // 忽略 getLoginState 错误,继续尝试发起登录
2054
+ }
2055
+ // 2. 设备码模式:监听到 device code 即返回 AUTH_PENDING,后续由 toolbox 异步轮询并更新本地 credential
2056
+ const effectiveMode = authMode && (authMode === "device" || authMode === "web")
2057
+ ? authMode
2058
+ : process.env.TCB_AUTH_MODE === "web"
2059
+ ? "web"
2060
+ : "device";
2061
+ if (effectiveMode === "device") {
2062
+ let resolveCode;
2063
+ let rejectCode;
2064
+ const codeReady = new Promise((resolve, reject) => {
2065
+ resolveCode = resolve;
2066
+ rejectCode = reject;
2067
+ });
2068
+ const deviceOnCode = (info) => {
2069
+ onDeviceCode(info);
2070
+ if (resolveCode) {
2071
+ resolveCode();
1879
2072
  }
1880
- catch (promptError) {
1881
- (0, logger_js_1.debug)("Failed to get CLAUDE prompt", { error: promptError });
1882
- // Continue with login success even if prompt fetch fails
2073
+ };
2074
+ try {
2075
+ // 启动 Device Flow,全流程由 toolbox 负责轮询和写入 credential,这里不等待完成
2076
+ auth
2077
+ .loginByWebAuth({
2078
+ flow: "device",
2079
+ onDeviceCode: deviceOnCode,
2080
+ })
2081
+ .then(() => {
2082
+ (0, auth_js_1.resolveAuthProgressState)();
2083
+ })
2084
+ .catch((err) => {
2085
+ (0, auth_js_1.rejectAuthProgressState)(err);
2086
+ // 如果在拿到 device code 之前就失败,则唤醒当前调用并返回错误
2087
+ if (!deviceAuthInfo && rejectCode) {
2088
+ rejectCode(err);
2089
+ }
2090
+ });
2091
+ }
2092
+ catch (err) {
2093
+ if (rejectCode) {
2094
+ rejectCode(err);
1883
2095
  }
1884
2096
  }
1885
- const successMessage = `✅ 登录成功,当前环境: ${selectedEnvId}`;
1886
- const promptMessage = promptContent
1887
- ? `\n\n⚠️ 重要提示:后续所有云开发相关的开发工作必须严格遵循以下开发规范和最佳实践:\n\n${promptContent}`
1888
- : "";
1889
- return {
1890
- content: [
1891
- {
1892
- type: "text",
1893
- text: successMessage + promptMessage,
1894
- },
1895
- ],
1896
- };
2097
+ try {
2098
+ await codeReady;
2099
+ }
2100
+ catch (err) {
2101
+ const message = err instanceof Error ? err.message : String(err ?? "unknown error");
2102
+ return (0, tool_result_js_1.buildJsonToolResult)({
2103
+ ok: false,
2104
+ code: "AUTH_REQUIRED",
2105
+ message: `设备码登录初始化失败: ${message}`,
2106
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("start_auth", {
2107
+ suggestedArgs: { action: "start_auth", authMode: "device" },
2108
+ }),
2109
+ });
2110
+ }
2111
+ if (!deviceAuthInfo) {
2112
+ return (0, tool_result_js_1.buildJsonToolResult)({
2113
+ ok: false,
2114
+ code: "AUTH_REQUIRED",
2115
+ message: "未获取到设备码信息,请重试设备码登录",
2116
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("start_auth", {
2117
+ suggestedArgs: { action: "start_auth", authMode: "device" },
2118
+ }),
2119
+ });
2120
+ }
2121
+ const envCandidates = await fetchAvailableEnvCandidates(cloudBaseOptions, server);
2122
+ return (0, tool_result_js_1.buildJsonToolResult)({
2123
+ ok: true,
2124
+ code: "AUTH_PENDING",
2125
+ message: "已发起设备码登录,请在浏览器中打开 verification_uri 并输入 user_code 完成授权。授权完成后请再次调用 auth(action=\"status\")。",
2126
+ auth_challenge: authChallenge(),
2127
+ env_candidates: envCandidates,
2128
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("status", {
2129
+ suggestedArgs: { action: "status" },
2130
+ }),
2131
+ });
1897
2132
  }
1898
- throw new Error("登录失败");
2133
+ // 3. 非 Device Flow(显式 web 模式)仍然使用 getLoginState 阻塞等待
2134
+ const loginState = await (0, auth_js_1.ensureLogin)({
2135
+ region,
2136
+ authMode: effectiveMode,
2137
+ });
2138
+ if (!loginState) {
2139
+ return (0, tool_result_js_1.buildJsonToolResult)({
2140
+ ok: false,
2141
+ code: "AUTH_REQUIRED",
2142
+ message: "未获取到登录态,请先完成认证",
2143
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("start_auth", {
2144
+ suggestedArgs: { action: "start_auth", authMode: effectiveMode },
2145
+ }),
2146
+ });
2147
+ }
2148
+ const envId = typeof loginState.envId === "string" ? loginState.envId : null;
2149
+ const envCandidates = envId
2150
+ ? []
2151
+ : await fetchAvailableEnvCandidates(cloudBaseOptions, server);
2152
+ return (0, tool_result_js_1.buildJsonToolResult)({
2153
+ ok: true,
2154
+ code: "AUTH_READY",
2155
+ message: envId ? `认证成功,当前登录态 envId: ${envId}` : "认证成功",
2156
+ auth_challenge: authChallenge(),
2157
+ env_candidates: envCandidates,
2158
+ next_step: envId
2159
+ ? (0, tool_result_js_1.buildAuthNextStep)("status", {
2160
+ suggestedArgs: { action: "status" },
2161
+ })
2162
+ : buildSetEnvNextStep(envCandidates),
2163
+ });
1899
2164
  }
2165
+ if (action === "set_env") {
2166
+ const loginState = await (0, auth_js_1.peekLoginState)();
2167
+ if (!loginState) {
2168
+ return (0, tool_result_js_1.buildJsonToolResult)({
2169
+ ok: false,
2170
+ code: "AUTH_REQUIRED",
2171
+ message: isCodeBuddyIde(server)
2172
+ ? "当前未登录。CodeBuddy 暂不支持在 tool 内发起认证,请在外部完成认证后再次调用 auth(action=\"status\")。"
2173
+ : "当前未登录,请先执行 auth(action=\"start_auth\")。",
2174
+ next_step: buildAuthRequiredNextStep(server),
2175
+ });
2176
+ }
2177
+ const envCandidates = await fetchAvailableEnvCandidates(cloudBaseOptions, server);
2178
+ if (!envId) {
2179
+ return (0, tool_result_js_1.buildJsonToolResult)({
2180
+ ok: false,
2181
+ code: "INVALID_ARGS",
2182
+ message: "action=set_env 时必须提供 envId",
2183
+ env_candidates: envCandidates,
2184
+ next_step: buildSetEnvNextStep(envCandidates),
2185
+ });
2186
+ }
2187
+ const target = envCandidates.find((item) => item.envId === envId);
2188
+ if (envCandidates.length > 0 && !target) {
2189
+ return (0, tool_result_js_1.buildJsonToolResult)({
2190
+ ok: false,
2191
+ code: "INVALID_ARGS",
2192
+ message: `未找到环境: ${envId}`,
2193
+ env_candidates: envCandidates,
2194
+ next_step: buildSetEnvNextStep(envCandidates),
2195
+ });
2196
+ }
2197
+ await cloudbase_manager_js_1.envManager.setEnvId(envId);
2198
+ return (0, tool_result_js_1.buildJsonToolResult)({
2199
+ ok: true,
2200
+ code: "ENV_READY",
2201
+ message: `环境设置成功,当前环境: ${envId}`,
2202
+ current_env_id: envId,
2203
+ });
2204
+ }
2205
+ if (action === "logout") {
2206
+ if (confirm !== "yes") {
2207
+ return (0, tool_result_js_1.buildJsonToolResult)({
2208
+ ok: false,
2209
+ code: "INVALID_ARGS",
2210
+ message: "action=logout 时必须传 confirm=\"yes\"",
2211
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("logout", {
2212
+ suggestedArgs: { action: "logout", confirm: "yes" },
2213
+ }),
2214
+ });
2215
+ }
2216
+ await (0, auth_js_1.logout)();
2217
+ (0, cloudbase_manager_js_1.resetCloudBaseManagerCache)();
2218
+ return (0, tool_result_js_1.buildJsonToolResult)({
2219
+ ok: true,
2220
+ code: "LOGGED_OUT",
2221
+ message: "✅ 已退出登录",
2222
+ });
2223
+ }
2224
+ return (0, tool_result_js_1.buildJsonToolResult)({
2225
+ ok: false,
2226
+ code: "NOT_SUPPORTED",
2227
+ message: `不支持的 auth action: ${action}`,
2228
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("status", {
2229
+ suggestedArgs: { action: "status" },
2230
+ }),
2231
+ });
1900
2232
  }
1901
2233
  catch (error) {
1902
- return {
1903
- content: [
1904
- {
1905
- type: "text",
1906
- text: `登录失败: ${error instanceof Error ? error.message : String(error)}`,
1907
- },
1908
- ],
1909
- };
1910
- }
1911
- });
1912
- // logout - 退出云开发环境
1913
- server.registerTool?.("logout", {
1914
- title: "退出登录",
1915
- description: "退出云开发环境",
1916
- inputSchema: {
1917
- confirm: zod_1.z.literal("yes").describe("确认操作,默认传 yes"),
1918
- },
1919
- annotations: {
1920
- readOnlyHint: false,
1921
- destructiveHint: false,
1922
- idempotentHint: true,
1923
- openWorldHint: false,
1924
- category: "env",
1925
- },
1926
- }, async () => {
1927
- try {
1928
- // 登出账户
1929
- await (0, auth_js_1.logout)();
1930
- // 清理环境ID缓存
1931
- (0, cloudbase_manager_js_1.resetCloudBaseManagerCache)();
1932
- return {
1933
- content: [
1934
- {
1935
- type: "text",
1936
- text: "✅ 已退出登录",
1937
- },
1938
- ],
1939
- };
1940
- }
1941
- catch (error) {
1942
- return {
1943
- content: [
1944
- {
1945
- type: "text",
1946
- text: `退出失败: ${error instanceof Error ? error.message : String(error)}`,
1947
- },
1948
- ],
1949
- };
2234
+ const message = error instanceof Error ? error.message : String(error);
2235
+ return (0, tool_result_js_1.buildJsonToolResult)({
2236
+ ok: false,
2237
+ code: "INTERNAL_ERROR",
2238
+ message: `auth 执行失败: ${message}`,
2239
+ auth_challenge: authChallenge(),
2240
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("status", {
2241
+ suggestedArgs: { action: "status" },
2242
+ }),
2243
+ });
1950
2244
  }
1951
2245
  });
1952
2246
  // envQuery - 环境查询(合并 listEnvs + getEnvInfo + getEnvAuthDomains + getWebsiteConfig)
@@ -2020,6 +2314,10 @@ function registerEnvTools(server) {
2020
2314
  }
2021
2315
  }
2022
2316
  catch (fallbackError) {
2317
+ const toolPayloadResult = (0, tool_result_js_1.toolPayloadErrorToResult)(fallbackError);
2318
+ if (toolPayloadResult) {
2319
+ return toolPayloadResult;
2320
+ }
2023
2321
  (0, logger_js_1.debug)("降级到 listEnvs() 也失败:", fallbackError instanceof Error ? fallbackError : new Error(String(fallbackError)));
2024
2322
  return {
2025
2323
  content: [
@@ -2083,6 +2381,10 @@ function registerEnvTools(server) {
2083
2381
  };
2084
2382
  }
2085
2383
  catch (error) {
2384
+ const toolPayloadResult = (0, tool_result_js_1.toolPayloadErrorToResult)(error);
2385
+ if (toolPayloadResult) {
2386
+ return toolPayloadResult;
2387
+ }
2086
2388
  return {
2087
2389
  content: [
2088
2390
  {
@@ -2136,6 +2438,10 @@ function registerEnvTools(server) {
2136
2438
  };
2137
2439
  }
2138
2440
  catch (error) {
2441
+ const toolPayloadResult = (0, tool_result_js_1.toolPayloadErrorToResult)(error);
2442
+ if (toolPayloadResult) {
2443
+ return toolPayloadResult;
2444
+ }
2139
2445
  return {
2140
2446
  content: [
2141
2447
  {
@@ -5336,7 +5642,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;/**
5336
5642
  var undefined;
5337
5643
 
5338
5644
  /** Used as the semantic version number. */
5339
- var VERSION = '4.17.21';
5645
+ var VERSION = '4.17.23';
5340
5646
 
5341
5647
  /** Used as the size to enable large array optimizations. */
5342
5648
  var LARGE_ARRAY_SIZE = 200;
@@ -9090,7 +9396,7 @@ var __WEBPACK_AMD_DEFINE_RESULT__;/**
9090
9396
  if (isArray(iteratee)) {
9091
9397
  return function(value) {
9092
9398
  return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee);
9093
- }
9399
+ };
9094
9400
  }
9095
9401
  return iteratee;
9096
9402
  });
@@ -9694,8 +10000,47 @@ var __WEBPACK_AMD_DEFINE_RESULT__;/**
9694
10000
  */
9695
10001
  function baseUnset(object, path) {
9696
10002
  path = castPath(path, object);
9697
- object = parent(object, path);
9698
- return object == null || delete object[toKey(last(path))];
10003
+
10004
+ // Prevent prototype pollution, see: https://github.com/lodash/lodash/security/advisories/GHSA-xxjr-mmjv-4gpg
10005
+ var index = -1,
10006
+ length = path.length;
10007
+
10008
+ if (!length) {
10009
+ return true;
10010
+ }
10011
+
10012
+ var isRootPrimitive = object == null || (typeof object !== 'object' && typeof object !== 'function');
10013
+
10014
+ while (++index < length) {
10015
+ var key = path[index];
10016
+
10017
+ // skip non-string keys (e.g., Symbols, numbers)
10018
+ if (typeof key !== 'string') {
10019
+ continue;
10020
+ }
10021
+
10022
+ // Always block "__proto__" anywhere in the path if it's not expected
10023
+ if (key === '__proto__' && !hasOwnProperty.call(object, '__proto__')) {
10024
+ return false;
10025
+ }
10026
+
10027
+ // Block "constructor.prototype" chains
10028
+ if (key === 'constructor' &&
10029
+ (index + 1) < length &&
10030
+ typeof path[index + 1] === 'string' &&
10031
+ path[index + 1] === 'prototype') {
10032
+
10033
+ // Allow ONLY when the path starts at a primitive root, e.g., _.unset(0, 'constructor.prototype.a')
10034
+ if (isRootPrimitive && index === 0) {
10035
+ continue;
10036
+ }
10037
+
10038
+ return false;
10039
+ }
10040
+ }
10041
+
10042
+ var obj = parent(object, path);
10043
+ return obj == null || delete obj[toKey(last(path))];
9699
10044
  }
9700
10045
 
9701
10046
  /**
@@ -23781,6 +24126,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
23781
24126
  };
23782
24127
  Object.defineProperty(exports, "__esModule", ({ value: true }));
23783
24128
  exports.envManager = void 0;
24129
+ exports.listAvailableEnvCandidates = listAvailableEnvCandidates;
23784
24130
  exports.getEnvId = getEnvId;
23785
24131
  exports.resetCloudBaseManagerCache = resetCloudBaseManagerCache;
23786
24132
  exports.getCachedEnvId = getCachedEnvId;
@@ -23790,9 +24136,134 @@ exports.extractRequestId = extractRequestId;
23790
24136
  exports.logCloudBaseResult = logCloudBaseResult;
23791
24137
  const manager_node_1 = __importDefault(__webpack_require__(95492));
23792
24138
  const auth_js_1 = __webpack_require__(77291);
23793
- const interactive_js_1 = __webpack_require__(3461);
23794
24139
  const logger_js_1 = __webpack_require__(13039);
23795
- const ENV_ID_TIMEOUT = 600000; // 10 minutes (600 seconds) - matches InteractiveServer timeout
24140
+ const tool_result_js_1 = __webpack_require__(9835);
24141
+ // Timeout for envId auto-resolution flow.
24142
+ // 10 minutes (600 seconds) - matches InteractiveServer timeout
24143
+ const ENV_ID_TIMEOUT = 600000;
24144
+ function toEnvCandidates(envList) {
24145
+ if (!Array.isArray(envList)) {
24146
+ return [];
24147
+ }
24148
+ return envList
24149
+ .filter((item) => item?.EnvId)
24150
+ .map((item) => ({
24151
+ envId: item.EnvId,
24152
+ alias: item.Alias,
24153
+ region: item.Region,
24154
+ status: item.Status,
24155
+ env_type: item.EnvType,
24156
+ }));
24157
+ }
24158
+ function createManagerFromLoginState(loginState, region) {
24159
+ return new manager_node_1.default({
24160
+ secretId: loginState.secretId,
24161
+ secretKey: loginState.secretKey,
24162
+ envId: loginState.envId,
24163
+ token: loginState.token,
24164
+ proxy: process.env.http_proxy,
24165
+ region,
24166
+ });
24167
+ }
24168
+ async function listAvailableEnvCandidates(options) {
24169
+ const { cloudBaseOptions, loginState: providedLoginState } = options ?? {};
24170
+ if (cloudBaseOptions?.envId) {
24171
+ return [{
24172
+ envId: cloudBaseOptions.envId,
24173
+ }];
24174
+ }
24175
+ let cloudbase;
24176
+ if (cloudBaseOptions?.secretId && cloudBaseOptions?.secretKey) {
24177
+ cloudbase = createCloudBaseManagerWithOptions(cloudBaseOptions);
24178
+ }
24179
+ else {
24180
+ const loginState = providedLoginState ?? await (0, auth_js_1.peekLoginState)();
24181
+ if (!loginState?.secretId || !loginState?.secretKey) {
24182
+ return [];
24183
+ }
24184
+ const region = cloudBaseOptions?.region ?? process.env.TCB_REGION ?? undefined;
24185
+ cloudbase = createManagerFromLoginState(loginState, region);
24186
+ }
24187
+ try {
24188
+ const result = await cloudbase.commonService("tcb", "2018-06-08").call({
24189
+ Action: "DescribeEnvs",
24190
+ Param: {
24191
+ EnvTypes: ["weda", "baas"],
24192
+ IsVisible: false,
24193
+ Channels: ["dcloud", "iotenable", "tem", "scene_module"],
24194
+ },
24195
+ });
24196
+ const envList = result?.EnvList || result?.Data?.EnvList || [];
24197
+ return toEnvCandidates(envList);
24198
+ }
24199
+ catch {
24200
+ try {
24201
+ const fallback = await cloudbase.env.listEnvs();
24202
+ return toEnvCandidates(fallback?.EnvList || []);
24203
+ }
24204
+ catch {
24205
+ return [];
24206
+ }
24207
+ }
24208
+ }
24209
+ function throwAuthRequiredError() {
24210
+ (0, tool_result_js_1.throwToolPayloadError)({
24211
+ ok: false,
24212
+ code: "AUTH_REQUIRED",
24213
+ message: "当前未登录,请先调用 auth 工具完成认证。",
24214
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("start_auth", {
24215
+ suggestedArgs: {
24216
+ action: "start_auth",
24217
+ authMode: "device",
24218
+ },
24219
+ }),
24220
+ });
24221
+ }
24222
+ async function throwPendingAuthError() {
24223
+ const authState = await (0, auth_js_1.getAuthProgressState)();
24224
+ (0, tool_result_js_1.throwToolPayloadError)({
24225
+ ok: false,
24226
+ code: "AUTH_PENDING",
24227
+ message: authState.lastError || "设备码授权进行中,请先完成登录后再重试当前工具。",
24228
+ auth_challenge: authState.authChallenge
24229
+ ? {
24230
+ user_code: authState.authChallenge.user_code,
24231
+ verification_uri: authState.authChallenge.verification_uri,
24232
+ expires_in: authState.authChallenge.expires_in,
24233
+ }
24234
+ : undefined,
24235
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("status", {
24236
+ suggestedArgs: {
24237
+ action: "status",
24238
+ },
24239
+ }),
24240
+ });
24241
+ }
24242
+ async function throwEnvRequiredError(options) {
24243
+ const envCandidates = options?.envCandidates ?? (await listAvailableEnvCandidates(options));
24244
+ const singleEnvId = envCandidates.length === 1 ? envCandidates[0].envId : undefined;
24245
+ (0, tool_result_js_1.throwToolPayloadError)({
24246
+ ok: false,
24247
+ code: "ENV_REQUIRED",
24248
+ message: envCandidates.length === 0
24249
+ ? "当前已登录,但还没有可用环境,请先调用 auth 工具完成环境选择或创建环境。"
24250
+ : envCandidates.length === 1
24251
+ ? `当前已登录,但尚未绑定环境。可直接选择环境 ${singleEnvId}。`
24252
+ : "当前已登录,但尚未绑定环境,请先调用 auth 工具选择环境。",
24253
+ env_candidates: envCandidates,
24254
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("set_env", {
24255
+ requiredParams: singleEnvId ? undefined : ["envId"],
24256
+ suggestedArgs: singleEnvId
24257
+ ? {
24258
+ action: "set_env",
24259
+ envId: singleEnvId,
24260
+ }
24261
+ : {
24262
+ action: "set_env",
24263
+ },
24264
+ }),
24265
+ });
24266
+ }
23796
24267
  // 统一的环境ID管理类
23797
24268
  class EnvironmentManager {
23798
24269
  cachedEnvId = null;
@@ -23804,7 +24275,7 @@ class EnvironmentManager {
23804
24275
  delete process.env.CLOUDBASE_ENV_ID;
23805
24276
  }
23806
24277
  // 获取环境ID的核心逻辑
23807
- async getEnvId(mcpServer) {
24278
+ async getEnvId() {
23808
24279
  // 1. 优先使用内存缓存
23809
24280
  if (this.cachedEnvId) {
23810
24281
  (0, logger_js_1.debug)('使用内存缓存的环境ID:', { envId: this.cachedEnvId });
@@ -23814,17 +24285,10 @@ class EnvironmentManager {
23814
24285
  if (this.envIdPromise) {
23815
24286
  return this.envIdPromise;
23816
24287
  }
23817
- // 3. 开始获取环境ID (pass mcpServer for IDE detection)
23818
- this.envIdPromise = this._fetchEnvId(mcpServer);
23819
- // 增加超时保护
23820
- const timeoutPromise = new Promise((_, reject) => {
23821
- const id = setTimeout(() => {
23822
- clearTimeout(id);
23823
- reject(new Error(`EnvId 获取超时(${ENV_ID_TIMEOUT / 1000}秒)`));
23824
- }, ENV_ID_TIMEOUT);
23825
- });
24288
+ // 3. 开始获取环境ID
24289
+ this.envIdPromise = this._fetchEnvId();
23826
24290
  try {
23827
- const result = await Promise.race([this.envIdPromise, timeoutPromise]);
24291
+ const result = await this.envIdPromise;
23828
24292
  return result;
23829
24293
  }
23830
24294
  catch (err) {
@@ -23832,7 +24296,7 @@ class EnvironmentManager {
23832
24296
  throw err;
23833
24297
  }
23834
24298
  }
23835
- async _fetchEnvId(mcpServer) {
24299
+ async _fetchEnvId() {
23836
24300
  try {
23837
24301
  // 1. 检查进程环境变量
23838
24302
  if (process.env.CLOUDBASE_ENV_ID) {
@@ -23840,48 +24304,23 @@ class EnvironmentManager {
23840
24304
  this.cachedEnvId = process.env.CLOUDBASE_ENV_ID;
23841
24305
  return this.cachedEnvId;
23842
24306
  }
23843
- // 2. 自动设置环境ID (pass mcpServer for IDE detection)
23844
- (0, logger_js_1.debug)('未找到环境ID,尝试自动设置...');
23845
- let setupResult;
23846
- try {
23847
- setupResult = await (0, interactive_js_1._promptAndSetEnvironmentId)(true, { server: mcpServer });
23848
- }
23849
- catch (setupError) {
23850
- // Preserve original error information
23851
- const errorObj = setupError instanceof Error ? setupError : new Error(String(setupError));
23852
- (0, logger_js_1.error)('自动设置环境ID时发生异常:', {
23853
- error: errorObj.message,
23854
- stack: errorObj.stack,
23855
- name: errorObj.name,
23856
- });
23857
- // Re-throw with enhanced context
23858
- const enhancedError = new Error(`自动设置环境ID失败: ${errorObj.message}`);
23859
- enhancedError.originalError = errorObj;
23860
- enhancedError.failureInfo = {
23861
- reason: 'unknown_error',
23862
- error: errorObj.message,
23863
- errorCode: 'SETUP_EXCEPTION',
23864
- };
23865
- throw enhancedError;
23866
- }
23867
- const autoEnvId = setupResult.selectedEnvId;
23868
- if (!autoEnvId) {
23869
- // Build detailed error message from failure info
23870
- const errorMessage = this._buildDetailedErrorMessage(setupResult.failureInfo);
23871
- (0, logger_js_1.error)('自动设置环境ID失败:', {
23872
- reason: setupResult.failureInfo?.reason,
23873
- errorCode: setupResult.failureInfo?.errorCode,
23874
- error: setupResult.failureInfo?.error,
23875
- details: setupResult.failureInfo?.details,
23876
- });
23877
- // Create error with detailed information
23878
- const detailedError = new Error(errorMessage);
23879
- detailedError.failureInfo = setupResult.failureInfo;
23880
- throw detailedError;
24307
+ // 2. 如果登录态里已有 envId,直接复用
24308
+ const loginState = await (0, auth_js_1.peekLoginState)();
24309
+ if (typeof loginState?.envId === 'string' && loginState.envId.length > 0) {
24310
+ (0, logger_js_1.debug)('使用登录态中的环境ID:', { envId: loginState.envId });
24311
+ this._setCachedEnvId(loginState.envId);
24312
+ return loginState.envId;
24313
+ }
24314
+ // 3. 单环境自动绑定;多环境时返回结构化引导,不再触发交互弹窗
24315
+ const envCandidates = await listAvailableEnvCandidates({ loginState });
24316
+ if (envCandidates.length === 1) {
24317
+ const singleEnvId = envCandidates[0].envId;
24318
+ (0, logger_js_1.debug)('自动绑定唯一环境:', { envId: singleEnvId });
24319
+ this._setCachedEnvId(singleEnvId);
24320
+ return singleEnvId;
23881
24321
  }
23882
- (0, logger_js_1.debug)('自动设置环境ID成功:', { envId: autoEnvId });
23883
- this._setCachedEnvId(autoEnvId);
23884
- return autoEnvId;
24322
+ await throwEnvRequiredError({ loginState, envCandidates });
24323
+ throw new Error('Unreachable after throwEnvRequiredError');
23885
24324
  }
23886
24325
  catch (err) {
23887
24326
  // Log the error with full context before re-throwing
@@ -23905,65 +24344,6 @@ class EnvironmentManager {
23905
24344
  process.env.CLOUDBASE_ENV_ID = envId;
23906
24345
  (0, logger_js_1.debug)('已更新环境ID缓存:', { envId });
23907
24346
  }
23908
- // Build detailed error message from failure info
23909
- _buildDetailedErrorMessage(failureInfo) {
23910
- if (!failureInfo) {
23911
- return "CloudBase Environment ID not found after auto setup. Please set CLOUDBASE_ENV_ID or run setupEnvironmentId tool.";
23912
- }
23913
- const { reason, error: errorMsg, errorCode, helpUrl, details } = failureInfo;
23914
- let message = "CloudBase Environment ID not found after auto setup.\n\n";
23915
- message += `原因: ${this._getReasonDescription(reason)}\n`;
23916
- if (errorMsg) {
23917
- message += `错误: ${errorMsg}\n`;
23918
- }
23919
- if (errorCode) {
23920
- message += `错误代码: ${errorCode}\n`;
23921
- }
23922
- // Add specific details based on failure reason
23923
- if (reason === 'tcb_init_failed' && details?.initTcbError) {
23924
- const initError = details.initTcbError;
23925
- if (initError.needRealNameAuth) {
23926
- message += "\n需要完成实名认证才能使用 CloudBase 服务。\n";
23927
- }
23928
- if (initError.needCamAuth) {
23929
- message += "\n需要 CAM 权限才能使用 CloudBase 服务。\n";
23930
- }
23931
- }
23932
- if (reason === 'env_creation_failed' && details?.createEnvError) {
23933
- const createError = details.createEnvError;
23934
- message += `\n环境创建失败: ${createError.message || '未知错误'}\n`;
23935
- }
23936
- if (reason === 'env_query_failed' && details?.queryEnvError) {
23937
- message += `\n环境查询失败: ${details.queryEnvError}\n`;
23938
- }
23939
- if (reason === 'timeout' && details?.timeoutDuration) {
23940
- message += `\n超时时间: ${details.timeoutDuration / 1000} 秒\n`;
23941
- message += "提示: 请确保浏览器窗口已打开,并在规定时间内完成环境选择。\n";
23942
- }
23943
- message += "\n解决方案:\n";
23944
- message += "1. 手动设置环境ID: 设置环境变量 CLOUDBASE_ENV_ID\n";
23945
- message += "2. 使用工具设置: 运行 setupEnvironmentId 工具\n";
23946
- if (helpUrl) {
23947
- message += `3. 查看帮助文档: ${helpUrl}\n`;
23948
- }
23949
- else {
23950
- message += "3. 查看帮助文档: https://docs.cloudbase.net/cli-v1/env\n";
23951
- }
23952
- return message;
23953
- }
23954
- _getReasonDescription(reason) {
23955
- const descriptions = {
23956
- 'timeout': '环境选择超时',
23957
- 'cancelled': '用户取消了环境选择',
23958
- 'no_environments': '没有可用环境',
23959
- 'login_failed': '登录失败',
23960
- 'tcb_init_failed': 'CloudBase 服务初始化失败',
23961
- 'env_query_failed': '环境列表查询失败',
23962
- 'env_creation_failed': '环境创建失败',
23963
- 'unknown_error': '未知错误',
23964
- };
23965
- return descriptions[reason] || '未知原因';
23966
- }
23967
24347
  // 手动设置环境ID(用于外部调用)
23968
24348
  async setEnvId(envId) {
23969
24349
  this._setCachedEnvId(envId);
@@ -23984,6 +24364,16 @@ async function getEnvId(cloudBaseOptions) {
23984
24364
  (0, logger_js_1.debug)('使用传入的 envId:', { envId: cloudBaseOptions.envId });
23985
24365
  return cloudBaseOptions.envId;
23986
24366
  }
24367
+ const cachedEnvId = envManager.getCachedEnvId() || process.env.CLOUDBASE_ENV_ID;
24368
+ if (cachedEnvId) {
24369
+ (0, logger_js_1.debug)('使用缓存中的 envId:', { envId: cachedEnvId });
24370
+ return cachedEnvId;
24371
+ }
24372
+ const loginState = await (0, auth_js_1.peekLoginState)();
24373
+ if (typeof loginState?.envId === 'string' && loginState.envId.length > 0) {
24374
+ (0, logger_js_1.debug)('使用登录态中的 envId:', { envId: loginState.envId });
24375
+ return loginState.envId;
24376
+ }
23987
24377
  // 否则使用默认逻辑
23988
24378
  return envManager.getEnvId();
23989
24379
  }
@@ -23999,37 +24389,89 @@ function getCachedEnvId() {
23999
24389
  * 每次都实时获取最新的 token/secretId/secretKey
24000
24390
  */
24001
24391
  async function getCloudBaseManager(options = {}) {
24002
- const { requireEnvId = true, cloudBaseOptions, mcpServer } = options;
24003
- // 如果传入了 cloudBaseOptions,直接使用传入的配置
24004
- if (cloudBaseOptions) {
24392
+ const { requireEnvId = true, cloudBaseOptions, authStrategy = 'fail_fast', } = options;
24393
+ const hasDirectCredentials = !!(cloudBaseOptions?.secretId && cloudBaseOptions?.secretKey);
24394
+ // 如果传入了完整凭据,优先使用显式 CloudBase 配置
24395
+ if (cloudBaseOptions && hasDirectCredentials) {
24396
+ let resolvedEnvId = cloudBaseOptions.envId;
24397
+ if (requireEnvId && !resolvedEnvId) {
24398
+ const envCandidates = await listAvailableEnvCandidates({ cloudBaseOptions });
24399
+ if (envCandidates.length === 1) {
24400
+ const singleEnvId = envCandidates[0].envId;
24401
+ cloudBaseOptions.envId = singleEnvId;
24402
+ resolvedEnvId = singleEnvId;
24403
+ (0, logger_js_1.debug)('自动绑定唯一环境(显式配置):', { envId: singleEnvId });
24404
+ }
24405
+ else if (authStrategy === 'fail_fast') {
24406
+ await throwEnvRequiredError({ cloudBaseOptions, envCandidates });
24407
+ }
24408
+ else {
24409
+ (0, tool_result_js_1.throwToolPayloadError)({
24410
+ ok: false,
24411
+ code: "ENV_REQUIRED",
24412
+ message: "当前显式 CloudBase 凭据未绑定环境,请补充 envId 或先选择环境。",
24413
+ env_candidates: envCandidates,
24414
+ next_step: (0, tool_result_js_1.buildAuthNextStep)("set_env", {
24415
+ suggestedArgs: { action: "set_env" },
24416
+ requiredParams: ["envId"],
24417
+ }),
24418
+ });
24419
+ }
24420
+ }
24005
24421
  (0, logger_js_1.debug)('使用传入的 CloudBase 配置');
24006
- return createCloudBaseManagerWithOptions(cloudBaseOptions);
24422
+ return createCloudBaseManagerWithOptions({
24423
+ ...cloudBaseOptions,
24424
+ envId: resolvedEnvId,
24425
+ });
24007
24426
  }
24008
24427
  try {
24009
24428
  // Get region from environment variable for auth URL
24010
- // Note: At this point, cloudBaseOptions is undefined (checked above), so only use env var
24011
- const region = process.env.TCB_REGION;
24012
- const loginState = await (0, auth_js_1.getLoginState)({ region });
24429
+ const region = cloudBaseOptions?.region ?? process.env.TCB_REGION;
24430
+ const loginState = authStrategy === 'ensure'
24431
+ ? await (0, auth_js_1.getLoginState)({ region })
24432
+ : await (0, auth_js_1.peekLoginState)();
24433
+ if (!loginState) {
24434
+ const authState = await (0, auth_js_1.getAuthProgressState)();
24435
+ if (authState.status === 'PENDING') {
24436
+ await throwPendingAuthError();
24437
+ }
24438
+ throwAuthRequiredError();
24439
+ }
24013
24440
  const { envId: loginEnvId, secretId, secretKey, token } = loginState;
24014
- let finalEnvId;
24441
+ let finalEnvId = cloudBaseOptions?.envId;
24015
24442
  if (requireEnvId) {
24016
- // Optimize: Check if envManager has cached envId first (fast path)
24017
- // If cached, use it directly; otherwise check loginEnvId before calling getEnvId()
24018
- // This avoids unnecessary async calls when we have a valid envId available
24019
- const cachedEnvId = envManager.getCachedEnvId();
24020
- if (cachedEnvId) {
24021
- (0, logger_js_1.debug)('使用 envManager 缓存的环境ID:', { cachedEnvId });
24022
- finalEnvId = cachedEnvId;
24023
- }
24024
- else if (loginEnvId) {
24025
- // If no cache but loginState has envId, use it to avoid triggering auto-setup
24026
- (0, logger_js_1.debug)('使用 loginState 中的环境ID:', { loginEnvId });
24027
- finalEnvId = loginEnvId;
24028
- }
24029
- else {
24030
- // Only call envManager.getEnvId() when neither cache nor loginState has envId
24031
- // This may trigger auto-setup flow (pass mcpServer for IDE detection)
24032
- finalEnvId = await envManager.getEnvId(mcpServer);
24443
+ if (!finalEnvId) {
24444
+ // Optimize: Check if envManager has cached envId first (fast path)
24445
+ // If cached, use it directly; otherwise check loginEnvId before calling getEnvId()
24446
+ // This avoids unnecessary async calls when we have a valid envId available
24447
+ const cachedEnvId = envManager.getCachedEnvId() || process.env.CLOUDBASE_ENV_ID;
24448
+ if (cachedEnvId) {
24449
+ (0, logger_js_1.debug)('使用 envManager 缓存的环境ID:', { cachedEnvId });
24450
+ finalEnvId = cachedEnvId;
24451
+ }
24452
+ else if (loginEnvId) {
24453
+ // If no cache but loginState has envId, use it directly
24454
+ (0, logger_js_1.debug)('使用 loginState 中的环境ID:', { loginEnvId });
24455
+ finalEnvId = loginEnvId;
24456
+ }
24457
+ else {
24458
+ if (authStrategy === 'fail_fast') {
24459
+ const envCandidates = await listAvailableEnvCandidates({ loginState });
24460
+ if (envCandidates.length === 1) {
24461
+ const singleEnvId = envCandidates[0].envId;
24462
+ await envManager.setEnvId(singleEnvId);
24463
+ finalEnvId = singleEnvId;
24464
+ (0, logger_js_1.debug)('自动绑定唯一环境:', { envId: singleEnvId });
24465
+ }
24466
+ else {
24467
+ await throwEnvRequiredError({ loginState, envCandidates });
24468
+ }
24469
+ }
24470
+ else {
24471
+ // ensure 模式下也保持非交互:单环境自动绑定,多环境返回 ENV_REQUIRED
24472
+ finalEnvId = await envManager.getEnvId();
24473
+ }
24474
+ }
24033
24475
  }
24034
24476
  }
24035
24477
  // envId priority: envManager.cachedEnvId > envManager.getEnvId() > loginState.envId > undefined
@@ -24267,6 +24709,7 @@ async function _promptAndSetEnvironmentId(autoSelectSingle, options) {
24267
24709
  hasServerServer: !!server?.server,
24268
24710
  hasServerIde: !!server?.ide,
24269
24711
  ignoreEnvVars: options?.ignoreEnvVars,
24712
+ authMode: options?.authMode,
24270
24713
  optionsKeys: options ? Object.keys(options).join(', ') : 'null',
24271
24714
  });
24272
24715
  if (!server) {
@@ -24283,6 +24726,9 @@ async function _promptAndSetEnvironmentId(autoSelectSingle, options) {
24283
24726
  fromCloudBaseLoginPage: options?.loginFromCloudBaseLoginPage,
24284
24727
  ignoreEnvVars: options?.ignoreEnvVars,
24285
24728
  region,
24729
+ authMode: options?.authMode,
24730
+ clientId: options?.clientId,
24731
+ onDeviceCode: options?.onDeviceCode,
24286
24732
  });
24287
24733
  (0, logger_js_1.debug)("[interactive] Login state:", {
24288
24734
  hasLoginState: !!loginState,
@@ -33910,7 +34356,13 @@ async function getUinForTelemetry() {
33910
34356
  const loginState = await (0, auth_js_1.getLoginState)({ region });
33911
34357
  // Try to extract UIN from loginState
33912
34358
  // Note: actual field name may vary, adjust based on actual response
33913
- return loginState.uin || undefined;
34359
+ if (loginState &&
34360
+ typeof loginState === "object" &&
34361
+ "uin" in loginState &&
34362
+ typeof loginState.uin !== "undefined") {
34363
+ return String(loginState.uin);
34364
+ }
34365
+ return undefined;
33914
34366
  }
33915
34367
  catch (err) {
33916
34368
  (0, logger_js_1.debug)('Failed to get UIN for telemetry', { error: err instanceof Error ? err.message : String(err) });
@@ -40675,6 +41127,61 @@ module.exports = (inputFunction, options = {}) => {
40675
41127
  };
40676
41128
 
40677
41129
 
41130
+ /***/ }),
41131
+
41132
+ /***/ 9835:
41133
+ /***/ ((__unused_webpack_module, exports) => {
41134
+
41135
+ "use strict";
41136
+
41137
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
41138
+ exports.ToolPayloadError = void 0;
41139
+ exports.buildJsonToolResult = buildJsonToolResult;
41140
+ exports.isToolPayloadError = isToolPayloadError;
41141
+ exports.toolPayloadErrorToResult = toolPayloadErrorToResult;
41142
+ exports.buildAuthNextStep = buildAuthNextStep;
41143
+ exports.throwToolPayloadError = throwToolPayloadError;
41144
+ function buildJsonToolResult(payload) {
41145
+ return {
41146
+ content: [
41147
+ {
41148
+ type: "text",
41149
+ text: JSON.stringify(payload, null, 2),
41150
+ },
41151
+ ],
41152
+ };
41153
+ }
41154
+ class ToolPayloadError extends Error {
41155
+ payload;
41156
+ constructor(payload) {
41157
+ super(typeof payload.message === "string" ? payload.message : "Tool payload error");
41158
+ this.name = "ToolPayloadError";
41159
+ this.payload = payload;
41160
+ }
41161
+ }
41162
+ exports.ToolPayloadError = ToolPayloadError;
41163
+ function isToolPayloadError(error) {
41164
+ return error instanceof ToolPayloadError;
41165
+ }
41166
+ function toolPayloadErrorToResult(error) {
41167
+ if (!isToolPayloadError(error)) {
41168
+ return null;
41169
+ }
41170
+ return buildJsonToolResult(error.payload);
41171
+ }
41172
+ function buildAuthNextStep(action, options) {
41173
+ return {
41174
+ tool: "auth",
41175
+ action,
41176
+ required_params: options?.requiredParams,
41177
+ suggested_args: options?.suggestedArgs ?? { action },
41178
+ };
41179
+ }
41180
+ function throwToolPayloadError(payload) {
41181
+ throw new ToolPayloadError(payload);
41182
+ }
41183
+
41184
+
40678
41185
  /***/ }),
40679
41186
 
40680
41187
  /***/ 9880:
@@ -83015,12 +83522,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
83015
83522
  Object.defineProperty(exports, "__esModule", ({ value: true }));
83016
83523
  exports.AuthSupevisor = exports.AuthSupervisor = void 0;
83017
83524
  const web_auth_1 = __webpack_require__(76097);
83525
+ const oauth_1 = __webpack_require__(92423);
83018
83526
  const common_1 = __webpack_require__(96711);
83019
83527
  const credential_1 = __webpack_require__(99795);
83020
83528
  const error_1 = __webpack_require__(64119);
83021
83529
  __exportStar(__webpack_require__(96711), exports);
83022
83530
  __exportStar(__webpack_require__(99795), exports);
83023
83531
  __exportStar(__webpack_require__(76097), exports);
83532
+ __exportStar(__webpack_require__(92423), exports);
83024
83533
  class AuthSupervisor {
83025
83534
  /**
83026
83535
  * 单例模式,全局缓存
@@ -83070,7 +83579,7 @@ class AuthSupervisor {
83070
83579
  */
83071
83580
  loginByWebAuth(options = {}) {
83072
83581
  return __awaiter(this, void 0, void 0, function* () {
83073
- const { getAuthUrl, throwError, noBrowser, callbackTimeout } = options;
83582
+ const { getAuthUrl, throwError, noBrowser, callbackTimeout, flow = 'device', client_id, onDeviceCode, getOAuthEndpoint, silent } = options;
83074
83583
  if (this.cacheCredential && this.needCache && !this.isCacheExpire()) {
83075
83584
  return this.cacheCredential;
83076
83585
  }
@@ -83078,12 +83587,19 @@ class AuthSupervisor {
83078
83587
  let credential = yield (0, credential_1.checkAndGetCredential)(this.requestConfig);
83079
83588
  if (credential)
83080
83589
  return credential;
83081
- // 兼容临时秘钥
83082
- credential = yield (0, web_auth_1.getAuthTokenFromWeb)({
83083
- getAuthUrl,
83084
- noBrowser,
83085
- callbackTimeout
83086
- });
83590
+ // 根据授权方式获取凭证
83591
+ if (flow === 'web') {
83592
+ credential = yield (0, web_auth_1.getAuthTokenFromWeb)({
83593
+ getAuthUrl,
83594
+ noBrowser,
83595
+ callbackTimeout,
83596
+ silent
83597
+ });
83598
+ }
83599
+ else {
83600
+ credential = yield (0, oauth_1.getAuthTokenByDeviceFlow)({ client_id, onDeviceCode, getOAuthEndpoint, getAuthUrl, silent });
83601
+ }
83602
+ credential = (0, common_1.resolveCredential)(credential);
83087
83603
  try {
83088
83604
  yield (0, common_1.checkAuth)(credential, this.requestConfig);
83089
83605
  }
@@ -85007,7 +85523,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
85007
85523
  return (mod && mod.__esModule) ? mod : { "default": mod };
85008
85524
  };
85009
85525
  Object.defineProperty(exports, "__esModule", ({ value: true }));
85010
- exports.getDataFromWeb = void 0;
85526
+ exports.getDataFromWeb = exports.openUrl = exports.isTruthyFlag = void 0;
85011
85527
  const open_1 = __importDefault(__webpack_require__(30353));
85012
85528
  const query_string_1 = __importDefault(__webpack_require__(86663));
85013
85529
  const http_1 = __importDefault(__webpack_require__(81630));
@@ -85054,6 +85570,7 @@ function isTruthyFlag(value) {
85054
85570
  }
85055
85571
  return ['1', 'true', 'yes', 'on'].includes(String(value).trim().toLowerCase());
85056
85572
  }
85573
+ exports.isTruthyFlag = isTruthyFlag;
85057
85574
  function isVSCodeEnvironment() {
85058
85575
  return Boolean(process.env.VSCODE_IPC_HOOK_CLI
85059
85576
  || process.env.VSCODE_PID
@@ -85109,19 +85626,23 @@ function openUrl(url) {
85109
85626
  }
85110
85627
  });
85111
85628
  }
85629
+ exports.openUrl = openUrl;
85112
85630
  // 从 Web 页面中获取数据
85113
85631
  function getDataFromWeb(getUrl, type, options = {}) {
85114
- var _a, _b;
85632
+ var _a, _b, _c;
85115
85633
  return __awaiter(this, void 0, void 0, function* () {
85116
85634
  const { server, port } = yield createLocalServer();
85117
85635
  const noBrowser = (_a = options.noBrowser) !== null && _a !== void 0 ? _a : isTruthyFlag(process.env.TCB_NO_BROWSER);
85118
85636
  const callbackTimeout = (_b = options.callbackTimeout) !== null && _b !== void 0 ? _b : 180000;
85637
+ const silent = (_c = options.silent) !== null && _c !== void 0 ? _c : false;
85119
85638
  if (!Number.isFinite(callbackTimeout) || callbackTimeout <= 0) {
85120
85639
  throw new error_1.CloudBaseError('callbackTimeout must be a positive number');
85121
85640
  }
85122
85641
  const url = getUrl(port);
85123
- console.log('\n\n若链接未自动打开,请手动复制至浏览器,或尝试其他登录方式:');
85124
- console.log(`\n${url}\n`);
85642
+ if (!silent) {
85643
+ console.log('\n\n若链接未自动打开,请手动复制至浏览器,或尝试其他登录方式:');
85644
+ console.log(`\n${url}\n`);
85645
+ }
85125
85646
  if (!noBrowser) {
85126
85647
  // 对 url 转码, 避免 wsl 无法正常打开地址
85127
85648
  // https://www.npmjs.com/package/open#url
@@ -86080,6 +86601,126 @@ class Profiler {
86080
86601
  module.exports = Profiler;
86081
86602
 
86082
86603
 
86604
+ /***/ }),
86605
+
86606
+ /***/ 23670:
86607
+ /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
86608
+
86609
+ /* @flow */
86610
+ /*::
86611
+
86612
+ type DotenvParseOptions = {
86613
+ debug?: boolean
86614
+ }
86615
+
86616
+ // keys and values from src
86617
+ type DotenvParseOutput = { [string]: string }
86618
+
86619
+ type DotenvConfigOptions = {
86620
+ path?: string, // path to .env file
86621
+ encoding?: string, // encoding of .env file
86622
+ debug?: string // turn on logging for debugging purposes
86623
+ }
86624
+
86625
+ type DotenvConfigOutput = {
86626
+ parsed?: DotenvParseOutput,
86627
+ error?: Error
86628
+ }
86629
+
86630
+ */
86631
+
86632
+ const fs = __webpack_require__(29021)
86633
+ const path = __webpack_require__(39902)
86634
+
86635
+ function log (message /*: string */) {
86636
+ console.log(`[dotenv][DEBUG] ${message}`)
86637
+ }
86638
+
86639
+ const NEWLINE = '\n'
86640
+ const RE_INI_KEY_VAL = /^\s*([\w.-]+)\s*=\s*(.*)?\s*$/
86641
+ const RE_NEWLINES = /\\n/g
86642
+ const NEWLINES_MATCH = /\n|\r|\r\n/
86643
+
86644
+ // Parses src into an Object
86645
+ function parse (src /*: string | Buffer */, options /*: ?DotenvParseOptions */) /*: DotenvParseOutput */ {
86646
+ const debug = Boolean(options && options.debug)
86647
+ const obj = {}
86648
+
86649
+ // convert Buffers before splitting into lines and processing
86650
+ src.toString().split(NEWLINES_MATCH).forEach(function (line, idx) {
86651
+ // matching "KEY' and 'VAL' in 'KEY=VAL'
86652
+ const keyValueArr = line.match(RE_INI_KEY_VAL)
86653
+ // matched?
86654
+ if (keyValueArr != null) {
86655
+ const key = keyValueArr[1]
86656
+ // default undefined or missing values to empty string
86657
+ let val = (keyValueArr[2] || '')
86658
+ const end = val.length - 1
86659
+ const isDoubleQuoted = val[0] === '"' && val[end] === '"'
86660
+ const isSingleQuoted = val[0] === "'" && val[end] === "'"
86661
+
86662
+ // if single or double quoted, remove quotes
86663
+ if (isSingleQuoted || isDoubleQuoted) {
86664
+ val = val.substring(1, end)
86665
+
86666
+ // if double quoted, expand newlines
86667
+ if (isDoubleQuoted) {
86668
+ val = val.replace(RE_NEWLINES, NEWLINE)
86669
+ }
86670
+ } else {
86671
+ // remove surrounding whitespace
86672
+ val = val.trim()
86673
+ }
86674
+
86675
+ obj[key] = val
86676
+ } else if (debug) {
86677
+ log(`did not match key and value when parsing line ${idx + 1}: ${line}`)
86678
+ }
86679
+ })
86680
+
86681
+ return obj
86682
+ }
86683
+
86684
+ // Populates process.env from .env file
86685
+ function config (options /*: ?DotenvConfigOptions */) /*: DotenvConfigOutput */ {
86686
+ let dotenvPath = path.resolve(process.cwd(), '.env')
86687
+ let encoding /*: string */ = 'utf8'
86688
+ let debug = false
86689
+
86690
+ if (options) {
86691
+ if (options.path != null) {
86692
+ dotenvPath = options.path
86693
+ }
86694
+ if (options.encoding != null) {
86695
+ encoding = options.encoding
86696
+ }
86697
+ if (options.debug != null) {
86698
+ debug = true
86699
+ }
86700
+ }
86701
+
86702
+ try {
86703
+ // specifying an encoding returns a string instead of a buffer
86704
+ const parsed = parse(fs.readFileSync(dotenvPath, { encoding }), { debug })
86705
+
86706
+ Object.keys(parsed).forEach(function (key) {
86707
+ if (!Object.prototype.hasOwnProperty.call(process.env, key)) {
86708
+ process.env[key] = parsed[key]
86709
+ } else if (debug) {
86710
+ log(`"${key}" is already defined in \`process.env\` and will not be overwritten`)
86711
+ }
86712
+ })
86713
+
86714
+ return { parsed }
86715
+ } catch (e) {
86716
+ return { error: e }
86717
+ }
86718
+ }
86719
+
86720
+ module.exports.config = config
86721
+ module.exports.parse = parse
86722
+
86723
+
86083
86724
  /***/ }),
86084
86725
 
86085
86726
  /***/ 23697:
@@ -89404,23 +90045,71 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
89404
90045
  return (mod && mod.__esModule) ? mod : { "default": mod };
89405
90046
  };
89406
90047
  Object.defineProperty(exports, "__esModule", ({ value: true }));
89407
- exports.TRIGGER_CONFIG_EXAMPLES = exports.SUPPORTED_TRIGGER_TYPES = exports.DEFAULT_NODEJS_RUNTIME = exports.SUPPORTED_NODEJS_RUNTIMES = void 0;
90048
+ 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;
90049
+ exports.formatRuntimeList = formatRuntimeList;
89408
90050
  exports.registerFunctionTools = registerFunctionTools;
89409
90051
  const zod_1 = __webpack_require__(21614);
89410
90052
  const cloudbase_manager_js_1 = __webpack_require__(3431);
89411
90053
  const logger_js_1 = __webpack_require__(13039);
89412
90054
  const path_1 = __importDefault(__webpack_require__(39902));
89413
- // 支持的 Node.js 运行时列表
89414
- exports.SUPPORTED_NODEJS_RUNTIMES = [
89415
- "Nodejs20.19",
89416
- "Nodejs18.15",
89417
- "Nodejs16.13",
89418
- "Nodejs14.18",
89419
- "Nodejs12.16",
89420
- "Nodejs10.15",
89421
- "Nodejs8.9",
89422
- ];
89423
- exports.DEFAULT_NODEJS_RUNTIME = "Nodejs18.15";
90055
+ // 所有支持的运行时环境(按语言分类)
90056
+ exports.SUPPORTED_RUNTIMES = {
90057
+ nodejs: [
90058
+ "Nodejs20.19",
90059
+ "Nodejs18.15",
90060
+ "Nodejs16.13",
90061
+ "Nodejs14.18",
90062
+ "Nodejs12.16",
90063
+ "Nodejs10.15",
90064
+ "Nodejs8.9",
90065
+ ],
90066
+ python: [
90067
+ "Python3.10",
90068
+ "Python3.9",
90069
+ "Python3.7",
90070
+ "Python3.6",
90071
+ "Python2.7",
90072
+ ],
90073
+ php: [
90074
+ "Php8.0",
90075
+ "Php7.4",
90076
+ "Php7.2",
90077
+ ],
90078
+ java: [
90079
+ "Java8",
90080
+ "Java11",
90081
+ ],
90082
+ golang: [
90083
+ "Golang1",
90084
+ ],
90085
+ };
90086
+ // 所有支持的运行时(扁平化数组,用于验证)
90087
+ exports.ALL_SUPPORTED_RUNTIMES = Object.values(exports.SUPPORTED_RUNTIMES).flat();
90088
+ // 默认运行时
90089
+ exports.DEFAULT_RUNTIME = "Nodejs18.15";
90090
+ // 推荐运行时(用于文档和提示)
90091
+ exports.RECOMMENDED_RUNTIMES = {
90092
+ nodejs: "Nodejs18.15",
90093
+ python: "Python3.9",
90094
+ php: "Php7.4",
90095
+ java: "Java11",
90096
+ golang: "Golang1",
90097
+ };
90098
+ // 保留向后兼容
90099
+ exports.SUPPORTED_NODEJS_RUNTIMES = exports.SUPPORTED_RUNTIMES.nodejs;
90100
+ exports.DEFAULT_NODEJS_RUNTIME = exports.DEFAULT_RUNTIME;
90101
+ /**
90102
+ * 格式化运行时列表(按语言分类)
90103
+ * 用于错误提示和用户引导
90104
+ */
90105
+ function formatRuntimeList() {
90106
+ return Object.entries(exports.SUPPORTED_RUNTIMES)
90107
+ .map(([lang, runtimes]) => {
90108
+ const capitalizedLang = lang.charAt(0).toUpperCase() + lang.slice(1);
90109
+ return ` ${capitalizedLang}: ${runtimes.join(', ')}`;
90110
+ })
90111
+ .join('\n');
90112
+ }
89424
90113
  // Supported trigger types
89425
90114
  exports.SUPPORTED_TRIGGER_TYPES = [
89426
90115
  "timer", // Timer trigger
@@ -89437,6 +90126,41 @@ exports.TRIGGER_CONFIG_EXAMPLES = {
89437
90126
  ],
89438
90127
  },
89439
90128
  };
90129
+ exports.READ_FUNCTION_LAYER_ACTIONS = [
90130
+ "listLayers",
90131
+ "listLayerVersions",
90132
+ "getLayerVersion",
90133
+ "getFunctionLayers",
90134
+ ];
90135
+ exports.WRITE_FUNCTION_LAYER_ACTIONS = [
90136
+ "createLayerVersion",
90137
+ "deleteLayerVersion",
90138
+ "attachLayer",
90139
+ "detachLayer",
90140
+ "updateFunctionLayers",
90141
+ ];
90142
+ function jsonContent(body) {
90143
+ return {
90144
+ content: [
90145
+ {
90146
+ type: "text",
90147
+ text: JSON.stringify(body, null, 2),
90148
+ },
90149
+ ],
90150
+ };
90151
+ }
90152
+ function normalizeFunctionLayers(layers) {
90153
+ if (!Array.isArray(layers)) {
90154
+ return [];
90155
+ }
90156
+ return layers
90157
+ .filter((layer) => Boolean(layer))
90158
+ .map((layer) => ({
90159
+ LayerName: String(layer.LayerName ?? ""),
90160
+ LayerVersion: Number(layer.LayerVersion ?? 0),
90161
+ }))
90162
+ .filter((layer) => Boolean(layer.LayerName) && Number.isFinite(layer.LayerVersion));
90163
+ }
89440
90164
  /**
89441
90165
  * 处理函数根目录路径,确保不包含函数名
89442
90166
  * @param functionRootPath 用户输入的路径
@@ -89464,12 +90188,12 @@ function registerFunctionTools(server) {
89464
90188
  // getFunctionList - 获取云函数列表或详情(推荐)
89465
90189
  server.registerTool?.("getFunctionList", {
89466
90190
  title: "查询云函数列表或详情",
89467
- description: "获取云函数列表或单个函数详情。通过 action 参数区分操作类型:list=获取函数列表(默认,无需额外参数),detail=获取函数详情(需要提供 name 参数指定函数名称)",
90191
+ description: "获取云函数列表或单个函数详情。通过 action 参数区分操作类型:list=获取函数列表(默认,无需额外参数),detail=获取函数详情(需要提供 name 参数指定函数名称,返回结果中包含函数当前绑定的 Layers 信息)",
89468
90192
  inputSchema: {
89469
90193
  action: zod_1.z
89470
90194
  .enum(["list", "detail"])
89471
90195
  .optional()
89472
- .describe("操作类型:list=获取函数列表(默认,无需额外参数),detail=获取函数详情(需要提供 name 参数)"),
90196
+ .describe("操作类型:list=获取函数列表(默认,无需额外参数),detail=获取函数详情(需要提供 name 参数,返回结果中包含当前绑定的 Layers)"),
89473
90197
  limit: zod_1.z.number().optional().describe("范围(list 操作时使用)"),
89474
90198
  offset: zod_1.z.number().optional().describe("偏移(list 操作时使用)"),
89475
90199
  name: zod_1.z
@@ -89523,7 +90247,11 @@ function registerFunctionTools(server) {
89523
90247
  // createFunction - 创建云函数 (cloud-incompatible)
89524
90248
  server.registerTool("createFunction", {
89525
90249
  title: "创建云函数",
89526
- description: "创建云函数。云函数分为事件型云函数和 HTTP 云函数,请确认你要创建的函数类型。",
90250
+ description: "创建云函数。云函数分为事件型云函数(Event)和 HTTP 云函数。\n\n" +
90251
+ "支持的运行时:\n" +
90252
+ "- Event 函数: Node.js, Python, PHP, Java, Go\n" +
90253
+ "- HTTP 函数: 所有语言(通过 scf_bootstrap 启动脚本)\n\n" +
90254
+ "注意: 运行时创建后不可修改,请谨慎选择。",
89527
90255
  inputSchema: {
89528
90256
  func: zod_1.z
89529
90257
  .object({
@@ -89566,8 +90294,18 @@ function registerFunctionTools(server) {
89566
90294
  runtime: zod_1.z
89567
90295
  .string()
89568
90296
  .optional()
89569
- .describe("运行时环境,建议指定为 'Nodejs18.15',其他可选值:" +
89570
- exports.SUPPORTED_NODEJS_RUNTIMES.join("")),
90297
+ .describe("运行时环境。Event 函数支持多种运行时:\n" +
90298
+ formatRuntimeList() + "\n\n" +
90299
+ "推荐运行时:\n" +
90300
+ ` Node.js: ${exports.RECOMMENDED_RUNTIMES.nodejs}\n` +
90301
+ ` Python: ${exports.RECOMMENDED_RUNTIMES.python}\n` +
90302
+ ` PHP: ${exports.RECOMMENDED_RUNTIMES.php}\n` +
90303
+ ` Java: ${exports.RECOMMENDED_RUNTIMES.java}\n` +
90304
+ ` Go: ${exports.RECOMMENDED_RUNTIMES.golang}\n\n` +
90305
+ "注意:\n" +
90306
+ "- HTTP 函数已支持所有语言(通过 scf_bootstrap 启动脚本)\n" +
90307
+ "- Node.js 函数会自动安装依赖\n" +
90308
+ "- Python/PHP/Java/Go 函数需要预先打包依赖到函数目录"),
89571
90309
  triggers: zod_1.z
89572
90310
  .array(zod_1.z.object({
89573
90311
  name: zod_1.z.string().describe("Trigger name"),
@@ -89615,12 +90353,14 @@ function registerFunctionTools(server) {
89615
90353
  if (!isHttpFunction) {
89616
90354
  // 自动填充默认 runtime
89617
90355
  if (!func.runtime) {
89618
- func.runtime = exports.DEFAULT_NODEJS_RUNTIME;
90356
+ func.runtime = exports.DEFAULT_RUNTIME;
90357
+ console.log(`未指定 runtime,使用默认值: ${exports.DEFAULT_RUNTIME}\n` +
90358
+ `可选运行时:\n${formatRuntimeList()}`);
89619
90359
  }
89620
90360
  else {
89621
90361
  // 验证 runtime 格式,防止常见的空格问题
89622
90362
  const normalizedRuntime = func.runtime.replace(/\s+/g, "");
89623
- if (exports.SUPPORTED_NODEJS_RUNTIMES.includes(normalizedRuntime)) {
90363
+ if (exports.ALL_SUPPORTED_RUNTIMES.includes(normalizedRuntime)) {
89624
90364
  func.runtime = normalizedRuntime;
89625
90365
  }
89626
90366
  else if (func.runtime.includes(" ")) {
@@ -89629,8 +90369,13 @@ function registerFunctionTools(server) {
89629
90369
  }
89630
90370
  }
89631
90371
  // 验证 runtime 是否有效
89632
- if (!exports.SUPPORTED_NODEJS_RUNTIMES.includes(func.runtime)) {
89633
- throw new Error(`不支持的运行时环境: "${func.runtime}"。支持的值:${exports.SUPPORTED_NODEJS_RUNTIMES.join(", ")}`);
90372
+ if (!exports.ALL_SUPPORTED_RUNTIMES.includes(func.runtime)) {
90373
+ throw new Error(`不支持的运行时环境: "${func.runtime}"\n\n` +
90374
+ `支持的运行时:\n${formatRuntimeList()}\n\n` +
90375
+ `提示:\n` +
90376
+ `- Node.js 函数会自动安装依赖\n` +
90377
+ `- Python/PHP/Java/Go 函数需要预先打包依赖到函数目录\n` +
90378
+ `- 详细信息请参考文档: https://docs.cloudbase.net/api-reference/manager/node/function#createfunction`);
89634
90379
  }
89635
90380
  }
89636
90381
  // 强制设置 installDependency 为 true(不暴露给AI)
@@ -89983,6 +90728,379 @@ function registerFunctionTools(server) {
89983
90728
  throw new Error(`不支持的操作类型: ${action}`);
89984
90729
  }
89985
90730
  });
90731
+ server.registerTool?.("readFunctionLayers", {
90732
+ title: "查询云函数层信息",
90733
+ description: "查询云函数层及函数层配置。通过 action 区分操作:listLayers=查询层列表,listLayerVersions=查询指定层的版本列表,getLayerVersion=查询层版本详情(含下载地址/元信息),getFunctionLayers=查询指定函数当前绑定的层。返回格式:JSON 包含 success、data(含 action 与对应结果字段)、message;data.layers 或 data.layerVersions 为数组,getFunctionLayers 的 data.layers 每项为 { LayerName, LayerVersion }。",
90734
+ inputSchema: {
90735
+ action: zod_1.z
90736
+ .enum(exports.READ_FUNCTION_LAYER_ACTIONS)
90737
+ .describe("操作类型:listLayers=查询层列表,listLayerVersions=查询指定层的版本列表,getLayerVersion=查询层版本详情,getFunctionLayers=查询指定函数当前绑定的层"),
90738
+ name: zod_1.z
90739
+ .string()
90740
+ .optional()
90741
+ .describe("层名称。listLayerVersions 和 getLayerVersion 操作时必填"),
90742
+ version: zod_1.z
90743
+ .number()
90744
+ .optional()
90745
+ .describe("层版本号。getLayerVersion 操作时必填"),
90746
+ runtime: zod_1.z
90747
+ .string()
90748
+ .optional()
90749
+ .describe("运行时筛选。listLayers 操作时可选"),
90750
+ searchKey: zod_1.z
90751
+ .string()
90752
+ .optional()
90753
+ .describe("层名称搜索关键字。listLayers 操作时可选"),
90754
+ offset: zod_1.z.number().optional().describe("分页偏移。listLayers 操作时可选"),
90755
+ limit: zod_1.z.number().optional().describe("分页数量。listLayers 操作时可选"),
90756
+ functionName: zod_1.z
90757
+ .string()
90758
+ .optional()
90759
+ .describe("函数名称。getFunctionLayers 操作时必填"),
90760
+ codeSecret: zod_1.z
90761
+ .string()
90762
+ .optional()
90763
+ .describe("代码保护密钥。getFunctionLayers 操作时可选"),
90764
+ },
90765
+ annotations: {
90766
+ readOnlyHint: true,
90767
+ openWorldHint: true,
90768
+ category: "functions",
90769
+ },
90770
+ }, async ({ action, name, version, runtime, searchKey, offset, limit, functionName, codeSecret, }) => {
90771
+ if (action === "listLayers") {
90772
+ const cloudbase = await getManager();
90773
+ const result = await cloudbase.functions.listLayers({
90774
+ offset,
90775
+ limit,
90776
+ runtime,
90777
+ searchKey,
90778
+ });
90779
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
90780
+ return jsonContent({
90781
+ success: true,
90782
+ data: {
90783
+ action,
90784
+ layers: result.Layers || [],
90785
+ totalCount: result.TotalCount || 0,
90786
+ requestId: result.RequestId,
90787
+ },
90788
+ message: `Successfully retrieved ${result.Layers?.length || 0} layer entries`,
90789
+ nextActions: [
90790
+ { tool: "readFunctionLayers", action: "listLayerVersions", reason: "List versions of a layer" },
90791
+ { tool: "writeFunctionLayers", action: "createLayerVersion", reason: "Create a new layer version" },
90792
+ ],
90793
+ });
90794
+ }
90795
+ if (action === "listLayerVersions") {
90796
+ if (!name) {
90797
+ throw new Error("查询层版本列表时,name 参数是必需的");
90798
+ }
90799
+ const cloudbase = await getManager();
90800
+ const result = await cloudbase.functions.listLayerVersions({ name });
90801
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
90802
+ return jsonContent({
90803
+ success: true,
90804
+ data: {
90805
+ action,
90806
+ name,
90807
+ layerVersions: result.LayerVersions || [],
90808
+ requestId: result.RequestId,
90809
+ },
90810
+ message: `Successfully retrieved ${result.LayerVersions?.length || 0} versions for layer '${name}'`,
90811
+ nextActions: [
90812
+ { tool: "readFunctionLayers", action: "getLayerVersion", reason: "Get version details and download info" },
90813
+ { tool: "writeFunctionLayers", action: "attachLayer", reason: "Bind this layer to a function" },
90814
+ ],
90815
+ });
90816
+ }
90817
+ if (action === "getLayerVersion") {
90818
+ if (!name) {
90819
+ throw new Error("查询层版本详情时,name 参数是必需的");
90820
+ }
90821
+ if (typeof version !== "number") {
90822
+ throw new Error("查询层版本详情时,version 参数是必需的");
90823
+ }
90824
+ const cloudbase = await getManager();
90825
+ const result = await cloudbase.functions.getLayerVersion({
90826
+ name,
90827
+ version,
90828
+ });
90829
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
90830
+ return jsonContent({
90831
+ success: true,
90832
+ data: {
90833
+ action,
90834
+ name,
90835
+ version,
90836
+ layerVersion: result,
90837
+ downloadInfo: {
90838
+ location: result.Location,
90839
+ codeSha256: result.CodeSha256,
90840
+ },
90841
+ requestId: result.RequestId,
90842
+ },
90843
+ message: `Successfully retrieved details for layer '${name}' version ${version}`,
90844
+ nextActions: [
90845
+ { tool: "writeFunctionLayers", action: "attachLayer", reason: "Bind this layer version to a function" },
90846
+ { tool: "writeFunctionLayers", action: "deleteLayerVersion", reason: "Delete this layer version" },
90847
+ ],
90848
+ });
90849
+ }
90850
+ if (!functionName) {
90851
+ throw new Error("查询函数层配置时,functionName 参数是必需的");
90852
+ }
90853
+ const cloudbase = await getManager();
90854
+ const result = await cloudbase.functions.getFunctionDetail(functionName, codeSecret);
90855
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
90856
+ const layers = normalizeFunctionLayers(result.Layers);
90857
+ return jsonContent({
90858
+ success: true,
90859
+ data: {
90860
+ action,
90861
+ functionName,
90862
+ layers,
90863
+ count: layers.length,
90864
+ requestId: result.RequestId,
90865
+ },
90866
+ message: `Successfully retrieved ${layers.length} bound layers for function '${functionName}'`,
90867
+ nextActions: [
90868
+ { tool: "writeFunctionLayers", action: "attachLayer", reason: "Add a layer to this function" },
90869
+ { tool: "writeFunctionLayers", action: "detachLayer", reason: "Remove a layer from this function" },
90870
+ { tool: "writeFunctionLayers", action: "updateFunctionLayers", reason: "Replace or reorder bound layers" },
90871
+ ],
90872
+ });
90873
+ });
90874
+ server.registerTool?.("writeFunctionLayers", {
90875
+ title: "管理云函数层",
90876
+ description: "管理云函数层和函数层绑定。通过 action 区分操作:createLayerVersion=创建层版本,deleteLayerVersion=删除层版本,attachLayer=给函数追加绑定层,detachLayer=解绑函数层,updateFunctionLayers=整体更新函数层数组以调整顺序或批量更新。返回格式:JSON 包含 success、data(含 action 与结果字段,如 layerVersion、layers)、message、nextActions(建议的后续操作)。",
90877
+ inputSchema: {
90878
+ action: zod_1.z
90879
+ .enum(exports.WRITE_FUNCTION_LAYER_ACTIONS)
90880
+ .describe("操作类型:createLayerVersion=创建层版本,deleteLayerVersion=删除层版本,attachLayer=追加绑定层,detachLayer=解绑层,updateFunctionLayers=整体更新函数层数组"),
90881
+ name: zod_1.z
90882
+ .string()
90883
+ .optional()
90884
+ .describe("层名称。createLayerVersion 和 deleteLayerVersion 操作时必填"),
90885
+ version: zod_1.z
90886
+ .number()
90887
+ .optional()
90888
+ .describe("层版本号。deleteLayerVersion 操作时必填"),
90889
+ contentPath: zod_1.z
90890
+ .string()
90891
+ .optional()
90892
+ .describe("层内容路径,可以是目录或 ZIP 文件路径。createLayerVersion 操作时与 base64Content 二选一"),
90893
+ base64Content: zod_1.z
90894
+ .string()
90895
+ .optional()
90896
+ .describe("层内容的 base64 编码。createLayerVersion 操作时与 contentPath 二选一"),
90897
+ runtimes: zod_1.z
90898
+ .array(zod_1.z.string())
90899
+ .optional()
90900
+ .describe("层适用的运行时列表。createLayerVersion 操作时必填"),
90901
+ description: zod_1.z
90902
+ .string()
90903
+ .optional()
90904
+ .describe("层版本描述。createLayerVersion 操作时可选"),
90905
+ licenseInfo: zod_1.z
90906
+ .string()
90907
+ .optional()
90908
+ .describe("许可证信息。createLayerVersion 操作时可选"),
90909
+ functionName: zod_1.z
90910
+ .string()
90911
+ .optional()
90912
+ .describe("函数名称。attachLayer、detachLayer、updateFunctionLayers 操作时必填"),
90913
+ layerName: zod_1.z
90914
+ .string()
90915
+ .optional()
90916
+ .describe("要绑定或解绑的层名称。attachLayer 和 detachLayer 操作时必填"),
90917
+ layerVersion: zod_1.z
90918
+ .number()
90919
+ .optional()
90920
+ .describe("要绑定或解绑的层版本号。attachLayer 和 detachLayer 操作时必填"),
90921
+ layers: zod_1.z
90922
+ .array(zod_1.z.object({
90923
+ LayerName: zod_1.z.string().describe("层名称"),
90924
+ LayerVersion: zod_1.z.number().describe("层版本号"),
90925
+ }))
90926
+ .optional()
90927
+ .describe("目标函数层数组。updateFunctionLayers 操作时必填,顺序即最终顺序"),
90928
+ codeSecret: zod_1.z
90929
+ .string()
90930
+ .optional()
90931
+ .describe("代码保护密钥。attachLayer 和 detachLayer 操作时可选"),
90932
+ },
90933
+ annotations: {
90934
+ readOnlyHint: false,
90935
+ destructiveHint: true,
90936
+ idempotentHint: false,
90937
+ openWorldHint: true,
90938
+ category: "functions",
90939
+ },
90940
+ }, async ({ action, name, version, contentPath, base64Content, runtimes, description, licenseInfo, functionName, layerName, layerVersion, layers, codeSecret, }) => {
90941
+ if (action === "createLayerVersion") {
90942
+ if (!name) {
90943
+ throw new Error("创建层版本时,name 参数是必需的");
90944
+ }
90945
+ if (!runtimes || runtimes.length === 0) {
90946
+ throw new Error("创建层版本时,runtimes 参数是必需的");
90947
+ }
90948
+ if (!contentPath && !base64Content) {
90949
+ throw new Error("创建层版本时,contentPath 和 base64Content 至少需要提供一个");
90950
+ }
90951
+ const cloudbase = await getManager();
90952
+ const result = await cloudbase.functions.createLayer({
90953
+ name,
90954
+ contentPath,
90955
+ base64Content,
90956
+ runtimes,
90957
+ description,
90958
+ licenseInfo,
90959
+ });
90960
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
90961
+ return jsonContent({
90962
+ success: true,
90963
+ data: {
90964
+ action,
90965
+ name,
90966
+ layerVersion: result.LayerVersion,
90967
+ requestId: result.RequestId,
90968
+ },
90969
+ message: `Successfully created a new version for layer '${name}'`,
90970
+ nextActions: [
90971
+ { tool: "readFunctionLayers", action: "listLayerVersions", reason: "List all versions of this layer" },
90972
+ { tool: "writeFunctionLayers", action: "attachLayer", reason: "Bind this version to a function" },
90973
+ ],
90974
+ });
90975
+ }
90976
+ if (action === "deleteLayerVersion") {
90977
+ if (!name) {
90978
+ throw new Error("删除层版本时,name 参数是必需的");
90979
+ }
90980
+ if (typeof version !== "number") {
90981
+ throw new Error("删除层版本时,version 参数是必需的");
90982
+ }
90983
+ const cloudbase = await getManager();
90984
+ const result = await cloudbase.functions.deleteLayerVersion({
90985
+ name,
90986
+ version,
90987
+ });
90988
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
90989
+ return jsonContent({
90990
+ success: true,
90991
+ data: {
90992
+ action,
90993
+ name,
90994
+ version,
90995
+ requestId: result.RequestId,
90996
+ },
90997
+ message: `Successfully deleted layer '${name}' version ${version}`,
90998
+ nextActions: [
90999
+ { tool: "readFunctionLayers", action: "listLayers", reason: "List remaining layers" },
91000
+ ],
91001
+ });
91002
+ }
91003
+ if (action === "attachLayer" ||
91004
+ action === "detachLayer" ||
91005
+ action === "updateFunctionLayers") {
91006
+ if (!functionName) {
91007
+ throw new Error(`${action} 操作时,functionName 参数是必需的`);
91008
+ }
91009
+ }
91010
+ const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
91011
+ const cloudbase = await getManager();
91012
+ if (action === "attachLayer") {
91013
+ if (!layerName) {
91014
+ throw new Error("attachLayer 操作时,layerName 参数是必需的");
91015
+ }
91016
+ if (typeof layerVersion !== "number") {
91017
+ throw new Error("attachLayer 操作时,layerVersion 参数是必需的");
91018
+ }
91019
+ const result = await cloudbase.functions.attachLayer({
91020
+ envId,
91021
+ functionName: functionName,
91022
+ layerName,
91023
+ layerVersion,
91024
+ codeSecret,
91025
+ });
91026
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
91027
+ const detail = await cloudbase.functions.getFunctionDetail(functionName, codeSecret);
91028
+ const boundLayers = normalizeFunctionLayers(detail.Layers);
91029
+ return jsonContent({
91030
+ success: true,
91031
+ data: {
91032
+ action,
91033
+ functionName,
91034
+ layers: boundLayers,
91035
+ requestId: result.RequestId,
91036
+ },
91037
+ message: `Successfully attached layer '${layerName}' version ${layerVersion} to function '${functionName}'`,
91038
+ nextActions: [
91039
+ { tool: "readFunctionLayers", action: "getFunctionLayers", reason: "Verify bound layers" },
91040
+ { tool: "writeFunctionLayers", action: "detachLayer", reason: "Remove this layer from function" },
91041
+ ],
91042
+ });
91043
+ }
91044
+ if (action === "detachLayer") {
91045
+ if (!layerName) {
91046
+ throw new Error("detachLayer 操作时,layerName 参数是必需的");
91047
+ }
91048
+ if (typeof layerVersion !== "number") {
91049
+ throw new Error("detachLayer 操作时,layerVersion 参数是必需的");
91050
+ }
91051
+ const result = await cloudbase.functions.unAttachLayer({
91052
+ envId,
91053
+ functionName: functionName,
91054
+ layerName,
91055
+ layerVersion,
91056
+ codeSecret,
91057
+ });
91058
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
91059
+ const detail = await cloudbase.functions.getFunctionDetail(functionName, codeSecret);
91060
+ const boundLayers = normalizeFunctionLayers(detail.Layers);
91061
+ return jsonContent({
91062
+ success: true,
91063
+ data: {
91064
+ action,
91065
+ functionName,
91066
+ layers: boundLayers,
91067
+ requestId: result.RequestId,
91068
+ },
91069
+ message: `Successfully detached layer '${layerName}' version ${layerVersion} from function '${functionName}'`,
91070
+ nextActions: [
91071
+ { tool: "readFunctionLayers", action: "getFunctionLayers", reason: "Verify current bound layers" },
91072
+ ],
91073
+ });
91074
+ }
91075
+ if (!layers || layers.length === 0) {
91076
+ throw new Error("updateFunctionLayers 操作时,layers 参数是必需的");
91077
+ }
91078
+ const normalizedLayers = normalizeFunctionLayers(layers);
91079
+ if (normalizedLayers.length === 0) {
91080
+ throw new Error("updateFunctionLayers 操作时,layers 参数必须包含有效的 LayerName 和 LayerVersion");
91081
+ }
91082
+ const result = await cloudbase.functions.updateFunctionLayer({
91083
+ envId,
91084
+ functionName: functionName,
91085
+ layers: normalizedLayers,
91086
+ });
91087
+ (0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
91088
+ const detail = await cloudbase.functions.getFunctionDetail(functionName);
91089
+ const boundLayers = normalizeFunctionLayers(detail.Layers);
91090
+ return jsonContent({
91091
+ success: true,
91092
+ data: {
91093
+ action,
91094
+ functionName,
91095
+ layers: boundLayers,
91096
+ requestId: result.RequestId,
91097
+ },
91098
+ message: `Successfully updated bound layers for function '${functionName}'`,
91099
+ nextActions: [
91100
+ { tool: "readFunctionLayers", action: "getFunctionLayers", reason: "Verify updated layer order" },
91101
+ ],
91102
+ });
91103
+ });
89986
91104
  // // Layer相关功能
89987
91105
  // // createLayer - 创建Layer
89988
91106
  // server.tool(
@@ -102898,6 +104016,7 @@ const security_rule_js_1 = __webpack_require__(7862);
102898
104016
  const cloud_mode_js_1 = __webpack_require__(89684);
102899
104017
  const logger_js_1 = __webpack_require__(13039);
102900
104018
  const tencet_cloud_js_1 = __webpack_require__(95018);
104019
+ const tool_result_js_1 = __webpack_require__(9835);
102901
104020
  const tool_wrapper_js_1 = __webpack_require__(71363);
102902
104021
  // 默认插件列表
102903
104022
  const DEFAULT_PLUGINS = [
@@ -103012,6 +104131,18 @@ async function createCloudBaseMcpServer(options) {
103012
104131
  ...(ide === "CodeBuddy" ? { logging: {} } : {}),
103013
104132
  },
103014
104133
  });
104134
+ const originalRegisterTool = server.registerTool.bind(server);
104135
+ server.registerTool = ((name, meta, handler) => originalRegisterTool(name, meta, async (args) => {
104136
+ try {
104137
+ return await handler(args);
104138
+ }
104139
+ catch (error) {
104140
+ if ((0, tool_result_js_1.isToolPayloadError)(error)) {
104141
+ return (0, tool_result_js_1.buildJsonToolResult)(error.payload);
104142
+ }
104143
+ throw error;
104144
+ }
104145
+ }));
103015
104146
  // Only set logging handler if logging capability is declared
103016
104147
  if (ide === "CodeBuddy") {
103017
104148
  server.server.setRequestHandler(types_js_1.SetLevelRequestSchema, (request, extra) => {
@@ -117418,10 +118549,10 @@ function registerHostingTools(server) {
117418
118549
  // uploadFiles - 上传文件到静态网站托管 (cloud-incompatible)
117419
118550
  server.registerTool("uploadFiles", {
117420
118551
  title: "上传静态文件",
117421
- description: "上传文件到静态网站托管",
118552
+ description: "上传文件到静态网站托管。部署前请先完成构建;如果站点会部署到子路径,请检查构建配置中的 publicPath、base、assetPrefix 等是否使用相对路径,避免静态资源加载失败。",
117422
118553
  inputSchema: {
117423
- localPath: zod_1.z.string().optional().describe("本地文件或文件夹路径,需要是绝对路径,例如 /tmp/files/data.txt"),
117424
- cloudPath: zod_1.z.string().optional().describe("云端文件或文件夹路径,例如files/data.txt"),
118554
+ localPath: zod_1.z.string().optional().describe("本地文件或文件夹路径,需要是绝对路径,例如 /tmp/files/data.txt"),
118555
+ cloudPath: zod_1.z.string().optional().describe("云端文件或文件夹路径,例如 files/data.txt。若部署到子路径,请同时检查构建配置中的 publicPath、base、assetPrefix 等是否为相对路径。"),
117425
118556
  files: zod_1.z.array(zod_1.z.object({
117426
118557
  localPath: zod_1.z.string(),
117427
118558
  cloudPath: zod_1.z.string()
@@ -125911,7 +127042,20 @@ function registerCapiTools(server) {
125911
127042
  throw new Error(`${service}/${action} Cloud API is not exposed or does not exist. Please use another API.`);
125912
127043
  }
125913
127044
  if (service === 'tcb') {
125914
- const tcbCapiForbidList = ['DescribeStorageACL', 'ModifyStorageACL', 'DescribeSecurityRule'];
127045
+ const tcbCapiForbidList = [
127046
+ // 未明确对外的云API
127047
+ 'DescribeStorageACL', 'ModifyStorageACL', 'DescribeSecurityRule',
127048
+ // 要下线的云API
127049
+ "ListTables",
127050
+ "DescribeCloudBaseGWAPI",
127051
+ "DescribeCloudBaseGWService",
127052
+ "CreateCloudBaseGWAPI",
127053
+ "DeleteCloudBaseGWAPI",
127054
+ "ModifyCloudBaseGWAPI",
127055
+ "DeleteCloudBaseGWDomain",
127056
+ "BindCloudBaseGWDomain",
127057
+ "BindCloudBaseAccessDomain"
127058
+ ];
125915
127059
  if (tcbCapiForbidList.includes(action)) {
125916
127060
  throw new Error(`${service}/${action} Cloud API is not exposed or does not exist. Please use another API.`);
125917
127061
  }
@@ -137522,7 +138666,7 @@ class TelemetryReporter {
137522
138666
  const nodeVersion = process.version; // Node.js版本
137523
138667
  const arch = os_1.default.arch(); // 系统架构
137524
138668
  // 从构建时注入的版本号获取MCP版本信息
137525
- const mcpVersion = process.env.npm_package_version || "2.13.0" || 0;
138669
+ const mcpVersion = process.env.npm_package_version || "2.14.2" || 0;
137526
138670
  return {
137527
138671
  userAgent: `${osType} ${osRelease} ${arch} ${nodeVersion} CloudBase-MCP/${mcpVersion}`,
137528
138672
  deviceId: this.deviceId,
@@ -155634,7 +156778,7 @@ const fs_1 = __importDefault(__webpack_require__(29021));
155634
156778
  const lodash_1 = __importDefault(__webpack_require__(2543));
155635
156779
  const path_1 = __importDefault(__webpack_require__(39902));
155636
156780
  const yargs_1 = __importDefault(__webpack_require__(5945));
155637
- const dotenv_1 = __importDefault(__webpack_require__(80998));
156781
+ const dotenv_1 = __importDefault(__webpack_require__(23670));
155638
156782
  exports.dotenv = dotenv_1.default;
155639
156783
  function readFile(target) {
155640
156784
  try {
@@ -189017,6 +190161,15 @@ async function registerRagTools(server) {
189017
190161
  ],
189018
190162
  };
189019
190163
  }
190164
+ // 向量检索模式下必须提供 id 和 content,避免后端报「知识库名称不能为空」
190165
+ if (mode === "vector") {
190166
+ if (!id) {
190167
+ throw new Error("知识库名称不能为空: please provide `id` when mode=vector (cloudbase / scf / miniprogram).");
190168
+ }
190169
+ if (!content || !content.trim()) {
190170
+ throw new Error("检索内容不能为空: please provide non-empty `content` when mode=vector.");
190171
+ }
190172
+ }
189020
190173
  // 枚举到后端 id 映射
189021
190174
  const backendId = KnowledgeBaseIdMap[id] || id;
189022
190175
  const signInRes = await fetch("https://tcb-advanced-a656fc.api.tcloudbasegateway.com/auth/v1/signin/anonymously", {
@@ -204174,6 +205327,7 @@ const cloudbase_manager_js_1 = __webpack_require__(3431);
204174
205327
  const cloud_mode_js_1 = __webpack_require__(89684);
204175
205328
  const logger_js_1 = __webpack_require__(13039);
204176
205329
  const telemetry_js_1 = __webpack_require__(45880);
205330
+ const tool_result_js_1 = __webpack_require__(9835);
204177
205331
  /**
204178
205332
  * 生成 GitHub Issue 创建链接
204179
205333
  * @param toolName 工具名称
@@ -204221,7 +205375,7 @@ ${envIdSection}
204221
205375
  ## 环境信息
204222
205376
  - 操作系统: ${os_1.default.type()} ${os_1.default.release()}
204223
205377
  - Node.js版本: ${process.version}
204224
- - MCP 版本:${process.env.npm_package_version || "2.13.0" || 0}
205378
+ - MCP 版本:${process.env.npm_package_version || "2.14.2" || 0}
204225
205379
  - 系统架构: ${os_1.default.arch()}
204226
205380
  - 时间: ${new Date().toISOString()}
204227
205381
  - 请求ID: ${requestId}
@@ -204286,6 +205440,11 @@ function createWrappedHandler(name, handler, server) {
204286
205440
  if (!isTestEnvironment) {
204287
205441
  server.logger?.({ type: 'errorToolCall', toolName: name, args: sanitizeArgs(args), message: errorMessage, duration: Date.now() - startTime });
204288
205442
  }
205443
+ // Preserve structured tool guidance such as next_step.
205444
+ // These errors are expected control flow and should be serialized by the outer server wrapper.
205445
+ if ((0, tool_result_js_1.isToolPayloadError)(error)) {
205446
+ throw error;
205447
+ }
204289
205448
  // In tests, avoid any extra work that may block (envId lookup, issue link generation, etc.)
204290
205449
  if (isTestEnvironment) {
204291
205450
  throw error instanceof Error ? error : new Error(String(error));
@@ -218105,16 +219264,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
218105
219264
  });
218106
219265
  };
218107
219266
  Object.defineProperty(exports, "__esModule", ({ value: true }));
218108
- exports.getAuthTokenFromWeb = void 0;
219267
+ exports.getAuthTokenFromWeb = exports.CLI_AUTH_BASE_URL = void 0;
218109
219268
  const common_1 = __webpack_require__(96711);
218110
219269
  const coding_1 = __webpack_require__(40540);
218111
219270
  const web_1 = __webpack_require__(2240);
218112
219271
  const system_1 = __webpack_require__(62179);
218113
- const CliAuthBaseUrl = 'https://tcb.cloud.tencent.com/dev';
219272
+ exports.CLI_AUTH_BASE_URL = 'https://tcb.cloud.tencent.com/dev';
218114
219273
  // 打开云开发控制台,获取授权
218115
219274
  function getAuthTokenFromWeb(options = {}) {
218116
219275
  return __awaiter(this, void 0, void 0, function* () {
218117
- const { getAuthUrl, noBrowser, callbackTimeout } = options;
219276
+ const { getAuthUrl, noBrowser, callbackTimeout, silent } = options;
218118
219277
  const mac = yield (0, system_1.getMacAddress)();
218119
219278
  const os = (0, system_1.getOSInfo)();
218120
219279
  const macHash = (0, coding_1.md5Encoding)(mac);
@@ -218127,7 +219286,7 @@ function getAuthTokenFromWeb(options = {}) {
218127
219286
  + '&from=cli';
218128
219287
  const encodedCallbackUrl = encodeURIComponent(callbackUrl);
218129
219288
  // 授权链接
218130
- const rawAuthUrl = `${CliAuthBaseUrl}?authCallbackUrl=${encodedCallbackUrl}#/cli-auth?${encodedQuery}`;
219289
+ const rawAuthUrl = `${exports.CLI_AUTH_BASE_URL}?authCallbackUrl=${encodedCallbackUrl}#/cli-auth?${encodedQuery}`;
218131
219290
  let cliAuthUrl = rawAuthUrl;
218132
219291
  if (getAuthUrl) {
218133
219292
  try {
@@ -218140,7 +219299,8 @@ function getAuthTokenFromWeb(options = {}) {
218140
219299
  return cliAuthUrl;
218141
219300
  }, 'login', {
218142
219301
  noBrowser,
218143
- callbackTimeout
219302
+ callbackTimeout,
219303
+ silent
218144
219304
  });
218145
219305
  const credential = (0, common_1.resolveCredential)(query);
218146
219306
  return credential;
@@ -218723,6 +219883,7 @@ const INTEGRATION_IDE_MAPPING = {
218723
219883
  CodeBuddy: "codebuddy",
218724
219884
  CodeBuddyManual: "codebuddy",
218725
219885
  CodeBuddyCode: "codebuddy",
219886
+ CodeBuddyPlugin: "codebuddy",
218726
219887
  "Claude Code": "claude-code",
218727
219888
  CLINE: "cline",
218728
219889
  "Gemini CLI": "gemini-cli",
@@ -218981,7 +220142,7 @@ function registerSetupTools(server) {
218981
220142
  title: "下载项目模板",
218982
220143
  description: `自动下载并部署CloudBase项目模板。⚠️ **MANDATORY FOR NEW PROJECTS** ⚠️
218983
220144
 
218984
- **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.13.0" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
220145
+ **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)`,
218985
220146
  inputSchema: {
218986
220147
  template: zod_1.z
218987
220148
  .enum(["react", "vue", "miniprogram", "uniapp", "rules"])
@@ -220273,56 +221434,181 @@ module.exports.sync = path => {
220273
221434
  "use strict";
220274
221435
 
220275
221436
  Object.defineProperty(exports, "__esModule", ({ value: true }));
221437
+ exports.getAuthProgressStateSync = getAuthProgressStateSync;
221438
+ exports.getAuthProgressState = getAuthProgressState;
221439
+ exports.setPendingAuthProgressState = setPendingAuthProgressState;
221440
+ exports.resolveAuthProgressState = resolveAuthProgressState;
221441
+ exports.rejectAuthProgressState = rejectAuthProgressState;
221442
+ exports.resetAuthProgressState = resetAuthProgressState;
221443
+ exports.peekLoginState = peekLoginState;
221444
+ exports.ensureLogin = ensureLogin;
220276
221445
  exports.getLoginState = getLoginState;
220277
221446
  exports.logout = logout;
220278
221447
  const toolbox_1 = __webpack_require__(25901);
220279
221448
  const logger_js_1 = __webpack_require__(13039);
220280
221449
  const tencet_cloud_js_1 = __webpack_require__(95018);
220281
- const auth = toolbox_1.AuthSupevisor.getInstance({});
220282
- async function getLoginState(options) {
221450
+ const auth = toolbox_1.AuthSupervisor.getInstance({});
221451
+ const authProgressState = {
221452
+ status: "IDLE",
221453
+ updatedAt: Date.now(),
221454
+ };
221455
+ function updateAuthProgressState(partial) {
221456
+ Object.assign(authProgressState, partial, {
221457
+ updatedAt: Date.now(),
221458
+ });
221459
+ return getAuthProgressStateSync();
221460
+ }
221461
+ function normalizeLoginStateFromEnvVars(options) {
220283
221462
  const { TENCENTCLOUD_SECRETID, TENCENTCLOUD_SECRETKEY, TENCENTCLOUD_SESSIONTOKEN, } = process.env;
220284
- (0, logger_js_1.debug)("TENCENTCLOUD_SECRETID", { secretId: TENCENTCLOUD_SECRETID });
220285
- // If ignoreEnvVars is true (e.g., when switching account), skip environment variables
220286
- // and force Web authentication to allow account switching
220287
221463
  if (!options?.ignoreEnvVars && TENCENTCLOUD_SECRETID && TENCENTCLOUD_SECRETKEY) {
220288
- (0, logger_js_1.debug)("loginByApiSecret");
220289
221464
  return {
220290
221465
  secretId: TENCENTCLOUD_SECRETID,
220291
221466
  secretKey: TENCENTCLOUD_SECRETKEY,
220292
221467
  token: TENCENTCLOUD_SESSIONTOKEN,
221468
+ envId: process.env.CLOUDBASE_ENV_ID,
220293
221469
  };
220294
- // await auth.loginByApiSecret(TENCENTCLOUD_SECRETID, TENCENTCLOUD_SECRETKEY, TENCENTCLOUD_SESSIONTOKEN)
220295
221470
  }
220296
- const loginState = await auth.getLoginState();
221471
+ return null;
221472
+ }
221473
+ function mapAuthErrorStatus(error) {
221474
+ const message = error instanceof Error ? error.message : String(error ?? "");
221475
+ if (message.includes("拒绝") || message.includes("denied")) {
221476
+ return "DENIED";
221477
+ }
221478
+ if (message.includes("过期") || message.includes("expired")) {
221479
+ return "EXPIRED";
221480
+ }
221481
+ return "ERROR";
221482
+ }
221483
+ function getAuthProgressStateSync() {
221484
+ return {
221485
+ ...authProgressState,
221486
+ authChallenge: authProgressState.authChallenge
221487
+ ? { ...authProgressState.authChallenge }
221488
+ : undefined,
221489
+ };
221490
+ }
221491
+ async function getAuthProgressState() {
221492
+ const loginState = await peekLoginState();
221493
+ if (loginState && authProgressState.status === "PENDING") {
221494
+ updateAuthProgressState({
221495
+ status: "READY",
221496
+ lastError: undefined,
221497
+ });
221498
+ }
221499
+ if (authProgressState.status === "PENDING" &&
221500
+ authProgressState.authChallenge?.expires_in) {
221501
+ const issuedAt = authProgressState.updatedAt;
221502
+ const expiresAt = issuedAt + authProgressState.authChallenge.expires_in * 1000;
221503
+ if (Date.now() > expiresAt) {
221504
+ updateAuthProgressState({
221505
+ status: "EXPIRED",
221506
+ lastError: "设备码已过期,请重新发起授权",
221507
+ });
221508
+ }
221509
+ }
221510
+ return getAuthProgressStateSync();
221511
+ }
221512
+ function setPendingAuthProgressState(challenge, authMode = "device") {
221513
+ return updateAuthProgressState({
221514
+ status: "PENDING",
221515
+ authMode,
221516
+ authChallenge: challenge,
221517
+ lastError: undefined,
221518
+ });
221519
+ }
221520
+ function resolveAuthProgressState() {
221521
+ return updateAuthProgressState({
221522
+ status: "READY",
221523
+ lastError: undefined,
221524
+ });
221525
+ }
221526
+ function rejectAuthProgressState(error) {
221527
+ const message = error instanceof Error ? error.message : String(error ?? "unknown error");
221528
+ return updateAuthProgressState({
221529
+ status: mapAuthErrorStatus(error),
221530
+ lastError: message,
221531
+ });
221532
+ }
221533
+ function resetAuthProgressState() {
221534
+ return updateAuthProgressState({
221535
+ status: "IDLE",
221536
+ authMode: undefined,
221537
+ authChallenge: undefined,
221538
+ lastError: undefined,
221539
+ });
221540
+ }
221541
+ async function peekLoginState(options) {
221542
+ const envVarLoginState = normalizeLoginStateFromEnvVars(options);
221543
+ if (envVarLoginState) {
221544
+ (0, logger_js_1.debug)("loginByApiSecret");
221545
+ return envVarLoginState;
221546
+ }
221547
+ return auth.getLoginState();
221548
+ }
221549
+ async function ensureLogin(options) {
221550
+ (0, logger_js_1.debug)("TENCENTCLOUD_SECRETID", { secretId: process.env.TENCENTCLOUD_SECRETID });
221551
+ const loginState = await peekLoginState({
221552
+ ignoreEnvVars: options?.ignoreEnvVars,
221553
+ });
220297
221554
  if (!loginState) {
220298
- await auth.loginByWebAuth((options?.fromCloudBaseLoginPage && !(0, tencet_cloud_js_1.isInternationalRegion)(options?.region))
220299
- ? {
220300
- getAuthUrl: (url) => {
220301
- // 国际站
220302
- const separator = url.includes('?') ? '&' : '?';
220303
- const urlWithParam = `${url}${separator}allowNoEnv=true`;
220304
- return `https://tcb.cloud.tencent.com/login?_redirect_uri=${encodeURIComponent(urlWithParam)}`;
220305
- },
220306
- }
220307
- : {
220308
- getAuthUrl: (url) => {
220309
- if ((0, tencet_cloud_js_1.isInternationalRegion)(options?.region)) {
220310
- url = url.replace('cloud.tencent.com', 'tencentcloud.com');
221555
+ const envMode = process.env.TCB_AUTH_MODE;
221556
+ const normalizedEnvMode = envMode === "web" || envMode === "device" ? envMode : undefined;
221557
+ const mode = options?.authMode || normalizedEnvMode || "device";
221558
+ const loginOptions = { flow: mode };
221559
+ if (mode === "web") {
221560
+ loginOptions.getAuthUrl =
221561
+ options?.fromCloudBaseLoginPage && !(0, tencet_cloud_js_1.isInternationalRegion)(options?.region)
221562
+ ? (url) => {
221563
+ const separator = url.includes("?") ? "&" : "?";
221564
+ const urlWithParam = `${url}${separator}allowNoEnv=true`;
221565
+ return `https://tcb.cloud.tencent.com/login?_redirect_uri=${encodeURIComponent(urlWithParam)}`;
220311
221566
  }
220312
- const separator = url.includes('?') ? '&' : '?';
220313
- return `${url}${separator}allowNoEnv=true`;
220314
- },
220315
- });
220316
- const loginState = await auth.getLoginState();
220317
- (0, logger_js_1.debug)("loginByWebAuth", loginState);
221567
+ : (url) => {
221568
+ if ((0, tencet_cloud_js_1.isInternationalRegion)(options?.region)) {
221569
+ url = url.replace("cloud.tencent.com", "tencentcloud.com");
221570
+ }
221571
+ const separator = url.includes("?") ? "&" : "?";
221572
+ return `${url}${separator}allowNoEnv=true`;
221573
+ };
221574
+ }
221575
+ else {
221576
+ if (options?.clientId) {
221577
+ loginOptions.client_id = options.clientId;
221578
+ }
221579
+ if (options?.onDeviceCode) {
221580
+ loginOptions.onDeviceCode = (info) => {
221581
+ setPendingAuthProgressState(info, mode);
221582
+ options.onDeviceCode?.(info);
221583
+ };
221584
+ }
221585
+ }
221586
+ (0, logger_js_1.debug)("beforeloginByWebAuth", { loginOptions });
221587
+ try {
221588
+ await auth.loginByWebAuth(loginOptions);
221589
+ resolveAuthProgressState();
221590
+ }
221591
+ catch (error) {
221592
+ rejectAuthProgressState(error);
221593
+ throw error;
221594
+ }
221595
+ const loginState = await peekLoginState({
221596
+ ignoreEnvVars: options?.ignoreEnvVars,
221597
+ });
221598
+ (0, logger_js_1.debug)("loginByWebAuth", { mode, hasLoginState: !!loginState });
220318
221599
  return loginState;
220319
221600
  }
220320
221601
  else {
221602
+ resolveAuthProgressState();
220321
221603
  return loginState;
220322
221604
  }
220323
221605
  }
221606
+ async function getLoginState(options) {
221607
+ return ensureLogin(options);
221608
+ }
220324
221609
  async function logout() {
220325
221610
  const result = await auth.logout();
221611
+ resetAuthProgressState();
220326
221612
  return result;
220327
221613
  }
220328
221614
 
@@ -221426,7 +222712,7 @@ function tryStat(path) {
221426
222712
  "use strict";
221427
222713
 
221428
222714
  Object.defineProperty(exports, "__esModule", ({ value: true }));
221429
- exports.RAW_IDE_FILE_MAPPINGS = exports.simplifyEnvList = exports.envManager = exports.createCloudBaseManagerWithOptions = exports.resetCloudBaseManagerCache = exports.getEnvId = exports.getCloudBaseManager = exports.shouldRegisterTool = exports.getCloudModeStatus = exports.enableCloudMode = exports.isCloudMode = exports.logout = exports.getLoginState = exports.warn = exports.error = exports.info = exports.reportToolCall = exports.reportToolkitLifecycle = exports.telemetryReporter = exports.StdioServerTransport = exports.getDefaultServer = exports.createCloudBaseMcpServer = void 0;
222715
+ exports.DEFAULT_NODEJS_RUNTIME = exports.SUPPORTED_NODEJS_RUNTIMES = exports.formatRuntimeList = exports.RECOMMENDED_RUNTIMES = exports.DEFAULT_RUNTIME = exports.ALL_SUPPORTED_RUNTIMES = exports.SUPPORTED_RUNTIMES = exports.RAW_IDE_FILE_MAPPINGS = exports.simplifyEnvList = exports.envManager = exports.createCloudBaseManagerWithOptions = exports.resetCloudBaseManagerCache = exports.getEnvId = exports.getCloudBaseManager = exports.shouldRegisterTool = exports.getCloudModeStatus = exports.enableCloudMode = exports.isCloudMode = exports.logout = exports.getLoginState = exports.warn = exports.error = exports.info = exports.reportToolCall = exports.reportToolkitLifecycle = exports.telemetryReporter = exports.StdioServerTransport = exports.getDefaultServer = exports.createCloudBaseMcpServer = void 0;
221430
222716
  exports.getInteractiveServerAsync = getInteractiveServerAsync;
221431
222717
  // CloudBase MCP Server Library
221432
222718
  var server_js_1 = __webpack_require__(31422);
@@ -221457,6 +222743,15 @@ var env_js_1 = __webpack_require__(622);
221457
222743
  Object.defineProperty(exports, "simplifyEnvList", ({ enumerable: true, get: function () { return env_js_1.simplifyEnvList; } }));
221458
222744
  var setup_js_1 = __webpack_require__(76556);
221459
222745
  Object.defineProperty(exports, "RAW_IDE_FILE_MAPPINGS", ({ enumerable: true, get: function () { return setup_js_1.RAW_IDE_FILE_MAPPINGS; } }));
222746
+ // Export runtime constants for multi-language support
222747
+ var functions_js_1 = __webpack_require__(25936);
222748
+ Object.defineProperty(exports, "SUPPORTED_RUNTIMES", ({ enumerable: true, get: function () { return functions_js_1.SUPPORTED_RUNTIMES; } }));
222749
+ Object.defineProperty(exports, "ALL_SUPPORTED_RUNTIMES", ({ enumerable: true, get: function () { return functions_js_1.ALL_SUPPORTED_RUNTIMES; } }));
222750
+ Object.defineProperty(exports, "DEFAULT_RUNTIME", ({ enumerable: true, get: function () { return functions_js_1.DEFAULT_RUNTIME; } }));
222751
+ Object.defineProperty(exports, "RECOMMENDED_RUNTIMES", ({ enumerable: true, get: function () { return functions_js_1.RECOMMENDED_RUNTIMES; } }));
222752
+ Object.defineProperty(exports, "formatRuntimeList", ({ enumerable: true, get: function () { return functions_js_1.formatRuntimeList; } }));
222753
+ Object.defineProperty(exports, "SUPPORTED_NODEJS_RUNTIMES", ({ enumerable: true, get: function () { return functions_js_1.SUPPORTED_NODEJS_RUNTIMES; } }));
222754
+ Object.defineProperty(exports, "DEFAULT_NODEJS_RUNTIME", ({ enumerable: true, get: function () { return functions_js_1.DEFAULT_NODEJS_RUNTIME; } }));
221460
222755
  /**
221461
222756
  * Get interactive server instance (CommonJS compatible)
221462
222757
  */
@@ -229855,126 +231150,6 @@ function onError(sender, err, cb) {
229855
231150
  }
229856
231151
 
229857
231152
 
229858
- /***/ }),
229859
-
229860
- /***/ 80998:
229861
- /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
229862
-
229863
- /* @flow */
229864
- /*::
229865
-
229866
- type DotenvParseOptions = {
229867
- debug?: boolean
229868
- }
229869
-
229870
- // keys and values from src
229871
- type DotenvParseOutput = { [string]: string }
229872
-
229873
- type DotenvConfigOptions = {
229874
- path?: string, // path to .env file
229875
- encoding?: string, // encoding of .env file
229876
- debug?: string // turn on logging for debugging purposes
229877
- }
229878
-
229879
- type DotenvConfigOutput = {
229880
- parsed?: DotenvParseOutput,
229881
- error?: Error
229882
- }
229883
-
229884
- */
229885
-
229886
- const fs = __webpack_require__(29021)
229887
- const path = __webpack_require__(39902)
229888
-
229889
- function log (message /*: string */) {
229890
- console.log(`[dotenv][DEBUG] ${message}`)
229891
- }
229892
-
229893
- const NEWLINE = '\n'
229894
- const RE_INI_KEY_VAL = /^\s*([\w.-]+)\s*=\s*(.*)?\s*$/
229895
- const RE_NEWLINES = /\\n/g
229896
- const NEWLINES_MATCH = /\n|\r|\r\n/
229897
-
229898
- // Parses src into an Object
229899
- function parse (src /*: string | Buffer */, options /*: ?DotenvParseOptions */) /*: DotenvParseOutput */ {
229900
- const debug = Boolean(options && options.debug)
229901
- const obj = {}
229902
-
229903
- // convert Buffers before splitting into lines and processing
229904
- src.toString().split(NEWLINES_MATCH).forEach(function (line, idx) {
229905
- // matching "KEY' and 'VAL' in 'KEY=VAL'
229906
- const keyValueArr = line.match(RE_INI_KEY_VAL)
229907
- // matched?
229908
- if (keyValueArr != null) {
229909
- const key = keyValueArr[1]
229910
- // default undefined or missing values to empty string
229911
- let val = (keyValueArr[2] || '')
229912
- const end = val.length - 1
229913
- const isDoubleQuoted = val[0] === '"' && val[end] === '"'
229914
- const isSingleQuoted = val[0] === "'" && val[end] === "'"
229915
-
229916
- // if single or double quoted, remove quotes
229917
- if (isSingleQuoted || isDoubleQuoted) {
229918
- val = val.substring(1, end)
229919
-
229920
- // if double quoted, expand newlines
229921
- if (isDoubleQuoted) {
229922
- val = val.replace(RE_NEWLINES, NEWLINE)
229923
- }
229924
- } else {
229925
- // remove surrounding whitespace
229926
- val = val.trim()
229927
- }
229928
-
229929
- obj[key] = val
229930
- } else if (debug) {
229931
- log(`did not match key and value when parsing line ${idx + 1}: ${line}`)
229932
- }
229933
- })
229934
-
229935
- return obj
229936
- }
229937
-
229938
- // Populates process.env from .env file
229939
- function config (options /*: ?DotenvConfigOptions */) /*: DotenvConfigOutput */ {
229940
- let dotenvPath = path.resolve(process.cwd(), '.env')
229941
- let encoding /*: string */ = 'utf8'
229942
- let debug = false
229943
-
229944
- if (options) {
229945
- if (options.path != null) {
229946
- dotenvPath = options.path
229947
- }
229948
- if (options.encoding != null) {
229949
- encoding = options.encoding
229950
- }
229951
- if (options.debug != null) {
229952
- debug = true
229953
- }
229954
- }
229955
-
229956
- try {
229957
- // specifying an encoding returns a string instead of a buffer
229958
- const parsed = parse(fs.readFileSync(dotenvPath, { encoding }), { debug })
229959
-
229960
- Object.keys(parsed).forEach(function (key) {
229961
- if (!Object.prototype.hasOwnProperty.call(process.env, key)) {
229962
- process.env[key] = parsed[key]
229963
- } else if (debug) {
229964
- log(`"${key}" is already defined in \`process.env\` and will not be overwritten`)
229965
- }
229966
- })
229967
-
229968
- return { parsed }
229969
- } catch (e) {
229970
- return { error: e }
229971
- }
229972
- }
229973
-
229974
- module.exports.config = config
229975
- module.exports.parse = parse
229976
-
229977
-
229978
231153
  /***/ }),
229979
231154
 
229980
231155
  /***/ 81115:
@@ -247320,8 +248495,7 @@ function shouldRegisterTool(toolName) {
247320
248495
  // Cloud-incompatible tools that involve local file operations
247321
248496
  const cloudIncompatibleTools = [
247322
248497
  // Auth tools - local file uploads
247323
- 'login',
247324
- 'logout',
248498
+ 'auth',
247325
248499
  // Storage tools - local file uploads
247326
248500
  'uploadFile',
247327
248501
  // Hosting tools - local file uploads
@@ -259864,6 +261038,141 @@ async function getInteractiveServerSafe(mcpServer) {
259864
261038
  }
259865
261039
 
259866
261040
 
261041
+ /***/ }),
261042
+
261043
+ /***/ 92423:
261044
+ /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
261045
+
261046
+ "use strict";
261047
+
261048
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
261049
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
261050
+ return new (P || (P = Promise))(function (resolve, reject) {
261051
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
261052
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
261053
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
261054
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
261055
+ });
261056
+ };
261057
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
261058
+ exports.getAuthTokenByDeviceFlow = void 0;
261059
+ const net_1 = __webpack_require__(31153);
261060
+ const web_1 = __webpack_require__(2240);
261061
+ const error_1 = __webpack_require__(64119);
261062
+ const coding_1 = __webpack_require__(40540);
261063
+ const system_1 = __webpack_require__(62179);
261064
+ const web_auth_1 = __webpack_require__(76097);
261065
+ /** 默认国内站 应用侧可通过 getOAuthEndpoint 覆写 */
261066
+ const OAUTH_ENDPOINT = process.env.TCB_OAUTH_ENDPOINT || 'https://tcb-api.cloud.tencent.com/qcloud-tcb/v1/oauth';
261067
+ const DEFAULT_CLIENT_ID = 'cloudbase-toolbox';
261068
+ const POLL_ERROR_CODES = {
261069
+ AUTHORIZATION_PENDING: 'authorization_pending',
261070
+ SLOW_DOWN: 'slow_down',
261071
+ EXPIRED_TOKEN: 'expired_token',
261072
+ ACCESS_DENIED: 'access_denied',
261073
+ };
261074
+ const SUCCESS_CODE = 'NORMAL';
261075
+ function fetchDeviceCode(options = {}) {
261076
+ const { client_id = DEFAULT_CLIENT_ID, endpoint = OAUTH_ENDPOINT } = options;
261077
+ return (0, net_1.postFetch)(`${endpoint}/device/code`, { client_id });
261078
+ }
261079
+ function fetchPollToken(options) {
261080
+ return __awaiter(this, void 0, void 0, function* () {
261081
+ const { device_code, client_id = DEFAULT_CLIENT_ID, endpoint = OAUTH_ENDPOINT } = options;
261082
+ const mac = yield (0, system_1.getMacAddress)();
261083
+ return (0, net_1.postFetch)(`${endpoint}/token`, {
261084
+ device_code,
261085
+ client_id,
261086
+ grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
261087
+ device_info: {
261088
+ mac,
261089
+ os: (0, system_1.getOSInfo)(),
261090
+ hash: (0, coding_1.md5Encoding)(mac),
261091
+ }
261092
+ });
261093
+ });
261094
+ }
261095
+ function sleep(ms) {
261096
+ return new Promise((resolve) => {
261097
+ setTimeout(resolve, ms);
261098
+ });
261099
+ }
261100
+ function getAuthTokenByDeviceFlow(options = {}) {
261101
+ return __awaiter(this, void 0, void 0, function* () {
261102
+ const { client_id, onDeviceCode, getOAuthEndpoint, getAuthUrl, silent } = options;
261103
+ const endpoint = getOAuthEndpoint ? getOAuthEndpoint(OAUTH_ENDPOINT) : OAUTH_ENDPOINT;
261104
+ const deviceCodeResp = yield fetchDeviceCode({ client_id, endpoint });
261105
+ if (deviceCodeResp.code !== SUCCESS_CODE) {
261106
+ throw new error_1.CloudBaseError('Device Flow fetchDeviceCode failed', {
261107
+ code: deviceCodeResp.code,
261108
+ requestId: deviceCodeResp.reqId,
261109
+ });
261110
+ }
261111
+ const { device_code, user_code, expires_in, interval } = deviceCodeResp.result;
261112
+ // 暂时不消费 verification_uri,由客户端控制跳转
261113
+ const defaultVerificationUri = `${web_auth_1.CLI_AUTH_BASE_URL}#/cli-auth`;
261114
+ // from=cli 后续考虑改用 client_id,因为 toolbox 作为公共依赖,可能被不同 client 所引用
261115
+ const rawVerificationUri = `${defaultVerificationUri}?user_code=${user_code}&from=cli&flow=device`;
261116
+ const verification_uri = getAuthUrl ? getAuthUrl(rawVerificationUri) : rawVerificationUri;
261117
+ if (!silent) {
261118
+ // 打印授权信息,引导用户操作
261119
+ console.log('\n\n若链接未自动打开,请手动复制至浏览器,或尝试其他登录方式:');
261120
+ console.log(`\n${verification_uri}`);
261121
+ console.log(`\n用户码: ${user_code}\n`);
261122
+ }
261123
+ // 尝试自动打开授权页面
261124
+ yield (0, web_1.openUrl)(verification_uri);
261125
+ if (onDeviceCode) {
261126
+ onDeviceCode({ user_code, verification_uri, device_code, expires_in });
261127
+ }
261128
+ let pollInterval = interval;
261129
+ const deadline = Date.now() + expires_in * 1000;
261130
+ while (Date.now() < deadline) {
261131
+ yield sleep(pollInterval * 1000);
261132
+ let resp;
261133
+ try {
261134
+ resp = yield fetchPollToken({ device_code, interval: pollInterval, client_id, endpoint });
261135
+ }
261136
+ catch (e) {
261137
+ throw new error_1.CloudBaseError('Device Flow 轮询请求失败', { original: e });
261138
+ }
261139
+ const { code, result } = resp;
261140
+ // 服务端返回业务错误(result 中携带 error 字段)
261141
+ if (result && 'error' in result) {
261142
+ const { error, error_description } = result;
261143
+ if (error === POLL_ERROR_CODES.AUTHORIZATION_PENDING) {
261144
+ continue;
261145
+ }
261146
+ if (error === POLL_ERROR_CODES.SLOW_DOWN) {
261147
+ pollInterval += 5;
261148
+ continue;
261149
+ }
261150
+ if (error === POLL_ERROR_CODES.EXPIRED_TOKEN) {
261151
+ throw new error_1.CloudBaseError('设备码已过期,请重新发起授权');
261152
+ }
261153
+ if (error === POLL_ERROR_CODES.ACCESS_DENIED) {
261154
+ throw new error_1.CloudBaseError('用户拒绝了授权请求');
261155
+ }
261156
+ throw new error_1.CloudBaseError(error_description || `Device Flow 授权失败,错误: ${error}`, {
261157
+ code: error,
261158
+ requestId: resp.reqId,
261159
+ });
261160
+ }
261161
+ // 服务端返回成功的 Credential
261162
+ if (code === SUCCESS_CODE && result) {
261163
+ return result;
261164
+ }
261165
+ throw new error_1.CloudBaseError(`Device Flow 授权失败,错误码: ${code}`, {
261166
+ code,
261167
+ requestId: resp.reqId,
261168
+ });
261169
+ }
261170
+ throw new error_1.CloudBaseError('授权超时,用户未在有效期内完成授权,请重试');
261171
+ });
261172
+ }
261173
+ exports.getAuthTokenByDeviceFlow = getAuthTokenByDeviceFlow;
261174
+
261175
+
259867
261176
  /***/ }),
259868
261177
 
259869
261178
  /***/ 92472: