@cloudbase/cloudbase-mcp 2.34.5 → 2.34.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli.cjs +1 -1
- package/dist/index.cjs +1874 -114
- package/dist/index.js +1888 -116
- package/package.json +1 -1
- package/server.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -199407,6 +199407,7 @@ exports.getLoginState = getLoginState;
|
|
|
199407
199407
|
exports.logout = logout;
|
|
199408
199408
|
const toolbox_1 = __webpack_require__(23233);
|
|
199409
199409
|
const logger_js_1 = __webpack_require__(40781);
|
|
199410
|
+
const project_config_js_1 = __webpack_require__(39175);
|
|
199410
199411
|
const site_map_js_1 = __webpack_require__(34533);
|
|
199411
199412
|
const auth = toolbox_1.AuthSupervisor.getInstance({});
|
|
199412
199413
|
const authProgressState = {
|
|
@@ -199811,8 +199812,7 @@ async function peekLoginState(options) {
|
|
|
199811
199812
|
if ('_type' in envVarLoginState && envVarLoginState._type === 'api_key') {
|
|
199812
199813
|
(0, logger_js_1.debug)("peekLoginState: detected CLOUDBASE_API_KEY env var");
|
|
199813
199814
|
try {
|
|
199814
|
-
|
|
199815
|
-
const projectCwd = process.env.WORKSPACE_FOLDER_PATHS || process.cwd();
|
|
199815
|
+
const projectCwd = (0, project_config_js_1.requireProjectRoot)();
|
|
199816
199816
|
// 换取网关按站点选型:显式 intl → ap-singapore;domestic/歧义 → toolbox 默认
|
|
199817
199817
|
// ap-shanghai(国内站多地域环境均经其全局路由,详见 resolveApiKeyExchangeRegion)
|
|
199818
199818
|
const exchangeRegion = (0, site_map_js_1.resolveApiKeyExchangeRegion)({
|
|
@@ -199969,7 +199969,7 @@ async function logout(options) {
|
|
|
199969
199969
|
await toolbox_1.authStore.set("credential", slotted);
|
|
199970
199970
|
}
|
|
199971
199971
|
else if (site === LEGACY_SITE) {
|
|
199972
|
-
const cwd =
|
|
199972
|
+
const cwd = (0, project_config_js_1.requireProjectRoot)();
|
|
199973
199973
|
await auth.logout({ cwd });
|
|
199974
199974
|
}
|
|
199975
199975
|
resetAuthProgressState();
|
|
@@ -200364,6 +200364,14 @@ class EnvironmentManager {
|
|
|
200364
200364
|
this._setCachedEnvId(loginState.envId);
|
|
200365
200365
|
return loginState.envId;
|
|
200366
200366
|
}
|
|
200367
|
+
// 3.1 未登录必须交回 AUTH_REQUIRED,不能继续往下走「选环境」。
|
|
200368
|
+
// 未登录时拿不到任何环境候选,落到 throwEnvRequiredError 会输出
|
|
200369
|
+
// 「当前已登录,但还没有可用环境」——把「没登录」误诊成「登录了但缺环境」。
|
|
200370
|
+
// 调用方读到这句会去 set_env 选环境,而候选列表永远为空,只能原样重试。
|
|
200371
|
+
// 与 getCloudBaseManager 的登录态分流保持同构。
|
|
200372
|
+
if (!loginState) {
|
|
200373
|
+
throwAuthRequiredError();
|
|
200374
|
+
}
|
|
200367
200375
|
// 4. 单环境自动绑定;多环境时返回结构化引导,不再触发交互弹窗
|
|
200368
200376
|
const envCandidates = await listAvailableEnvCandidates({ loginState });
|
|
200369
200377
|
if (envCandidates.length === 1) {
|
|
@@ -201626,6 +201634,7 @@ const msgPush_js_1 = __webpack_require__(26191);
|
|
|
201626
201634
|
const setup_js_1 = __webpack_require__(8707);
|
|
201627
201635
|
const envSetup_js_1 = __webpack_require__(57148);
|
|
201628
201636
|
const interactive_js_1 = __webpack_require__(91838);
|
|
201637
|
+
const feedback_js_1 = __webpack_require__(99391);
|
|
201629
201638
|
exports.en = {
|
|
201630
201639
|
env: env_js_1.env.en,
|
|
201631
201640
|
storage: storage_js_1.storage.en,
|
|
@@ -201655,6 +201664,7 @@ exports.en = {
|
|
|
201655
201664
|
setup: setup_js_1.setup.en,
|
|
201656
201665
|
envSetup: envSetup_js_1.envSetup.en,
|
|
201657
201666
|
interactive: interactive_js_1.interactive.en,
|
|
201667
|
+
feedback: feedback_js_1.feedback.en,
|
|
201658
201668
|
};
|
|
201659
201669
|
|
|
201660
201670
|
|
|
@@ -202008,7 +202018,7 @@ exports.capi = (0, types_js_1.defineModule)({
|
|
|
202008
202018
|
docGuidanceCloudbase: "优先查阅 CloudBase API 概览 {controlPlaneUrl} 与云开发依赖资源接口指引 {dependencyUrl}。",
|
|
202009
202019
|
docGuidanceMonitor: "请优先核对云监控(腾讯云可观测平台)官方 API 文档:API 概览 https://cloud.tencent.com/document/product/649/30343 ,单 Action 详细文档在 https://cloud.tencent.com/document/api/248/ 产品线下。",
|
|
202010
202020
|
docGuidanceGeneric: "请优先核对对应官方云 API 文档;若你的场景其实是通过 HTTP 协议直接集成 auth/functions/cloudrun/storage/mysqldb 等 CloudBase 业务 API,请优先使用 OpenAPI / Swagger 或 searchKnowledgeBase(mode=\"openapi\"),不要继续猜测管控面 Action。",
|
|
202011
|
-
camAuthGuidance: "
|
|
202021
|
+
camAuthGuidance: "这是 CAM 权限不足。先分清是谁缺权限,再决定怎么补:用 auth(action=\"status\") 看 credential_scope,用 callCloudApi(service=\"sts\", action=\"GetCallerIdentity\") 看实际调用者(Type=CAMRole 表示角色扮演身份,UserId 里带角色名)。若缺权限的是角色(如 TCB_QcsRole),补的是挂在**角色**上的策略 —— 给用户一条 cam/role/grant 一键授权链接,拼法与 principal 取值见 skill cloud-api-operations 的 §3.2;若是账号级身份本人,则由主账号给这个身份追加策略(用腾讯云 SecretId/SecretKey 登录时,调用者就是该身份)。环境级 API Key 只能访问绑定环境的数据面,跨产品调用需改用账号级凭据:auth(action=\"start_auth\", authMode=\"device\")。另请确认目标资源确实属于当前账号。",
|
|
202012
202022
|
errorInvalidAction: "Action `{action}` 可能不存在或不对外开放。请不要继续猜测 Action 名称,先确认 service=`{service}` 下该 Action 在当前 API 版本是否真实存在。",
|
|
202013
202023
|
errorSuggestedActions: "可能的 tcb Action:{candidates}。",
|
|
202014
202024
|
errorRegionParam: "Region 不是 Action body 参数。请使用 callCloudApi 顶层参数 region(例如 region=\"ap-singapore\"),对应 X-TC-Region。",
|
|
@@ -202042,7 +202052,7 @@ exports.capi = (0, types_js_1.defineModule)({
|
|
|
202042
202052
|
docGuidanceCloudbase: "Prefer the CloudBase API overview {controlPlaneUrl} and the dependent-resource API guide {dependencyUrl}.",
|
|
202043
202053
|
docGuidanceMonitor: "Check the official Cloud Monitor (Tencent Cloud Observability Platform) API docs first: API overview https://cloud.tencent.com/document/product/649/30343 , per-Action docs live under https://cloud.tencent.com/document/api/248/ .",
|
|
202044
202054
|
docGuidanceGeneric: "Check the corresponding official cloud API docs first; if your scenario is actually integrating CloudBase business APIs such as auth/functions/cloudrun/storage/mysqldb over HTTP, prefer OpenAPI / Swagger or searchKnowledgeBase(mode=\"openapi\") instead of guessing control-plane Actions.",
|
|
202045
|
-
camAuthGuidance: "This is
|
|
202055
|
+
camAuthGuidance: "This is a CAM permission gap. Work out who is missing it before choosing a fix: auth(action=\"status\") shows credential_scope, and callCloudApi(service=\"sts\", action=\"GetCallerIdentity\") shows the actual caller (Type=CAMRole means an assumed role; the UserId carries the role name). When the role is the one missing permission (e.g. TCB_QcsRole), the fix is a policy attached to that role — give the user a cam/role/grant authorization link, built as described in the cloud-api-operations skill, section 3.2. When an account-level identity is the caller, the main account attaches the policy to it (signing in with a Tencent Cloud SecretId/SecretKey makes the caller that identity). An environment-level API Key can only reach the bound environment's data plane; for cross-product calls switch to account-level credentials: auth(action=\"start_auth\", authMode=\"device\"). Also confirm the target resource belongs to the current account.",
|
|
202046
202056
|
errorInvalidAction: "Action `{action}` may not exist or is not publicly available. Do not keep guessing Action names; first confirm the Action actually exists under service=`{service}` in the current API version.",
|
|
202047
202057
|
errorSuggestedActions: "Possible tcb Actions: {candidates}.",
|
|
202048
202058
|
errorRegionParam: "Region is not an Action body parameter. Use the callCloudApi top-level region parameter (e.g. region=\"ap-singapore\"), which maps to X-TC-Region.",
|
|
@@ -202086,7 +202096,7 @@ exports.cloudrun = (0, types_js_1.defineModule)({
|
|
|
202086
202096
|
"manage.description": "管理云托管服务,按开发顺序支持:开通云托管环境(initEnv)、初始化项目(可从模板开始,模板列表可通过 queryCloudRun 查询)、下载服务代码、本地运行(仅函数型服务)、部署代码、仅更新配置(updateConfig,无需重新上传代码)、删除服务。deploy 支持两种方式:1) 源码构建(传入 targetPath,本地代码打包上传,默认路径);2) 已有镜像部署(传入 imageUrl,如 ccr.ccs.tencentyun.com/ns/img:v1,走 DeployType=image 容器型部署,targetPath 可省略)。deploy 语义为「触发部署 + 轻量等待任务注册」(最多约 45s;不需要 buildId 时可传 waitRegistration=false 跳过等待)。源码构建返回 buildId,用 getDeployLog 轮询构建进度后再 getProcessLog;镜像部署(imageUrl)BuildId 常为 0,跳过 getDeployLog,返回 runId/next_step 引导 getProcessLog(或先 getDeployRecords 取 RunId)。若用户明确指定镜像或无需重新构建,必须传 imageUrl,不要仅因本地有源码目录就回退到源码构建。deploy 对已存在服务会先读取远程配置再合并(保留 VpcConf/EnvParams/OpenAccessTypes)。updateConfig 对齐控制台服务设置页。删除操作需要确认,建议设置force=true。新环境首次部署前若提示未开通云托管,先调用 initEnv 开通(异步、幂等)。",
|
|
202087
202097
|
"error.managerInitFailed": "CloudBase Manager 初始化失败,请检查凭据与环境配置。",
|
|
202088
202098
|
"error.unsupportedAction": "不支持的操作:{action}",
|
|
202089
|
-
"error.pathOutsideCwd": "路径必须在当前工作目录内:{cwd}",
|
|
202099
|
+
"error.pathOutsideCwd": "路径必须在当前工作目录内:{cwd}。允许:`{cwd}` 下的路径,或传入项目目录的绝对路径(相对路径不能通过 `../` 逃逸 CWD)。收到的解析路径:{resolvedPath}。建议:将 targetPath 设为项目绝对路径(deploy/download/init)。",
|
|
202090
202100
|
"error.commonServiceQueryEnv": "当前 CloudBase Manager 不支持 commonService,无法查询云托管环境开通状态。",
|
|
202091
202101
|
"error.commonServiceInitEnv": "当前 CloudBase Manager 不支持 commonService,无法初始化云托管环境。",
|
|
202092
202102
|
"error.commonServiceSubmitDiff": "当前 CloudBase Manager 不支持 commonService,无法调用 SubmitServerConfigChangeDiff。",
|
|
@@ -202276,7 +202286,7 @@ exports.cloudrun = (0, types_js_1.defineModule)({
|
|
|
202276
202286
|
"manage.description": "Manage CloudRun services, in development order: provision the CloudRun env (initEnv), initialize a project (optionally from a template; list templates via queryCloudRun), download service code, run locally (function services only), deploy code, update config only (updateConfig, no code upload needed), and delete the service. deploy supports two modes: 1) source build (pass targetPath; local code is packaged and uploaded, the default); 2) existing image deploy (pass imageUrl, e.g. ccr.ccs.tencentyun.com/ns/img:v1; DeployType=image container deploy, targetPath optional). deploy means \"trigger deploy + lightweight wait for task registration\" (up to ~45s; pass waitRegistration=false to skip the wait when you don't need the buildId). Source builds return buildId — poll getDeployLog for build progress, then getProcessLog; image deploys (imageUrl) usually have BuildId=0 — getDeployLog is skipped, and runId/next_step guide you to getProcessLog (or getDeployRecords first for RunId). If the user explicitly specifies an image or no rebuild is needed, you must pass imageUrl instead of falling back to a source build just because a local source directory exists. For existing services, deploy reads the remote config first and merges (preserving VpcConf/EnvParams/OpenAccessTypes). updateConfig aligns with the console service settings page. Deletion requires confirmation; set force=true. If a new env reports CloudRun not provisioned before the first deploy, call initEnv first (async, idempotent).",
|
|
202277
202287
|
"error.managerInitFailed": "Failed to initialize CloudBase manager. Please check your credentials and environment configuration.",
|
|
202278
202288
|
"error.unsupportedAction": "Unsupported action: {action}",
|
|
202279
|
-
"error.pathOutsideCwd": "Path must be within current working directory: {cwd}",
|
|
202289
|
+
"error.pathOutsideCwd": "Path must be within current working directory: {cwd}. Allowed: paths under `{cwd}`, or pass an absolute path to the project directory (relative paths cannot escape CWD via `../`). Received resolved path: {resolvedPath}. Suggestion: set targetPath to the absolute project path (deploy/download/init).",
|
|
202280
202290
|
"error.commonServiceQueryEnv": "Current CloudBase Manager does not support commonService; cannot query CloudRun env status.",
|
|
202281
202291
|
"error.commonServiceInitEnv": "Current CloudBase Manager does not support commonService; cannot initialize CloudRun env.",
|
|
202282
202292
|
"error.commonServiceSubmitDiff": "Current CloudBase Manager does not support commonService; cannot call SubmitServerConfigChangeDiff.",
|
|
@@ -203215,11 +203225,28 @@ exports.databaseSQL = (0, types_js_1.defineModule)({
|
|
|
203215
203225
|
"gate.pgOnlyMode": "当前环境({envId})已开通 PostgreSQL,MySQL 不可用。请改用 managePgDatabase / queryPgDatabase,而不是 manageMysqlDatabase / queryMysqlDatabase。",
|
|
203216
203226
|
"gate.useManagePg": "请使用 managePgDatabase 执行 PostgreSQL 操作",
|
|
203217
203227
|
"queryMysqlDatabase.title": "查询 CloudBase MySQL 数据库状态或执行只读 SQL",
|
|
203218
|
-
"queryMysqlDatabase.description": "查询 CloudBase MySQL 数据库信息。支持执行只读 SQL、查询 MySQL 开通结果、查询 MySQL
|
|
203219
|
-
"schema.query.action": "runQuery=执行只读 SQL;describeCreateResult=查询 CreateMySQL 结果;describeTaskStatus=查询 MySQL 任务状态;getInstanceInfo=获取不含连接凭据的生命周期上下文;describeInstance=getInstanceInfo 的别名;getConnectionInfo=透传可能包含凭据的原始连接/集群载荷(仅限 TCP
|
|
203228
|
+
"queryMysqlDatabase.description": "查询 CloudBase MySQL 数据库信息。支持执行只读 SQL、查询 MySQL 开通结果、查询 MySQL 任务状态、获取当前实例生命周期上下文,以及查询实例慢查询/错误日志(对齐 Manager SDK describeInstanceSlowQueries / describeInstanceErrorLogs)。标准 getInstanceInfo/describeInstance 不返回连接凭据;仅 getConnectionInfo 透传原始连接/集群载荷(含可能的凭据),且仅用于显式 TCP 迁移。业务 CRUD 优先使用 SDK 或 runQuery/runStatement。",
|
|
203229
|
+
"schema.query.action": "runQuery=执行只读 SQL;describeCreateResult=查询 CreateMySQL 结果;describeTaskStatus=查询 MySQL 任务状态;getInstanceInfo=获取不含连接凭据的生命周期上下文;describeInstance=getInstanceInfo 的别名;getConnectionInfo=透传可能包含凭据的原始连接/集群载荷(仅限 TCP 迁移例外场景);describeInstanceSlowQueries=查询实例慢查询日志;describeInstanceErrorLogs=查询实例错误日志",
|
|
203220
203230
|
"schema.query.sql": "action=runQuery 使用的只读 SQL",
|
|
203221
|
-
"schema.query.request": "describeCreateResult/describeTaskStatus
|
|
203222
|
-
"schema.query.dbInstance": "runQuery
|
|
203231
|
+
"schema.query.request": "describeCreateResult/describeTaskStatus/describeInstanceSlowQueries/describeInstanceErrorLogs 使用的官方请求载荷(可含 InstanceId 等)",
|
|
203232
|
+
"schema.query.dbInstance": "runQuery / 慢查/错误日志可选的 SQL 数据库实例上下文",
|
|
203233
|
+
"schema.query.startTime": "慢查/错误日志查询开始时间(YYYY-MM-DD HH:mm:ss)",
|
|
203234
|
+
"schema.query.endTime": "慢查/错误日志查询结束时间(YYYY-MM-DD HH:mm:ss)",
|
|
203235
|
+
"schema.query.limit": "慢查/错误日志返回条数限制",
|
|
203236
|
+
"schema.query.offset": "慢查/错误日志分页偏移",
|
|
203237
|
+
"schema.query.username": "慢查过滤:用户名",
|
|
203238
|
+
"schema.query.host": "慢查过滤:客户端 host",
|
|
203239
|
+
"schema.query.database": "慢查过滤:数据库名",
|
|
203240
|
+
"schema.query.orderBy": "排序字段。慢查支持 QueryTime/LockTime/RowsExamined/RowsSent;错误日志支持 Timestamp",
|
|
203241
|
+
"schema.query.orderByType": "排序方向:asc/desc(大小写均可)",
|
|
203242
|
+
"schema.query.sqlText": "慢查过滤:SQL 文本片段",
|
|
203243
|
+
"schema.query.logLevels": "错误日志等级过滤,可选值:error / warning / note",
|
|
203244
|
+
"schema.query.keyWords": "错误日志关键字模糊搜索列表",
|
|
203245
|
+
"instanceLogs.notProvisioned": "MySQL 尚未开通,无法查询实例慢查/错误日志。",
|
|
203246
|
+
"instanceLogs.instanceIdRequired": "无法解析 CynosDB InstanceId。请先 getInstanceInfo,或通过 dbInstance.instanceId / request.InstanceId 传入。",
|
|
203247
|
+
"instanceLogs.resolveInstanceId": "先查询实例信息以获取可用的 InstanceId。",
|
|
203248
|
+
"instanceLogs.slowQueriesSuccess": "MySQL 实例慢查询日志检索成功。",
|
|
203249
|
+
"instanceLogs.errorLogsSuccess": "MySQL 实例错误日志检索成功。",
|
|
203223
203250
|
"manageMysqlDatabase.title": "管理 CloudBase MySQL 数据库生命周期或执行写入 SQL",
|
|
203224
203251
|
"manageMysqlDatabase.description": "管理 CloudBase MySQL 数据库资源。支持开通 MySQL、销毁 MySQL、执行写入 SQL/DDL,以及初始化数据库 Schema。注意:必须先开通 MySQL(action=provisionMySQL,confirm=true)才能执行 runStatement 或 initializeSchema。若 MySQL 尚未开通,工具会返回 MYSQL_NOT_CREATED 并给出开通的 nextAction 提示。",
|
|
203225
203252
|
"schema.manage.action": "provisionMySQL=创建 MySQL 实例;destroyMySQL=销毁 MySQL 实例;runStatement=执行写入 SQL 或 DDL;initializeSchema=按顺序执行 Schema 初始化语句",
|
|
@@ -203290,11 +203317,28 @@ exports.databaseSQL = (0, types_js_1.defineModule)({
|
|
|
203290
203317
|
"gate.pgOnlyMode": "This environment ({envId}) has PostgreSQL enabled but MySQL is NOT available. Use managePgDatabase / queryPgDatabase instead of manageMysqlDatabase / queryMysqlDatabase.",
|
|
203291
203318
|
"gate.useManagePg": "Use managePgDatabase for PostgreSQL operations",
|
|
203292
203319
|
"queryMysqlDatabase.title": "Query CloudBase MySQL database status or run read-only SQL",
|
|
203293
|
-
"queryMysqlDatabase.description": "Query CloudBase MySQL database information. Supports running read-only SQL, checking the MySQL provisioning result, querying MySQL task status,
|
|
203294
|
-
"schema.query.action": "runQuery=execute read-only SQL; describeCreateResult=query CreateMySQL result; describeTaskStatus=query MySQL task status; getInstanceInfo=get lifecycle context without connection credentials; describeInstance=alias of getInstanceInfo; getConnectionInfo=passthrough raw connection/cluster payload including possible credentials (TCP migration exception only)",
|
|
203320
|
+
"queryMysqlDatabase.description": "Query CloudBase MySQL database information. Supports running read-only SQL, checking the MySQL provisioning result, querying MySQL task status, getting the current instance lifecycle context, and querying instance slow queries / error logs (aligned with Manager SDK describeInstanceSlowQueries / describeInstanceErrorLogs). Standard getInstanceInfo/describeInstance never returns connection credentials; only getConnectionInfo passes through the raw connection/cluster payload (possibly including credentials), and only for explicit TCP migration. Prefer the SDK or runQuery/runStatement for business CRUD.",
|
|
203321
|
+
"schema.query.action": "runQuery=execute read-only SQL; describeCreateResult=query CreateMySQL result; describeTaskStatus=query MySQL task status; getInstanceInfo=get lifecycle context without connection credentials; describeInstance=alias of getInstanceInfo; getConnectionInfo=passthrough raw connection/cluster payload including possible credentials (TCP migration exception only); describeInstanceSlowQueries=query instance slow query logs; describeInstanceErrorLogs=query instance error logs",
|
|
203295
203322
|
"schema.query.sql": "Read-only SQL used by action=runQuery",
|
|
203296
|
-
"schema.query.request": "Official request payload used by describeCreateResult/describeTaskStatus",
|
|
203297
|
-
"schema.query.dbInstance": "Optional SQL database instance context for runQuery",
|
|
203323
|
+
"schema.query.request": "Official request payload used by describeCreateResult/describeTaskStatus/describeInstanceSlowQueries/describeInstanceErrorLogs (may include InstanceId, etc.)",
|
|
203324
|
+
"schema.query.dbInstance": "Optional SQL database instance context for runQuery / slow-query / error-log actions",
|
|
203325
|
+
"schema.query.startTime": "Slow-query / error-log query start time (YYYY-MM-DD HH:mm:ss)",
|
|
203326
|
+
"schema.query.endTime": "Slow-query / error-log query end time (YYYY-MM-DD HH:mm:ss)",
|
|
203327
|
+
"schema.query.limit": "Max rows for slow-query / error-log results",
|
|
203328
|
+
"schema.query.offset": "Pagination offset for slow-query / error-log results",
|
|
203329
|
+
"schema.query.username": "Slow-query filter: username",
|
|
203330
|
+
"schema.query.host": "Slow-query filter: client host",
|
|
203331
|
+
"schema.query.database": "Slow-query filter: database name",
|
|
203332
|
+
"schema.query.orderBy": "Sort field. Slow queries: QueryTime/LockTime/RowsExamined/RowsSent; error logs: Timestamp",
|
|
203333
|
+
"schema.query.orderByType": "Sort direction: asc/desc (case-insensitive)",
|
|
203334
|
+
"schema.query.sqlText": "Slow-query filter: SQL text fragment",
|
|
203335
|
+
"schema.query.logLevels": "Error log level filter. Allowed values: error / warning / note",
|
|
203336
|
+
"schema.query.keyWords": "Error log keyword fuzzy-search list",
|
|
203337
|
+
"instanceLogs.notProvisioned": "MySQL is not provisioned yet, so instance slow/error logs cannot be queried.",
|
|
203338
|
+
"instanceLogs.instanceIdRequired": "Unable to resolve CynosDB InstanceId. Call getInstanceInfo first, or pass dbInstance.instanceId / request.InstanceId.",
|
|
203339
|
+
"instanceLogs.resolveInstanceId": "Query instance info first to obtain a usable InstanceId.",
|
|
203340
|
+
"instanceLogs.slowQueriesSuccess": "MySQL instance slow query logs retrieved successfully.",
|
|
203341
|
+
"instanceLogs.errorLogsSuccess": "MySQL instance error logs retrieved successfully.",
|
|
203298
203342
|
"manageMysqlDatabase.title": "Manage CloudBase MySQL database lifecycle or run write SQL",
|
|
203299
203343
|
"manageMysqlDatabase.description": "Manage CloudBase MySQL database resources. Supports provisioning MySQL, destroying MySQL, running write SQL/DDL, and initializing the database schema. Note: MySQL must be provisioned first (action=provisionMySQL, confirm=true) before runStatement or initializeSchema can run. If MySQL is not provisioned, the tool returns MYSQL_NOT_CREATED with a provisioning nextAction hint.",
|
|
203300
203344
|
"schema.manage.action": "provisionMySQL=create MySQL instance; destroyMySQL=destroy MySQL instance; runStatement=execute write SQL or DDL; initializeSchema=run ordered schema initialization statements",
|
|
@@ -204104,6 +204148,49 @@ exports.envSetup = (0, types_js_1.defineModule)({
|
|
|
204104
204148
|
});
|
|
204105
204149
|
|
|
204106
204150
|
|
|
204151
|
+
/***/ },
|
|
204152
|
+
|
|
204153
|
+
/***/ 99391
|
|
204154
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
204155
|
+
|
|
204156
|
+
"use strict";
|
|
204157
|
+
|
|
204158
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
204159
|
+
exports.feedback = void 0;
|
|
204160
|
+
const types_js_1 = __webpack_require__(89921);
|
|
204161
|
+
exports.feedback = (0, types_js_1.defineModule)({
|
|
204162
|
+
title: "整理本次开发反馈",
|
|
204163
|
+
description: "把当前这次 CloudBase 开发整理成用户可以自己提交的反馈。" +
|
|
204164
|
+
"作品做出来了,用它生成案例,方便展示;开发不顺利,用它生成复盘,方便把卡点反馈给平台。" +
|
|
204165
|
+
"\n\n**什么时候用**:" +
|
|
204166
|
+
"\n- `channel=\"case\"`:部署或发布已经成功,用户愿意把作品放到案例墙时使用。返回案例草稿;用户确认后附上预填好的新建 issue 链接。" +
|
|
204167
|
+
"\n- `channel=\"retrospective\"`:用户表示这次开发不顺利、想反馈时使用。根据本会话里真实的工具调用失败生成复盘草稿;用户确认后同样附上预填链接。" +
|
|
204168
|
+
"\n\n**怎么用**:" +
|
|
204169
|
+
"\n- 第一次不要传 `confirmed`。先把返回的草稿全文给用户看。" +
|
|
204170
|
+
"\n- 用户明确同意后,再以 `confirmed=true` 调用。这时才会返回可打开的链接。" +
|
|
204171
|
+
"\n- 本工具不会替用户提交。链接里的正文就是本次返回的 draft,不要改写成另一份再让用户提交。" +
|
|
204172
|
+
"\n- 不采集对话轮次,不要编造轮次、作品名、简介或公网地址。" +
|
|
204173
|
+
"\n- 国际站是英文草稿和 GitHub 链接(body 参数)。国内站是中文草稿,链接指向 CNB 上公开的 CloudBase-AI-ToolKit 仓库,正文放在模板字段 session。若页面没自动填上,把 draft 粘贴到「本次会话记录」。",
|
|
204174
|
+
"schema.channel": "反馈用途:`case` 是把已完成的作品整理成案例;`retrospective` 是把这次不顺利的开发整理成复盘。",
|
|
204175
|
+
"schema.confirmed": "用户是否已经看过草稿全文并明确同意提交。省略或 false 时只返回草稿、不给链接。",
|
|
204176
|
+
}, {
|
|
204177
|
+
title: "Prepare feedback for this session",
|
|
204178
|
+
description: "Turn this CloudBase session into feedback the user can submit themselves. " +
|
|
204179
|
+
"Use it to showcase a finished work, or to report a session that was hard to finish." +
|
|
204180
|
+
"\n\n**When to use**:" +
|
|
204181
|
+
"\n- `channel=\"case\"`: the deploy or publish already succeeded and the user wants the work on the case wall. Returns a case draft, and a prefilled new-issue link after the user confirms." +
|
|
204182
|
+
"\n- `channel=\"retrospective\"`: the user says this session went badly and wants to report it. Builds the retrospective from tool failures that actually happened in this session, and adds a prefilled link after confirmation." +
|
|
204183
|
+
"\n\n**How to use**:" +
|
|
204184
|
+
"\n- Do not pass `confirmed` on the first call. Show the returned draft to the user in full." +
|
|
204185
|
+
"\n- Call again with `confirmed=true` only after the user explicitly agrees. That call returns the link." +
|
|
204186
|
+
"\n- This tool does not submit the issue. The link body is the draft in this response. Do not rewrite it and ask the user to submit the rewrite." +
|
|
204187
|
+
"\n- Conversation turns are not collected. Do not invent a turn count, title, summary, or public URL." +
|
|
204188
|
+
"\n- International site: English draft and a GitHub link (body parameter). China site: Chinese draft and a link to the public CloudBase-AI-ToolKit repo on CNB. The draft is placed in the template field id session. If the page does not fill it, paste the draft into that field.",
|
|
204189
|
+
"schema.channel": "What the feedback is for: `case` turns a finished work into a showcase entry; `retrospective` turns a difficult session into a write-up.",
|
|
204190
|
+
"schema.confirmed": "Whether the user has read the full draft and agreed to submit it. Omit or pass false to return the draft only, with no link.",
|
|
204191
|
+
});
|
|
204192
|
+
|
|
204193
|
+
|
|
204107
204194
|
/***/ },
|
|
204108
204195
|
|
|
204109
204196
|
/***/ 28015
|
|
@@ -204343,8 +204430,8 @@ const types_js_1 = __webpack_require__(89921);
|
|
|
204343
204430
|
exports.functions = (0, types_js_1.defineModule)({
|
|
204344
204431
|
// ---- 工具 meta ----
|
|
204345
204432
|
queryTitle: "查询 CloudBase 云函数",
|
|
204346
|
-
queryDescription: "CloudBase 云函数统一只读入口。通过更自解释的 action 查询 CloudBase
|
|
204347
|
-
"\n\n**分页说明**:`listFunctions`、`listLayers` 支持 `limit` 和 `offset` 参数。" +
|
|
204433
|
+
queryDescription: "CloudBase 云函数统一只读入口。通过更自解释的 action 查询 CloudBase 云函数列表、函数详情、执行日志、层、触发器、代码下载地址、已发布版本与流量别名。" +
|
|
204434
|
+
"\n\n**分页说明**:`listFunctions`、`listLayers`、`listVersionByFunction` 支持 `limit` 和 `offset` 参数。" +
|
|
204348
204435
|
"\n- `limit`: 分页数量,默认值由后端决定" +
|
|
204349
204436
|
"\n- `offset`: 分页偏移,从 0 开始" +
|
|
204350
204437
|
"\n- 示例:`queryFunctions(action=\"listFunctions\", offset=10, limit=10)`" +
|
|
@@ -204352,6 +204439,7 @@ exports.functions = (0, types_js_1.defineModule)({
|
|
|
204352
204439
|
"\n- 示例:`queryFunctions(action=\"listFunctionLogs\", functionName=\"my-function\")`" +
|
|
204353
204440
|
"\n- 如需查看日志详情:`queryFunctions(action=\"getFunctionLogDetail\", requestId=\"xxx\")`" +
|
|
204354
204441
|
"\n\n**定时任务 / cron / 定时跑**:使用 `listFunctionTriggers` 查询函数的 timer 触发器配置。" +
|
|
204442
|
+
"\n\n**版本与流量路由**:`listVersionByFunction` 列出已发布版本(对齐 tcb fn list-function-versions);`getFunctionAlias` 查看别名/灰度配置(对齐 tcb fn get-route,aliasName 默认 `$DEFAULT`)。" +
|
|
204355
204443
|
"\n\n**层(Layer)说明**:" +
|
|
204356
204444
|
"\n- 层为 SCF 账号级共享命名空间:不同环境创建同名层会共享同一层的版本序列;删除某版本会影响所有绑定该版本的环境的函数" +
|
|
204357
204445
|
"\n- 创建层必须用带环境标识的唯一层名,固定格式:`{layerName}_{当前envId}`(如 `common_cloud1-d9ghadgak3edf6b36`)。不要在不同环境使用相同裸层名,创建前先 `listLayers` 查重" +
|
|
@@ -204360,8 +204448,9 @@ exports.functions = (0, types_js_1.defineModule)({
|
|
|
204360
204448
|
"\n- 本工具用于查询特定 CloudBase 云函数的执行日志" +
|
|
204361
204449
|
"\n- `queryLogs` 工具用于搜索 CLS 日志服务(跨服务日志聚合)",
|
|
204362
204450
|
manageTitle: "管理 CloudBase 云函数",
|
|
204363
|
-
manageDescription: "CloudBase
|
|
204451
|
+
manageDescription: "CloudBase 云函数统一写入口。支持创建函数、更新代码、更新配置、调用函数、发布版本、配置流量别名、管理定时跑 / 定时任务 / scheduled job 的 timer 触发器和层绑定。" +
|
|
204364
204452
|
"如果要创建 cron 定时任务,先用 createFunction 创建函数,再用 createFunctionTrigger 创建 timer 触发器(支持7段cron表达式),deleteFunctionTrigger 删除触发器。" +
|
|
204453
|
+
"版本发布:`publishVersion` 对齐 tcb fn publish-version / SDK publishVersion;灰度/切流:`updateFunctionAliasConfig` 对齐 tcb fn config-route / SDK updateFunctionAliasConfig(aliasName 默认 `$DEFAULT`)。" +
|
|
204365
204454
|
"HTTP 云函数镜像构建部署:createFunction / updateFunctionCode 通过 func.buildStrategy 区分。" +
|
|
204366
204455
|
"func.buildStrategy=image(已有镜像,填 func.imageConfig.imageUri)直接创建/更新 HTTP 函数;" +
|
|
204367
204456
|
"func.buildStrategy=local(本地 Docker 构建推送)、cloud(CloudApp 云端构建)走镜像构建部署编排(需要 func.imageConfig;build 非必填,缺省仓库坐标自动补齐:namespace 默认 envId、repository 默认函数名)," +
|
|
@@ -204411,7 +204500,7 @@ exports.functions = (0, types_js_1.defineModule)({
|
|
|
204411
204500
|
"opErr.default": "请检查函数名、目录结构和环境中的函数状态后重试。",
|
|
204412
204501
|
"opErr.prefix": "[{operation}] {message}\n建议:",
|
|
204413
204502
|
confirmRequired: "{action} 是危险操作,请显式传入 confirm=true 后再执行",
|
|
204414
|
-
"cloudMode.localOnly": "{action} 在 cloud mode
|
|
204503
|
+
"cloudMode.localOnly": "{action} 在 cloud mode 下不可用,因为该操作依赖本地函数代码目录。可用出路:1) 使用镜像部署(runtime=CustomImage + imageConfig);2) 使用 ZIP 两段式部署:先 queryFunctions action=getFunctionUploadUrl 获取预签名上传地址,PUT 代码 zip 后通过 manageFunctions 的 code 入参部署(阶段 B 同样不依赖本地目录)。",
|
|
204415
204504
|
"cloudMode.contentPathUnsupported": "createLayerVersion 在 cloud mode 下不支持 contentPath,本地文件内容请改为 base64Content 或改用本地模式执行。",
|
|
204416
204505
|
offsetLimitTooLarge: "offset+limit 不能大于 10000",
|
|
204417
204506
|
startTimeInvalid: "startTime 格式错误: \"{value}\"。必须使用 YYYY-MM-DD HH:mm:ss 格式(如 2024-01-01 00:00:00)",
|
|
@@ -204424,6 +204513,8 @@ exports.functions = (0, types_js_1.defineModule)({
|
|
|
204424
204513
|
"deployStatus.cloudMode": "{action} 在 cloud mode 下不可用:异步部署任务只由 buildStrategy=cloud/local 的真实部署创建,而这两种策略的真实执行在 cloud mode 下都不支持(需要读取本地构建上下文或本地 Docker),因此不会存在任何 taskId。buildStrategy=image 走同步部署,直接在 manageFunctions 的返回里拿结果,也不需要查询部署状态。如需异步镜像构建部署,请改用本地 MCP 模式。",
|
|
204425
204514
|
deployTaskNotFound: "未找到部署任务 {taskId};部署任务不存在,可能已过期、不属于当前环境 {envId},或 MCP Server 已重启(任务仅保存在 MCP 进程内存中)。",
|
|
204426
204515
|
unsupportedAction: "不支持的操作类型: {action}",
|
|
204516
|
+
storageMissing: "当前环境没有可用的对象存储桶(DescribeEnvs 未返回 Storages),无法使用 COS 两段式部署。请检查环境存储配置,或改用本地模式部署。共享存储桶(ExternalStorage)环境同样不支持该通道。",
|
|
204517
|
+
credentialMissing: "当前凭据缺少 SecretId/SecretKey(如 IDE 代理模式),无法本地铸造 COS 预签名上传地址。请改用本地模式或包含永久密钥/临时密钥的登录方式。",
|
|
204427
204518
|
// ---- nextActions reasons ----
|
|
204428
204519
|
"reason.continuePolling": "继续查询云函数部署状态",
|
|
204429
204520
|
"reason.getDetail": "查看单个函数详情",
|
|
@@ -204462,8 +204553,15 @@ exports.functions = (0, types_js_1.defineModule)({
|
|
|
204462
204553
|
"reason.imageFnReady": "确认镜像函数已就绪(Active)",
|
|
204463
204554
|
"reason.imageUpdateReady": "确认镜像更新后函数已就绪(Active)",
|
|
204464
204555
|
"reason.imageNextIteration": "后续迭代只需用新镜像 tag 调用 updateFunctionCode 更新镜像",
|
|
204556
|
+
"reason.cosCreate": "把 PUT 好的代码 zip 通过 code 入参部署为函数(两段式阶段 B)",
|
|
204465
204557
|
"reason.imageGatewayRoute": "如需通过 URL 访问镜像 HTTP 函数,显式创建 Domain/Route 访问入口并传 type=\"HTTP\"(映射 WEB_SCF)",
|
|
204466
204558
|
"reason.latestConfig": "确认最新函数配置",
|
|
204559
|
+
"reason.publishVersion": "发布函数新版本(对齐 tcb fn publish-version)",
|
|
204560
|
+
"reason.getFunctionAlias": "查看函数流量别名配置(对齐 tcb fn get-route)",
|
|
204561
|
+
"reason.updateFunctionAlias": "更新函数流量别名/灰度路由(对齐 tcb fn config-route)",
|
|
204562
|
+
"reason.listVersions": "查看函数已发布版本列表(对齐 tcb fn list-function-versions)",
|
|
204563
|
+
"reason.routeTraffic": "将流量切到新版本或配置灰度权重",
|
|
204564
|
+
"reason.confirmAlias": "确认别名与流量配置已生效",
|
|
204467
204565
|
// ---- 成功 message ----
|
|
204468
204566
|
listedFunctions: "已获取 {count} 个云函数",
|
|
204469
204567
|
gotFunctionDetail: "已获取函数 {fnName} 的详情",
|
|
@@ -204475,8 +204573,15 @@ exports.functions = (0, types_js_1.defineModule)({
|
|
|
204475
204573
|
gotLayerVersionDetail: "已获取层 {layerName} 版本 {layerVersion} 的详情",
|
|
204476
204574
|
gotFunctionTriggers: "已获取函数 {fnName} 的触发器列表",
|
|
204477
204575
|
gotDownloadUrl: "已获取函数 {fnName} 的代码下载链接",
|
|
204576
|
+
gotUploadUrl: "已生成函数代码包上传地址({seconds} 秒内有效)。下一步:PUT 代码 zip 到 uploadUrl(uploadHeaders 非空时须随请求携带),再调用 manageFunctions createFunction/updateFunctionCode 并传入 code 三元组(cosBucketName/cosObjectName/cosBucketRegion)完成部署",
|
|
204577
|
+
gotFunctionVersions: "已获取函数 {fnName} 的版本列表",
|
|
204578
|
+
gotFunctionAlias: "已获取函数 {fnName} 的别名 {aliasName}",
|
|
204579
|
+
publishedVersion: "已发布函数 {fnName} 的新版本 {version}",
|
|
204580
|
+
updatedFunctionAlias: "已更新函数 {fnName} 别名 {aliasName}(主版本 {version})",
|
|
204478
204581
|
createdHttpFunctionMessage: "已创建 HTTP 函数 {fnName}。如果后续需要通过 URL 访问,请显式调用 manageGateway(action=\"createRoute\"),并把 upstreamResourceType=\"WEB_SCF\" 一起传入,再按实际路径和鉴权需求创建访问入口。评测或其他外部调用方可能会以匿名身份访问,而且失败后不一定会把 EXCEED_AUTHORITY 再反馈给 AI;交付前请主动确认访问路径和函数安全规则,若已出现 EXCEED_AUTHORITY,请先调用 queryPermissions(action=\"getResourcePermission\", resourceType=\"function\", resourceId=\"{fnName}\") 查看当前规则,再按需要使用 managePermissions(action=\"updateResourcePermission\") 调整权限。",
|
|
204479
204582
|
createdFunction: "已创建函数 {fnName}",
|
|
204583
|
+
cosCreatedMessage: "已基于环境 COS 桶中的代码包(deployMode=cos)创建函数 {fnName}。部署后可用 queryFunctions(action=\"getFunctionDetail\") 确认函数已就绪。",
|
|
204584
|
+
cosUpdatedMessage: "已用环境 COS 桶中的新代码包(deployMode=cos)更新函数 {fnName} 的代码。部署后可用 queryFunctions(action=\"getFunctionDetail\") 确认函数已就绪(Active)。",
|
|
204480
204585
|
imageCreatedMessage: "已基于镜像 {imageUri} 创建 HTTP 函数 {fnName}。请确认 TCR、SCF 与构建管道处于同一地域;如需通过 URL 访问,请显式调用 manageGateway(action=\"createRoute\", upstreamResourceType=\"WEB_SCF\") 并按需调整函数安全规则。部署后可用 queryFunctions(action=\"getFunctionDetail\") 确认函数已就绪。",
|
|
204481
204586
|
imageUpdatedMessage: "已将函数 {fnName} 的镜像更新为 {imageUri}。部署后可用 queryFunctions(action=\"getFunctionDetail\") 确认函数已就绪(Active)。",
|
|
204482
204587
|
updatedCode: "已更新函数 {fnName} 的代码",
|
|
@@ -204542,12 +204647,12 @@ exports.functions = (0, types_js_1.defineModule)({
|
|
|
204542
204647
|
"schema.create.layers": "Layer 配置",
|
|
204543
204648
|
"schema.manageLayer.name": "层名称",
|
|
204544
204649
|
"schema.manageLayer.version": "层版本号",
|
|
204545
|
-
"schema.query.action": "只读操作类型:\n- `listFunctions`: 列出所有 CloudBase 云函数\n- `getFunctionDetail`: 获取 CloudBase 云函数详情(需要 functionName)\n- `listFunctionLogs`: 查询 CloudBase 云函数执行日志(需要 functionName)\n- `getFunctionLogDetail`: 获取日志详情(需要 requestId)\n- `listFunctionLayers`: 列出函数绑定的层\n- `listLayers`: 列出所有层(账号级视图,含其他环境创建的层)\n- `listLayerVersions`: 列出层的版本(注意:是 Versions 不是 Version;账号级视图)\n- `getLayerVersionDetail`: 获取层版本详情(账号级视图)\n- `listFunctionTriggers`: 列出函数触发器(用于查看定时任务 / cron / timer 配置)\n- `getFunctionDownloadUrl`: 获取函数代码下载地址\n- `getFunctionDeployStatus`: 按 taskId 查询异步部署状态、阶段进度和最终结果。返回 data.build(构建子状态)、data.deploy(部署子状态)、data.progress(阶段事件);status=running 时 data.result 与 data.error 一律为 null,不得报告部署完成。调用方必须持续轮询直到 status=succeeded/failed;status=expired 表示任务超过最长保留时间(2 小时)被终结,云端可能仍在部署,需用 getFunctionDetail 确认。任务只保存在 MCP 进程内存中,过期或 MCP Server 重启后返回 errorCode=DEPLOY_TASK_NOT_FOUND;任务按环境隔离,只能查到当前环境自己发起的部署。cloud mode 下本 action 不可用:异步任务只由 buildStrategy=cloud/local 的真实部署创建,而这两种策略在 cloud mode 下都不支持真实执行,image 策略则走同步部署不产生 taskId
|
|
204546
|
-
"schema.query.functionName": "CloudBase 云函数名称。`getFunctionDetail`、`listFunctionLogs`、`listFunctionLayers`、`listFunctionTriggers`、`getFunctionDownloadUrl`
|
|
204650
|
+
"schema.query.action": "只读操作类型:\n- `listFunctions`: 列出所有 CloudBase 云函数\n- `getFunctionDetail`: 获取 CloudBase 云函数详情(需要 functionName)\n- `listFunctionLogs`: 查询 CloudBase 云函数执行日志(需要 functionName)\n- `getFunctionLogDetail`: 获取日志详情(需要 requestId)\n- `listFunctionLayers`: 列出函数绑定的层\n- `listLayers`: 列出所有层(账号级视图,含其他环境创建的层)\n- `listLayerVersions`: 列出层的版本(注意:是 Versions 不是 Version;账号级视图)\n- `getLayerVersionDetail`: 获取层版本详情(账号级视图)\n- `listFunctionTriggers`: 列出函数触发器(用于查看定时任务 / cron / timer 配置)\n- `getFunctionDownloadUrl`: 获取函数代码下载地址\n- `getFunctionDeployStatus`: 按 taskId 查询异步部署状态、阶段进度和最终结果。返回 data.build(构建子状态)、data.deploy(部署子状态)、data.progress(阶段事件);status=running 时 data.result 与 data.error 一律为 null,不得报告部署完成。调用方必须持续轮询直到 status=succeeded/failed;status=expired 表示任务超过最长保留时间(2 小时)被终结,云端可能仍在部署,需用 getFunctionDetail 确认。任务只保存在 MCP 进程内存中,过期或 MCP Server 重启后返回 errorCode=DEPLOY_TASK_NOT_FOUND;任务按环境隔离,只能查到当前环境自己发起的部署。cloud mode 下本 action 不可用:异步任务只由 buildStrategy=cloud/local 的真实部署创建,而这两种策略在 cloud mode 下都不支持真实执行,image 策略则走同步部署不产生 taskId。\n- `listVersionByFunction`: 列出函数已发布版本(对齐 tcb fn list-function-versions / SDK listVersionByFunction;需要 functionName)\n- `getFunctionAlias`: 查询函数别名与流量路由(对齐 tcb fn get-route / SDK getFunctionAlias;需要 functionName;aliasName 默认 $DEFAULT)\n- `getFunctionUploadUrl`: 获取函数代码包的 COS 预签名上传地址(ZIP 两段式部署阶段 A):PUT 代码 zip 到 uploadUrl(uploadHeaders 非空时须随请求携带对应请求头),再调用 manageFunctions 的 createFunction/updateFunctionCode 并传 code 三元组(阶段 B)。functionName 可选,仅用于生成上传对象 key。返回的 uploadUrl 含凭据签名,不得写入日志或持久化",
|
|
204651
|
+
"schema.query.functionName": "CloudBase 云函数名称。`getFunctionDetail`、`listFunctionLogs`、`listFunctionLayers`、`listFunctionTriggers`、`getFunctionDownloadUrl`、`listVersionByFunction`、`getFunctionAlias` 时必填;`getFunctionUploadUrl` 可选(仅用于生成上传对象 key)",
|
|
204547
204652
|
"schema.query.limit": "分页数量(limit)。列表类 action 可选,默认值由后端决定",
|
|
204548
204653
|
"schema.query.offset": "分页偏移(offset)。列表类 action 可选,默认 0",
|
|
204549
204654
|
"schema.query.codeSecret": "代码保护密钥,用于解密函数代码",
|
|
204550
|
-
"schema.query.revealEnvValues": "getFunctionDetail / listFunctionTriggers 时是否返回环境变量明文值。默认 false:Value 脱敏为 ***,仅保留 Key 与 ValueLength,足以确认配置了哪些变量及变更是否生效;true 时返回明文,敏感变量会进入模型上下文,谨慎使用。如需查看明文,建议优先使用控制台或 CLI",
|
|
204655
|
+
"schema.query.revealEnvValues": "getFunctionDetail / listFunctionTriggers / listFunctionLayers 时是否返回环境变量明文值。默认 false:Value 脱敏为 ***,仅保留 Key 与 ValueLength,足以确认配置了哪些变量及变更是否生效;true 时返回明文,敏感变量会进入模型上下文,谨慎使用。如需查看明文,建议优先使用控制台或 CLI",
|
|
204551
204656
|
"schema.query.startTime": "日志查询开始时间,格式必须为 YYYY-MM-DD HH:mm:ss(如 2024-01-01 00:00:00)。与 endTime 间隔不能超过一天。不传时默认查询最近一天",
|
|
204552
204657
|
"schema.query.endTime": "日志查询结束时间,格式必须为 YYYY-MM-DD HH:mm:ss(如 2024-01-01 23:59:59)。与 startTime 间隔不能超过一天。不传时默认为当前时间",
|
|
204553
204658
|
"schema.query.requestId": "日志请求 ID。`getFunctionLogDetail` 操作必填,可从 `listFunctionLogs` 结果中获取",
|
|
@@ -204557,12 +204662,19 @@ exports.functions = (0, types_js_1.defineModule)({
|
|
|
204557
204662
|
"schema.query.layerName": "层名称。`listLayerVersions`、`getLayerVersionDetail` 操作必填。层为账号级共享命名空间;推荐固定格式 `{layerName}_{当前envId}`(如 common_cloud1-d9ghadgak3edf6b36)",
|
|
204558
204663
|
"schema.query.layerVersion": "层版本号。`getLayerVersionDetail` 操作必填",
|
|
204559
204664
|
"schema.query.taskId": "`getFunctionDeployStatus` 操作时的异步部署任务 ID(由 manageFunctions 的 wait=false 返回)。任务仅保存在当前 MCP 进程内存中:终态任务保留约 30 分钟,运行中任务最长保留 2 小时。",
|
|
204560
|
-
"schema.
|
|
204665
|
+
"schema.query.order": "`listVersionByFunction` 排序方向,如 ASC / DESC",
|
|
204666
|
+
"schema.query.orderBy": "`listVersionByFunction` 排序字段,如 AddTime / ModTime",
|
|
204667
|
+
"schema.query.aliasName": "`getFunctionAlias` 的别名名称。省略时默认 `$DEFAULT`(与 tcb fn get-route 一致)",
|
|
204668
|
+
"schema.manage.action": "写操作类型,例如 createFunction、updateFunctionCode、incrementalDeployFunction、invokeFunction、deleteFunction、createFunctionTrigger(定时任务 / cron / timer)、deleteFunctionTrigger、createLayerVersion、deleteLayerVersion、attachLayer、detachLayer、updateFunctionLayers、publishVersion(发布新版本,对齐 tcb fn publish-version)、updateFunctionAliasConfig(更新别名/流量路由,对齐 tcb fn config-route)。层名推荐固定格式 `{layerName}_{当前envId}`(如 common_cloud1-d9ghadgak3edf6b36)",
|
|
204561
204669
|
"schema.manage.func": "createFunction / updateFunctionCode 的函数配置。镜像/构建部署通过 func.buildStrategy(zip/cloud/local/image)区分,镜像相关字段收敛在 func.imageConfig 命名空间下。",
|
|
204562
204670
|
"schema.manage.functionRootPath": "创建或更新函数代码时默认推荐的本地目录方式。必须是直接包含函数文件夹的目录绝对路径(如 /abs/path/cloudfunctions 或 /abs/path/functions),不要传项目根目录(如 /abs/path),也不要传到函数名子目录(如 /abs/path/cloudfunctions/hello)。本地应按 cloudfunctions/<functionName>/index.js 或 functions/<functionName>/index.js 布局,此参数传 cloudfunctions 或 functions 目录的绝对路径。SDK 会自动拼接函数名子目录,无需预先压缩 zip 或 base64 编码。",
|
|
204563
204671
|
"schema.manage.force": "createFunction 时是否覆盖",
|
|
204564
|
-
"schema.manage.functionName": "目标函数名称(顶层)。updateFunctionCode / updateFunctionConfig / invokeFunction 等 action 使用此字段。不要只写在 func.name:createFunction 用 func.name,其它 action 用顶层 functionName。若误传 func.name,也会被识别为 functionName。",
|
|
204672
|
+
"schema.manage.functionName": "目标函数名称(顶层)。updateFunctionCode / updateFunctionConfig / invokeFunction / publishVersion / updateFunctionAliasConfig 等 action 使用此字段。不要只写在 func.name:createFunction 用 func.name,其它 action 用顶层 functionName。若误传 func.name,也会被识别为 functionName。",
|
|
204565
204673
|
"schema.manage.zipFile": "仅兼容特殊场景:预先准备好的代码包 base64 编码。普通 createFunction/updateFunctionCode 默认不要先压缩 zip,优先使用 functionRootPath。",
|
|
204674
|
+
"schema.manage.code": "ZIP 两段式部署阶段 B:代码包已通过 queryFunctions action=getFunctionUploadUrl 上传到环境 COS 桶。三元组(cosBucketName/cosObjectName/cosBucketRegion)直接使用 getFunctionUploadUrl 返回值原样透传。传入 code 后 createFunction/updateFunctionCode 不再读取本地目录(functionRootPath/zipFile 均不需要),默认不触发云端依赖安装(可用 func.installDependency 覆盖)。",
|
|
204675
|
+
"schema.code.cosBucketName": "环境存储桶短名(不含 -appid 后缀),直接使用 getFunctionUploadUrl 返回的 cosBucketName,不要自填",
|
|
204676
|
+
"schema.code.cosObjectName": "上传对象 key,直接使用 getFunctionUploadUrl 返回的 cosObjectName",
|
|
204677
|
+
"schema.code.cosBucketRegion": "存储桶地域,省略时自动使用当前环境存储桶地域",
|
|
204566
204678
|
"schema.manage.handler": "函数入口",
|
|
204567
204679
|
"schema.manage.timeout": "配置更新时的超时时间",
|
|
204568
204680
|
"schema.manage.envVariables": "配置更新时要合并的环境变量。若含 DATABASE_URL / MYSQL_* / POSTGRES_* / REDIS_* 等 TCP 连库变量,必须同时提供真实 vpc(或函数已绑定完整 VPC)。禁止猜测 vpcId/subnetId。",
|
|
@@ -204575,7 +204687,7 @@ exports.functions = (0, types_js_1.defineModule)({
|
|
|
204575
204687
|
"schema.manage.contentPath": "层内容路径,可为目录或 ZIP 文件",
|
|
204576
204688
|
"schema.manage.base64Content": "层内容的 base64 编码",
|
|
204577
204689
|
"schema.manage.runtimes": "层适用的运行时列表",
|
|
204578
|
-
"schema.manage.description": "
|
|
204690
|
+
"schema.manage.description": "描述信息。createLayerVersion 时为层版本描述;publishVersion / updateFunctionAliasConfig 时为版本或别名描述",
|
|
204579
204691
|
"schema.manage.licenseInfo": "层许可证信息",
|
|
204580
204692
|
"schema.manage.layers": "updateFunctionLayers 的目标层列表,顺序即最终顺序",
|
|
204581
204693
|
"schema.manage.codeSecret": "层绑定时的代码保护密钥",
|
|
@@ -204584,11 +204696,22 @@ exports.functions = (0, types_js_1.defineModule)({
|
|
|
204584
204696
|
"schema.manage.autoGrant": "镜像部署是否允许 manager-node 自动补齐固定白名单 CAM 策略。默认 false;仅在明确确认权限变更时设为 true。",
|
|
204585
204697
|
"schema.manage.confirm": "危险操作确认开关。deleteFunction、deleteFunctionTrigger、deleteLayerVersion、detachLayer 等删除类操作以及镜像构建部署(func.buildStrategy=cloud/local)真实执行需要显式传入 confirm=true",
|
|
204586
204698
|
"schema.manage.incrementalFile": "incrementalDeployFunction 增量部署时的变更文件路径",
|
|
204699
|
+
"schema.manage.aliasName": "`updateFunctionAliasConfig` 的别名名称。省略时默认 `$DEFAULT`(与 tcb fn config-route 一致)",
|
|
204700
|
+
"schema.manage.functionVersion": "`updateFunctionAliasConfig` 的主版本。可为具体版本号或 `$LATEST`",
|
|
204701
|
+
"schema.manage.routingConfig": "`updateFunctionAliasConfig` 的流量路由配置。AdditionalVersionWeights 用于灰度权重;AddtionVersionMatchs 为 SCF/SDK 历史字段名(含拼写)",
|
|
204702
|
+
"schema.routing.version": "附加流量版本号",
|
|
204703
|
+
"schema.routing.weight": "附加流量权重(0-1 或百分比,按 SCF 约定)",
|
|
204704
|
+
"schema.routing.matchVersion": "匹配规则指向的版本号",
|
|
204705
|
+
"schema.routing.matchKey": "匹配规则的 Header/Query Key",
|
|
204706
|
+
"schema.routing.matchMethod": "匹配方法,如 Exact / Regex",
|
|
204707
|
+
"schema.routing.matchExpression": "匹配表达式",
|
|
204708
|
+
"schema.routing.additionalWeights": "附加版本权重列表(灰度发布)",
|
|
204709
|
+
"schema.routing.additionalMatches": "附加版本匹配规则列表(字段名保持 SCF AddtionVersionMatchs)",
|
|
204587
204710
|
}, {
|
|
204588
204711
|
// ---- Tool meta ----
|
|
204589
204712
|
queryTitle: "Query CloudBase Cloud Functions",
|
|
204590
|
-
queryDescription: "Unified read-only entry for CloudBase cloud functions. Query function lists, function details, execution logs, layers, triggers,
|
|
204591
|
-
"\n\n**Pagination**: `listFunctions` and `
|
|
204713
|
+
queryDescription: "Unified read-only entry for CloudBase cloud functions. Query function lists, function details, execution logs, layers, triggers, code download URLs, published versions, and traffic aliases through self-explanatory actions." +
|
|
204714
|
+
"\n\n**Pagination**: `listFunctions`, `listLayers`, and `listVersionByFunction` support `limit` and `offset` parameters." +
|
|
204592
204715
|
"\n- `limit`: page size, the default is decided by the backend" +
|
|
204593
204716
|
"\n- `offset`: pagination offset, starting from 0" +
|
|
204594
204717
|
"\n- Example: `queryFunctions(action=\"listFunctions\", offset=10, limit=10)`" +
|
|
@@ -204596,6 +204719,7 @@ exports.functions = (0, types_js_1.defineModule)({
|
|
|
204596
204719
|
"\n- Example: `queryFunctions(action=\"listFunctionLogs\", functionName=\"my-function\")`" +
|
|
204597
204720
|
"\n- To view log details: `queryFunctions(action=\"getFunctionLogDetail\", requestId=\"xxx\")`" +
|
|
204598
204721
|
"\n\n**Scheduled tasks / cron / timers**: use `listFunctionTriggers` to query a function's timer trigger configuration." +
|
|
204722
|
+
"\n\n**Versions and traffic routing**: `listVersionByFunction` lists published versions (aligns with tcb fn list-function-versions); `getFunctionAlias` views alias / canary config (aligns with tcb fn get-route; aliasName defaults to `$DEFAULT`)." +
|
|
204599
204723
|
"\n\n**Layers**:" +
|
|
204600
204724
|
"\n- Layers are account-level shared namespaces in SCF: same-named layers created in different environments share one version sequence; deleting a version affects functions in every environment bound to it" +
|
|
204601
204725
|
"\n- When creating a layer, use a unique name with the environment suffix, in the fixed format `{layerName}_{current envId}` (e.g. `common_cloud1-d9ghadgak3edf6b36`). Do not reuse the same bare layer name across environments; check with `listLayers` before creating" +
|
|
@@ -204604,8 +204728,9 @@ exports.functions = (0, types_js_1.defineModule)({
|
|
|
204604
204728
|
"\n- This tool queries execution logs of a specific CloudBase cloud function" +
|
|
204605
204729
|
"\n- The `queryLogs` tool searches the CLS log service (cross-service log aggregation)",
|
|
204606
204730
|
manageTitle: "Manage CloudBase Cloud Functions",
|
|
204607
|
-
manageDescription: "Unified write entry for CloudBase cloud functions. Supports creating functions, updating code, updating configuration, invoking functions, and managing timer triggers (scheduled jobs / cron) and layer bindings." +
|
|
204731
|
+
manageDescription: "Unified write entry for CloudBase cloud functions. Supports creating functions, updating code, updating configuration, invoking functions, publishing versions, configuring traffic aliases, and managing timer triggers (scheduled jobs / cron) and layer bindings." +
|
|
204608
204732
|
" To create a cron scheduled task, first create the function with createFunction, then create the timer trigger with createFunctionTrigger (7-field cron expression supported), and delete triggers with deleteFunctionTrigger." +
|
|
204733
|
+
" Version publish: `publishVersion` aligns with tcb fn publish-version / SDK publishVersion; canary / traffic shift: `updateFunctionAliasConfig` aligns with tcb fn config-route / SDK updateFunctionAliasConfig (aliasName defaults to `$DEFAULT`)." +
|
|
204609
204734
|
" HTTP function image build & deploy: createFunction / updateFunctionCode distinguish via func.buildStrategy." +
|
|
204610
204735
|
" func.buildStrategy=image (existing image, set func.imageConfig.imageUri) creates/updates the HTTP function directly;" +
|
|
204611
204736
|
" func.buildStrategy=local (local Docker build & push) and cloud (CloudApp cloud build) go through the image build/deploy orchestration (func.imageConfig required; build optional — missing registry coordinates are auto-filled: namespace defaults to envId, repository defaults to the function name)," +
|
|
@@ -204655,7 +204780,7 @@ exports.functions = (0, types_js_1.defineModule)({
|
|
|
204655
204780
|
"opErr.default": "Please check the function name, directory structure, and the function status in the environment, then retry.",
|
|
204656
204781
|
"opErr.prefix": "[{operation}] {message}\nSuggestions: ",
|
|
204657
204782
|
confirmRequired: "{action} is a dangerous operation; pass confirm=true explicitly before executing",
|
|
204658
|
-
"cloudMode.localOnly": "{action} is unavailable in cloud mode because the operation depends on a local function code directory.
|
|
204783
|
+
"cloudMode.localOnly": "{action} is unavailable in cloud mode because the operation depends on a local function code directory. Options: 1) use image deployment (runtime=CustomImage + imageConfig); 2) use two-phase ZIP deployment: first call queryFunctions action=getFunctionUploadUrl to get a presigned upload URL, PUT the code zip, then deploy via the manageFunctions code parameter (phase B also needs no local directory).",
|
|
204659
204784
|
"cloudMode.contentPathUnsupported": "createLayerVersion does not support contentPath in cloud mode; switch local file content to base64Content or run in local mode.",
|
|
204660
204785
|
offsetLimitTooLarge: "offset+limit must not be greater than 10000",
|
|
204661
204786
|
startTimeInvalid: "Invalid startTime: \"{value}\". It must use the YYYY-MM-DD HH:mm:ss format (e.g. 2024-01-01 00:00:00)",
|
|
@@ -204668,6 +204793,8 @@ exports.functions = (0, types_js_1.defineModule)({
|
|
|
204668
204793
|
"deployStatus.cloudMode": "{action} is unavailable in cloud mode: async deployment tasks are only created by real deployments with buildStrategy=cloud/local, and real execution of both strategies is unsupported in cloud mode (they need the local build context or local Docker), so no taskId can exist. buildStrategy=image uses synchronous deployment and returns the result directly from manageFunctions, so no deployment status query is needed. For async image build deployment, switch to local MCP mode.",
|
|
204669
204794
|
deployTaskNotFound: "Deployment task {taskId} not found; the task does not exist — it may have expired, belong to a different environment than {envId}, or the MCP Server was restarted (tasks are only kept in MCP process memory).",
|
|
204670
204795
|
unsupportedAction: "Unsupported action: {action}",
|
|
204796
|
+
storageMissing: "The current environment has no usable object storage bucket (DescribeEnvs returned no Storages), so COS two-phase deployment is unavailable. Check the environment storage configuration, or deploy in local mode. Environments with a shared bucket (ExternalStorage) are not supported either.",
|
|
204797
|
+
credentialMissing: "The current credential lacks SecretId/SecretKey (e.g. IDE proxy mode), so a COS presigned upload URL cannot be minted locally. Use local mode or a login method with permanent/temporary keys.",
|
|
204671
204798
|
// ---- nextActions reasons ----
|
|
204672
204799
|
"reason.continuePolling": "Keep polling the cloud function deployment status",
|
|
204673
204800
|
"reason.getDetail": "View details of a single function",
|
|
@@ -204706,8 +204833,15 @@ exports.functions = (0, types_js_1.defineModule)({
|
|
|
204706
204833
|
"reason.imageFnReady": "Confirm the image function is ready (Active)",
|
|
204707
204834
|
"reason.imageUpdateReady": "Confirm the function is ready (Active) after the image update",
|
|
204708
204835
|
"reason.imageNextIteration": "For later iterations, just call updateFunctionCode with the new image tag to update the image",
|
|
204836
|
+
"reason.cosCreate": "Deploy the uploaded code zip as a function via the code parameter (two-phase deployment phase B)",
|
|
204709
204837
|
"reason.imageGatewayRoute": "To access the image HTTP function via URL, explicitly create a Domain/Route access entry and pass type=\"HTTP\" (mapped to WEB_SCF)",
|
|
204710
204838
|
"reason.latestConfig": "Confirm the latest function configuration",
|
|
204839
|
+
"reason.publishVersion": "Publish a new function version (aligns with tcb fn publish-version)",
|
|
204840
|
+
"reason.getFunctionAlias": "View function traffic alias config (aligns with tcb fn get-route)",
|
|
204841
|
+
"reason.updateFunctionAlias": "Update function traffic alias / canary routing (aligns with tcb fn config-route)",
|
|
204842
|
+
"reason.listVersions": "List published function versions (aligns with tcb fn list-function-versions)",
|
|
204843
|
+
"reason.routeTraffic": "Shift traffic to the new version or configure canary weights",
|
|
204844
|
+
"reason.confirmAlias": "Confirm the alias and traffic config have taken effect",
|
|
204711
204845
|
// ---- Success messages ----
|
|
204712
204846
|
listedFunctions: "Retrieved {count} cloud functions",
|
|
204713
204847
|
gotFunctionDetail: "Retrieved details of function {fnName}",
|
|
@@ -204719,8 +204853,15 @@ exports.functions = (0, types_js_1.defineModule)({
|
|
|
204719
204853
|
gotLayerVersionDetail: "Retrieved details of layer {layerName} version {layerVersion}",
|
|
204720
204854
|
gotFunctionTriggers: "Retrieved the trigger list of function {fnName}",
|
|
204721
204855
|
gotDownloadUrl: "Retrieved the code download URL of function {fnName}",
|
|
204856
|
+
gotUploadUrl: "Generated the code package upload URL (valid for {seconds} seconds). Next: PUT the code zip to uploadUrl (include the uploadHeaders when non-empty), then call manageFunctions createFunction/updateFunctionCode with the code triplet (cosBucketName/cosObjectName/cosBucketRegion) to deploy",
|
|
204857
|
+
gotFunctionVersions: "Retrieved the version list of function {fnName}",
|
|
204858
|
+
gotFunctionAlias: "Retrieved alias {aliasName} of function {fnName}",
|
|
204859
|
+
publishedVersion: "Published new version {version} of function {fnName}",
|
|
204860
|
+
updatedFunctionAlias: "Updated alias {aliasName} of function {fnName} (primary version {version})",
|
|
204722
204861
|
createdHttpFunctionMessage: "Created HTTP function {fnName} from the image. If URL access is needed later, explicitly call manageGateway(action=\"createRoute\") with upstreamResourceType=\"WEB_SCF\", then create the access entry according to the actual path and auth requirements. Evaluators or other external callers may access anonymously, and failures may not feed EXCEED_AUTHORITY back to the AI; before delivery, proactively confirm the access path and the function security rules. If EXCEED_AUTHORITY has already appeared, first call queryPermissions(action=\"getResourcePermission\", resourceType=\"function\", resourceId=\"{fnName}\") to view the current rules, then adjust permissions with managePermissions(action=\"updateResourcePermission\") as needed.",
|
|
204723
204862
|
createdFunction: "Created function {fnName}",
|
|
204863
|
+
cosCreatedMessage: "Created function {fnName} from the code package in the environment COS bucket (deployMode=cos). Use queryFunctions(action=\"getFunctionDetail\") after deployment to confirm the function is ready.",
|
|
204864
|
+
cosUpdatedMessage: "Updated the code of function {fnName} with the new package in the environment COS bucket (deployMode=cos). Use queryFunctions(action=\"getFunctionDetail\") after deployment to confirm the function is ready (Active).",
|
|
204724
204865
|
imageCreatedMessage: "Created HTTP function {fnName} from image {imageUri}. Please confirm TCR, SCF, and the build pipeline are in the same region; for URL access, explicitly call manageGateway(action=\"createRoute\", upstreamResourceType=\"WEB_SCF\") and adjust the function security rules as needed. After deployment, use queryFunctions(action=\"getFunctionDetail\") to confirm the function is ready.",
|
|
204725
204866
|
imageUpdatedMessage: "Updated the image of function {fnName} to {imageUri}. After deployment, use queryFunctions(action=\"getFunctionDetail\") to confirm the function is ready (Active).",
|
|
204726
204867
|
updatedCode: "Updated the code of function {fnName}",
|
|
@@ -204786,12 +204927,12 @@ exports.functions = (0, types_js_1.defineModule)({
|
|
|
204786
204927
|
"schema.create.layers": "Layer configuration",
|
|
204787
204928
|
"schema.manageLayer.name": "Layer name",
|
|
204788
204929
|
"schema.manageLayer.version": "Layer version number",
|
|
204789
|
-
"schema.query.action": "Read-only action type:\n- `listFunctions`: list all CloudBase cloud functions\n- `getFunctionDetail`: get function details (requires functionName)\n- `listFunctionLogs`: query function execution logs (requires functionName)\n- `getFunctionLogDetail`: get log details (requires requestId)\n- `listFunctionLayers`: list layers bound to a function\n- `listLayers`: list all layers (account-level view, including layers from other environments)\n- `listLayerVersions`: list layer versions (Versions, not Version; account-level view)\n- `getLayerVersionDetail`: get layer version details (account-level view)\n- `listFunctionTriggers`: list function triggers (scheduled task / cron / timer configuration)\n- `getFunctionDownloadUrl`: get the function code download URL\n- `getFunctionDeployStatus`: query async deployment status, stage progress, and final result by taskId. Returns data.build, data.deploy, and data.progress. While status=running, data.result and data.error are null and deployment must not be reported as complete. Keep polling until status=succeeded/failed. status=expired means the task exceeded the 2-hour retention limit; cloud deployment may still be running, so confirm with getFunctionDetail. Tasks exist only in MCP process memory; expired tasks or a restarted MCP Server return errorCode=DEPLOY_TASK_NOT_FOUND. Tasks are isolated by environment. This action is unavailable in cloud mode because real cloud/local builds cannot run there, while image deployment is synchronous and creates no taskId.",
|
|
204790
|
-
"schema.query.functionName": "CloudBase cloud function name. Required for `getFunctionDetail`, `listFunctionLogs`, `listFunctionLayers`, `listFunctionTriggers`, and `
|
|
204930
|
+
"schema.query.action": "Read-only action type:\n- `listFunctions`: list all CloudBase cloud functions\n- `getFunctionDetail`: get function details (requires functionName)\n- `listFunctionLogs`: query function execution logs (requires functionName)\n- `getFunctionLogDetail`: get log details (requires requestId)\n- `listFunctionLayers`: list layers bound to a function\n- `listLayers`: list all layers (account-level view, including layers from other environments)\n- `listLayerVersions`: list layer versions (Versions, not Version; account-level view)\n- `getLayerVersionDetail`: get layer version details (account-level view)\n- `listFunctionTriggers`: list function triggers (scheduled task / cron / timer configuration)\n- `getFunctionDownloadUrl`: get the function code download URL\n- `getFunctionDeployStatus`: query async deployment status, stage progress, and final result by taskId. Returns data.build, data.deploy, and data.progress. While status=running, data.result and data.error are null and deployment must not be reported as complete. Keep polling until status=succeeded/failed. status=expired means the task exceeded the 2-hour retention limit; cloud deployment may still be running, so confirm with getFunctionDetail. Tasks exist only in MCP process memory; expired tasks or a restarted MCP Server return errorCode=DEPLOY_TASK_NOT_FOUND. Tasks are isolated by environment. This action is unavailable in cloud mode because real cloud/local builds cannot run there, while image deployment is synchronous and creates no taskId.\n- `listVersionByFunction`: list published function versions (aligns with tcb fn list-function-versions / SDK listVersionByFunction; requires functionName)\n- `getFunctionAlias`: get function alias and traffic routing (aligns with tcb fn get-route / SDK getFunctionAlias; requires functionName; aliasName defaults to $DEFAULT)\n- `getFunctionUploadUrl`: get a COS presigned upload URL for a function code package (two-phase ZIP deployment phase A): PUT the code zip to uploadUrl (include the corresponding request headers when uploadHeaders is non-empty), then call manageFunctions createFunction/updateFunctionCode with the code triplet (phase B). functionName is optional and only shapes the upload object key. The uploadUrl carries credential-bound signatures; never log or persist it",
|
|
204931
|
+
"schema.query.functionName": "CloudBase cloud function name. Required for `getFunctionDetail`, `listFunctionLogs`, `listFunctionLayers`, `listFunctionTriggers`, `getFunctionDownloadUrl`, `listVersionByFunction`, and `getFunctionAlias`. Optional for `getFunctionUploadUrl` (only used to generate the upload object key).",
|
|
204791
204932
|
"schema.query.limit": "Page size (limit). Optional for list actions; the backend determines the default.",
|
|
204792
204933
|
"schema.query.offset": "Pagination offset. Optional for list actions; defaults to 0.",
|
|
204793
204934
|
"schema.query.codeSecret": "Code protection secret used to decrypt function code.",
|
|
204794
|
-
"schema.query.revealEnvValues": "Whether `getFunctionDetail` / `listFunctionTriggers` returns plaintext environment variable values. Defaults to false: Value is masked as ***, while Key and ValueLength remain, which is sufficient to verify configured variables and changes. true returns plaintext and may expose secrets to the model context; use cautiously. Prefer the console or CLI for plaintext values.",
|
|
204935
|
+
"schema.query.revealEnvValues": "Whether `getFunctionDetail` / `listFunctionTriggers` / `listFunctionLayers` returns plaintext environment variable values. Defaults to false: Value is masked as ***, while Key and ValueLength remain, which is sufficient to verify configured variables and changes. true returns plaintext and may expose secrets to the model context; use cautiously. Prefer the console or CLI for plaintext values.",
|
|
204795
204936
|
"schema.query.startTime": "Log query start time in YYYY-MM-DD HH:mm:ss format (for example, 2024-01-01 00:00:00). The interval to endTime must not exceed one day. Defaults to the most recent day when omitted.",
|
|
204796
204937
|
"schema.query.endTime": "Log query end time in YYYY-MM-DD HH:mm:ss format (for example, 2024-01-01 23:59:59). The interval from startTime must not exceed one day. Defaults to the current time when omitted.",
|
|
204797
204938
|
"schema.query.requestId": "Log request ID. Required for `getFunctionLogDetail`; obtain it from `listFunctionLogs`.",
|
|
@@ -204801,12 +204942,19 @@ exports.functions = (0, types_js_1.defineModule)({
|
|
|
204801
204942
|
"schema.query.layerName": "Layer name. Required for `listLayerVersions` and `getLayerVersionDetail`. Layers use an account-level shared namespace; use the fixed format `{layerName}_{current envId}` (for example, common_cloud1-d9ghadgak3edf6b36).",
|
|
204802
204943
|
"schema.query.layerVersion": "Layer version number. Required for `getLayerVersionDetail`.",
|
|
204803
204944
|
"schema.query.taskId": "Async deployment task ID for `getFunctionDeployStatus` (returned by manageFunctions with wait=false). Tasks exist only in current MCP process memory: terminal tasks are retained for about 30 minutes and running tasks for at most 2 hours.",
|
|
204804
|
-
"schema.
|
|
204945
|
+
"schema.query.order": "Sort direction for `listVersionByFunction`, such as ASC / DESC.",
|
|
204946
|
+
"schema.query.orderBy": "Sort field for `listVersionByFunction`, such as AddTime / ModTime.",
|
|
204947
|
+
"schema.query.aliasName": "Alias name for `getFunctionAlias`. Defaults to `$DEFAULT` when omitted (same as tcb fn get-route).",
|
|
204948
|
+
"schema.manage.action": "Write action type, such as createFunction, updateFunctionCode, incrementalDeployFunction, invokeFunction, deleteFunction, createFunctionTrigger (scheduled task / cron / timer), deleteFunctionTrigger, createLayerVersion, deleteLayerVersion, attachLayer, detachLayer, updateFunctionLayers, publishVersion (publish a new version; aligns with tcb fn publish-version), or updateFunctionAliasConfig (update alias / traffic routing; aligns with tcb fn config-route). Use the fixed layer naming format `{layerName}_{current envId}` (for example, common_cloud1-d9ghadgak3edf6b36).",
|
|
204805
204949
|
"schema.manage.func": "Function configuration for createFunction / updateFunctionCode. Image/build deployment is selected by func.buildStrategy (zip/cloud/local/image), with image fields under func.imageConfig.",
|
|
204806
204950
|
"schema.manage.functionRootPath": "Recommended local-directory input for creating or updating function code. It must be the absolute directory that directly contains function folders (for example, /abs/path/cloudfunctions or /abs/path/functions), not the project root or the function subdirectory. Local layout should be cloudfunctions/<functionName>/index.js or functions/<functionName>/index.js. Pass the absolute cloudfunctions/functions directory; the SDK appends the function subdirectory. Do not precompress ZIP or base64 content.",
|
|
204807
204951
|
"schema.manage.force": "Whether createFunction overwrites an existing function.",
|
|
204808
|
-
"schema.manage.functionName": "Target function name at the top level. Used by updateFunctionCode, updateFunctionConfig, invokeFunction, and similar actions. createFunction uses func.name; other actions use top-level functionName. A mistakenly supplied func.name is also recognized as functionName.",
|
|
204952
|
+
"schema.manage.functionName": "Target function name at the top level. Used by updateFunctionCode, updateFunctionConfig, invokeFunction, publishVersion, updateFunctionAliasConfig, and similar actions. createFunction uses func.name; other actions use top-level functionName. A mistakenly supplied func.name is also recognized as functionName.",
|
|
204809
204953
|
"schema.manage.zipFile": "Compatibility only: base64-encoded prebuilt code package. For ordinary createFunction/updateFunctionCode, do not create a ZIP first; prefer functionRootPath.",
|
|
204954
|
+
"schema.manage.code": "Two-phase ZIP deployment phase B: the code package has been uploaded to the environment COS bucket via queryFunctions action=getFunctionUploadUrl. Pass the triplet (cosBucketName/cosObjectName/cosBucketRegion) through unchanged from the getFunctionUploadUrl response. With code provided, createFunction/updateFunctionCode no longer reads local directories (functionRootPath/zipFile are unnecessary), and cloud dependency installation is skipped by default (override with func.installDependency).",
|
|
204955
|
+
"schema.code.cosBucketName": "Environment bucket short name (without the -appid suffix); pass through the cosBucketName returned by getFunctionUploadUrl, do not invent one",
|
|
204956
|
+
"schema.code.cosObjectName": "Uploaded object key; pass through the cosObjectName returned by getFunctionUploadUrl",
|
|
204957
|
+
"schema.code.cosBucketRegion": "Bucket region; defaults to the current environment bucket region when omitted",
|
|
204810
204958
|
"schema.manage.handler": "Function entry point",
|
|
204811
204959
|
"schema.manage.timeout": "Timeout used for configuration updates.",
|
|
204812
204960
|
"schema.manage.envVariables": "Environment variables to merge during a configuration update. If they contain TCP database variables such as DATABASE_URL, MYSQL_*, POSTGRES_*, or REDIS_*, also provide a real vpc (or ensure the function already has a complete VPC binding). Never guess vpcId/subnetId.",
|
|
@@ -204819,7 +204967,7 @@ exports.functions = (0, types_js_1.defineModule)({
|
|
|
204819
204967
|
"schema.manage.contentPath": "Layer content path, either a directory or ZIP file.",
|
|
204820
204968
|
"schema.manage.base64Content": "Base64-encoded layer content.",
|
|
204821
204969
|
"schema.manage.runtimes": "Runtimes supported by the layer.",
|
|
204822
|
-
"schema.manage.description": "Layer version description.",
|
|
204970
|
+
"schema.manage.description": "Description. Layer version description for createLayerVersion; version or alias description for publishVersion / updateFunctionAliasConfig.",
|
|
204823
204971
|
"schema.manage.licenseInfo": "Layer license information.",
|
|
204824
204972
|
"schema.manage.layers": "Target layer list for updateFunctionLayers; array order becomes final order.",
|
|
204825
204973
|
"schema.manage.codeSecret": "Code protection secret used when binding a layer.",
|
|
@@ -204828,6 +204976,17 @@ exports.functions = (0, types_js_1.defineModule)({
|
|
|
204828
204976
|
"schema.manage.autoGrant": "Whether manager-node may automatically add the fixed allowlist of CAM policies for image deployment. Defaults to false; set true only after explicitly confirming permission changes.",
|
|
204829
204977
|
"schema.manage.confirm": "Dangerous-operation confirmation. deleteFunction, deleteFunctionTrigger, deleteLayerVersion, detachLayer, other delete actions, and real image build deployment (func.buildStrategy=cloud/local) require confirm=true.",
|
|
204830
204978
|
"schema.manage.incrementalFile": "Changed-file path for incrementalDeployFunction incremental deployment.",
|
|
204979
|
+
"schema.manage.aliasName": "Alias name for `updateFunctionAliasConfig`. Defaults to `$DEFAULT` when omitted (same as tcb fn config-route).",
|
|
204980
|
+
"schema.manage.functionVersion": "Primary version for `updateFunctionAliasConfig`. May be a concrete version number or `$LATEST`.",
|
|
204981
|
+
"schema.manage.routingConfig": "Traffic routing config for `updateFunctionAliasConfig`. AdditionalVersionWeights is used for canary weights; AddtionVersionMatchs keeps the SCF/SDK historical field name (including the typo).",
|
|
204982
|
+
"schema.routing.version": "Additional traffic version number",
|
|
204983
|
+
"schema.routing.weight": "Additional traffic weight (0-1 or percentage per SCF convention)",
|
|
204984
|
+
"schema.routing.matchVersion": "Version targeted by a match rule",
|
|
204985
|
+
"schema.routing.matchKey": "Header/Query key for a match rule",
|
|
204986
|
+
"schema.routing.matchMethod": "Match method, such as Exact / Regex",
|
|
204987
|
+
"schema.routing.matchExpression": "Match expression",
|
|
204988
|
+
"schema.routing.additionalWeights": "Additional version weight list (canary release)",
|
|
204989
|
+
"schema.routing.additionalMatches": "Additional version match rules (field name keeps SCF AddtionVersionMatchs)",
|
|
204831
204990
|
});
|
|
204832
204991
|
|
|
204833
204992
|
|
|
@@ -205161,10 +205320,11 @@ exports.hosting = (0, types_js_1.defineModule)({
|
|
|
205161
205320
|
queryDescription: "查询 CloudBase 静态托管的只读信息。适合 AI 先做发现再决定下一步:action=websiteConfig 查询首页/错误页/路由规则与站点域名信息;action=status 查询托管服务状态;action=findFiles 按前缀查找文件;action=listFiles 列出全部托管文件;action=domainStatus 查询自定义域名的当前状态与配置。该工具不会产生任何副作用。",
|
|
205162
205321
|
manageTitle: "管理 CloudBase 静态托管",
|
|
205163
205322
|
manageDescription: "管理 CloudBase 静态托管的变更操作。action=upload 上传本地构建产物到共享域名(域名格式:<envId>-<appId>.tcloudbaseapp.com/<cloudPath>);action=delete 删除托管文件或目录(必须 confirm=true);action=setWebsiteDocument 设置首页/错误页/路由规则;action=enableService 开通静态托管;action=bindDomain / unbindDomain / updateDomain 管理自定义域名;action=downloadFile / downloadDirectory 下载托管内容到本地。⚠️ 底层每次托管操作都会请求 DescribeStaticStore 管控接口(20 次/秒 QPS 限制):批量删除多个文件请逐次调用并保持间隔(建议每秒不超过 10 次),同一目录下多个文件可优先用 isDir=true 一次删除整个目录;若报错含 \"frequency limit\" 说明触发了限流,请等待 1-2 秒后重试,不要连续快速重试。⚠️ 本工具没有关闭默认域名(*.tcloudbaseapp.com)的 action;要禁用该默认公网域名,请用 manageGateway(action=\"disableRoute\", domain=该 STATIC_STORE IsDefault 域名, path=\"/\")(底层 ModifyHTTPServiceRoute,不是 ModifyGatewayRoute)。⚠️ 新项目部署优先使用 manageApps(部署到独立子域名),本工具适合已有老项目继续使用或作为 manageApps 的 fallback。manageApps 与 manageHosting 域名不同,切换会导致老链接失效。若任务只是查看配置、文件或域名状态,请改用 queryHosting。",
|
|
205323
|
+
manageDescriptionCloud: "管理 CloudBase 静态托管的变更操作(cloud mode 版本)。⚠️ 依赖本地文件路径的 action 在 cloud mode 下不可用:action=upload / downloadFile / downloadDirectory 会直接报错,请勿调用。部署静态站点请改用 manageApps 云端链路:queryApps(action=\"getUploadUrl\", serviceName=\"<应用名>\") 获取预签名上传 URL → 将代码 zip PUT 上传到 uploadUrl(带 uploadHeaders 与 Content-Type: application/zip)→ manageApps(action=\"deployApp\", serviceName, cosTimestamp=<返回的 unixTimestamp>) 触发部署。可正常使用的远端管理操作:action=delete 删除托管文件或目录(必须 confirm=true);action=setWebsiteDocument 设置首页/错误页/路由规则;action=enableService 开通静态托管;action=bindDomain / unbindDomain / updateDomain 管理自定义域名。⚠️ 底层每次托管操作都会请求 DescribeStaticStore 管控接口(20 次/秒 QPS 限制):批量删除多个文件请逐次调用并保持间隔(建议每秒不超过 10 次);若报错含 \"frequency limit\" 说明触发了限流,请等待 1-2 秒后重试。若任务只是查看配置、文件或域名状态,请改用 queryHosting。",
|
|
205164
205324
|
commonServiceUnsupported: "当前 CloudBase Manager 实例不支持 commonService.call,无法执行 {action}。",
|
|
205165
205325
|
managerUnavailable: "CloudBase Manager 实例不可用。",
|
|
205166
205326
|
hostingStoreMissing: "当前环境 {envId} 未发现静态托管资源配置,无法上传文件。请先确认 MCP 已绑定到已开通静态托管的 CloudBase 环境;如需切换环境,请调用 auth(action=\"set_env\", envId=\"目标环境ID\") 后重试。",
|
|
205167
|
-
cloudModeLocalActionUnavailable: "manageHosting(action=\"{action}\") 在 cloud mode
|
|
205327
|
+
cloudModeLocalActionUnavailable: "manageHosting(action=\"{action}\") 在 cloud mode 下不可用,因为该操作依赖本地文件路径。若需要部署静态站点,请改用 manageApps 云端链路:queryApps(action=\"getUploadUrl\", serviceName=\"<应用名>\") 获取预签名上传 URL → 将代码 zip PUT 上传到 uploadUrl(带 uploadHeaders 与 Content-Type: application/zip)→ manageApps(action=\"deployApp\", serviceName, cosTimestamp=<返回的 unixTimestamp>) 触发部署;若只是要上传/下载已有托管文件且无本地文件系统,该操作在云端没有替代路径,请改用本地模式执行。远端管理操作(delete / setWebsiteDocument / enableService / bindDomain / unbindDomain / updateDomain)不受影响,可继续使用。",
|
|
205168
205328
|
uploadArgsRequired: "manageHosting(action=\"upload\") 需要提供 localPath + cloudPath,或提供 files 多文件上传列表。",
|
|
205169
205329
|
uploadSuccess: "静态托管文件上传成功。若需要校验上传结果,请继续调用 queryHosting(action=\"findFiles\") 或 queryHosting(action=\"listFiles\")。",
|
|
205170
205330
|
uploadRouteDisabledWithFallback: "静态托管文件上传成功。默认静态托管域名的网关路由已禁用(访问会返回 GATEWAY_ROUTE_DISABLED),已改用其他可达域名作为 accessUrl。可用 manageGateway(action=\"updateRoute\", route.enable=true) 重新启用默认域路由。",
|
|
@@ -205264,10 +205424,11 @@ exports.hosting = (0, types_js_1.defineModule)({
|
|
|
205264
205424
|
queryDescription: "Read-only information about CloudBase static hosting. Lets the AI discover state first and then decide the next step: action=websiteConfig queries the index/error document, routing rules, and site domain info; action=status queries the hosting service status; action=findFiles finds files by prefix; action=listFiles lists all hosted files; action=domainStatus queries the current status and configuration of custom domains. This tool has no side effects.",
|
|
205265
205425
|
manageTitle: "Manage CloudBase static hosting",
|
|
205266
205426
|
manageDescription: "Mutation operations for CloudBase static hosting. action=upload uploads local build artifacts to the shared domain (domain format: <envId>-<appId>.tcloudbaseapp.com/<cloudPath>); action=delete deletes hosted files or directories (confirm=true required); action=setWebsiteDocument sets the index/error document and routing rules; action=enableService enables static hosting; action=bindDomain / unbindDomain / updateDomain manage custom domains; action=downloadFile / downloadDirectory download hosted content to local disk. ⚠️ Every hosting operation calls the DescribeStaticStore control-plane API underneath (20 req/s QPS limit): when deleting multiple files, call sequentially with intervals (no more than 10 calls per second recommended); for multiple files in the same directory, prefer isDir=true to delete the whole directory in one call. If the error contains \"frequency limit\", rate limiting was triggered — wait 1-2 seconds and retry; do not retry in rapid succession. ⚠️ This tool has no action to disable the default domain (*.tcloudbaseapp.com); to disable that default public domain, use manageGateway(action=\"disableRoute\", domain=the STATIC_STORE IsDefault domain, path=\"/\") (backed by ModifyHTTPServiceRoute, not ModifyGatewayRoute). ⚠️ For new projects prefer manageApps (deploys to a dedicated subdomain); this tool suits existing legacy projects or as a fallback for manageApps. manageApps and manageHosting use different domains, so switching invalidates old links. If the task is only inspecting config, files, or domain status, use queryHosting instead.",
|
|
205427
|
+
manageDescriptionCloud: "Mutation operations for CloudBase static hosting (cloud mode variant). ⚠️ Actions that depend on local file paths are unavailable in cloud mode: action=upload / downloadFile / downloadDirectory will fail immediately — do not call them. To deploy a static site, use the manageApps cloud path instead: queryApps(action=\"getUploadUrl\", serviceName=\"<app name>\") to get a presigned upload URL → PUT the code zip to uploadUrl (with uploadHeaders and Content-Type: application/zip) → manageApps(action=\"deployApp\", serviceName, cosTimestamp=<returned unixTimestamp>) to trigger deployment. Remote-only management actions remain available: action=delete deletes hosted files or directories (confirm=true required); action=setWebsiteDocument sets the index/error document and routing rules; action=enableService enables static hosting; action=bindDomain / unbindDomain / updateDomain manage custom domains. ⚠️ Every hosting operation calls the DescribeStaticStore control-plane API underneath (20 req/s QPS limit): when deleting multiple files, call sequentially with intervals (no more than 10 calls per second recommended); if the error contains \"frequency limit\", rate limiting was triggered — wait 1-2 seconds and retry. If the task is only inspecting config, files, or domain status, use queryHosting instead.",
|
|
205267
205428
|
commonServiceUnsupported: "The current CloudBase Manager instance does not support commonService.call; cannot execute {action}.",
|
|
205268
205429
|
managerUnavailable: "CloudBase manager is unavailable.",
|
|
205269
205430
|
hostingStoreMissing: "No static hosting storage config found for environment {envId}; cannot upload files. Make sure MCP is bound to a CloudBase environment with static hosting enabled; to switch environments, call auth(action=\"set_env\", envId=\"<target env ID>\") and retry.",
|
|
205270
|
-
cloudModeLocalActionUnavailable: "manageHosting(action=\"{action}\") is unavailable in cloud mode because the operation depends on local file paths.
|
|
205431
|
+
cloudModeLocalActionUnavailable: "manageHosting(action=\"{action}\") is unavailable in cloud mode because the operation depends on local file paths. To deploy a static site, use the manageApps cloud path instead: queryApps(action=\"getUploadUrl\", serviceName=\"<app name>\") to get a presigned upload URL → PUT the code zip to uploadUrl (with uploadHeaders and Content-Type: application/zip) → manageApps(action=\"deployApp\", serviceName, cosTimestamp=<returned unixTimestamp>) to trigger deployment. If you only need to upload/download existing hosted files and there is no local filesystem, there is no cloud alternative for this action — run MCP in local mode instead. Remote-only management actions (delete / setWebsiteDocument / enableService / bindDomain / unbindDomain / updateDomain) are unaffected and remain available.",
|
|
205271
205432
|
uploadArgsRequired: "manageHosting(action=\"upload\") requires localPath + cloudPath, or a files list for multi-file upload.",
|
|
205272
205433
|
uploadSuccess: "Static hosting files uploaded. To verify the upload result, call queryHosting(action=\"findFiles\") or queryHosting(action=\"listFiles\").",
|
|
205273
205434
|
uploadRouteDisabledWithFallback: "Static hosting files uploaded. The gateway route for the default static hosting domain is disabled (access returns GATEWAY_ROUTE_DISABLED); another reachable domain is used as accessUrl. Use manageGateway(action=\"updateRoute\", route.enable=true) to re-enable the default domain route.",
|
|
@@ -205422,6 +205583,7 @@ exports.logs = (0, types_js_1.defineModule)({
|
|
|
205422
205583
|
"\n\n**重要区分**:" +
|
|
205423
205584
|
"\n- 查询云函数日志:使用 `queryFunctions(action=\"listFunctionLogs\", functionName=\"xxx\")`" +
|
|
205424
205585
|
"\n- 查询 CLS 日志(跨服务日志聚合):使用本工具 `queryLogs(action=\"searchLogs\")`" +
|
|
205586
|
+
"\n- 开通 CLS 日志服务:使用 `manageLogs(action=\"createLogService\", confirm=true)`" +
|
|
205425
205587
|
"\n\n**适用场景**:" +
|
|
205426
205588
|
"\n- 检查 CLS 日志服务是否开通:`action=\"checkLogService\"`" +
|
|
205427
205589
|
"\n- 跨服务日志搜索(如搜索所有 ERROR 日志):`action=\"searchLogs\"`" +
|
|
@@ -205467,12 +205629,28 @@ exports.logs = (0, types_js_1.defineModule)({
|
|
|
205467
205629
|
"schema.limit": "返回日志条数限制,默认 20",
|
|
205468
205630
|
"schema.context": "翻页上下文,用于继续上一次查询",
|
|
205469
205631
|
"schema.sort": "按时间排序:`asc` 升序,`desc` 降序",
|
|
205632
|
+
"manage.title": "管理 CloudBase 日志服务",
|
|
205633
|
+
"manage.description": "CloudBase 日志域写入入口。用于开通 CLS 日志服务(对齐 Manager SDK `log.createLogService` / CreateEnvResource Resources=['log'])。" +
|
|
205634
|
+
"\n\n**适用场景**:" +
|
|
205635
|
+
"\n- 开通 CLS 日志服务:`action=\"createLogService\", confirm=true`" +
|
|
205636
|
+
"\n\n开通为异步操作:接口成功不代表立即可用,请随后用 `queryLogs(action=\"checkLogService\")` 轮询确认。",
|
|
205637
|
+
"manage.schema.action": "操作类型:" +
|
|
205638
|
+
"\n- `createLogService`: 开通 CLS 日志服务(需 `confirm=true`)",
|
|
205639
|
+
"manage.schema.confirm": "开通日志服务前的显式确认。必须传 `confirm=true`;未传时返回 CONFIRM_REQUIRED。",
|
|
205640
|
+
"manage.create.confirmRequired": "开通日志服务会创建 CLS 日志资源。请使用 `confirm: true` 重新执行以继续。",
|
|
205641
|
+
"manage.create.needsConfirmation": "开通日志服务前需要显式确认。",
|
|
205642
|
+
"manage.create.alreadyEnabled": "当前环境日志服务已开通,无需重复开通。",
|
|
205643
|
+
"manage.create.submitted": "日志服务开通请求已提交。请使用 queryLogs(action=\"checkLogService\") 轮询直至 enabled=true。",
|
|
205644
|
+
"manage.create.nextCheck": "轮询日志服务是否已就绪。",
|
|
205645
|
+
"manage.create.nextSearch": "日志服务已就绪,可开始搜索 CLS 日志。",
|
|
205646
|
+
"manage.unsupportedAction": "不支持的日志管理 action:{action}",
|
|
205470
205647
|
}, {
|
|
205471
205648
|
title: "Query CloudBase log service",
|
|
205472
205649
|
description: "Unified read-only entry for the CloudBase logs domain. Supports checking log service status and searching CLS logs." +
|
|
205473
205650
|
"\n\n**Important distinction**:" +
|
|
205474
205651
|
"\n- Query cloud function logs: use `queryFunctions(action=\"listFunctionLogs\", functionName=\"xxx\")`" +
|
|
205475
205652
|
"\n- Query CLS logs (cross-service log aggregation): use this tool `queryLogs(action=\"searchLogs\")`" +
|
|
205653
|
+
"\n- Enable the CLS log service: use `manageLogs(action=\"createLogService\", confirm=true)`" +
|
|
205476
205654
|
"\n\n**Use cases**:" +
|
|
205477
205655
|
"\n- Check whether the CLS log service is enabled: `action=\"checkLogService\"`" +
|
|
205478
205656
|
"\n- Cross-service log search (e.g. find all ERROR logs): `action=\"searchLogs\"`" +
|
|
@@ -205518,6 +205696,21 @@ exports.logs = (0, types_js_1.defineModule)({
|
|
|
205518
205696
|
"schema.limit": "Maximum number of log entries to return; defaults to 20.",
|
|
205519
205697
|
"schema.context": "Pagination context used to continue the previous query.",
|
|
205520
205698
|
"schema.sort": "Time sort order: `asc` for ascending or `desc` for descending.",
|
|
205699
|
+
"manage.title": "Manage CloudBase log service",
|
|
205700
|
+
"manage.description": "Write entry for the CloudBase logs domain. Enables the CLS log service (aligned with Manager SDK `log.createLogService` / CreateEnvResource Resources=['log'])." +
|
|
205701
|
+
"\n\n**Use cases**:" +
|
|
205702
|
+
"\n- Enable CLS log service: `action=\"createLogService\", confirm=true`" +
|
|
205703
|
+
"\n\nProvisioning is asynchronous: API success does not mean the service is immediately ready. Poll with `queryLogs(action=\"checkLogService\")` afterward.",
|
|
205704
|
+
"manage.schema.action": "Operation type:" +
|
|
205705
|
+
"\n- `createLogService`: Enable the CLS log service (requires `confirm=true`)",
|
|
205706
|
+
"manage.schema.confirm": "Explicit confirmation before enabling the log service. Must pass `confirm=true`; omitting it returns CONFIRM_REQUIRED.",
|
|
205707
|
+
"manage.create.confirmRequired": "Enabling the log service creates CLS log resources. Re-run with `confirm: true` to continue.",
|
|
205708
|
+
"manage.create.needsConfirmation": "Explicit confirmation is required before enabling the log service.",
|
|
205709
|
+
"manage.create.alreadyEnabled": "The log service is already enabled for this environment; no need to enable again.",
|
|
205710
|
+
"manage.create.submitted": "Log service enablement request submitted. Poll with queryLogs(action=\"checkLogService\") until enabled=true.",
|
|
205711
|
+
"manage.create.nextCheck": "Poll whether the log service is ready.",
|
|
205712
|
+
"manage.create.nextSearch": "Log service is ready; you can start searching CLS logs.",
|
|
205713
|
+
"manage.unsupportedAction": "Unsupported log manage action: {action}",
|
|
205521
205714
|
});
|
|
205522
205715
|
|
|
205523
205716
|
|
|
@@ -205811,19 +206004,19 @@ exports.permissions = (0, types_js_1.defineModule)({
|
|
|
205811
206004
|
"或 securityRule='{\"invoke\":true}'(放通所有云函数)。" +
|
|
205812
206005
|
"底层错误:{message}",
|
|
205813
206006
|
mustBeArray: "{label} 必须是数组",
|
|
205814
|
-
roleLookupNote: "如果你需要 app-level admin override(例如 CMS 中 admin 可编辑所有文章,而 editor 只能编辑自己的文章),CUSTOM 规则通常是必要的。一个已验证可用的模式是:角色集合文档主键就是 auth.uid,并在文章权限里写 get(
|
|
205815
|
-
recommendedClientWritePattern: "对于 CMS 文章这类使用 app-level admin override 的 CUSTOM 规则,前端可继续使用 db.collection('{resourceId}').doc(id).update(...) / remove(...)。关键是安全规则要采用已验证模式:get(
|
|
206007
|
+
roleLookupNote: "如果你需要 app-level admin override(例如 CMS 中 admin 可编辑所有文章,而 editor 只能编辑自己的文章),CUSTOM 规则通常是必要的。一个已验证可用的模式是:角色集合文档主键就是 auth.uid,并在文章权限里写 get(`database.user_roles.${auth.uid}`).role == 'admin' || doc.authorId == auth.uid。若现有 schema 已经有 users / profiles / user_roles 其一,请复用已存在且能通过 _id == auth.uid 直接 get() 到的那一份;不要把 where({ uid }) 查询得到的集合误写成 get(`database.users.${auth.uid}`)。",
|
|
206008
|
+
recommendedClientWritePattern: "对于 CMS 文章这类使用 app-level admin override 的 CUSTOM 规则,前端可继续使用 db.collection('{resourceId}').doc(id).update(...) / remove(...)。关键是安全规则要采用已验证模式:get(`database.user_roles.${auth.uid}`).role == 'admin' || doc.authorId == auth.uid,并且文章文档中要真实写入 authorId。",
|
|
205816
206009
|
createRuleSummary: "create 规则不应引用 doc.*,因为 create 时文档尚未存在。",
|
|
205817
206010
|
createRuleDetail: "CloudBase 的 create 规则验证的是写入数据(request.data),此时文档尚不存在,doc.* 不可用。" +
|
|
205818
206011
|
"请将 create 规则改为仅使用 auth.* 检查(如 auth.uid != null && auth.loginType != 'ANONYMOUS')," +
|
|
205819
206012
|
"或在写入时将 owner 字段(如 _openid / authorId)写入 request.data,然后在 create 规则中用 request.data._openid == auth.openid 做校验。" +
|
|
205820
206013
|
"read / update / delete 规则可以使用 doc.* 引用已有文档字段,且客户端查询条件必须是规则约束的子集(如 _openid: '{openid}')。",
|
|
205821
206014
|
docIdWriteSummary: "当前安全规则在 document-id 写入场景下可能被后端直接拒绝。",
|
|
205822
|
-
docIdWriteDetail: "这类规则经常在 owner-only 集合里被写错,但对于 CMS 文章这种“admin 可编辑所有文章、editor 只能编辑自己的文章”的场景,已验证可用的做法是保留 doc.authorId,并通过独立角色集合做 admin override:get(
|
|
206015
|
+
docIdWriteDetail: "这类规则经常在 owner-only 集合里被写错,但对于 CMS 文章这种“admin 可编辑所有文章、editor 只能编辑自己的文章”的场景,已验证可用的做法是保留 doc.authorId,并通过独立角色集合做 admin override:get(`database.user_roles.${auth.uid}`).role == 'admin' || doc.authorId == auth.uid。不要默认改成 where(...),也不要把同集合 owner 判断重写成 ``get(`database.collection.${doc._id}`)``。",
|
|
205823
206016
|
invalidGetPathSummary: "get() 的 path 只应包含 collection 和 documentId,不应把字段名拼进 path 字符串。",
|
|
205824
|
-
invalidGetPathDetail: "请写成 get(
|
|
205825
|
-
templateLiteralSummary: "
|
|
205826
|
-
templateLiteralDetail: "
|
|
206017
|
+
invalidGetPathDetail: "请写成 ``get(`database.collection.${doc._id}`).fieldName``,而不是把字段名拼进 path。安全规则的表达式不支持用 + 拼接 get() 的 path 参数——形如 get('database.collection.' + doc._id) 的规则在保存时就会被判 rule invalid,请改用反引号模板字符串。但在 CMS 文章权限里,不要把同集合文档当成默认首选方案;更稳的模式是读取单独的角色集合:``get(`database.user_roles.${auth.uid}`).role == 'admin' || doc.authorId == auth.uid``。",
|
|
206018
|
+
templateLiteralSummary: "${...} 出现在引号字符串里也能被引擎识别,但官方形态是反引号模板字符串。",
|
|
206019
|
+
templateLiteralDetail: "推荐统一写成 ``get(`database.user_roles.${auth.uid}`).role == 'admin'``。真正会被拒绝的不是 ${...},而是另外两种写法:不含 ${...} 的裸引号字面量(如 get('database.admin_locks.article_lock'),请求时会返回 500),以及用 + 拼接的 get(`database.user_roles.${auth.uid}`)(保存规则时判 rule invalid)。对于 CMS 文章这类需要 app-level admin override 的规则,请优先使用 user_roles + doc.authorId 模式。",
|
|
205827
206020
|
bucketMissing: "存储 Bucket {bucket} 不存在",
|
|
205828
206021
|
bucketsMissing: "以下存储 Bucket 不存在: {buckets}",
|
|
205829
206022
|
paramRequired: "action={action} 时必须提供 {param}",
|
|
@@ -205892,19 +206085,19 @@ exports.permissions = (0, types_js_1.defineModule)({
|
|
|
205892
206085
|
"(package authz.user) or securityRule='{\"invoke\":true}' for public functions. " +
|
|
205893
206086
|
"Underlying error: {message}",
|
|
205894
206087
|
mustBeArray: "{label} must be an array",
|
|
205895
|
-
roleLookupNote: "If you need app-level admin override (e.g. in a CMS, admins can edit all articles while editors can only edit their own), a CUSTOM rule is usually required. A verified pattern is: make the role collection's document primary key auth.uid itself, and in the article permission write get(
|
|
205896
|
-
recommendedClientWritePattern: "For CMS articles using CUSTOM rules with app-level admin override, the frontend can keep using db.collection('{resourceId}').doc(id).update(...) / remove(...). The key is that the security rule uses the verified pattern: get(
|
|
206088
|
+
roleLookupNote: "If you need app-level admin override (e.g. in a CMS, admins can edit all articles while editors can only edit their own), a CUSTOM rule is usually required. A verified pattern is: make the role collection's document primary key auth.uid itself, and in the article permission write get(`database.user_roles.${auth.uid}`).role == 'admin' || doc.authorId == auth.uid. If the existing schema already has users / profiles / user_roles, reuse the one that exists and can be fetched directly via _id == auth.uid with get(); do not mistakenly write the collection obtained by a where({ uid }) query as get(`database.users.${auth.uid}`).",
|
|
206089
|
+
recommendedClientWritePattern: "For CMS articles using CUSTOM rules with app-level admin override, the frontend can keep using db.collection('{resourceId}').doc(id).update(...) / remove(...). The key is that the security rule uses the verified pattern: get(`database.user_roles.${auth.uid}`).role == 'admin' || doc.authorId == auth.uid, and the article document must actually contain the authorId field.",
|
|
205897
206090
|
createRuleSummary: "The create rule should not reference doc.*, because the document does not exist yet at create time.",
|
|
205898
206091
|
createRuleDetail: "CloudBase's create rule validates the written data (request.data); the document does not exist yet, so doc.* is unavailable. " +
|
|
205899
206092
|
"Change the create rule to use only auth.* checks (e.g. auth.uid != null && auth.loginType != 'ANONYMOUS'), " +
|
|
205900
206093
|
"or write the owner field (e.g. _openid / authorId) into request.data at write time, then validate with request.data._openid == auth.openid in the create rule. " +
|
|
205901
206094
|
"read / update / delete rules may use doc.* to reference existing document fields, and the client's query conditions must be a subset of the rule constraints (e.g. _openid: '{openid}').",
|
|
205902
206095
|
docIdWriteSummary: "The current security rule may be rejected by the backend in document-id write scenarios.",
|
|
205903
|
-
docIdWriteDetail: "Such rules are often written incorrectly in owner-only collections, but for the CMS article scenario where \"admins can edit all articles and editors can only edit their own\", the verified approach is to keep doc.authorId and do admin override through a separate role collection: get(
|
|
206096
|
+
docIdWriteDetail: "Such rules are often written incorrectly in owner-only collections, but for the CMS article scenario where \"admins can edit all articles and editors can only edit their own\", the verified approach is to keep doc.authorId and do admin override through a separate role collection: get(`database.user_roles.${auth.uid}`).role == 'admin' || doc.authorId == auth.uid. Do not default to where(...), and do not rewrite the same-collection owner check as ``get(`database.collection.${doc._id}`)``.",
|
|
205904
206097
|
invalidGetPathSummary: "The get() path should only contain the collection and documentId; do not concatenate field names into the path string.",
|
|
205905
|
-
invalidGetPathDetail: "Write get(
|
|
205906
|
-
templateLiteralSummary: "
|
|
205907
|
-
templateLiteralDetail: "
|
|
206098
|
+
invalidGetPathDetail: "Write ``get(`database.collection.${doc._id}`).fieldName`` instead of embedding the field name in the path. Security rule expressions do not support concatenating the get() path with +: a rule such as get('database.collection.' + doc._id) is rejected with rule invalid when the rule is saved, so use a backtick template literal. However, for CMS article permissions, do not treat a same-collection document as the default first choice; the more robust pattern is reading a separate role collection: ``get(`database.user_roles.${auth.uid}`).role == 'admin' || doc.authorId == auth.uid``.",
|
|
206099
|
+
templateLiteralSummary: "${...} inside a quoted string is understood by the engine, but the official form is a backtick template literal.",
|
|
206100
|
+
templateLiteralDetail: "Prefer ``get(`database.user_roles.${auth.uid}`).role == 'admin'``. What actually breaks is not ${...} but two other spellings: a bare quoted literal with no ${...} (e.g. get('database.admin_locks.article_lock'), which returns 500 at request time), and a concatenated path such as get(`database.user_roles.${auth.uid}`) (rejected with rule invalid when the rule is saved). For rules needing app-level admin override like CMS articles, prefer the user_roles + doc.authorId pattern.",
|
|
205908
206101
|
bucketMissing: "Storage bucket {bucket} does not exist",
|
|
205909
206102
|
bucketsMissing: "The following storage buckets do not exist: {buckets}",
|
|
205910
206103
|
paramRequired: "{param} is required when action={action}",
|
|
@@ -205996,6 +206189,8 @@ exports.rag = (0, types_js_1.defineModule)({
|
|
|
205996
206189
|
findByNameSuccess: "CloudBase 文档查找成功",
|
|
205997
206190
|
readDocSuccess: "CloudBase 文档读取成功",
|
|
205998
206191
|
readDocNotMarkdown: "文档 {docPath} 没有可用的 Markdown 版本(站点对该路径返回了 HTML 页面)。请用 action=searchDocs 或 action=findByName 确认正确地址后重试;也可以直接抓取网页版:{pageUrl}",
|
|
206192
|
+
readDocUrlNotAllowed: "readDoc 只读取 CloudBase 官方文档站({host})上的文档,不接受其他主机的地址:{docPath}。请改传站内相对路径(如 /quick-start),或该文档站上的地址。",
|
|
206193
|
+
readDocPathEmpty: "readDoc 需要一个具体文档路径,{docPath} 里没有路径部分。例如传 /quick-start,或传 action=findByName / action=searchDocs 返回的文档地址。",
|
|
205999
206194
|
searchDocsSuccess: "CloudBase 文档搜索成功",
|
|
206000
206195
|
skillNotFound: "未找到技能文档 \"{skillName}\"。可用技能文档:{available}。{remoteHint}",
|
|
206001
206196
|
skillRemoteHint: " 你也可以直接从这个地址获取技能文档:{url}",
|
|
@@ -206016,7 +206211,7 @@ exports.rag = (0, types_js_1.defineModule)({
|
|
|
206016
206211
|
"schema.action": "仅 mode=docs 时指定;mode=openapi 不要传 action。CloudBase 文档操作类型:listModules=列出所有文档模块,listModuleDocs=获取指定模块的目录结构,findByName=按名称/路径/URL 智能查找,readDoc=读取指定文档 Markdown,searchDocs=全文搜索官方文档。",
|
|
206017
206212
|
"schema.moduleName": "mode=docs 且 action=listModuleDocs 时指定。模块名称。",
|
|
206018
206213
|
"schema.input": "mode=docs 且 action=findByName 时指定。支持模块名、文档标题、层级路径或 URL。",
|
|
206019
|
-
"schema.docPath": "mode=docs 且 action=readDoc
|
|
206214
|
+
"schema.docPath": "mode=docs 且 action=readDoc 时指定。站内相对路径(如 /quick-start),或 action=findByName / action=searchDocs 返回的文档地址 —— 传地址时只取其中的路径,主机部分一律忽略。",
|
|
206020
206215
|
"schema.query": "mode=docs 且 action=searchDocs 时指定。全文检索关键词。",
|
|
206021
206216
|
}, {
|
|
206022
206217
|
title: "CloudBase knowledge base search",
|
|
@@ -206052,6 +206247,8 @@ exports.rag = (0, types_js_1.defineModule)({
|
|
|
206052
206247
|
findByNameSuccess: "CloudBase doc lookup succeeded",
|
|
206053
206248
|
readDocSuccess: "CloudBase doc read successfully",
|
|
206054
206249
|
readDocNotMarkdown: "No Markdown version is available for {docPath} (the site returned an HTML page for it). Use action=searchDocs or action=findByName to confirm the correct address and retry; you can also fetch the rendered page directly: {pageUrl}",
|
|
206250
|
+
readDocUrlNotAllowed: "readDoc only reads documents on the official CloudBase docs site ({host}); other hosts are not accepted: {docPath}. Pass a site-relative path such as /quick-start, or an address on that docs site.",
|
|
206251
|
+
readDocPathEmpty: "readDoc needs a concrete document path; {docPath} carries no path. For example pass /quick-start, or a document address returned by action=findByName / action=searchDocs.",
|
|
206055
206252
|
searchDocsSuccess: "CloudBase doc search succeeded",
|
|
206056
206253
|
skillNotFound: "Skill document \"{skillName}\" not found. Available skill docs: {available}.{remoteHint}",
|
|
206057
206254
|
skillRemoteHint: " You can also try fetching the skill doc directly from: {url}",
|
|
@@ -206072,7 +206269,7 @@ exports.rag = (0, types_js_1.defineModule)({
|
|
|
206072
206269
|
"schema.action": "Only for mode=docs; do not pass action with mode=openapi. CloudBase documentation action: listModules lists all documentation modules; listModuleDocs gets the catalog for a module; findByName searches intelligently by name, path, or URL; readDoc reads document Markdown; searchDocs performs a full-text search of the official documentation.",
|
|
206073
206270
|
"schema.moduleName": "Required when mode=docs and action=listModuleDocs. The module name.",
|
|
206074
206271
|
"schema.input": "Required when mode=docs and action=findByName. Accepts a module name, document title, hierarchical path, or URL.",
|
|
206075
|
-
"schema.docPath": "Required when mode=docs and action=readDoc. A relative document path
|
|
206272
|
+
"schema.docPath": "Required when mode=docs and action=readDoc. A site-relative path such as /quick-start, or a document address returned by action=findByName / action=searchDocs — only the path is used; any host is ignored.",
|
|
206076
206273
|
"schema.query": "Required when mode=docs and action=searchDocs. Full-text search keywords.",
|
|
206077
206274
|
});
|
|
206078
206275
|
|
|
@@ -206151,6 +206348,7 @@ exports.setup = (0, types_js_1.defineModule)({
|
|
|
206151
206348
|
"schema.template": "要下载的模板类型",
|
|
206152
206349
|
"schema.ide": "指定要下载的IDE类型。",
|
|
206153
206350
|
"schema.overwrite": "是否覆盖已存在的文件,默认为false(不覆盖)",
|
|
206351
|
+
"projectRoot.hostConfigDir": "拒绝把 {dir} 当作项目根目录。这是宿主配置目录,不是项目。请由宿主设置 WORKSPACE_FOLDER_PATHS 为项目目录后再试。",
|
|
206154
206352
|
}, {
|
|
206155
206353
|
"downloadTemplate.title": "Download project template",
|
|
206156
206354
|
"downloadTemplate.description": "Automatically downloads and deploys CloudBase project templates.\n**Note**: Call this tool when the user requests to create a new project using a CloudBase template.\n\nSupported templates:\n- react: React + CloudBase full-stack app template\n- vue: Vue + CloudBase full-stack app template\n- miniprogram: WeChat Mini Program + CloudBase template\n- uniapp: UniApp + CloudBase cross-platform app template\n- rules: AI editor configuration files only (includes configurations for all mainstream editors such as Cursor, WindSurf, and CodeBuddy), suitable for adding AI editor configuration to an existing project\n\nSupported IDE types:\n- all: download configurations for all IDEs\n- cursor: Cursor AI editor\n- see the list below for other IDE types\n\nNote: if the ide parameter is not provided and the IDE cannot be detected from environment variables, an error will be returned asking for the ide parameter\n- windsurf: WindSurf AI editor\n- codebuddy: CodeBuddy AI editor\n- claude-code: Claude Code AI editor\n- cline: Cline AI editor\n- gemini-cli: Gemini CLI\n- opencode: OpenCode AI editor\n- qwen-code: Tongyi Lingma\n- baidu-comate: Baidu Comate\n- openai-codex-cli: OpenAI Codex CLI\n- augment-code: Augment Code\n- github-copilot: GitHub Copilot\n- roocode: RooCode AI editor\n- tongyi-lingma: Tongyi Lingma\n- trae: Trae AI editor\n- qoder: Qoder AI editor\n- antigravity: Google Antigravity AI editor\n- vscode: Visual Studio Code\n- kiro: Kiro AI editor\n- aider: Aider AI editor\n\nNotes:\n- the rules template automatically embeds the current MCP version for future maintenance and version tracking\n- when downloading the rules template, if a README.md file already exists in the project, the system protects it from being overwritten (unless overwrite=true is set)",
|
|
@@ -206215,6 +206413,7 @@ exports.setup = (0, types_js_1.defineModule)({
|
|
|
206215
206413
|
"schema.template": "The type of template to download",
|
|
206216
206414
|
"schema.ide": "The IDE type whose configuration should be downloaded.",
|
|
206217
206415
|
"schema.overwrite": "Whether to overwrite existing files. Defaults to false (do not overwrite).",
|
|
206416
|
+
"projectRoot.hostConfigDir": "Refusing to use {dir} as the project root. That directory belongs to the host, not a project. Set WORKSPACE_FOLDER_PATHS to the project directory and retry.",
|
|
206218
206417
|
});
|
|
206219
206418
|
|
|
206220
206419
|
|
|
@@ -206422,6 +206621,7 @@ const msgPush_js_1 = __webpack_require__(26191);
|
|
|
206422
206621
|
const setup_js_1 = __webpack_require__(8707);
|
|
206423
206622
|
const envSetup_js_1 = __webpack_require__(57148);
|
|
206424
206623
|
const interactive_js_1 = __webpack_require__(91838);
|
|
206624
|
+
const feedback_js_1 = __webpack_require__(99391);
|
|
206425
206625
|
exports.zh = {
|
|
206426
206626
|
env: env_js_1.env.zh,
|
|
206427
206627
|
storage: storage_js_1.storage.zh,
|
|
@@ -206451,6 +206651,7 @@ exports.zh = {
|
|
|
206451
206651
|
setup: setup_js_1.setup.zh,
|
|
206452
206652
|
envSetup: envSetup_js_1.envSetup.zh,
|
|
206453
206653
|
interactive: interactive_js_1.interactive.zh,
|
|
206654
|
+
feedback: feedback_js_1.feedback.zh,
|
|
206454
206655
|
};
|
|
206455
206656
|
|
|
206456
206657
|
|
|
@@ -206630,6 +206831,7 @@ const apps_js_1 = __webpack_require__(38267);
|
|
|
206630
206831
|
const logs_js_1 = __webpack_require__(61628);
|
|
206631
206832
|
const permissions_js_1 = __webpack_require__(52639);
|
|
206632
206833
|
const msg_push_js_1 = __webpack_require__(87707);
|
|
206834
|
+
const feedback_js_1 = __webpack_require__(6332);
|
|
206633
206835
|
const index_js_1 = __webpack_require__(24908);
|
|
206634
206836
|
const schema_js_1 = __webpack_require__(56273);
|
|
206635
206837
|
const cloud_mode_js_1 = __webpack_require__(88694);
|
|
@@ -206659,6 +206861,7 @@ const DEFAULT_PLUGINS = [
|
|
|
206659
206861
|
"logs",
|
|
206660
206862
|
"agents",
|
|
206661
206863
|
"capi",
|
|
206864
|
+
"feedback",
|
|
206662
206865
|
];
|
|
206663
206866
|
function registerDatabase(server) {
|
|
206664
206867
|
// NoSQL 数据库按站点能力集合注册(国际站默认不支持 NoSQL)
|
|
@@ -206708,6 +206911,7 @@ const AVAILABLE_PLUGINS = {
|
|
|
206708
206911
|
deploy: { name: "deploy", register: deploy_js_1.registerDeployTools },
|
|
206709
206912
|
capi: { name: "capi", register: capi_js_1.registerCapiTools },
|
|
206710
206913
|
"msg-push": { name: "msg-push", register: msg_push_js_1.registerMsgPushTools },
|
|
206914
|
+
feedback: { name: "feedback", register: feedback_js_1.registerFeedbackTools },
|
|
206711
206915
|
};
|
|
206712
206916
|
const PLUGIN_ALIASES = {
|
|
206713
206917
|
"access-control": "permissions",
|
|
@@ -208535,6 +208739,8 @@ exports.SERVICE_VERSIONS = {
|
|
|
208535
208739
|
tag: ["2018-08-13"],
|
|
208536
208740
|
billing: ["2018-07-09"],
|
|
208537
208741
|
region: ["2022-06-27"],
|
|
208742
|
+
// 备案
|
|
208743
|
+
ba: ["2020-07-20"],
|
|
208538
208744
|
// 计算 / 容器 / 存储
|
|
208539
208745
|
cvm: ["2017-03-12"],
|
|
208540
208746
|
lighthouse: ["2020-03-24"],
|
|
@@ -209191,6 +209397,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
209191
209397
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
209192
209398
|
exports.CLOUDRUN_ENV_TYPE = exports.CLOUDRUN_DEPLOY_REGISTRATION_INTERVAL_MS = exports.CLOUDRUN_DEPLOY_REGISTRATION_MAX_WAIT_MS = exports.MASKED_CLOUDRUN_ENV_VALUE = exports.CLOUDRUN_PACKAGE_TYPES = exports.CLOUDRUN_ACCESS_TYPES = exports.CLOUDRUN_SERVICE_TYPES = void 0;
|
|
209193
209399
|
exports.maskCloudRunDetailEnvParams = maskCloudRunDetailEnvParams;
|
|
209400
|
+
exports.validateAndNormalizePath = validateAndNormalizePath;
|
|
209194
209401
|
exports.resolveCloudRunProjectDir = resolveCloudRunProjectDir;
|
|
209195
209402
|
exports.buildManageCloudRunErrorMessage = buildManageCloudRunErrorMessage;
|
|
209196
209403
|
exports.isValidCloudRunBuildId = isValidCloudRunBuildId;
|
|
@@ -209217,6 +209424,7 @@ const zod_1 = __webpack_require__(21504);
|
|
|
209217
209424
|
const cloudbase_manager_js_1 = __webpack_require__(33109);
|
|
209218
209425
|
const index_js_1 = __webpack_require__(24908);
|
|
209219
209426
|
const logger_js_1 = __webpack_require__(40781);
|
|
209427
|
+
const project_config_js_1 = __webpack_require__(39175);
|
|
209220
209428
|
const gateway_access_urls_js_1 = __webpack_require__(84173);
|
|
209221
209429
|
const notification_js_1 = __webpack_require__(4718);
|
|
209222
209430
|
const capi_js_1 = __webpack_require__(88900);
|
|
@@ -209421,31 +209629,20 @@ function checkIfAgentProject(projectPath) {
|
|
|
209421
209629
|
}
|
|
209422
209630
|
}
|
|
209423
209631
|
/**
|
|
209424
|
-
* Validate and normalize file path.
|
|
209425
|
-
*
|
|
209426
|
-
*
|
|
209427
|
-
* @param inputPath User provided path
|
|
209428
|
-
* @returns Absolute path
|
|
209632
|
+
* Validate and normalize a file path.
|
|
209633
|
+
* Absolute paths are accepted as-is. Relative paths resolve against the project
|
|
209634
|
+
* root and must stay inside it.
|
|
209429
209635
|
*/
|
|
209430
209636
|
function validateAndNormalizePath(inputPath) {
|
|
209431
|
-
|
|
209432
|
-
|
|
209433
|
-
|
|
209434
|
-
|
|
209435
|
-
|
|
209436
|
-
const
|
|
209437
|
-
|
|
209438
|
-
|
|
209439
|
-
|
|
209440
|
-
// Same filesystem root — ensure the resolved path is still inside CWD
|
|
209441
|
-
// (or is exactly CWD) to block "../" traversal.
|
|
209442
|
-
const prefix = cwd.endsWith(path_1.default.sep) ? cwd : cwd + path_1.default.sep;
|
|
209443
|
-
if (!normalizedPath.startsWith(prefix) && normalizedPath !== cwd) {
|
|
209444
|
-
throw new Error((0, index_js_1.t)("cloudrun.error.pathOutsideCwd", { cwd }));
|
|
209445
|
-
}
|
|
209446
|
-
}
|
|
209447
|
-
// Cross-root absolute paths (e.g. D:\ on Windows when CWD is C:\) are
|
|
209448
|
-
// allowed — the user own the machine and the path is explicitly absolute.
|
|
209637
|
+
if (path_1.default.isAbsolute(inputPath)) {
|
|
209638
|
+
return path_1.default.resolve(inputPath);
|
|
209639
|
+
}
|
|
209640
|
+
const projectRoot = (0, project_config_js_1.requireProjectRoot)();
|
|
209641
|
+
const normalizedPath = path_1.default.resolve(projectRoot, inputPath);
|
|
209642
|
+
const prefix = projectRoot.endsWith(path_1.default.sep) ? projectRoot : projectRoot + path_1.default.sep;
|
|
209643
|
+
if (!normalizedPath.startsWith(prefix) && normalizedPath !== projectRoot) {
|
|
209644
|
+
throw new Error((0, index_js_1.t)("cloudrun.error.pathOutsideCwd", { cwd: projectRoot, resolvedPath: normalizedPath }));
|
|
209645
|
+
}
|
|
209449
209646
|
return normalizedPath;
|
|
209450
209647
|
}
|
|
209451
209648
|
/**
|
|
@@ -213875,6 +214072,7 @@ const zod_1 = __webpack_require__(21504);
|
|
|
213875
214072
|
const cloudbase_manager_js_1 = __webpack_require__(33109);
|
|
213876
214073
|
const env_js_1 = __webpack_require__(56504);
|
|
213877
214074
|
const index_js_1 = __webpack_require__(24908);
|
|
214075
|
+
const project_config_js_1 = __webpack_require__(39175);
|
|
213878
214076
|
const tool_result_js_1 = __webpack_require__(69645);
|
|
213879
214077
|
const sql_risk_js_1 = __webpack_require__(29885);
|
|
213880
214078
|
const CATEGORY = "PostgreSQL database";
|
|
@@ -214159,19 +214357,7 @@ function validateMigrationName(name, actionLabel) {
|
|
|
214159
214357
|
return null;
|
|
214160
214358
|
}
|
|
214161
214359
|
function getMigrationProjectRoot() {
|
|
214162
|
-
|
|
214163
|
-
process.env.PROJECT_ROOT ||
|
|
214164
|
-
process.env.GITHUB_WORKSPACE ||
|
|
214165
|
-
process.env.CI_PROJECT_DIR ||
|
|
214166
|
-
process.env.BUILD_SOURCESDIRECTORY;
|
|
214167
|
-
if (fromEnv && fromEnv.trim()) {
|
|
214168
|
-
// IDEs may inject multiple folders separated by path.delimiter.
|
|
214169
|
-
const first = fromEnv.split(path.delimiter).map((p) => p.trim()).find(Boolean);
|
|
214170
|
-
if (first) {
|
|
214171
|
-
return first;
|
|
214172
|
-
}
|
|
214173
|
-
}
|
|
214174
|
-
return process.cwd();
|
|
214360
|
+
return (0, project_config_js_1.requireProjectRoot)();
|
|
214175
214361
|
}
|
|
214176
214362
|
function buildLocalMigrationFileName(version, name) {
|
|
214177
214363
|
return `${version}_${name}.sql`;
|
|
@@ -216546,7 +216732,17 @@ const QUERY_ACTIONS = [
|
|
|
216546
216732
|
"getInstanceInfo",
|
|
216547
216733
|
"describeInstance",
|
|
216548
216734
|
"getConnectionInfo",
|
|
216735
|
+
"describeInstanceSlowQueries",
|
|
216736
|
+
"describeInstanceErrorLogs",
|
|
216737
|
+
];
|
|
216738
|
+
const SLOW_QUERY_ORDER_BY = [
|
|
216739
|
+
"QueryTime",
|
|
216740
|
+
"LockTime",
|
|
216741
|
+
"RowsExamined",
|
|
216742
|
+
"RowsSent",
|
|
216549
216743
|
];
|
|
216744
|
+
const ERROR_LOG_LEVELS = ["error", "warning", "note"];
|
|
216745
|
+
const ORDER_BY_TYPE = ["asc", "desc", "ASC", "DESC"];
|
|
216550
216746
|
const MANAGE_ACTIONS = [
|
|
216551
216747
|
"provisionMySQL",
|
|
216552
216748
|
"destroyMySQL",
|
|
@@ -217053,6 +217249,138 @@ async function handleGetConnectionInfo(context) {
|
|
|
217053
217249
|
],
|
|
217054
217250
|
});
|
|
217055
217251
|
}
|
|
217252
|
+
function resolveMysqlInstanceId(instanceInfo, args) {
|
|
217253
|
+
const fromRequest = typeof args.request?.InstanceId === "string"
|
|
217254
|
+
? args.request.InstanceId
|
|
217255
|
+
: undefined;
|
|
217256
|
+
const fromDbInstance = args.dbInstance?.instanceId;
|
|
217257
|
+
const candidate = fromRequest || fromDbInstance || instanceInfo.instanceId;
|
|
217258
|
+
if (!candidate || candidate === "default") {
|
|
217259
|
+
return null;
|
|
217260
|
+
}
|
|
217261
|
+
return candidate;
|
|
217262
|
+
}
|
|
217263
|
+
async function requireReadyMysqlInstance(args, context) {
|
|
217264
|
+
const instanceInfo = await getSqlInstanceInfo(context);
|
|
217265
|
+
if (!instanceInfo.exists) {
|
|
217266
|
+
return {
|
|
217267
|
+
ok: false,
|
|
217268
|
+
payload: buildSqlToolResult({
|
|
217269
|
+
success: false,
|
|
217270
|
+
errorCode: "MYSQL_NOT_CREATED",
|
|
217271
|
+
data: sanitizeInstanceInfo(instanceInfo),
|
|
217272
|
+
message: (0, index_js_1.t)("databaseSQL.instanceLogs.notProvisioned"),
|
|
217273
|
+
nextActions: [
|
|
217274
|
+
buildNextAction(MANAGE_MYSQL_DATABASE, "provisionMySQL", (0, index_js_1.t)("databaseSQL.next.provisionBeforeSql"), { action: "provisionMySQL", confirm: true }),
|
|
217275
|
+
],
|
|
217276
|
+
}),
|
|
217277
|
+
};
|
|
217278
|
+
}
|
|
217279
|
+
const instanceId = resolveMysqlInstanceId(instanceInfo, args);
|
|
217280
|
+
if (!instanceId) {
|
|
217281
|
+
return {
|
|
217282
|
+
ok: false,
|
|
217283
|
+
payload: buildSqlToolResult({
|
|
217284
|
+
success: false,
|
|
217285
|
+
errorCode: "MYSQL_INSTANCE_ID_REQUIRED",
|
|
217286
|
+
data: sanitizeInstanceInfo(instanceInfo),
|
|
217287
|
+
message: (0, index_js_1.t)("databaseSQL.instanceLogs.instanceIdRequired"),
|
|
217288
|
+
nextActions: [
|
|
217289
|
+
buildNextAction(QUERY_MYSQL_DATABASE, "getInstanceInfo", (0, index_js_1.t)("databaseSQL.instanceLogs.resolveInstanceId"), { action: "getInstanceInfo" }),
|
|
217290
|
+
],
|
|
217291
|
+
}),
|
|
217292
|
+
};
|
|
217293
|
+
}
|
|
217294
|
+
return { ok: true, instanceInfo, instanceId };
|
|
217295
|
+
}
|
|
217296
|
+
async function handleDescribeInstanceSlowQueries(args, context) {
|
|
217297
|
+
const ready = await requireReadyMysqlInstance(args, context);
|
|
217298
|
+
if (!ready.ok) {
|
|
217299
|
+
return ready.payload;
|
|
217300
|
+
}
|
|
217301
|
+
const request = args.request || {};
|
|
217302
|
+
const cloudbase = await context.getManager();
|
|
217303
|
+
const result = await cloudbase.mysql.describeInstanceSlowQueries({
|
|
217304
|
+
InstanceId: ready.instanceId,
|
|
217305
|
+
StartTime: (typeof request.StartTime === "string" ? request.StartTime : undefined) ??
|
|
217306
|
+
args.startTime,
|
|
217307
|
+
EndTime: (typeof request.EndTime === "string" ? request.EndTime : undefined) ??
|
|
217308
|
+
args.endTime,
|
|
217309
|
+
Limit: (typeof request.Limit === "number" ? request.Limit : undefined) ??
|
|
217310
|
+
args.limit,
|
|
217311
|
+
Offset: (typeof request.Offset === "number" ? request.Offset : undefined) ??
|
|
217312
|
+
args.offset,
|
|
217313
|
+
Username: (typeof request.Username === "string" ? request.Username : undefined) ??
|
|
217314
|
+
args.username,
|
|
217315
|
+
Host: (typeof request.Host === "string" ? request.Host : undefined) ??
|
|
217316
|
+
args.host,
|
|
217317
|
+
Database: (typeof request.Database === "string" ? request.Database : undefined) ??
|
|
217318
|
+
args.database,
|
|
217319
|
+
OrderBy: (typeof request.OrderBy === "string" ? request.OrderBy : undefined) ??
|
|
217320
|
+
args.orderBy,
|
|
217321
|
+
OrderByType: (typeof request.OrderByType === "string"
|
|
217322
|
+
? request.OrderByType
|
|
217323
|
+
: undefined) ?? args.orderByType,
|
|
217324
|
+
SqlText: (typeof request.SqlText === "string" ? request.SqlText : undefined) ??
|
|
217325
|
+
args.sqlText,
|
|
217326
|
+
});
|
|
217327
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(context.server.logger, result);
|
|
217328
|
+
return buildSqlToolResult({
|
|
217329
|
+
success: true,
|
|
217330
|
+
data: {
|
|
217331
|
+
action: "describeInstanceSlowQueries",
|
|
217332
|
+
instanceId: ready.instanceId,
|
|
217333
|
+
totalCount: result.TotalCount ?? 0,
|
|
217334
|
+
slowQueries: result.SlowQueries ?? [],
|
|
217335
|
+
requestId: result.RequestId,
|
|
217336
|
+
raw: result,
|
|
217337
|
+
},
|
|
217338
|
+
message: (0, index_js_1.t)("databaseSQL.instanceLogs.slowQueriesSuccess"),
|
|
217339
|
+
});
|
|
217340
|
+
}
|
|
217341
|
+
async function handleDescribeInstanceErrorLogs(args, context) {
|
|
217342
|
+
const ready = await requireReadyMysqlInstance(args, context);
|
|
217343
|
+
if (!ready.ok) {
|
|
217344
|
+
return ready.payload;
|
|
217345
|
+
}
|
|
217346
|
+
const request = args.request || {};
|
|
217347
|
+
const cloudbase = await context.getManager();
|
|
217348
|
+
const result = await cloudbase.mysql.describeInstanceErrorLogs({
|
|
217349
|
+
InstanceId: ready.instanceId,
|
|
217350
|
+
Limit: (typeof request.Limit === "number" ? request.Limit : undefined) ??
|
|
217351
|
+
args.limit,
|
|
217352
|
+
Offset: (typeof request.Offset === "number" ? request.Offset : undefined) ??
|
|
217353
|
+
args.offset,
|
|
217354
|
+
StartTime: (typeof request.StartTime === "string" ? request.StartTime : undefined) ??
|
|
217355
|
+
args.startTime,
|
|
217356
|
+
EndTime: (typeof request.EndTime === "string" ? request.EndTime : undefined) ??
|
|
217357
|
+
args.endTime,
|
|
217358
|
+
OrderBy: (typeof request.OrderBy === "string" ? request.OrderBy : undefined) ??
|
|
217359
|
+
(args.orderBy === "Timestamp" ? args.orderBy : undefined),
|
|
217360
|
+
OrderByType: (typeof request.OrderByType === "string"
|
|
217361
|
+
? request.OrderByType
|
|
217362
|
+
: undefined) ?? args.orderByType,
|
|
217363
|
+
LogLevels: (Array.isArray(request.LogLevels)
|
|
217364
|
+
? request.LogLevels
|
|
217365
|
+
: undefined) ?? args.logLevels,
|
|
217366
|
+
KeyWords: (Array.isArray(request.KeyWords)
|
|
217367
|
+
? request.KeyWords
|
|
217368
|
+
: undefined) ?? args.keyWords,
|
|
217369
|
+
});
|
|
217370
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(context.server.logger, result);
|
|
217371
|
+
return buildSqlToolResult({
|
|
217372
|
+
success: true,
|
|
217373
|
+
data: {
|
|
217374
|
+
action: "describeInstanceErrorLogs",
|
|
217375
|
+
instanceId: ready.instanceId,
|
|
217376
|
+
totalCount: result.TotalCount ?? 0,
|
|
217377
|
+
errorLogs: result.ErrorLogs ?? [],
|
|
217378
|
+
requestId: result.RequestId,
|
|
217379
|
+
raw: result,
|
|
217380
|
+
},
|
|
217381
|
+
message: (0, index_js_1.t)("databaseSQL.instanceLogs.errorLogsSuccess"),
|
|
217382
|
+
});
|
|
217383
|
+
}
|
|
217056
217384
|
async function handleProvisionMySQL(args, context) {
|
|
217057
217385
|
if (args.confirm !== true) {
|
|
217058
217386
|
return buildSqlToolResult({
|
|
@@ -217423,6 +217751,54 @@ function registerSQLDatabaseTools(server) {
|
|
|
217423
217751
|
})
|
|
217424
217752
|
.optional()
|
|
217425
217753
|
.describe("databaseSQL.schema.query.dbInstance"),
|
|
217754
|
+
startTime: zod_1.z
|
|
217755
|
+
.string()
|
|
217756
|
+
.optional()
|
|
217757
|
+
.describe("databaseSQL.schema.query.startTime"),
|
|
217758
|
+
endTime: zod_1.z
|
|
217759
|
+
.string()
|
|
217760
|
+
.optional()
|
|
217761
|
+
.describe("databaseSQL.schema.query.endTime"),
|
|
217762
|
+
limit: zod_1.z
|
|
217763
|
+
.number()
|
|
217764
|
+
.optional()
|
|
217765
|
+
.describe("databaseSQL.schema.query.limit"),
|
|
217766
|
+
offset: zod_1.z
|
|
217767
|
+
.number()
|
|
217768
|
+
.optional()
|
|
217769
|
+
.describe("databaseSQL.schema.query.offset"),
|
|
217770
|
+
username: zod_1.z
|
|
217771
|
+
.string()
|
|
217772
|
+
.optional()
|
|
217773
|
+
.describe("databaseSQL.schema.query.username"),
|
|
217774
|
+
host: zod_1.z
|
|
217775
|
+
.string()
|
|
217776
|
+
.optional()
|
|
217777
|
+
.describe("databaseSQL.schema.query.host"),
|
|
217778
|
+
database: zod_1.z
|
|
217779
|
+
.string()
|
|
217780
|
+
.optional()
|
|
217781
|
+
.describe("databaseSQL.schema.query.database"),
|
|
217782
|
+
orderBy: zod_1.z
|
|
217783
|
+
.enum([...SLOW_QUERY_ORDER_BY, "Timestamp"])
|
|
217784
|
+
.optional()
|
|
217785
|
+
.describe("databaseSQL.schema.query.orderBy"),
|
|
217786
|
+
orderByType: zod_1.z
|
|
217787
|
+
.enum(ORDER_BY_TYPE)
|
|
217788
|
+
.optional()
|
|
217789
|
+
.describe("databaseSQL.schema.query.orderByType"),
|
|
217790
|
+
sqlText: zod_1.z
|
|
217791
|
+
.string()
|
|
217792
|
+
.optional()
|
|
217793
|
+
.describe("databaseSQL.schema.query.sqlText"),
|
|
217794
|
+
logLevels: zod_1.z
|
|
217795
|
+
.array(zod_1.z.enum(ERROR_LOG_LEVELS))
|
|
217796
|
+
.optional()
|
|
217797
|
+
.describe("databaseSQL.schema.query.logLevels"),
|
|
217798
|
+
keyWords: zod_1.z
|
|
217799
|
+
.array(zod_1.z.string())
|
|
217800
|
+
.optional()
|
|
217801
|
+
.describe("databaseSQL.schema.query.keyWords"),
|
|
217426
217802
|
},
|
|
217427
217803
|
annotations: {
|
|
217428
217804
|
readOnlyHint: true,
|
|
@@ -217446,6 +217822,10 @@ function registerSQLDatabaseTools(server) {
|
|
|
217446
217822
|
return handleGetInstanceInfo(context);
|
|
217447
217823
|
case "getConnectionInfo":
|
|
217448
217824
|
return handleGetConnectionInfo(context);
|
|
217825
|
+
case "describeInstanceSlowQueries":
|
|
217826
|
+
return handleDescribeInstanceSlowQueries(args, context);
|
|
217827
|
+
case "describeInstanceErrorLogs":
|
|
217828
|
+
return handleDescribeInstanceErrorLogs(args, context);
|
|
217449
217829
|
default:
|
|
217450
217830
|
throw new Error((0, index_js_1.t)("databaseSQL.unsupportedQueryAction", { action: args.action }));
|
|
217451
217831
|
}
|
|
@@ -217543,6 +217923,7 @@ const zod_1 = __webpack_require__(21504);
|
|
|
217543
217923
|
const cloudbase_manager_js_1 = __webpack_require__(33109);
|
|
217544
217924
|
const index_js_1 = __webpack_require__(24908);
|
|
217545
217925
|
const json_content_js_1 = __webpack_require__(18027);
|
|
217926
|
+
const project_config_js_1 = __webpack_require__(39175);
|
|
217546
217927
|
const sql_risk_js_1 = __webpack_require__(29885);
|
|
217547
217928
|
const hosting_build_utils_js_1 = __webpack_require__(27572);
|
|
217548
217929
|
// 声明式部署可编排的资源类型,与 DeployOrchestrator 的部署顺序一致:
|
|
@@ -217807,7 +218188,7 @@ function registerDeployTools(server) {
|
|
|
217807
218188
|
},
|
|
217808
218189
|
}, async ({ cwd, mode }) => {
|
|
217809
218190
|
try {
|
|
217810
|
-
const projectRoot =
|
|
218191
|
+
const projectRoot = (0, project_config_js_1.requireProjectRoot)(cwd);
|
|
217811
218192
|
const config = await resolveDeployConfig({ cwd: projectRoot, mode });
|
|
217812
218193
|
assertConfigValid(config);
|
|
217813
218194
|
const hostingItems = Array.isArray(config.hosting)
|
|
@@ -217879,7 +218260,7 @@ function registerDeployTools(server) {
|
|
|
217879
218260
|
},
|
|
217880
218261
|
}, async ({ cwd, mode, envId: envIdInput, only, skip, yes, }) => {
|
|
217881
218262
|
try {
|
|
217882
|
-
const projectRoot =
|
|
218263
|
+
const projectRoot = (0, project_config_js_1.requireProjectRoot)(cwd);
|
|
217883
218264
|
const config = await resolveDeployConfig({ cwd: projectRoot, mode });
|
|
217884
218265
|
assertConfigValid(config);
|
|
217885
218266
|
const envId = await resolveDeployEnvId({
|
|
@@ -217963,7 +218344,7 @@ function registerDeployTools(server) {
|
|
|
217963
218344
|
if (confirm !== true) {
|
|
217964
218345
|
throw new DeployError(exports.DEPLOY_ERROR_CODES.CONFIRM_REQUIRED, (0, index_js_1.t)("deploy.confirmRequired"));
|
|
217965
218346
|
}
|
|
217966
|
-
const projectRoot =
|
|
218347
|
+
const projectRoot = (0, project_config_js_1.requireProjectRoot)(cwd);
|
|
217967
218348
|
const config = await resolveDeployConfig({ cwd: projectRoot, mode });
|
|
217968
218349
|
assertConfigValid(config);
|
|
217969
218350
|
const envId = await resolveDeployEnvId({
|
|
@@ -221900,6 +222281,507 @@ function registerEnvTools(server) {
|
|
|
221900
222281
|
}
|
|
221901
222282
|
|
|
221902
222283
|
|
|
222284
|
+
/***/ },
|
|
222285
|
+
|
|
222286
|
+
/***/ 6332
|
|
222287
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
222288
|
+
|
|
222289
|
+
"use strict";
|
|
222290
|
+
|
|
222291
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
222292
|
+
exports.FEEDBACK_PREFILL_URL_LIMIT = exports.FEEDBACK_ISSUE_NEW_URL = exports.FEEDBACK_TOOL_NAME = void 0;
|
|
222293
|
+
exports.resolveMcpVersion = resolveMcpVersion;
|
|
222294
|
+
exports.buildFeedbackIssueUrl = buildFeedbackIssueUrl;
|
|
222295
|
+
exports.buildFeedbackIssueLink = buildFeedbackIssueLink;
|
|
222296
|
+
exports.buildFeedbackPayload = buildFeedbackPayload;
|
|
222297
|
+
exports.registerFeedbackTools = registerFeedbackTools;
|
|
222298
|
+
const zod_1 = __webpack_require__(21504);
|
|
222299
|
+
const feedback_session_js_1 = __webpack_require__(23379);
|
|
222300
|
+
const json_content_js_1 = __webpack_require__(18027);
|
|
222301
|
+
const site_map_js_1 = __webpack_require__(34533);
|
|
222302
|
+
/**
|
|
222303
|
+
* Not a CloudBase resource, so this does not use the query* / manage* pair.
|
|
222304
|
+
* The feedback plugin is in the default set and always registers this tool.
|
|
222305
|
+
*/
|
|
222306
|
+
exports.FEEDBACK_TOOL_NAME = "prepareFeedback";
|
|
222307
|
+
const CASE_TEMPLATE_FILE = "1-case-showcase.yml";
|
|
222308
|
+
const RETROSPECTIVE_TEMPLATE_FILE = "2-dev-retrospective.yml";
|
|
222309
|
+
/** Fixed new-issue pages. Intl uses GitHub. Domestic uses the CNB CloudBase-AI-ToolKit repo. */
|
|
222310
|
+
exports.FEEDBACK_ISSUE_NEW_URL = {
|
|
222311
|
+
intl: "https://github.com/TencentCloudBase/CloudBase-AI-ToolKit/issues/new",
|
|
222312
|
+
domestic: "https://cnb.cool/tencent/cloud/cloudbase/CloudBase-AI-ToolKit/-/issues/new",
|
|
222313
|
+
};
|
|
222314
|
+
const RESOURCE_BY_TOOL = {
|
|
222315
|
+
queryHosting: { zh: "静态托管", en: "Static hosting" },
|
|
222316
|
+
manageHosting: { zh: "静态托管", en: "Static hosting" },
|
|
222317
|
+
readNoSqlDatabaseStructure: { zh: "云数据库(文档型)", en: "Document database" },
|
|
222318
|
+
writeNoSqlDatabaseStructure: { zh: "云数据库(文档型)", en: "Document database" },
|
|
222319
|
+
readNoSqlDatabaseContent: { zh: "云数据库(文档型)", en: "Document database" },
|
|
222320
|
+
writeNoSqlDatabaseContent: { zh: "云数据库(文档型)", en: "Document database" },
|
|
222321
|
+
queryMysqlDatabase: { zh: "云数据库(MySQL)", en: "MySQL" },
|
|
222322
|
+
manageMysqlDatabase: { zh: "云数据库(MySQL)", en: "MySQL" },
|
|
222323
|
+
queryPgDatabase: { zh: "云数据库(PostgreSQL)", en: "PostgreSQL" },
|
|
222324
|
+
managePgDatabase: { zh: "云数据库(PostgreSQL)", en: "PostgreSQL" },
|
|
222325
|
+
queryFunctions: { zh: "云函数", en: "Cloud functions" },
|
|
222326
|
+
manageFunctions: { zh: "云函数", en: "Cloud functions" },
|
|
222327
|
+
queryStorage: { zh: "云存储", en: "Cloud storage" },
|
|
222328
|
+
manageStorage: { zh: "云存储", en: "Cloud storage" },
|
|
222329
|
+
queryPgStorage: { zh: "云存储", en: "Cloud storage" },
|
|
222330
|
+
queryAppAuth: { zh: "身份认证", en: "Auth" },
|
|
222331
|
+
manageAppAuth: { zh: "身份认证", en: "Auth" },
|
|
222332
|
+
queryCloudRun: { zh: "CloudRun", en: "CloudRun" },
|
|
222333
|
+
manageCloudRun: { zh: "CloudRun", en: "CloudRun" },
|
|
222334
|
+
};
|
|
222335
|
+
/** Stay under common browser and proxy URL limits. Longer drafts are pasted by the user. */
|
|
222336
|
+
exports.FEEDBACK_PREFILL_URL_LIMIT = 6000;
|
|
222337
|
+
function resolveMcpVersion(declared, packageVersion) {
|
|
222338
|
+
const fromBuild = typeof declared === "string" ? declared.trim() : "";
|
|
222339
|
+
if (fromBuild) {
|
|
222340
|
+
return fromBuild;
|
|
222341
|
+
}
|
|
222342
|
+
const fromPackage = typeof packageVersion === "string" ? packageVersion.trim() : "";
|
|
222343
|
+
return fromPackage;
|
|
222344
|
+
}
|
|
222345
|
+
function readDeclaredMcpVersion() {
|
|
222346
|
+
return true ? "2.34.7" : 0;
|
|
222347
|
+
}
|
|
222348
|
+
function blank(value, lang) {
|
|
222349
|
+
return value.trim().length > 0 ? value.trim() : (lang === "en" ? "blank" : "留空");
|
|
222350
|
+
}
|
|
222351
|
+
function feedbackSite(server) {
|
|
222352
|
+
return (0, site_map_js_1.resolveSiteAndRegion)({
|
|
222353
|
+
site: server.cloudBaseOptions?.site,
|
|
222354
|
+
region: server.cloudBaseOptions?.region,
|
|
222355
|
+
}).site;
|
|
222356
|
+
}
|
|
222357
|
+
function feedbackLang(site) {
|
|
222358
|
+
return site === "intl" ? "en" : "zh";
|
|
222359
|
+
}
|
|
222360
|
+
function uniqueJoin(parts) {
|
|
222361
|
+
const seen = new Set();
|
|
222362
|
+
const ordered = [];
|
|
222363
|
+
for (const part of parts) {
|
|
222364
|
+
const trimmed = part.trim();
|
|
222365
|
+
if (!trimmed || seen.has(trimmed)) {
|
|
222366
|
+
continue;
|
|
222367
|
+
}
|
|
222368
|
+
seen.add(trimmed);
|
|
222369
|
+
ordered.push(trimmed);
|
|
222370
|
+
}
|
|
222371
|
+
return ordered.join(" / ");
|
|
222372
|
+
}
|
|
222373
|
+
function readAgentLabel(server) {
|
|
222374
|
+
const ide = server.ide || process.env.INTEGRATION_IDE || "";
|
|
222375
|
+
const client = server.client || process.env.CLOUDBASE_MCP_CLIENT || "";
|
|
222376
|
+
return uniqueJoin([ide, client]);
|
|
222377
|
+
}
|
|
222378
|
+
function toLocalIso(iso) {
|
|
222379
|
+
const date = new Date(iso);
|
|
222380
|
+
if (Number.isNaN(date.getTime())) {
|
|
222381
|
+
return "";
|
|
222382
|
+
}
|
|
222383
|
+
const pad = (value) => String(value).padStart(2, "0");
|
|
222384
|
+
const offsetMinutes = -date.getTimezoneOffset();
|
|
222385
|
+
const sign = offsetMinutes >= 0 ? "+" : "-";
|
|
222386
|
+
const absolute = Math.abs(offsetMinutes);
|
|
222387
|
+
return (`${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}` +
|
|
222388
|
+
`T${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}` +
|
|
222389
|
+
`${sign}${pad(Math.floor(absolute / 60))}:${pad(absolute % 60)}`);
|
|
222390
|
+
}
|
|
222391
|
+
function resourceTypesFrom(outcomes, lang) {
|
|
222392
|
+
const seen = new Set();
|
|
222393
|
+
const types = [];
|
|
222394
|
+
for (const outcome of outcomes) {
|
|
222395
|
+
if (outcome.failed) {
|
|
222396
|
+
continue;
|
|
222397
|
+
}
|
|
222398
|
+
const resourceType = RESOURCE_BY_TOOL[outcome.toolName]?.[lang];
|
|
222399
|
+
if (!resourceType || seen.has(resourceType)) {
|
|
222400
|
+
continue;
|
|
222401
|
+
}
|
|
222402
|
+
seen.add(resourceType);
|
|
222403
|
+
types.push(resourceType);
|
|
222404
|
+
}
|
|
222405
|
+
return types;
|
|
222406
|
+
}
|
|
222407
|
+
function formatDeployDuration(outcomes, lang) {
|
|
222408
|
+
const build = outcomes.filter((item) => !item.failed && item.toolName === "deployBuild");
|
|
222409
|
+
const apply = outcomes.filter((item) => !item.failed && item.toolName === "deployApply");
|
|
222410
|
+
if (build.length === 0 && apply.length === 0) {
|
|
222411
|
+
return "";
|
|
222412
|
+
}
|
|
222413
|
+
const sum = (items) => items.reduce((total, item) => total + item.durationMs, 0);
|
|
222414
|
+
const parts = [];
|
|
222415
|
+
if (build.length > 0) {
|
|
222416
|
+
parts.push(`deployBuild ${sum(build)}ms`);
|
|
222417
|
+
}
|
|
222418
|
+
if (apply.length > 0) {
|
|
222419
|
+
parts.push(`deployApply ${sum(apply)}ms`);
|
|
222420
|
+
}
|
|
222421
|
+
const joined = parts.join(lang === "en" ? "; " : ";");
|
|
222422
|
+
return lang === "en"
|
|
222423
|
+
? `${joined}. Cloud build time and end-to-end time cannot be separated from these tool names.`
|
|
222424
|
+
: `${joined}。无法区分云端构建与端到端,只记录上述工具耗时,未补另一项`;
|
|
222425
|
+
}
|
|
222426
|
+
function latestDeployTime(outcomes) {
|
|
222427
|
+
const deployOutcomes = outcomes.filter((item) => !item.failed && (item.toolName === "deployBuild" || item.toolName === "deployApply"));
|
|
222428
|
+
if (deployOutcomes.length === 0) {
|
|
222429
|
+
return "";
|
|
222430
|
+
}
|
|
222431
|
+
const latest = deployOutcomes.reduce((current, item) => (item.at > current.at ? item : current));
|
|
222432
|
+
return toLocalIso(latest.at);
|
|
222433
|
+
}
|
|
222434
|
+
function failureLines(server, outcomes, lang) {
|
|
222435
|
+
const counts = new Map();
|
|
222436
|
+
for (const outcome of outcomes) {
|
|
222437
|
+
if (!outcome.failed) {
|
|
222438
|
+
continue;
|
|
222439
|
+
}
|
|
222440
|
+
counts.set(outcome.toolName, (counts.get(outcome.toolName) ?? 0) + 1);
|
|
222441
|
+
}
|
|
222442
|
+
const lines = [];
|
|
222443
|
+
for (const [toolName, count] of counts) {
|
|
222444
|
+
lines.push(lang === "en"
|
|
222445
|
+
? `- Verified: tool call failed ${toolName} ×${count}`
|
|
222446
|
+
: `- 可验证事实:工具调用失败 ${toolName} ×${count}`);
|
|
222447
|
+
}
|
|
222448
|
+
const repeatPeak = (0, feedback_session_js_1.readRepeatPeak)(server);
|
|
222449
|
+
if (repeatPeak > 0) {
|
|
222450
|
+
lines.push(lang === "en"
|
|
222451
|
+
? `- Verified: peak consecutive identical structured errors ${repeatPeak}`
|
|
222452
|
+
: `- 可验证事实:连续相同结构化错误峰值 ${repeatPeak}`);
|
|
222453
|
+
}
|
|
222454
|
+
return lines;
|
|
222455
|
+
}
|
|
222456
|
+
function collectSecretValues(server) {
|
|
222457
|
+
const options = server.cloudBaseOptions;
|
|
222458
|
+
return [options?.envId, options?.secretId, options?.secretKey, options?.token].filter((value) => typeof value === "string" && value.trim().length >= 6);
|
|
222459
|
+
}
|
|
222460
|
+
function redact(text, secrets) {
|
|
222461
|
+
let redacted = text;
|
|
222462
|
+
for (const secret of secrets) {
|
|
222463
|
+
redacted = redacted.split(secret).join("");
|
|
222464
|
+
}
|
|
222465
|
+
return redacted;
|
|
222466
|
+
}
|
|
222467
|
+
function buildCaseDraft(server, outcomes, lang) {
|
|
222468
|
+
const resources = resourceTypesFrom(outcomes, lang);
|
|
222469
|
+
const empty = blank("", lang);
|
|
222470
|
+
const resourceText = resources.length > 0 ? resources.join(lang === "en" ? ", " : "、") : empty;
|
|
222471
|
+
const version = blank(resolveMcpVersion(readDeclaredMcpVersion(), process.env.npm_package_version), lang);
|
|
222472
|
+
if (lang === "en") {
|
|
222473
|
+
return [
|
|
222474
|
+
"This issue will be public. Do not add an environment ID, secrets, or user data.",
|
|
222475
|
+
`Work name: ${empty}`,
|
|
222476
|
+
`One-line summary: ${empty}`,
|
|
222477
|
+
`Public URL: ${empty}`,
|
|
222478
|
+
`Cover / screenshot: ${empty}`,
|
|
222479
|
+
`Agent / CLI: ${blank(readAgentLabel(server), lang)}`,
|
|
222480
|
+
`Model: ${empty}`,
|
|
222481
|
+
`MCP version: ${version}`,
|
|
222482
|
+
`Deploy duration: ${blank(formatDeployDuration(outcomes, lang), lang)}`,
|
|
222483
|
+
`Cloud resources: ${resourceText}`,
|
|
222484
|
+
`Deploy time: ${blank(latestDeployTime(outcomes), lang)}`,
|
|
222485
|
+
`Author: ${empty}`,
|
|
222486
|
+
`Pitfalls: ${empty}`,
|
|
222487
|
+
`Other notes: ${empty}`,
|
|
222488
|
+
].join("\n");
|
|
222489
|
+
}
|
|
222490
|
+
return [
|
|
222491
|
+
"这条 Issue 会公开。不要补充环境 ID、密钥或用户数据。",
|
|
222492
|
+
`作品名称:${empty}`,
|
|
222493
|
+
`一句话简介:${empty}`,
|
|
222494
|
+
`公网访问地址:${empty}`,
|
|
222495
|
+
`封面 / 截图地址:${empty}`,
|
|
222496
|
+
`Agent / CLI:${blank(readAgentLabel(server), lang)}`,
|
|
222497
|
+
`所用模型:${empty}`,
|
|
222498
|
+
`MCP 版本:${version}`,
|
|
222499
|
+
`部署耗时:${blank(formatDeployDuration(outcomes, lang), lang)}`,
|
|
222500
|
+
`用到的云资源:${resourceText}`,
|
|
222501
|
+
`部署时间:${blank(latestDeployTime(outcomes), lang)}`,
|
|
222502
|
+
`作者署名 / 主页:${empty}`,
|
|
222503
|
+
`开发过程中踩到的坑:${empty}`,
|
|
222504
|
+
`其他补充:${empty}`,
|
|
222505
|
+
].join("\n");
|
|
222506
|
+
}
|
|
222507
|
+
function buildRetrospectiveDraft(server, outcomes, lang) {
|
|
222508
|
+
const resources = resourceTypesFrom(outcomes, lang);
|
|
222509
|
+
const failures = failureLines(server, outcomes, lang);
|
|
222510
|
+
const empty = blank("", lang);
|
|
222511
|
+
if (lang === "en") {
|
|
222512
|
+
const failureBlock = failures.length > 0
|
|
222513
|
+
? failures.join("\n")
|
|
222514
|
+
: "No tool failures recorded in this session.";
|
|
222515
|
+
const resourceBlock = resources.length > 0
|
|
222516
|
+
? resources.join(", ")
|
|
222517
|
+
: empty;
|
|
222518
|
+
return [
|
|
222519
|
+
"This issue will be public. Do not add an environment ID, secrets, collection names, or function names.",
|
|
222520
|
+
"Conversation turns are not collected. Do not invent a turn count.",
|
|
222521
|
+
"",
|
|
222522
|
+
"Tool failures:",
|
|
222523
|
+
failureBlock,
|
|
222524
|
+
"",
|
|
222525
|
+
"Cloud resources:",
|
|
222526
|
+
resourceBlock,
|
|
222527
|
+
].join("\n");
|
|
222528
|
+
}
|
|
222529
|
+
const failureBlock = failures.length > 0
|
|
222530
|
+
? failures.join("\n")
|
|
222531
|
+
: "本次会话没有记录到工具失败。";
|
|
222532
|
+
const resourceBlock = resources.length > 0
|
|
222533
|
+
? resources.join("、")
|
|
222534
|
+
: empty;
|
|
222535
|
+
return [
|
|
222536
|
+
"这条 Issue 会公开。不要补充环境 ID、密钥、集合名或函数名。",
|
|
222537
|
+
"不采集对话轮次。不要把失败次数写成轮次,也不要补一个数字。",
|
|
222538
|
+
"",
|
|
222539
|
+
"工具失败:",
|
|
222540
|
+
failureBlock,
|
|
222541
|
+
"",
|
|
222542
|
+
"云资源:",
|
|
222543
|
+
resourceBlock,
|
|
222544
|
+
].join("\n");
|
|
222545
|
+
}
|
|
222546
|
+
function buildFeedbackIssueUrl(site, channel, draft) {
|
|
222547
|
+
return buildFeedbackIssueLink(site, channel, draft).url;
|
|
222548
|
+
}
|
|
222549
|
+
function buildFeedbackIssueLink(site, channel, draft) {
|
|
222550
|
+
const title = site === "intl"
|
|
222551
|
+
? (channel === "case" ? "[case] " : "[retrospective] ")
|
|
222552
|
+
: (channel === "case" ? "[案例] " : "[复盘] ");
|
|
222553
|
+
const base = exports.FEEDBACK_ISSUE_NEW_URL[site];
|
|
222554
|
+
const draftQuery = site === "intl"
|
|
222555
|
+
? `body=${encodeURIComponent(draft)}`
|
|
222556
|
+
: `session=${encodeURIComponent(draft)}`;
|
|
222557
|
+
const head = site === "intl"
|
|
222558
|
+
? `${base}?title=${encodeURIComponent(title)}`
|
|
222559
|
+
: `${base}?template=${encodeURIComponent(channel === "case" ? CASE_TEMPLATE_FILE : RETROSPECTIVE_TEMPLATE_FILE)}&title=${encodeURIComponent(title)}`;
|
|
222560
|
+
const prefilled = `${head}&${draftQuery}`;
|
|
222561
|
+
if (prefilled.length <= exports.FEEDBACK_PREFILL_URL_LIMIT) {
|
|
222562
|
+
return { url: prefilled, prefilled: true };
|
|
222563
|
+
}
|
|
222564
|
+
return { url: head, prefilled: false };
|
|
222565
|
+
}
|
|
222566
|
+
function buildFeedbackPayload(input) {
|
|
222567
|
+
const site = feedbackSite(input.server);
|
|
222568
|
+
const lang = feedbackLang(site);
|
|
222569
|
+
const outcomes = (0, feedback_session_js_1.readToolOutcomes)(input.server);
|
|
222570
|
+
const secrets = collectSecretValues(input.server);
|
|
222571
|
+
const draft = redact(input.channel === "case"
|
|
222572
|
+
? buildCaseDraft(input.server, outcomes, lang)
|
|
222573
|
+
: buildRetrospectiveDraft(input.server, outcomes, lang), secrets);
|
|
222574
|
+
if (!input.confirmed) {
|
|
222575
|
+
return {
|
|
222576
|
+
success: true,
|
|
222577
|
+
channel: input.channel,
|
|
222578
|
+
confirmed: false,
|
|
222579
|
+
submittable: false,
|
|
222580
|
+
draft,
|
|
222581
|
+
nextStep: lang === "en"
|
|
222582
|
+
? "Show this draft to the user unchanged. Do not give a submission link before they explicitly confirm. Do not rewrite it into a different write-up."
|
|
222583
|
+
: "把这份 draft 原样给用户看。用户明确确认之前,不要给出提交链接,也不要改写成另一份说明。",
|
|
222584
|
+
};
|
|
222585
|
+
}
|
|
222586
|
+
const link = buildFeedbackIssueLink(site, input.channel, draft);
|
|
222587
|
+
const pasteHint = link.prefilled
|
|
222588
|
+
? ""
|
|
222589
|
+
: (lang === "en"
|
|
222590
|
+
? " The link does not include the draft because the URL would be too long. Paste the draft into the session field."
|
|
222591
|
+
: " 链接没有带上正文,因为地址过长。请把 draft 粘贴到「本次会话记录」。");
|
|
222592
|
+
return {
|
|
222593
|
+
success: true,
|
|
222594
|
+
channel: input.channel,
|
|
222595
|
+
confirmed: true,
|
|
222596
|
+
submittable: true,
|
|
222597
|
+
draft,
|
|
222598
|
+
url: link.url,
|
|
222599
|
+
nextStep: (lang === "en"
|
|
222600
|
+
? "The user confirmed. The link body is this draft. Do not submit a rewritten version, and do not submit it for them."
|
|
222601
|
+
: "用户已确认。链接里的正文就是这份 draft。不要另写一版再提交,也不要代为提交。") + pasteHint,
|
|
222602
|
+
};
|
|
222603
|
+
}
|
|
222604
|
+
function registerFeedbackTools(server) {
|
|
222605
|
+
server.registerTool(exports.FEEDBACK_TOOL_NAME, {
|
|
222606
|
+
title: "feedback.title",
|
|
222607
|
+
description: "feedback.description",
|
|
222608
|
+
inputSchema: {
|
|
222609
|
+
channel: zod_1.z
|
|
222610
|
+
.enum(["case", "retrospective"])
|
|
222611
|
+
.describe("feedback.schema.channel"),
|
|
222612
|
+
confirmed: zod_1.z
|
|
222613
|
+
.boolean()
|
|
222614
|
+
.optional()
|
|
222615
|
+
.describe("feedback.schema.confirmed"),
|
|
222616
|
+
},
|
|
222617
|
+
annotations: {
|
|
222618
|
+
readOnlyHint: true,
|
|
222619
|
+
destructiveHint: false,
|
|
222620
|
+
openWorldHint: false,
|
|
222621
|
+
category: "feedback",
|
|
222622
|
+
},
|
|
222623
|
+
}, async ({ channel, confirmed }) => {
|
|
222624
|
+
return (0, json_content_js_1.jsonContent)(buildFeedbackPayload({
|
|
222625
|
+
server,
|
|
222626
|
+
channel,
|
|
222627
|
+
confirmed: confirmed === true,
|
|
222628
|
+
}));
|
|
222629
|
+
});
|
|
222630
|
+
}
|
|
222631
|
+
|
|
222632
|
+
|
|
222633
|
+
/***/ },
|
|
222634
|
+
|
|
222635
|
+
/***/ 65735
|
|
222636
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
222637
|
+
|
|
222638
|
+
"use strict";
|
|
222639
|
+
|
|
222640
|
+
/**
|
|
222641
|
+
* 云函数 ZIP 两段式部署·阶段 A:生成 COS 预签名上传地址。
|
|
222642
|
+
*
|
|
222643
|
+
* 通道来源(R1 探针实测裁决,见 output/2026-09-23-functions-zip-two-phase-design.md §4):
|
|
222644
|
+
* - DescribeBuildServiceCosInfo / build-service 上传 / GetTempCosInfo 三条通道全部判死
|
|
222645
|
+
* (CosTimestamp 稳定 InternalError;SCF 拉代码强制给桶名拼 -appid 后缀,共享 build 桶
|
|
222646
|
+
* 永远拉不到;tempcos 桶全 region 404)。
|
|
222647
|
+
* - 活通道:用环境自有存储桶(DescribeEnvs → Storages[0].Bucket/Region)+ 用户凭据
|
|
222648
|
+
* 本地铸 COS q-sign 预签名 PUT URL。CloudBase 临时凭据可直接用于 COS(manager-node
|
|
222649
|
+
* storage 同款 SecretId+SecretKey+token 范式),但必须把 x-cos-security-token 纳入
|
|
222650
|
+
* 签名 Headers 且请求时携带同名头。
|
|
222651
|
+
*
|
|
222652
|
+
* 设计约束:
|
|
222653
|
+
* - 纯函数、零第三方依赖(node:crypto 即可):签名算法从 cos-nodejs-sdk-v5 getAuth
|
|
222654
|
+
* 逐行复刻,测试里与 SDK 真实现做黄金值对照,防止复刻漂移。
|
|
222655
|
+
* - 预签名是本地 HMAC 计算:CAM 零新增权限、不暴露 appId(URL 用全桶名,阶段 B 回传
|
|
222656
|
+
* TCB 的 CosBucketName 用短名)、国际站天然可用。
|
|
222657
|
+
*/
|
|
222658
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
222659
|
+
exports.stripAppIdSuffix = stripAppIdSuffix;
|
|
222660
|
+
exports.camSafeUrlEncode = camSafeUrlEncode;
|
|
222661
|
+
exports.buildCosPutAuthorization = buildCosPutAuthorization;
|
|
222662
|
+
exports.buildFunctionZipUpload = buildFunctionZipUpload;
|
|
222663
|
+
const crypto_1 = __webpack_require__(55511);
|
|
222664
|
+
/** 环境存储桶全名形如 `mybucket-1258016615`;TCB CosBucketName 只收短名(不带 -appid 后缀)。 */
|
|
222665
|
+
function stripAppIdSuffix(bucket) {
|
|
222666
|
+
return bucket.replace(/-\d+$/, "");
|
|
222667
|
+
}
|
|
222668
|
+
/** 复刻 cos-nodejs-sdk-v5 util.camSafeUrlEncode:encodeURIComponent 强制编码 !'()* 五个字符。 */
|
|
222669
|
+
function camSafeUrlEncode(str) {
|
|
222670
|
+
return encodeURIComponent(str)
|
|
222671
|
+
.replace(/!/g, "%21")
|
|
222672
|
+
.replace(/'/g, "%27")
|
|
222673
|
+
.replace(/\(/g, "%28")
|
|
222674
|
+
.replace(/\)/g, "%29")
|
|
222675
|
+
.replace(/\*/g, "%2A");
|
|
222676
|
+
}
|
|
222677
|
+
/** 复刻 SDK getObjectKeys:原始 key 按小写比较排序(排序在编码之前)。 */
|
|
222678
|
+
function sortedKeys(obj) {
|
|
222679
|
+
return Object.keys(obj).sort((a, b) => {
|
|
222680
|
+
a = a.toLowerCase();
|
|
222681
|
+
b = b.toLowerCase();
|
|
222682
|
+
return a === b ? 0 : a > b ? 1 : -1;
|
|
222683
|
+
});
|
|
222684
|
+
}
|
|
222685
|
+
/** 复刻 SDK obj2str(obj, true):key 编码后小写、value 编码,按 key 升序以 & 连接。 */
|
|
222686
|
+
function encodeKv(obj) {
|
|
222687
|
+
return sortedKeys(obj)
|
|
222688
|
+
.map((key) => {
|
|
222689
|
+
const k = camSafeUrlEncode(key).toLowerCase();
|
|
222690
|
+
const v = camSafeUrlEncode(obj[key] ?? "");
|
|
222691
|
+
return `${k}=${v}`;
|
|
222692
|
+
})
|
|
222693
|
+
.join("&");
|
|
222694
|
+
}
|
|
222695
|
+
/**
|
|
222696
|
+
* 生成 COS q-sign 预签名授权串(PUT 方法)。
|
|
222697
|
+
* 算法逐行复刻 cos-nodejs-sdk-v5 getAuth:
|
|
222698
|
+
* signKey = HMAC-SHA1(SecretKey, KeyTime)
|
|
222699
|
+
* formatString = method \n pathname \n query-str \n header-str \n
|
|
222700
|
+
* stringToSign = sha1 \n KeyTime \n sha1(formatString) \n
|
|
222701
|
+
* signature = HMAC-SHA1(signKey, stringToSign)
|
|
222702
|
+
* Host 头始终签入(对齐 SDK ForceSignHost 默认 true),query 为空故 q-url-param-list 为空。
|
|
222703
|
+
*/
|
|
222704
|
+
function buildCosPutAuthorization(options) {
|
|
222705
|
+
const { secretId, secretKey, bucket, region, objectKey, securityToken, expiresInSeconds = 3600, } = options;
|
|
222706
|
+
if (!secretId)
|
|
222707
|
+
throw new Error("missing param SecretId");
|
|
222708
|
+
if (!secretKey)
|
|
222709
|
+
throw new Error("missing param SecretKey");
|
|
222710
|
+
if (!bucket)
|
|
222711
|
+
throw new Error("missing param Bucket");
|
|
222712
|
+
if (!region)
|
|
222713
|
+
throw new Error("missing param Region");
|
|
222714
|
+
if (!objectKey)
|
|
222715
|
+
throw new Error("missing param objectKey");
|
|
222716
|
+
const headers = {
|
|
222717
|
+
host: `${bucket}.cos.${region}.myqcloud.com`,
|
|
222718
|
+
};
|
|
222719
|
+
if (securityToken) {
|
|
222720
|
+
headers["x-cos-security-token"] = securityToken;
|
|
222721
|
+
}
|
|
222722
|
+
const keyTime = options.keyTime ??
|
|
222723
|
+
(() => {
|
|
222724
|
+
const now = options.now ?? Math.floor(Date.now() / 1000);
|
|
222725
|
+
return `${now - 1};${now + expiresInSeconds}`;
|
|
222726
|
+
})();
|
|
222727
|
+
// 与请求 URL 一致的编码路径(对象 key 仅允许安全字符时与原始 key 相同)。
|
|
222728
|
+
const pathname = `/${objectKey.split("/").map(encodeURIComponent).join("/")}`;
|
|
222729
|
+
const signKey = (0, crypto_1.createHmac)("sha1", secretKey).update(keyTime).digest("hex");
|
|
222730
|
+
const formatString = ["put", pathname, "", encodeKv(headers), ""].join("\n");
|
|
222731
|
+
const stringToSign = [
|
|
222732
|
+
"sha1",
|
|
222733
|
+
keyTime,
|
|
222734
|
+
(0, crypto_1.createHash)("sha1").update(Buffer.from(formatString, "utf8")).digest("hex"),
|
|
222735
|
+
"",
|
|
222736
|
+
].join("\n");
|
|
222737
|
+
const signature = (0, crypto_1.createHmac)("sha1", signKey).update(stringToSign).digest("hex");
|
|
222738
|
+
const headerList = sortedKeys(headers)
|
|
222739
|
+
.map((key) => camSafeUrlEncode(key).toLowerCase())
|
|
222740
|
+
.join(";");
|
|
222741
|
+
return [
|
|
222742
|
+
"q-sign-algorithm=sha1",
|
|
222743
|
+
`q-ak=${secretId}`,
|
|
222744
|
+
`q-sign-time=${keyTime}`,
|
|
222745
|
+
`q-key-time=${keyTime}`,
|
|
222746
|
+
`q-header-list=${headerList}`,
|
|
222747
|
+
"q-url-param-list=",
|
|
222748
|
+
`q-signature=${signature}`,
|
|
222749
|
+
].join("&");
|
|
222750
|
+
}
|
|
222751
|
+
/**
|
|
222752
|
+
* 生成两段式部署阶段 A 的完整返回体:预签名 PUT URL + 阶段 B 所需的 COS 三元组。
|
|
222753
|
+
* 对象 key 形如 `fnzip-upload/{ts}-{rand}/{functionName|code}.zip`,全部为 COS 签名
|
|
222754
|
+
* 安全字符(字母数字与 -_. /),保证签名 pathname 与请求 URL 一致。
|
|
222755
|
+
*/
|
|
222756
|
+
function buildFunctionZipUpload(params) {
|
|
222757
|
+
const { storage, credential, functionName } = params;
|
|
222758
|
+
const expiresIn = params.expiresIn ?? 3600;
|
|
222759
|
+
const ts = params.now ?? Math.floor(Date.now() / 1000);
|
|
222760
|
+
const rand = params.randomSuffix ?? (0, crypto_1.randomBytes)(8).toString("hex");
|
|
222761
|
+
const objectKey = `fnzip-upload/${ts}-${rand}/${functionName || "code"}.zip`;
|
|
222762
|
+
const keyTime = params.keyTime ?? `${ts - 1};${ts + expiresIn}`;
|
|
222763
|
+
const authorization = buildCosPutAuthorization({
|
|
222764
|
+
secretId: credential.secretId,
|
|
222765
|
+
secretKey: credential.secretKey,
|
|
222766
|
+
bucket: storage.bucket,
|
|
222767
|
+
region: storage.region,
|
|
222768
|
+
objectKey,
|
|
222769
|
+
securityToken: credential.token || undefined,
|
|
222770
|
+
keyTime,
|
|
222771
|
+
});
|
|
222772
|
+
return {
|
|
222773
|
+
uploadUrl: `https://${storage.bucket}.cos.${storage.region}.myqcloud.com/${objectKey}?${authorization}`,
|
|
222774
|
+
uploadHeaders: credential.token
|
|
222775
|
+
? [{ Key: "x-cos-security-token", Value: credential.token }]
|
|
222776
|
+
: [],
|
|
222777
|
+
cosBucketName: stripAppIdSuffix(storage.bucket),
|
|
222778
|
+
cosBucketRegion: storage.region,
|
|
222779
|
+
cosObjectName: objectKey,
|
|
222780
|
+
expiresInSeconds: expiresIn,
|
|
222781
|
+
};
|
|
222782
|
+
}
|
|
222783
|
+
|
|
222784
|
+
|
|
221903
222785
|
/***/ },
|
|
221904
222786
|
|
|
221905
222787
|
/***/ 84931
|
|
@@ -223270,7 +224152,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
223270
224152
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
223271
224153
|
};
|
|
223272
224154
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
223273
|
-
exports.CUSTOM_IMAGE_RUNTIME = exports.MASKED_ENV_VALUE = exports.LAYER_SOFT_WARN = exports.MANAGE_FUNCTION_ACTIONS = exports.QUERY_FUNCTION_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;
|
|
224155
|
+
exports.CUSTOM_IMAGE_RUNTIME = exports.MASKED_ENV_VALUE = exports.LAYER_SOFT_WARN = exports.DEFAULT_FUNCTION_ALIAS = exports.MANAGE_FUNCTION_ACTIONS = exports.QUERY_FUNCTION_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;
|
|
223274
224156
|
exports.formatRuntimeList = formatRuntimeList;
|
|
223275
224157
|
exports.layerNameIncludesEnvId = layerNameIncludesEnvId;
|
|
223276
224158
|
exports.buildCreateLayerNameWarning = buildCreateLayerNameWarning;
|
|
@@ -223290,6 +224172,7 @@ const logger_js_1 = __webpack_require__(40781);
|
|
|
223290
224172
|
const tool_result_js_1 = __webpack_require__(69645);
|
|
223291
224173
|
const function_deploy_js_1 = __webpack_require__(39151);
|
|
223292
224174
|
const function_deploy_schema_js_1 = __webpack_require__(76427);
|
|
224175
|
+
const function_cos_upload_js_1 = __webpack_require__(65735);
|
|
223293
224176
|
const function_updating_js_1 = __webpack_require__(70326);
|
|
223294
224177
|
const index_js_1 = __webpack_require__(24908);
|
|
223295
224178
|
const fs_1 = __webpack_require__(29021);
|
|
@@ -223369,6 +224252,9 @@ exports.QUERY_FUNCTION_ACTIONS = [
|
|
|
223369
224252
|
"listFunctionTriggers",
|
|
223370
224253
|
"getFunctionDownloadUrl",
|
|
223371
224254
|
"getFunctionDeployStatus",
|
|
224255
|
+
"listVersionByFunction",
|
|
224256
|
+
"getFunctionAlias",
|
|
224257
|
+
"getFunctionUploadUrl",
|
|
223372
224258
|
];
|
|
223373
224259
|
exports.MANAGE_FUNCTION_ACTIONS = [
|
|
223374
224260
|
"createFunction",
|
|
@@ -223383,8 +224269,12 @@ exports.MANAGE_FUNCTION_ACTIONS = [
|
|
|
223383
224269
|
"attachLayer",
|
|
223384
224270
|
"detachLayer",
|
|
223385
224271
|
"updateFunctionLayers",
|
|
224272
|
+
"publishVersion",
|
|
224273
|
+
"updateFunctionAliasConfig",
|
|
223386
224274
|
"incrementalDeployFunction", // 增量部署,需通过 pluginOptions.functions 注入实现
|
|
223387
224275
|
];
|
|
224276
|
+
/** Default SCF traffic alias used by CloudBase CLI `fn get-route` / `fn config-route`. */
|
|
224277
|
+
exports.DEFAULT_FUNCTION_ALIAS = "$DEFAULT";
|
|
223388
224278
|
/** Layer soft-warn copy — account-scoped SCF LayerName guidance (no hard fail). */
|
|
223389
224279
|
exports.LAYER_SOFT_WARN = {
|
|
223390
224280
|
createNameFormat: (envId) => (0, index_js_1.t)("functions.layerWarn.createNameFormat", { envId }),
|
|
@@ -223544,6 +224434,46 @@ const MANAGE_LAYER_SCHEMA = zod_1.z.object({
|
|
|
223544
224434
|
layerName: zod_1.z.string().describe("functions.schema.manageLayer.name"),
|
|
223545
224435
|
layerVersion: zod_1.z.number().describe("functions.schema.manageLayer.version"),
|
|
223546
224436
|
});
|
|
224437
|
+
/**
|
|
224438
|
+
* ZIP 两段式部署阶段 B 的 code 入参(camelCase,映射为 SDK 的 PascalCase code 三元组)。
|
|
224439
|
+
* 三件套均来自 queryFunctions getFunctionUploadUrl 的返回体,原样透传即可。
|
|
224440
|
+
* strict:拼错字段名直接报错,而不是被静默丢弃后按本地目录语义执行。
|
|
224441
|
+
*/
|
|
224442
|
+
const FUNCTION_CODE_SCHEMA = zod_1.z
|
|
224443
|
+
.object({
|
|
224444
|
+
cosBucketName: zod_1.z
|
|
224445
|
+
.string()
|
|
224446
|
+
.describe("functions.schema.code.cosBucketName"),
|
|
224447
|
+
cosObjectName: zod_1.z
|
|
224448
|
+
.string()
|
|
224449
|
+
.describe("functions.schema.code.cosObjectName"),
|
|
224450
|
+
cosBucketRegion: zod_1.z
|
|
224451
|
+
.string()
|
|
224452
|
+
.optional()
|
|
224453
|
+
.describe("functions.schema.code.cosBucketRegion"),
|
|
224454
|
+
})
|
|
224455
|
+
.strict();
|
|
224456
|
+
const FUNCTION_VERSION_WEIGHT_SCHEMA = zod_1.z.object({
|
|
224457
|
+
Version: zod_1.z.string().describe("functions.schema.routing.version"),
|
|
224458
|
+
Weight: zod_1.z.number().describe("functions.schema.routing.weight"),
|
|
224459
|
+
});
|
|
224460
|
+
const FUNCTION_VERSION_MATCH_SCHEMA = zod_1.z.object({
|
|
224461
|
+
Version: zod_1.z.string().describe("functions.schema.routing.matchVersion"),
|
|
224462
|
+
Key: zod_1.z.string().describe("functions.schema.routing.matchKey"),
|
|
224463
|
+
Method: zod_1.z.string().describe("functions.schema.routing.matchMethod"),
|
|
224464
|
+
Expression: zod_1.z.string().describe("functions.schema.routing.matchExpression"),
|
|
224465
|
+
});
|
|
224466
|
+
const FUNCTION_ROUTING_CONFIG_SCHEMA = zod_1.z.object({
|
|
224467
|
+
AdditionalVersionWeights: zod_1.z
|
|
224468
|
+
.array(FUNCTION_VERSION_WEIGHT_SCHEMA)
|
|
224469
|
+
.optional()
|
|
224470
|
+
.describe("functions.schema.routing.additionalWeights"),
|
|
224471
|
+
// Keep SCF/SDK historical field name (typo included) as the public contract.
|
|
224472
|
+
AddtionVersionMatchs: zod_1.z
|
|
224473
|
+
.array(FUNCTION_VERSION_MATCH_SCHEMA)
|
|
224474
|
+
.optional()
|
|
224475
|
+
.describe("functions.schema.routing.additionalMatches"),
|
|
224476
|
+
});
|
|
223547
224477
|
/**
|
|
223548
224478
|
* Prefer top-level functionName; fall back to func.name for the common
|
|
223549
224479
|
* mistake of nesting the target name under func (createFunction shape).
|
|
@@ -223722,6 +224652,48 @@ function registerFunctionTools(server) {
|
|
|
223722
224652
|
throw new Error((0, index_js_1.t)("functions.confirmRequired", { action }));
|
|
223723
224653
|
}
|
|
223724
224654
|
};
|
|
224655
|
+
/**
|
|
224656
|
+
* 解析当前环境的自有存储桶(DescribeEnvs → Storages[0])。
|
|
224657
|
+
* 两段式部署的上传桶必须用环境自己的桶:共享 build 桶会被 SCF 拉
|
|
224658
|
+
* 代码时的 -appid 拼接判死(R1 探针实测)。无存储的环境直接报错引导。
|
|
224659
|
+
*
|
|
224660
|
+
* DescribeEnvs 是账号级动作,环境级凭据(如 API Key 换取的 STS,
|
|
224661
|
+
* remote MCP 临时 API Key 即此类)调用会被网关拒绝(invalid token),
|
|
224662
|
+
* 此时回退到环境级的 DescribeEnvInfo —— 其 EnvBaseInfo.Storages 与
|
|
224663
|
+
* DescribeEnvs 的 Storages 同构(实测两者均含 Bucket/Region/Status)。
|
|
224664
|
+
*/
|
|
224665
|
+
const resolveEnvFunctionCosStorage = async () => {
|
|
224666
|
+
const cloudbase = await getManager();
|
|
224667
|
+
const envId = cloudBaseOptions?.envId ?? (await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions));
|
|
224668
|
+
const tcbService = cloudbase.commonService("tcb", "2018-06-08");
|
|
224669
|
+
const fetchStorages = async () => {
|
|
224670
|
+
try {
|
|
224671
|
+
const envsResult = (await tcbService.call({
|
|
224672
|
+
Action: "DescribeEnvs",
|
|
224673
|
+
Param: { EnvId: envId },
|
|
224674
|
+
}));
|
|
224675
|
+
const storages = envsResult?.EnvList?.[0]?.Storages ?? envsResult?.EnvInfo?.Storages ?? [];
|
|
224676
|
+
if (storages.length > 0) {
|
|
224677
|
+
return storages;
|
|
224678
|
+
}
|
|
224679
|
+
}
|
|
224680
|
+
catch (e) {
|
|
224681
|
+
(0, logger_js_1.debug)("resolveEnvFunctionCosStorage: DescribeEnvs failed, falling back to DescribeEnvInfo", { envId, error: e instanceof Error ? e.message : String(e) });
|
|
224682
|
+
}
|
|
224683
|
+
const infoResult = (await tcbService.call({
|
|
224684
|
+
Action: "DescribeEnvInfo",
|
|
224685
|
+
Param: { EnvId: envId },
|
|
224686
|
+
}));
|
|
224687
|
+
return infoResult?.EnvInfo?.EnvBaseInfo?.Storages ?? [];
|
|
224688
|
+
};
|
|
224689
|
+
const storages = await fetchStorages();
|
|
224690
|
+
const bucket = storages[0]?.Bucket ?? "";
|
|
224691
|
+
const region = storages[0]?.Region ?? "";
|
|
224692
|
+
if (!bucket || !region) {
|
|
224693
|
+
throw new Error((0, index_js_1.t)("functions.storageMissing"));
|
|
224694
|
+
}
|
|
224695
|
+
return { bucket, region };
|
|
224696
|
+
};
|
|
223725
224697
|
const ensureActionAllowedInCloudMode = (input) => {
|
|
223726
224698
|
if (!(0, cloud_mode_js_1.isCloudMode)()) {
|
|
223727
224699
|
return;
|
|
@@ -223736,6 +224708,11 @@ function registerFunctionTools(server) {
|
|
|
223736
224708
|
if (hasImageDeploy) {
|
|
223737
224709
|
return;
|
|
223738
224710
|
}
|
|
224711
|
+
// 两段式部署阶段 B:代码包已上传到环境 COS 桶,全程不依赖本地目录,
|
|
224712
|
+
// 与镜像部署同属可在 cloud mode 下真实执行的路径。
|
|
224713
|
+
if (Boolean(input.code)) {
|
|
224714
|
+
return;
|
|
224715
|
+
}
|
|
223739
224716
|
throw new Error((0, index_js_1.t)("functions.cloudMode.localOnly", { action: input.action }));
|
|
223740
224717
|
}
|
|
223741
224718
|
if (input.action === "createLayerVersion" && input.contentPath) {
|
|
@@ -223954,7 +224931,13 @@ function registerFunctionTools(server) {
|
|
|
223954
224931
|
}
|
|
223955
224932
|
const cloudbase = await getManager();
|
|
223956
224933
|
const result = await cloudbase.functions.getFunctionDetail(input.functionName, input.codeSecret);
|
|
223957
|
-
|
|
224934
|
+
// 与 getFunctionDetail / listFunctionTriggers 一致:本 action 只想取 Layers,
|
|
224935
|
+
// 但 getFunctionDetail 的返回里带着环境变量明文,日志与 raw 都必须脱敏 ——
|
|
224936
|
+
// 否则一个只读的「看层」动作会把明文环境变量带进模型上下文与持久化日志。
|
|
224937
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, maskFunctionDetailEnvValues(result));
|
|
224938
|
+
const detail = input.revealEnvValues === true
|
|
224939
|
+
? result
|
|
224940
|
+
: maskFunctionDetailEnvValues(result);
|
|
223958
224941
|
const layers = normalizeFunctionLayers(result.Layers);
|
|
223959
224942
|
return buildEnvelope({
|
|
223960
224943
|
action: input.action,
|
|
@@ -223962,7 +224945,7 @@ function registerFunctionTools(server) {
|
|
|
223962
224945
|
layers,
|
|
223963
224946
|
count: layers.length,
|
|
223964
224947
|
requestId: result.RequestId,
|
|
223965
|
-
raw:
|
|
224948
|
+
raw: detail,
|
|
223966
224949
|
}, (0, index_js_1.t)("functions.gotFunctionLayers", { fnName: input.functionName }), [
|
|
223967
224950
|
{
|
|
223968
224951
|
tool: "manageFunctions",
|
|
@@ -224110,6 +225093,116 @@ function registerFunctionTools(server) {
|
|
|
224110
225093
|
raw: result,
|
|
224111
225094
|
}, (0, index_js_1.t)("functions.gotDownloadUrl", { fnName: input.functionName }));
|
|
224112
225095
|
}
|
|
225096
|
+
case "listVersionByFunction": {
|
|
225097
|
+
if (!input.functionName) {
|
|
225098
|
+
throw new Error((0, index_js_1.t)("functions.paramRequired", { action: input.action, param: "functionName" }));
|
|
225099
|
+
}
|
|
225100
|
+
const cloudbase = await getManager();
|
|
225101
|
+
const result = await cloudbase.functions.listVersionByFunction({
|
|
225102
|
+
functionName: input.functionName,
|
|
225103
|
+
offset: input.offset,
|
|
225104
|
+
limit: input.limit,
|
|
225105
|
+
order: input.order,
|
|
225106
|
+
orderBy: input.orderBy,
|
|
225107
|
+
});
|
|
225108
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
225109
|
+
return buildEnvelope({
|
|
225110
|
+
action: input.action,
|
|
225111
|
+
functionName: input.functionName,
|
|
225112
|
+
functionVersions: result.FunctionVersion || [],
|
|
225113
|
+
versions: result.Versions || [],
|
|
225114
|
+
totalCount: result.TotalCount,
|
|
225115
|
+
requestId: result.RequestId,
|
|
225116
|
+
raw: result,
|
|
225117
|
+
}, (0, index_js_1.t)("functions.gotFunctionVersions", { fnName: input.functionName }), [
|
|
225118
|
+
{
|
|
225119
|
+
tool: "manageFunctions",
|
|
225120
|
+
action: "publishVersion",
|
|
225121
|
+
reason: (0, index_js_1.t)("functions.reason.publishVersion"),
|
|
225122
|
+
},
|
|
225123
|
+
{
|
|
225124
|
+
tool: "queryFunctions",
|
|
225125
|
+
action: "getFunctionAlias",
|
|
225126
|
+
reason: (0, index_js_1.t)("functions.reason.getFunctionAlias"),
|
|
225127
|
+
},
|
|
225128
|
+
]);
|
|
225129
|
+
}
|
|
225130
|
+
case "getFunctionAlias": {
|
|
225131
|
+
if (!input.functionName) {
|
|
225132
|
+
throw new Error((0, index_js_1.t)("functions.paramRequired", { action: input.action, param: "functionName" }));
|
|
225133
|
+
}
|
|
225134
|
+
const aliasName = input.aliasName || exports.DEFAULT_FUNCTION_ALIAS;
|
|
225135
|
+
const cloudbase = await getManager();
|
|
225136
|
+
const result = await cloudbase.functions.getFunctionAlias({
|
|
225137
|
+
functionName: input.functionName,
|
|
225138
|
+
name: aliasName,
|
|
225139
|
+
});
|
|
225140
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
225141
|
+
return buildEnvelope({
|
|
225142
|
+
action: input.action,
|
|
225143
|
+
functionName: input.functionName,
|
|
225144
|
+
aliasName,
|
|
225145
|
+
functionVersion: result.FunctionVersion,
|
|
225146
|
+
routingConfig: result.RoutingConfig,
|
|
225147
|
+
description: result.Description,
|
|
225148
|
+
addTime: result.AddTime,
|
|
225149
|
+
modTime: result.ModTime,
|
|
225150
|
+
requestId: result.RequestId,
|
|
225151
|
+
raw: result,
|
|
225152
|
+
}, (0, index_js_1.t)("functions.gotFunctionAlias", {
|
|
225153
|
+
fnName: input.functionName,
|
|
225154
|
+
aliasName,
|
|
225155
|
+
}), [
|
|
225156
|
+
{
|
|
225157
|
+
tool: "manageFunctions",
|
|
225158
|
+
action: "updateFunctionAliasConfig",
|
|
225159
|
+
reason: (0, index_js_1.t)("functions.reason.updateFunctionAlias"),
|
|
225160
|
+
},
|
|
225161
|
+
{
|
|
225162
|
+
tool: "queryFunctions",
|
|
225163
|
+
action: "listVersionByFunction",
|
|
225164
|
+
reason: (0, index_js_1.t)("functions.reason.listVersions"),
|
|
225165
|
+
},
|
|
225166
|
+
]);
|
|
225167
|
+
}
|
|
225168
|
+
case "getFunctionUploadUrl": {
|
|
225169
|
+
// ZIP 两段式部署阶段 A:环境自有存储桶 + 用户凭据本地铸 COS 预签名 PUT URL。
|
|
225170
|
+
// functionName 可选,仅用于生成可读的对象 key。
|
|
225171
|
+
const cloudbase = await getManager();
|
|
225172
|
+
const authConfig = cloudbase.currentEnvironment().getAuthConfig();
|
|
225173
|
+
if (!authConfig?.secretId || !authConfig?.secretKey) {
|
|
225174
|
+
throw new Error((0, index_js_1.t)("functions.credentialMissing"));
|
|
225175
|
+
}
|
|
225176
|
+
const storage = await resolveEnvFunctionCosStorage();
|
|
225177
|
+
const upload = (0, function_cos_upload_js_1.buildFunctionZipUpload)({
|
|
225178
|
+
storage,
|
|
225179
|
+
credential: {
|
|
225180
|
+
secretId: authConfig.secretId,
|
|
225181
|
+
secretKey: authConfig.secretKey,
|
|
225182
|
+
// 永久密钥时 token 为空串,转 undefined 才不签入 token 头
|
|
225183
|
+
token: authConfig.token || undefined,
|
|
225184
|
+
},
|
|
225185
|
+
functionName: input.functionName,
|
|
225186
|
+
});
|
|
225187
|
+
// uploadUrl 内含凭据绑定的签名(临时凭据还绑定 token),禁止落日志
|
|
225188
|
+
(0, logger_js_1.debug)(`[getFunctionUploadUrl] envId=${authConfig.envId ?? "n/a"}, cosObjectName=${upload.cosObjectName}, expiresIn=${upload.expiresInSeconds}s`);
|
|
225189
|
+
return buildEnvelope({
|
|
225190
|
+
action: input.action,
|
|
225191
|
+
...(input.functionName ? { functionName: input.functionName } : {}),
|
|
225192
|
+
uploadUrl: upload.uploadUrl,
|
|
225193
|
+
uploadHeaders: upload.uploadHeaders,
|
|
225194
|
+
cosBucketName: upload.cosBucketName,
|
|
225195
|
+
cosBucketRegion: upload.cosBucketRegion,
|
|
225196
|
+
cosObjectName: upload.cosObjectName,
|
|
225197
|
+
expiresInSeconds: upload.expiresInSeconds,
|
|
225198
|
+
}, (0, index_js_1.t)("functions.gotUploadUrl", { seconds: upload.expiresInSeconds }), [
|
|
225199
|
+
{
|
|
225200
|
+
tool: "manageFunctions",
|
|
225201
|
+
action: "createFunction",
|
|
225202
|
+
reason: (0, index_js_1.t)("functions.reason.cosCreate"),
|
|
225203
|
+
},
|
|
225204
|
+
]);
|
|
225205
|
+
}
|
|
224113
225206
|
default:
|
|
224114
225207
|
throw new Error((0, index_js_1.t)("functions.unsupportedAction", { action: input.action }));
|
|
224115
225208
|
}
|
|
@@ -224366,6 +225459,63 @@ function registerFunctionTools(server) {
|
|
|
224366
225459
|
},
|
|
224367
225460
|
]);
|
|
224368
225461
|
}
|
|
225462
|
+
// code 入参(ZIP 两段式部署阶段 B):代码包已由 getFunctionUploadUrl 上传到
|
|
225463
|
+
// 环境 COS 桶,直接 deployMode=cos 提交,跳过本地目录 / 依赖安装逻辑。
|
|
225464
|
+
if (input.code) {
|
|
225465
|
+
const storage = await resolveEnvFunctionCosStorage();
|
|
225466
|
+
const cosBucketName = (0, function_cos_upload_js_1.stripAppIdSuffix)(input.code.cosBucketName || storage.bucket);
|
|
225467
|
+
const cosBucketRegion = input.code.cosBucketRegion ?? storage.region;
|
|
225468
|
+
const codeFunc = { ...func };
|
|
225469
|
+
// 用户 zip 自带依赖语义(装没装由上传方决定),默认不触发云端依赖安装
|
|
225470
|
+
delete codeFunc.installDependency;
|
|
225471
|
+
if (input.func?.installDependency !== undefined) {
|
|
225472
|
+
codeFunc.installDependency = input.func.installDependency;
|
|
225473
|
+
}
|
|
225474
|
+
if (codeFunc.type !== "HTTP") {
|
|
225475
|
+
codeFunc.runtime = resolveEventFunctionRuntime(codeFunc.runtime);
|
|
225476
|
+
}
|
|
225477
|
+
let cosCreateResult;
|
|
225478
|
+
try {
|
|
225479
|
+
cosCreateResult = await cloudbase.functions.createFunction({
|
|
225480
|
+
func: codeFunc,
|
|
225481
|
+
code: {
|
|
225482
|
+
CosBucketName: cosBucketName,
|
|
225483
|
+
CosBucketRegion: cosBucketRegion,
|
|
225484
|
+
CosObjectName: input.code.cosObjectName,
|
|
225485
|
+
},
|
|
225486
|
+
deployMode: "cos",
|
|
225487
|
+
force: Boolean(input.force),
|
|
225488
|
+
});
|
|
225489
|
+
}
|
|
225490
|
+
catch (error) {
|
|
225491
|
+
throw wrapFunctionOperationError("createFunction", functionName, undefined, error);
|
|
225492
|
+
}
|
|
225493
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, cosCreateResult);
|
|
225494
|
+
return buildEnvelope({
|
|
225495
|
+
action: input.action,
|
|
225496
|
+
functionName,
|
|
225497
|
+
deployMode: "cos",
|
|
225498
|
+
cosBucketName,
|
|
225499
|
+
cosBucketRegion,
|
|
225500
|
+
cosObjectName: input.code.cosObjectName,
|
|
225501
|
+
raw: cosCreateResult,
|
|
225502
|
+
}, (0, index_js_1.t)("functions.cosCreatedMessage", { fnName: functionName }), [
|
|
225503
|
+
{
|
|
225504
|
+
tool: "queryFunctions",
|
|
225505
|
+
action: "getFunctionDetail",
|
|
225506
|
+
reason: (0, index_js_1.t)("functions.reason.confirmConfig"),
|
|
225507
|
+
},
|
|
225508
|
+
...(codeFunc.type === "HTTP"
|
|
225509
|
+
? [
|
|
225510
|
+
{
|
|
225511
|
+
tool: "manageGateway",
|
|
225512
|
+
action: "createRoute",
|
|
225513
|
+
reason: (0, index_js_1.t)("functions.reason.gatewayRouteForHttp"),
|
|
225514
|
+
},
|
|
225515
|
+
]
|
|
225516
|
+
: []),
|
|
225517
|
+
]);
|
|
225518
|
+
}
|
|
224369
225519
|
if (func.type !== "HTTP") {
|
|
224370
225520
|
const originalRuntime = typeof func.runtime === "string" ? func.runtime : undefined;
|
|
224371
225521
|
func.runtime = resolveEventFunctionRuntime(func.runtime);
|
|
@@ -224574,6 +225724,58 @@ function registerFunctionTools(server) {
|
|
|
224574
225724
|
},
|
|
224575
225725
|
]);
|
|
224576
225726
|
}
|
|
225727
|
+
// code 入参(ZIP 两段式部署阶段 B):zip 已在环境 COS 桶,直接 deployMode=cos
|
|
225728
|
+
// 更新代码包,跳过 functionRootPath / zipFile 本地语义。
|
|
225729
|
+
if (input.code) {
|
|
225730
|
+
const storage = await resolveEnvFunctionCosStorage();
|
|
225731
|
+
const cosBucketName = (0, function_cos_upload_js_1.stripAppIdSuffix)(input.code.cosBucketName || storage.bucket);
|
|
225732
|
+
const cosBucketRegion = input.code.cosBucketRegion ?? storage.region;
|
|
225733
|
+
let cosUpdateResult;
|
|
225734
|
+
try {
|
|
225735
|
+
cosUpdateResult = await cloudbase.functions.updateFunctionCode({
|
|
225736
|
+
func: {
|
|
225737
|
+
name: input.functionName,
|
|
225738
|
+
// 与 create 的 code 分支一致:默认不触发云端依赖安装,显式传参才覆盖
|
|
225739
|
+
...(input.func?.installDependency !== undefined
|
|
225740
|
+
? { installDependency: input.func.installDependency }
|
|
225741
|
+
: {}),
|
|
225742
|
+
...(input.handler ? { handler: input.handler } : {}),
|
|
225743
|
+
},
|
|
225744
|
+
code: {
|
|
225745
|
+
CosBucketName: cosBucketName,
|
|
225746
|
+
CosBucketRegion: cosBucketRegion,
|
|
225747
|
+
CosObjectName: input.code.cosObjectName,
|
|
225748
|
+
},
|
|
225749
|
+
deployMode: "cos",
|
|
225750
|
+
});
|
|
225751
|
+
}
|
|
225752
|
+
catch (error) {
|
|
225753
|
+
if ((0, function_updating_js_1.isFunctionUpdatingError)(error)) {
|
|
225754
|
+
return (0, function_updating_js_1.buildFunctionUpdatingPayload)({
|
|
225755
|
+
action: "updateFunctionCode",
|
|
225756
|
+
functionName: input.functionName,
|
|
225757
|
+
rawMessage: (0, function_updating_js_1.getErrorMessage)(error),
|
|
225758
|
+
});
|
|
225759
|
+
}
|
|
225760
|
+
throw wrapFunctionOperationError("updateFunctionCode", input.functionName, undefined, error);
|
|
225761
|
+
}
|
|
225762
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, cosUpdateResult);
|
|
225763
|
+
return buildEnvelope({
|
|
225764
|
+
action: input.action,
|
|
225765
|
+
functionName: input.functionName,
|
|
225766
|
+
deployMode: "cos",
|
|
225767
|
+
cosBucketName,
|
|
225768
|
+
cosBucketRegion,
|
|
225769
|
+
cosObjectName: input.code.cosObjectName,
|
|
225770
|
+
raw: cosUpdateResult,
|
|
225771
|
+
}, (0, index_js_1.t)("functions.cosUpdatedMessage", { fnName: input.functionName }), [
|
|
225772
|
+
{
|
|
225773
|
+
tool: "queryFunctions",
|
|
225774
|
+
action: "getFunctionDetail",
|
|
225775
|
+
reason: (0, index_js_1.t)("functions.reason.confirmConfig"),
|
|
225776
|
+
},
|
|
225777
|
+
]);
|
|
225778
|
+
}
|
|
224577
225779
|
const processedRootPath = processFunctionRootPath(input.functionRootPath, input.functionName);
|
|
224578
225780
|
const updateParams = {
|
|
224579
225781
|
func: {
|
|
@@ -224948,6 +226150,94 @@ function registerFunctionTools(server) {
|
|
|
224948
226150
|
},
|
|
224949
226151
|
], bindWarnings);
|
|
224950
226152
|
}
|
|
226153
|
+
case "publishVersion": {
|
|
226154
|
+
if (!input.functionName) {
|
|
226155
|
+
throw new Error((0, index_js_1.t)("functions.paramRequired", { action: input.action, param: "functionName" }));
|
|
226156
|
+
}
|
|
226157
|
+
const cloudbase = await getManager();
|
|
226158
|
+
const result = await cloudbase.functions.publishVersion({
|
|
226159
|
+
functionName: input.functionName,
|
|
226160
|
+
description: input.description,
|
|
226161
|
+
});
|
|
226162
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
226163
|
+
return buildEnvelope({
|
|
226164
|
+
action: input.action,
|
|
226165
|
+
functionName: input.functionName,
|
|
226166
|
+
functionVersion: result.FunctionVersion,
|
|
226167
|
+
description: result.Description,
|
|
226168
|
+
codeSize: result.CodeSize,
|
|
226169
|
+
memorySize: result.MemorySize,
|
|
226170
|
+
handler: result.Handler,
|
|
226171
|
+
timeout: result.Timeout,
|
|
226172
|
+
runtime: result.Runtime,
|
|
226173
|
+
namespace: result.Namespace,
|
|
226174
|
+
requestId: result.RequestId,
|
|
226175
|
+
raw: result,
|
|
226176
|
+
}, (0, index_js_1.t)("functions.publishedVersion", {
|
|
226177
|
+
fnName: input.functionName,
|
|
226178
|
+
version: result.FunctionVersion,
|
|
226179
|
+
}), [
|
|
226180
|
+
{
|
|
226181
|
+
tool: "queryFunctions",
|
|
226182
|
+
action: "listVersionByFunction",
|
|
226183
|
+
reason: (0, index_js_1.t)("functions.reason.listVersions"),
|
|
226184
|
+
},
|
|
226185
|
+
{
|
|
226186
|
+
tool: "manageFunctions",
|
|
226187
|
+
action: "updateFunctionAliasConfig",
|
|
226188
|
+
reason: (0, index_js_1.t)("functions.reason.routeTraffic"),
|
|
226189
|
+
suggested_args: {
|
|
226190
|
+
functionName: input.functionName,
|
|
226191
|
+
functionVersion: result.FunctionVersion,
|
|
226192
|
+
aliasName: exports.DEFAULT_FUNCTION_ALIAS,
|
|
226193
|
+
},
|
|
226194
|
+
},
|
|
226195
|
+
]);
|
|
226196
|
+
}
|
|
226197
|
+
case "updateFunctionAliasConfig": {
|
|
226198
|
+
if (!input.functionName) {
|
|
226199
|
+
throw new Error((0, index_js_1.t)("functions.paramRequired", { action: input.action, param: "functionName" }));
|
|
226200
|
+
}
|
|
226201
|
+
if (!input.functionVersion) {
|
|
226202
|
+
throw new Error((0, index_js_1.t)("functions.paramRequired", {
|
|
226203
|
+
action: input.action,
|
|
226204
|
+
param: "functionVersion",
|
|
226205
|
+
}));
|
|
226206
|
+
}
|
|
226207
|
+
const aliasName = input.aliasName || exports.DEFAULT_FUNCTION_ALIAS;
|
|
226208
|
+
const cloudbase = await getManager();
|
|
226209
|
+
const result = await cloudbase.functions.updateFunctionAliasConfig({
|
|
226210
|
+
functionName: input.functionName,
|
|
226211
|
+
name: aliasName,
|
|
226212
|
+
functionVersion: input.functionVersion,
|
|
226213
|
+
description: input.description,
|
|
226214
|
+
routingConfig: input.routingConfig,
|
|
226215
|
+
});
|
|
226216
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
226217
|
+
return buildEnvelope({
|
|
226218
|
+
action: input.action,
|
|
226219
|
+
functionName: input.functionName,
|
|
226220
|
+
aliasName,
|
|
226221
|
+
functionVersion: input.functionVersion,
|
|
226222
|
+
routingConfig: input.routingConfig,
|
|
226223
|
+
requestId: result.RequestId,
|
|
226224
|
+
raw: result,
|
|
226225
|
+
}, (0, index_js_1.t)("functions.updatedFunctionAlias", {
|
|
226226
|
+
fnName: input.functionName,
|
|
226227
|
+
aliasName,
|
|
226228
|
+
version: input.functionVersion,
|
|
226229
|
+
}), [
|
|
226230
|
+
{
|
|
226231
|
+
tool: "queryFunctions",
|
|
226232
|
+
action: "getFunctionAlias",
|
|
226233
|
+
reason: (0, index_js_1.t)("functions.reason.confirmAlias"),
|
|
226234
|
+
suggested_args: {
|
|
226235
|
+
functionName: input.functionName,
|
|
226236
|
+
aliasName,
|
|
226237
|
+
},
|
|
226238
|
+
},
|
|
226239
|
+
]);
|
|
226240
|
+
}
|
|
224951
226241
|
default:
|
|
224952
226242
|
// incrementalDeployFunction:无默认实现,必须通过 pluginOptions 注入
|
|
224953
226243
|
if (input.action === 'incrementalDeployFunction') {
|
|
@@ -225007,6 +226297,12 @@ function registerFunctionTools(server) {
|
|
|
225007
226297
|
.string()
|
|
225008
226298
|
.optional()
|
|
225009
226299
|
.describe("functions.schema.query.taskId"),
|
|
226300
|
+
order: zod_1.z.string().optional().describe("functions.schema.query.order"),
|
|
226301
|
+
orderBy: zod_1.z.string().optional().describe("functions.schema.query.orderBy"),
|
|
226302
|
+
aliasName: zod_1.z
|
|
226303
|
+
.string()
|
|
226304
|
+
.optional()
|
|
226305
|
+
.describe("functions.schema.query.aliasName"),
|
|
225010
226306
|
},
|
|
225011
226307
|
annotations: {
|
|
225012
226308
|
readOnlyHint: true,
|
|
@@ -225030,6 +226326,7 @@ function registerFunctionTools(server) {
|
|
|
225030
226326
|
.optional()
|
|
225031
226327
|
.describe("functions.schema.manage.functionName"),
|
|
225032
226328
|
zipFile: zod_1.z.string().optional().describe("functions.schema.manage.zipFile"),
|
|
226329
|
+
code: FUNCTION_CODE_SCHEMA.optional().describe("functions.schema.manage.code"),
|
|
225033
226330
|
handler: zod_1.z.string().optional().describe("functions.schema.manage.handler"),
|
|
225034
226331
|
timeout: zod_1.z.number().optional().describe("functions.schema.manage.timeout"),
|
|
225035
226332
|
envVariables: zod_1.z
|
|
@@ -225075,6 +226372,15 @@ function registerFunctionTools(server) {
|
|
|
225075
226372
|
.describe("functions.schema.manage.autoGrant"),
|
|
225076
226373
|
confirm: zod_1.z.boolean().optional().describe("functions.schema.manage.confirm"),
|
|
225077
226374
|
incrementalFile: zod_1.z.string().optional().describe("functions.schema.manage.incrementalFile"),
|
|
226375
|
+
aliasName: zod_1.z
|
|
226376
|
+
.string()
|
|
226377
|
+
.optional()
|
|
226378
|
+
.describe("functions.schema.manage.aliasName"),
|
|
226379
|
+
functionVersion: zod_1.z
|
|
226380
|
+
.string()
|
|
226381
|
+
.optional()
|
|
226382
|
+
.describe("functions.schema.manage.functionVersion"),
|
|
226383
|
+
routingConfig: FUNCTION_ROUTING_CONFIG_SCHEMA.optional().describe("functions.schema.manage.routingConfig"),
|
|
225078
226384
|
},
|
|
225079
226385
|
annotations: {
|
|
225080
226386
|
readOnlyHint: false,
|
|
@@ -227215,7 +228521,12 @@ function registerHostingTools(server) {
|
|
|
227215
228521
|
});
|
|
227216
228522
|
server.registerTool('manageHosting', {
|
|
227217
228523
|
title: 'hosting.manageTitle',
|
|
227218
|
-
|
|
228524
|
+
// cloud mode 下注册期即切换描述:upload/download 系 action 不可用、部署引导走
|
|
228525
|
+
// manageApps 云端链路(getUploadUrl → PUT zip → deployApp(cosTimestamp)),
|
|
228526
|
+
// 让 agent 在 tools/list 阶段就避开必败调用,而不是等报错后浪费一轮。
|
|
228527
|
+
description: (0, cloud_mode_js_1.isCloudMode)()
|
|
228528
|
+
? 'hosting.manageDescriptionCloud'
|
|
228529
|
+
: 'hosting.manageDescription',
|
|
227219
228530
|
inputSchema: manageHostingInputSchema,
|
|
227220
228531
|
annotations: {
|
|
227221
228532
|
readOnlyHint: false,
|
|
@@ -227653,18 +228964,23 @@ const cloudbase_manager_js_1 = __webpack_require__(33109);
|
|
|
227653
228964
|
const json_content_js_1 = __webpack_require__(18027);
|
|
227654
228965
|
const index_js_1 = __webpack_require__(24908);
|
|
227655
228966
|
const QUERY_LOG_ACTIONS = ["checkLogService", "searchLogs"];
|
|
227656
|
-
|
|
228967
|
+
const MANAGE_LOG_ACTIONS = ["createLogService"];
|
|
228968
|
+
function buildEnvelope(data, message, extras) {
|
|
227657
228969
|
return {
|
|
227658
228970
|
success: true,
|
|
227659
228971
|
data,
|
|
227660
228972
|
message,
|
|
228973
|
+
...extras,
|
|
227661
228974
|
};
|
|
227662
228975
|
}
|
|
227663
|
-
function buildErrorEnvelope(error) {
|
|
228976
|
+
function buildErrorEnvelope(error, extras) {
|
|
227664
228977
|
return {
|
|
227665
228978
|
success: false,
|
|
227666
|
-
data: {},
|
|
227667
|
-
message:
|
|
228979
|
+
data: extras?.data ?? {},
|
|
228980
|
+
message: extras?.message ??
|
|
228981
|
+
(error instanceof Error ? error.message : String(error)),
|
|
228982
|
+
errorCode: extras?.errorCode,
|
|
228983
|
+
nextActions: extras?.nextActions,
|
|
227668
228984
|
};
|
|
227669
228985
|
}
|
|
227670
228986
|
function registerLogTools(server) {
|
|
@@ -227737,6 +229053,89 @@ function registerLogTools(server) {
|
|
|
227737
229053
|
return (0, json_content_js_1.jsonContent)(buildErrorEnvelope(error));
|
|
227738
229054
|
}
|
|
227739
229055
|
});
|
|
229056
|
+
server.registerTool?.("manageLogs", {
|
|
229057
|
+
title: "logs.manage.title",
|
|
229058
|
+
description: "logs.manage.description",
|
|
229059
|
+
inputSchema: {
|
|
229060
|
+
action: zod_1.z
|
|
229061
|
+
.enum(MANAGE_LOG_ACTIONS)
|
|
229062
|
+
.describe("logs.manage.schema.action"),
|
|
229063
|
+
confirm: zod_1.z
|
|
229064
|
+
.boolean()
|
|
229065
|
+
.optional()
|
|
229066
|
+
.describe("logs.manage.schema.confirm"),
|
|
229067
|
+
},
|
|
229068
|
+
annotations: {
|
|
229069
|
+
readOnlyHint: false,
|
|
229070
|
+
destructiveHint: false,
|
|
229071
|
+
idempotentHint: false,
|
|
229072
|
+
openWorldHint: false,
|
|
229073
|
+
category: "logs",
|
|
229074
|
+
},
|
|
229075
|
+
}, async ({ action, confirm, }) => {
|
|
229076
|
+
try {
|
|
229077
|
+
if (action !== "createLogService") {
|
|
229078
|
+
return (0, json_content_js_1.jsonContent)(buildErrorEnvelope(new Error((0, index_js_1.t)("logs.manage.unsupportedAction", { action })), {
|
|
229079
|
+
errorCode: "UNSUPPORTED_ACTION",
|
|
229080
|
+
}));
|
|
229081
|
+
}
|
|
229082
|
+
if (confirm !== true) {
|
|
229083
|
+
return (0, json_content_js_1.jsonContent)(buildErrorEnvelope(null, {
|
|
229084
|
+
errorCode: "CONFIRM_REQUIRED",
|
|
229085
|
+
message: (0, index_js_1.t)("logs.manage.create.confirmRequired"),
|
|
229086
|
+
data: { action },
|
|
229087
|
+
nextActions: [
|
|
229088
|
+
{
|
|
229089
|
+
tool: "manageLogs",
|
|
229090
|
+
action: "createLogService",
|
|
229091
|
+
suggested_args: { action: "createLogService", confirm: true },
|
|
229092
|
+
reason: (0, index_js_1.t)("logs.manage.create.needsConfirmation"),
|
|
229093
|
+
},
|
|
229094
|
+
],
|
|
229095
|
+
}));
|
|
229096
|
+
}
|
|
229097
|
+
const cloudbase = await getManager();
|
|
229098
|
+
const enabled = await cloudbase.log.checkLogServiceEnabled();
|
|
229099
|
+
if (enabled) {
|
|
229100
|
+
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
229101
|
+
action,
|
|
229102
|
+
enabled: true,
|
|
229103
|
+
alreadyEnabled: true,
|
|
229104
|
+
}, (0, index_js_1.t)("logs.manage.create.alreadyEnabled"), {
|
|
229105
|
+
nextActions: [
|
|
229106
|
+
{
|
|
229107
|
+
tool: "queryLogs",
|
|
229108
|
+
action: "searchLogs",
|
|
229109
|
+
suggested_args: {
|
|
229110
|
+
action: "searchLogs",
|
|
229111
|
+
queryString: 'log:"ERROR"',
|
|
229112
|
+
},
|
|
229113
|
+
reason: (0, index_js_1.t)("logs.manage.create.nextSearch"),
|
|
229114
|
+
},
|
|
229115
|
+
],
|
|
229116
|
+
}));
|
|
229117
|
+
}
|
|
229118
|
+
const result = await cloudbase.log.createLogService();
|
|
229119
|
+
(0, cloudbase_manager_js_1.logCloudBaseResult)(server.logger, result);
|
|
229120
|
+
return (0, json_content_js_1.jsonContent)(buildEnvelope({
|
|
229121
|
+
action,
|
|
229122
|
+
requestId: result.RequestId ?? null,
|
|
229123
|
+
raw: result,
|
|
229124
|
+
}, (0, index_js_1.t)("logs.manage.create.submitted"), {
|
|
229125
|
+
nextActions: [
|
|
229126
|
+
{
|
|
229127
|
+
tool: "queryLogs",
|
|
229128
|
+
action: "checkLogService",
|
|
229129
|
+
suggested_args: { action: "checkLogService" },
|
|
229130
|
+
reason: (0, index_js_1.t)("logs.manage.create.nextCheck"),
|
|
229131
|
+
},
|
|
229132
|
+
],
|
|
229133
|
+
}));
|
|
229134
|
+
}
|
|
229135
|
+
catch (error) {
|
|
229136
|
+
return (0, json_content_js_1.jsonContent)(buildErrorEnvelope(error));
|
|
229137
|
+
}
|
|
229138
|
+
});
|
|
227740
229139
|
}
|
|
227741
229140
|
|
|
227742
229141
|
|
|
@@ -229083,7 +230482,7 @@ function extractRiskyDocFieldOperations(securityRule) {
|
|
|
229083
230482
|
continue;
|
|
229084
230483
|
}
|
|
229085
230484
|
const referencesNonIdDocField = /doc\.(?!_id\b)[A-Za-z_][A-Za-z0-9_]*/.test(expression);
|
|
229086
|
-
const usesGetByDocId = /get\('database\.[^']+'\s*\+\s*doc\._id\)/.test(expression);
|
|
230485
|
+
const usesGetByDocId = /get\(('database\.[^']+'\s*\+\s*doc\._id|`database\.[^`]*\$\{\s*doc\._id\s*\})\)/.test(expression);
|
|
229087
230486
|
if (referencesNonIdDocField && !usesGetByDocId) {
|
|
229088
230487
|
operations.push(operation);
|
|
229089
230488
|
}
|
|
@@ -229093,8 +230492,8 @@ function extractRiskyDocFieldOperations(securityRule) {
|
|
|
229093
230492
|
function buildRecommendedOwnerWriteRule(resourceId) {
|
|
229094
230493
|
return JSON.stringify({
|
|
229095
230494
|
create: "auth.uid != null",
|
|
229096
|
-
update: "auth.uid != null && (get(
|
|
229097
|
-
delete: "auth.uid != null && (get(
|
|
230495
|
+
update: "auth.uid != null && (get(`database.user_roles.${auth.uid}`).role == 'admin' || doc.authorId == auth.uid)",
|
|
230496
|
+
delete: "auth.uid != null && (get(`database.user_roles.${auth.uid}`).role == 'admin' || doc.authorId == auth.uid)",
|
|
229098
230497
|
});
|
|
229099
230498
|
}
|
|
229100
230499
|
function buildRoleLookupNote() {
|
|
@@ -229156,7 +230555,9 @@ function buildInvalidGetPathHint(securityRule, resourceId) {
|
|
|
229156
230555
|
if (!securityRule) {
|
|
229157
230556
|
return undefined;
|
|
229158
230557
|
}
|
|
229159
|
-
|
|
230558
|
+
// get() 的 path 里嵌了字段名:拼接形态,或反引号模板里在 ${} 之后又接字段
|
|
230559
|
+
const hasFieldEmbeddedInsideGetPath = /get\('database\.[^']+'\s*\+\s*[^)]*\+\s*'\.[A-Za-z_][A-Za-z0-9_]*'\)/.test(securityRule) ||
|
|
230560
|
+
/get\(`database\.[^`]*\.\$\{[^}]+\}\.[A-Za-z_][A-Za-z0-9_]*`\)/.test(securityRule);
|
|
229160
230561
|
if (!hasFieldEmbeddedInsideGetPath) {
|
|
229161
230562
|
return undefined;
|
|
229162
230563
|
}
|
|
@@ -229176,7 +230577,9 @@ function buildTemplateLiteralRuleHint(securityRule, resourceId) {
|
|
|
229176
230577
|
if (!securityRule) {
|
|
229177
230578
|
return undefined;
|
|
229178
230579
|
}
|
|
229179
|
-
|
|
230580
|
+
// 反引号模板字符串是官方形态,必须先剥掉再判——否则会把正确的写法误报成错误
|
|
230581
|
+
const withoutTemplateLiterals = securityRule.replace(/`[^`]*`/g, '');
|
|
230582
|
+
const usesTemplateLiteralPlaceholderInRule = /['"][^'"]*\$\{(?:auth\.uid|doc\._id|doc\.[A-Za-z_][A-Za-z0-9_]*)\}/.test(withoutTemplateLiterals);
|
|
229180
230583
|
if (!usesTemplateLiteralPlaceholderInRule) {
|
|
229181
230584
|
return undefined;
|
|
229182
230585
|
}
|
|
@@ -229737,9 +231140,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
229737
231140
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
229738
231141
|
};
|
|
229739
231142
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
229740
|
-
exports.SKILL_REMOTE_BASE_URL = void 0;
|
|
231143
|
+
exports.DOCS_BASE_HOST = exports.SKILL_REMOTE_BASE_URL = void 0;
|
|
229741
231144
|
exports.resolveSkillSearchRoots = resolveSkillSearchRoots;
|
|
229742
231145
|
exports.resolveDocsMarkdownPath = resolveDocsMarkdownPath;
|
|
231146
|
+
exports.toSiteRelativeDocPath = toSiteRelativeDocPath;
|
|
231147
|
+
exports.assertNoHostInDocPath = assertNoHostInDocPath;
|
|
229743
231148
|
exports.isDocsHtmlFallback = isDocsHtmlFallback;
|
|
229744
231149
|
exports.registerRagTools = registerRagTools;
|
|
229745
231150
|
exports.buildSkillRawUrl = buildSkillRawUrl;
|
|
@@ -230168,6 +231573,74 @@ function resolveDocsMarkdownPath(docPath) {
|
|
|
230168
231573
|
: `${base.replace(/\/index$/i, "")}.md`;
|
|
230169
231574
|
return `${normalized}${hash}`;
|
|
230170
231575
|
}
|
|
231576
|
+
/**
|
|
231577
|
+
* 交给 `DocsService.readDoc()` 的地址**永远不含 host**。
|
|
231578
|
+
*
|
|
231579
|
+
* Manager SDK 的 `DocsService.readDoc()` 见到 `http` 前缀就把入参原样 fetch、并把整段响应体
|
|
231580
|
+
* 回显给调用方(`@cloudbase/manager-node/lib/docs/index.js:101`)。等于 docPath 是一条「由服务端
|
|
231581
|
+
* 发起任意 HTTP 请求、把响应交给调用方」的通路:只要入参能带主机,`http://127.0.0.1/...`、
|
|
231582
|
+
* `http://169.254.169.254/...`(云主机元数据)就能把工具变成 SSRF 原语。
|
|
231583
|
+
*
|
|
231584
|
+
* 而 docPath 收到完整 URL 是**主线用法**,不能靠「拒绝一切 URL」收口:`findByName` /
|
|
231585
|
+
* `listModuleDocs` 的数据源 `category.json` 里 1016 个文档值全部是
|
|
231586
|
+
* `https://docs.cloudbase.net/...` 形态,`searchDocs`(Algolia)返回的 `url` 也是完整地址,
|
|
231587
|
+
* AI 拿到之后自然是原样喂回 readDoc。
|
|
231588
|
+
*
|
|
231589
|
+
* 所以这里的做法是**剥掉主机**:官方文档站的地址只取 pathname(+ 锚点),其余主机直接拒绝。
|
|
231590
|
+
* 效果比白名单更强 —— 不是「允许的 host 恰好只有一个」,而是**没有任何 host 能走到 fetch**,
|
|
231591
|
+
* 请求目标恒为 SDK 里的 `DOCS_BASE_URL`;顺带也让 `resolveDocsMarkdownPath` 的 `.md` 后缀
|
|
231592
|
+
* 拼接不再可能作用在主机上(旧实现里裸主机名会被拼成 `docs.cloudbase.net.md`——`.md` 是
|
|
231593
|
+
* 可被第三方注册的国家顶级域)。
|
|
231594
|
+
*/
|
|
231595
|
+
exports.DOCS_BASE_HOST = "docs.cloudbase.net";
|
|
231596
|
+
/** 带 scheme 的绝对地址(`//host/path` 这类 protocol-relative 也算「指定了主机」)。 */
|
|
231597
|
+
const ABSOLUTE_DOC_URL_PATTERN = /^[a-z][a-z0-9+.-]*:\/\//i;
|
|
231598
|
+
function parseAbsoluteDocUrl(value) {
|
|
231599
|
+
const candidate = value.startsWith("//") ? `https:${value}` : value;
|
|
231600
|
+
if (!ABSOLUTE_DOC_URL_PATTERN.test(candidate)) {
|
|
231601
|
+
return null;
|
|
231602
|
+
}
|
|
231603
|
+
try {
|
|
231604
|
+
return new URL(candidate);
|
|
231605
|
+
}
|
|
231606
|
+
catch {
|
|
231607
|
+
return null;
|
|
231608
|
+
}
|
|
231609
|
+
}
|
|
231610
|
+
/**
|
|
231611
|
+
* 把 docPath 折成站内相对路径:官方文档站地址**丢掉 host**只留路径,非首方主机直接拒绝。
|
|
231612
|
+
*
|
|
231613
|
+
* 查询串一并丢弃:站点用 `<路径>.md` 寻址,query 不属于寻址的一部分,留着只会拼出
|
|
231614
|
+
* `.../x.md?foo` 这种畸形地址。锚点保留(`resolveDocsMarkdownPath` 本就支持 `#`)。
|
|
231615
|
+
*/
|
|
231616
|
+
function toSiteRelativeDocPath(docPath) {
|
|
231617
|
+
const raw = docPath.trim();
|
|
231618
|
+
const parsed = parseAbsoluteDocUrl(raw);
|
|
231619
|
+
if (!parsed) {
|
|
231620
|
+
return raw;
|
|
231621
|
+
}
|
|
231622
|
+
const host = parsed.hostname.toLowerCase().replace(/\.$/, "");
|
|
231623
|
+
const isAllowedProtocol = parsed.protocol === "http:" || parsed.protocol === "https:";
|
|
231624
|
+
if (!isAllowedProtocol || host !== exports.DOCS_BASE_HOST) {
|
|
231625
|
+
throw new Error((0, index_js_1.t)("rag.readDocUrlNotAllowed", { docPath: raw, host: exports.DOCS_BASE_HOST }));
|
|
231626
|
+
}
|
|
231627
|
+
const sitePath = `${parsed.pathname}${parsed.hash}`;
|
|
231628
|
+
if (!sitePath.replace(/^\/+|\/+$/g, "")) {
|
|
231629
|
+
throw new Error((0, index_js_1.t)("rag.readDocPathEmpty", { docPath: raw }));
|
|
231630
|
+
}
|
|
231631
|
+
return sitePath;
|
|
231632
|
+
}
|
|
231633
|
+
/**
|
|
231634
|
+
* invariant:走到 SDK 的地址不能含 host。
|
|
231635
|
+
*
|
|
231636
|
+
* 归一化之后再过一次,保证「fetch 目标恒为首方基址」这条性质不依赖
|
|
231637
|
+
* `resolveDocsMarkdownPath` 的实现细节 —— 它以后改动了也漏不掉。
|
|
231638
|
+
*/
|
|
231639
|
+
function assertNoHostInDocPath(sitePath) {
|
|
231640
|
+
if (parseAbsoluteDocUrl(sitePath.trim())) {
|
|
231641
|
+
throw new Error((0, index_js_1.t)("rag.readDocUrlNotAllowed", { docPath: sitePath, host: exports.DOCS_BASE_HOST }));
|
|
231642
|
+
}
|
|
231643
|
+
}
|
|
230171
231644
|
/**
|
|
230172
231645
|
* 识别 SPA 兜底页:站点对不存在的 markdown 路径同样返回 200,正文是站点 HTML 外壳。
|
|
230173
231646
|
* 用于把「静默返回一坨 HTML」换成明确的失败信息。
|
|
@@ -230288,14 +231761,22 @@ async function registerRagTools(server) {
|
|
|
230288
231761
|
}
|
|
230289
231762
|
if (resolvedAction === "readDoc") {
|
|
230290
231763
|
const resolvedDocPath = requireStringParam(docPath, "docPath", resolvedAction);
|
|
230291
|
-
|
|
231764
|
+
// 先剥掉 host(非首方主机直接拒绝),再做 `.md` 归一化,最后复核一遍不含 host。
|
|
231765
|
+
// 三者顺序不能换:归一化会给路径补后缀,若让它作用在主机上就会把
|
|
231766
|
+
// `docs.cloudbase.net` 拼成 `docs.cloudbase.net.md`(`.md` 是第三方可注册的 TLD)。
|
|
231767
|
+
const siteDocPath = toSiteRelativeDocPath(resolvedDocPath);
|
|
231768
|
+
const markdownPath = resolveDocsMarkdownPath(siteDocPath);
|
|
231769
|
+
assertNoHostInDocPath(markdownPath);
|
|
230292
231770
|
const markdown = await docsManager.readDoc(markdownPath);
|
|
230293
231771
|
// 站点对没有 markdown 的路径也返回 200 + HTML 外壳,必须显式判失败,
|
|
230294
231772
|
// 否则会把整页 HTML 当成文档正文交给模型(旧行为就是这样静默出错的)。
|
|
230295
231773
|
if (isDocsHtmlFallback(markdown)) {
|
|
231774
|
+
// 「网页版」退路必须是绝对地址:走到这里 markdownPath 已不含 host,只给路径
|
|
231775
|
+
// 调用方没法直接抓。
|
|
231776
|
+
const pageUrl = `https://${exports.DOCS_BASE_HOST}${markdownPath.replace(/\.md(?=#|$)/i, "")}`;
|
|
230296
231777
|
throw new Error((0, index_js_1.t)("rag.readDocNotMarkdown", {
|
|
230297
231778
|
docPath: markdownPath,
|
|
230298
|
-
pageUrl
|
|
231779
|
+
pageUrl,
|
|
230299
231780
|
}));
|
|
230300
231781
|
}
|
|
230301
231782
|
return (0, json_content_js_1.jsonContent)(buildDocsEnvelope(resolvedAction, { docPath: resolvedDocPath, markdownPath, content: markdown }, (0, index_js_1.t)("rag.readDocSuccess")));
|
|
@@ -230634,6 +232115,7 @@ const url_1 = __webpack_require__(79551);
|
|
|
230634
232115
|
const zod_1 = __webpack_require__(21504);
|
|
230635
232116
|
const index_js_1 = __webpack_require__(24908);
|
|
230636
232117
|
const remote_url_safety_js_1 = __webpack_require__(23694);
|
|
232118
|
+
const project_config_js_1 = __webpack_require__(39175);
|
|
230637
232119
|
// CloudBase 模板配置
|
|
230638
232120
|
const TEMPLATES = {
|
|
230639
232121
|
react: {
|
|
@@ -231119,6 +232601,23 @@ function registerSetupTools(server) {
|
|
|
231119
232601
|
};
|
|
231120
232602
|
}
|
|
231121
232603
|
const resolvedIDE = ideResolution.resolvedIDE;
|
|
232604
|
+
let workspaceFolder;
|
|
232605
|
+
try {
|
|
232606
|
+
workspaceFolder = (0, project_config_js_1.resolveProjectRoot)();
|
|
232607
|
+
}
|
|
232608
|
+
catch (error) {
|
|
232609
|
+
if (error instanceof project_config_js_1.ProjectRootError) {
|
|
232610
|
+
return {
|
|
232611
|
+
content: [
|
|
232612
|
+
{
|
|
232613
|
+
type: "text",
|
|
232614
|
+
text: (0, index_js_1.t)("setup.projectRoot.hostConfigDir", { dir: error.dir }),
|
|
232615
|
+
},
|
|
232616
|
+
],
|
|
232617
|
+
};
|
|
232618
|
+
}
|
|
232619
|
+
throw error;
|
|
232620
|
+
}
|
|
231122
232621
|
// 验证IDE类型
|
|
231123
232622
|
const ideValidation = validateIDE(resolvedIDE);
|
|
231124
232623
|
if (!ideValidation.valid) {
|
|
@@ -231156,7 +232655,6 @@ function registerSetupTools(server) {
|
|
|
231156
232655
|
// 创建过滤后的目录结构(当选择特定IDE时)
|
|
231157
232656
|
const workingDir = await createFilteredDirectory(extractDir, filteredFiles, resolvedIDE);
|
|
231158
232657
|
// 检查是否需要复制到项目目录
|
|
231159
|
-
const workspaceFolder = process.env.WORKSPACE_FOLDER_PATHS || process.cwd();
|
|
231160
232658
|
let finalFiles = [];
|
|
231161
232659
|
let createdCount = 0;
|
|
231162
232660
|
let overwrittenCount = 0;
|
|
@@ -232361,6 +233859,143 @@ function resolveRequestId(error) {
|
|
|
232361
233859
|
}
|
|
232362
233860
|
|
|
232363
233861
|
|
|
233862
|
+
/***/ },
|
|
233863
|
+
|
|
233864
|
+
/***/ 23379
|
|
233865
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
233866
|
+
|
|
233867
|
+
"use strict";
|
|
233868
|
+
|
|
233869
|
+
/**
|
|
233870
|
+
* In-process log of tool outcomes for an explicitly requested feedback draft.
|
|
233871
|
+
*
|
|
233872
|
+
* Hosted gateways may construct a new server object per request. The log is
|
|
233873
|
+
* therefore keyed by a hash of the credential when one is present, and only
|
|
233874
|
+
* falls back to the server object when no credential is available. The cache
|
|
233875
|
+
* is bounded. Arguments are never stored, and the raw credential is not stored.
|
|
233876
|
+
*/
|
|
233877
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
233878
|
+
exports.FEEDBACK_CREDENTIAL_LIMIT = exports.FEEDBACK_SESSION_LIMIT = void 0;
|
|
233879
|
+
exports.recordToolOutcome = recordToolOutcome;
|
|
233880
|
+
exports.readToolOutcomes = readToolOutcomes;
|
|
233881
|
+
exports.noteRepeatCount = noteRepeatCount;
|
|
233882
|
+
exports.readRepeatPeak = readRepeatPeak;
|
|
233883
|
+
exports.clearToolOutcomes = clearToolOutcomes;
|
|
233884
|
+
exports.__resetFeedbackSessionsForTests = __resetFeedbackSessionsForTests;
|
|
233885
|
+
const node_crypto_1 = __webpack_require__(75305);
|
|
233886
|
+
const MAX_OUTCOMES = 200;
|
|
233887
|
+
const MAX_CREDENTIALS = 64;
|
|
233888
|
+
const MAX_TOOL_NAME_LENGTH = 80;
|
|
233889
|
+
const byCredential = new Map();
|
|
233890
|
+
const byServer = new WeakMap();
|
|
233891
|
+
function credentialKey(server) {
|
|
233892
|
+
const options = server.cloudBaseOptions;
|
|
233893
|
+
const secretId = typeof options?.secretId === "string" ? options.secretId.trim() : "";
|
|
233894
|
+
if (!secretId) {
|
|
233895
|
+
return undefined;
|
|
233896
|
+
}
|
|
233897
|
+
const token = typeof options?.token === "string" ? options.token.trim() : "";
|
|
233898
|
+
const site = typeof options?.site === "string" ? options.site.trim() : "";
|
|
233899
|
+
return (0, node_crypto_1.createHash)("sha256").update(`${site}\n${secretId}\n${token}`).digest("hex");
|
|
233900
|
+
}
|
|
233901
|
+
function emptyBucket() {
|
|
233902
|
+
return { outcomes: [], repeatPeak: 0, touchedAt: Date.now() };
|
|
233903
|
+
}
|
|
233904
|
+
function evictOldestCredential() {
|
|
233905
|
+
let oldestKey;
|
|
233906
|
+
let oldestTouched = Number.POSITIVE_INFINITY;
|
|
233907
|
+
for (const [key, bucket] of byCredential) {
|
|
233908
|
+
if (bucket.touchedAt < oldestTouched) {
|
|
233909
|
+
oldestTouched = bucket.touchedAt;
|
|
233910
|
+
oldestKey = key;
|
|
233911
|
+
}
|
|
233912
|
+
}
|
|
233913
|
+
if (oldestKey) {
|
|
233914
|
+
byCredential.delete(oldestKey);
|
|
233915
|
+
}
|
|
233916
|
+
}
|
|
233917
|
+
function bucketFor(server) {
|
|
233918
|
+
if (!server || typeof server !== "object") {
|
|
233919
|
+
return undefined;
|
|
233920
|
+
}
|
|
233921
|
+
const key = credentialKey(server);
|
|
233922
|
+
if (key) {
|
|
233923
|
+
let bucket = byCredential.get(key);
|
|
233924
|
+
if (!bucket) {
|
|
233925
|
+
if (byCredential.size >= MAX_CREDENTIALS) {
|
|
233926
|
+
evictOldestCredential();
|
|
233927
|
+
}
|
|
233928
|
+
bucket = emptyBucket();
|
|
233929
|
+
byCredential.set(key, bucket);
|
|
233930
|
+
}
|
|
233931
|
+
bucket.touchedAt = Date.now();
|
|
233932
|
+
return bucket;
|
|
233933
|
+
}
|
|
233934
|
+
let bucket = byServer.get(server);
|
|
233935
|
+
if (!bucket) {
|
|
233936
|
+
bucket = emptyBucket();
|
|
233937
|
+
byServer.set(server, bucket);
|
|
233938
|
+
}
|
|
233939
|
+
return bucket;
|
|
233940
|
+
}
|
|
233941
|
+
function recordToolOutcome(server, input) {
|
|
233942
|
+
const bucket = bucketFor(server);
|
|
233943
|
+
if (!bucket) {
|
|
233944
|
+
return;
|
|
233945
|
+
}
|
|
233946
|
+
const toolName = typeof input.toolName === "string" ? input.toolName.trim() : "";
|
|
233947
|
+
if (!toolName) {
|
|
233948
|
+
return;
|
|
233949
|
+
}
|
|
233950
|
+
const durationMs = Number.isFinite(input.durationMs) && input.durationMs >= 0
|
|
233951
|
+
? Math.round(input.durationMs)
|
|
233952
|
+
: 0;
|
|
233953
|
+
const at = typeof input.at === "string" && input.at.length > 0
|
|
233954
|
+
? input.at
|
|
233955
|
+
: new Date().toISOString();
|
|
233956
|
+
bucket.outcomes.push({
|
|
233957
|
+
toolName: toolName.slice(0, MAX_TOOL_NAME_LENGTH),
|
|
233958
|
+
durationMs,
|
|
233959
|
+
failed: input.failed === true,
|
|
233960
|
+
at,
|
|
233961
|
+
});
|
|
233962
|
+
if (bucket.outcomes.length > MAX_OUTCOMES) {
|
|
233963
|
+
bucket.outcomes.splice(0, bucket.outcomes.length - MAX_OUTCOMES);
|
|
233964
|
+
}
|
|
233965
|
+
}
|
|
233966
|
+
function readToolOutcomes(server) {
|
|
233967
|
+
return bucketFor(server)?.outcomes ?? [];
|
|
233968
|
+
}
|
|
233969
|
+
function noteRepeatCount(server, count) {
|
|
233970
|
+
const bucket = bucketFor(server);
|
|
233971
|
+
if (!bucket || !Number.isFinite(count) || count <= 0) {
|
|
233972
|
+
return;
|
|
233973
|
+
}
|
|
233974
|
+
const rounded = Math.round(count);
|
|
233975
|
+
if (rounded > bucket.repeatPeak) {
|
|
233976
|
+
bucket.repeatPeak = rounded;
|
|
233977
|
+
}
|
|
233978
|
+
}
|
|
233979
|
+
function readRepeatPeak(server) {
|
|
233980
|
+
return bucketFor(server)?.repeatPeak ?? 0;
|
|
233981
|
+
}
|
|
233982
|
+
function clearToolOutcomes(server) {
|
|
233983
|
+
const key = server && typeof server === "object" ? credentialKey(server) : undefined;
|
|
233984
|
+
if (key) {
|
|
233985
|
+
byCredential.delete(key);
|
|
233986
|
+
return;
|
|
233987
|
+
}
|
|
233988
|
+
if (server && typeof server === "object") {
|
|
233989
|
+
byServer.delete(server);
|
|
233990
|
+
}
|
|
233991
|
+
}
|
|
233992
|
+
function __resetFeedbackSessionsForTests() {
|
|
233993
|
+
byCredential.clear();
|
|
233994
|
+
}
|
|
233995
|
+
exports.FEEDBACK_SESSION_LIMIT = MAX_OUTCOMES;
|
|
233996
|
+
exports.FEEDBACK_CREDENTIAL_LIMIT = MAX_CREDENTIALS;
|
|
233997
|
+
|
|
233998
|
+
|
|
232364
233999
|
/***/ },
|
|
232365
234000
|
|
|
232366
234001
|
/***/ 84173
|
|
@@ -232826,14 +234461,101 @@ async function sendDeployNotification(server, notificationData) {
|
|
|
232826
234461
|
"use strict";
|
|
232827
234462
|
|
|
232828
234463
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
234464
|
+
exports.ProjectRootError = void 0;
|
|
234465
|
+
exports.resolveProjectRoot = resolveProjectRoot;
|
|
234466
|
+
exports.requireProjectRoot = requireProjectRoot;
|
|
232829
234467
|
exports.readCloudbaseRcBinding = readCloudbaseRcBinding;
|
|
232830
234468
|
exports.readProjectConfig = readProjectConfig;
|
|
232831
234469
|
exports.readProjectEnvId = readProjectEnvId;
|
|
232832
234470
|
exports.writeProjectConfig = writeProjectConfig;
|
|
232833
234471
|
const node_fs_1 = __webpack_require__(89971);
|
|
234472
|
+
const node_os_1 = __webpack_require__(81258);
|
|
232834
234473
|
const node_path_1 = __webpack_require__(26743);
|
|
232835
234474
|
const toolbox_1 = __webpack_require__(23233);
|
|
234475
|
+
const index_js_1 = __webpack_require__(24908);
|
|
232836
234476
|
const CLOUDBASE_RC_FILENAME = "cloudbaserc.json";
|
|
234477
|
+
const PROJECT_ROOT_ENV_KEYS = [
|
|
234478
|
+
"WORKSPACE_FOLDER_PATHS",
|
|
234479
|
+
"PROJECT_ROOT",
|
|
234480
|
+
"GITHUB_WORKSPACE",
|
|
234481
|
+
"CI_PROJECT_DIR",
|
|
234482
|
+
"BUILD_SOURCESDIRECTORY",
|
|
234483
|
+
];
|
|
234484
|
+
/** Thrown when the resolved directory is a host config root, not a project. */
|
|
234485
|
+
class ProjectRootError extends Error {
|
|
234486
|
+
dir;
|
|
234487
|
+
constructor(dir) {
|
|
234488
|
+
super("setup.projectRoot.hostConfigDir");
|
|
234489
|
+
this.name = "ProjectRootError";
|
|
234490
|
+
this.dir = dir;
|
|
234491
|
+
}
|
|
234492
|
+
}
|
|
234493
|
+
exports.ProjectRootError = ProjectRootError;
|
|
234494
|
+
function firstPathSegment(value) {
|
|
234495
|
+
return value
|
|
234496
|
+
.split(node_path_1.delimiter)
|
|
234497
|
+
.map((segment) => segment.trim())
|
|
234498
|
+
.find((segment) => segment.length > 0);
|
|
234499
|
+
}
|
|
234500
|
+
function isUnderHostConfig(candidate) {
|
|
234501
|
+
const hostRoot = (0, node_path_1.resolve)((0, node_os_1.homedir)(), ".dsh");
|
|
234502
|
+
const resolved = (0, node_path_1.resolve)(candidate);
|
|
234503
|
+
const rel = (0, node_path_1.relative)(hostRoot, resolved);
|
|
234504
|
+
return rel === "" || (!rel.startsWith("..") && !(0, node_path_1.isAbsolute)(rel));
|
|
234505
|
+
}
|
|
234506
|
+
/**
|
|
234507
|
+
* Project directory for reads and writes.
|
|
234508
|
+
*
|
|
234509
|
+
* Explicit path, then host-injected workspace env vars, then process.cwd().
|
|
234510
|
+
* A result under ~/.dsh is refused so tools do not treat the host profile as a project.
|
|
234511
|
+
*/
|
|
234512
|
+
function resolveProjectRoot(explicit) {
|
|
234513
|
+
const trimmed = explicit?.trim();
|
|
234514
|
+
let chosen;
|
|
234515
|
+
if (trimmed) {
|
|
234516
|
+
chosen = (0, node_path_1.resolve)(trimmed);
|
|
234517
|
+
}
|
|
234518
|
+
else {
|
|
234519
|
+
let fromEnv;
|
|
234520
|
+
for (const key of PROJECT_ROOT_ENV_KEYS) {
|
|
234521
|
+
const raw = process.env[key];
|
|
234522
|
+
if (!raw?.trim())
|
|
234523
|
+
continue;
|
|
234524
|
+
const first = firstPathSegment(raw);
|
|
234525
|
+
if (first) {
|
|
234526
|
+
fromEnv = (0, node_path_1.resolve)(first);
|
|
234527
|
+
break;
|
|
234528
|
+
}
|
|
234529
|
+
}
|
|
234530
|
+
chosen = fromEnv ?? (0, node_path_1.resolve)(process.cwd());
|
|
234531
|
+
}
|
|
234532
|
+
if (isUnderHostConfig(chosen)) {
|
|
234533
|
+
throw new ProjectRootError(chosen);
|
|
234534
|
+
}
|
|
234535
|
+
return chosen;
|
|
234536
|
+
}
|
|
234537
|
+
/** Same as resolveProjectRoot, with the refusal already translated for tool output. */
|
|
234538
|
+
function requireProjectRoot(explicit) {
|
|
234539
|
+
try {
|
|
234540
|
+
return resolveProjectRoot(explicit);
|
|
234541
|
+
}
|
|
234542
|
+
catch (error) {
|
|
234543
|
+
if (error instanceof ProjectRootError) {
|
|
234544
|
+
throw new Error((0, index_js_1.t)("setup.projectRoot.hostConfigDir", { dir: error.dir }));
|
|
234545
|
+
}
|
|
234546
|
+
throw error;
|
|
234547
|
+
}
|
|
234548
|
+
}
|
|
234549
|
+
function projectRootForConfig(cwd) {
|
|
234550
|
+
try {
|
|
234551
|
+
return resolveProjectRoot(cwd);
|
|
234552
|
+
}
|
|
234553
|
+
catch (error) {
|
|
234554
|
+
if (error instanceof ProjectRootError)
|
|
234555
|
+
return undefined;
|
|
234556
|
+
throw error;
|
|
234557
|
+
}
|
|
234558
|
+
}
|
|
232837
234559
|
/**
|
|
232838
234560
|
* 解析 cloudbaserc.json 字段值用于绑定(fail-safe:解析不出一律返回 undefined 回落下一级):
|
|
232839
234561
|
* - 字面量 → trim 后直接返回
|
|
@@ -232891,7 +234613,9 @@ function resolveBindingValue(raw, projectRoot) {
|
|
|
232891
234613
|
*/
|
|
232892
234614
|
function readCloudbaseRcBinding(cwd) {
|
|
232893
234615
|
try {
|
|
232894
|
-
const projectRoot = cwd
|
|
234616
|
+
const projectRoot = projectRootForConfig(cwd);
|
|
234617
|
+
if (!projectRoot)
|
|
234618
|
+
return undefined;
|
|
232895
234619
|
const configPath = (0, node_path_1.join)(projectRoot, CLOUDBASE_RC_FILENAME);
|
|
232896
234620
|
if (!(0, node_fs_1.existsSync)(configPath)) {
|
|
232897
234621
|
return undefined;
|
|
@@ -232925,7 +234649,9 @@ function readCloudbaseRcBinding(cwd) {
|
|
|
232925
234649
|
*/
|
|
232926
234650
|
function readProjectConfig(cwd) {
|
|
232927
234651
|
try {
|
|
232928
|
-
const projectRoot = cwd
|
|
234652
|
+
const projectRoot = projectRootForConfig(cwd);
|
|
234653
|
+
if (!projectRoot)
|
|
234654
|
+
return undefined;
|
|
232929
234655
|
const configPath = (0, node_path_1.join)(projectRoot, ".cloudbase", "project.json");
|
|
232930
234656
|
if (!(0, node_fs_1.existsSync)(configPath)) {
|
|
232931
234657
|
return undefined;
|
|
@@ -232973,7 +234699,9 @@ function readProjectEnvId(cwd) {
|
|
|
232973
234699
|
*/
|
|
232974
234700
|
function writeProjectConfig(patch, cwd) {
|
|
232975
234701
|
try {
|
|
232976
|
-
const projectRoot = cwd
|
|
234702
|
+
const projectRoot = projectRootForConfig(cwd);
|
|
234703
|
+
if (!projectRoot)
|
|
234704
|
+
return false;
|
|
232977
234705
|
const configPath = (0, node_path_1.join)(projectRoot, ".cloudbase", "project.json");
|
|
232978
234706
|
let existing = {};
|
|
232979
234707
|
if ((0, node_fs_1.existsSync)(configPath)) {
|
|
@@ -233199,6 +234927,7 @@ function getRemoteUrlSafetyErrorMessage() {
|
|
|
233199
234927
|
|
|
233200
234928
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
233201
234929
|
exports.REPEAT_GUARD_THRESHOLD = void 0;
|
|
234930
|
+
exports.getRepeatGuardSnapshot = getRepeatGuardSnapshot;
|
|
233202
234931
|
exports.applyRepeatGuardToPayload = applyRepeatGuardToPayload;
|
|
233203
234932
|
exports.resetRepeatGuard = resetRepeatGuard;
|
|
233204
234933
|
exports.__resetRepeatGuardForTests = __resetRepeatGuardForTests;
|
|
@@ -233217,6 +234946,13 @@ exports.REPEAT_GUARD_THRESHOLD = 3;
|
|
|
233217
234946
|
const REPEAT_GUARD_KEY_MAX_LENGTH = 200;
|
|
233218
234947
|
let lastKey = null;
|
|
233219
234948
|
let consecutiveCount = 0;
|
|
234949
|
+
/**
|
|
234950
|
+
* Live streak only. Does not expose the dedup key: that key contains the raw
|
|
234951
|
+
* error message, which may include secrets or identifiers.
|
|
234952
|
+
*/
|
|
234953
|
+
function getRepeatGuardSnapshot() {
|
|
234954
|
+
return { consecutiveCount };
|
|
234955
|
+
}
|
|
233220
234956
|
function buildRepeatGuardKey(payload) {
|
|
233221
234957
|
const code = typeof payload.code === "string" ? payload.code : "";
|
|
233222
234958
|
const message = typeof payload.message === "string" ? payload.message : "";
|
|
@@ -233689,7 +235425,7 @@ class TelemetryReporter {
|
|
|
233689
235425
|
const arch = os_1.default.arch(); // 系统架构
|
|
233690
235426
|
// Build-time injected version; guard for vitest / non-webpack runtimes.
|
|
233691
235427
|
const mcpVersion = process.env.npm_package_version ||
|
|
233692
|
-
( true ? "2.34.
|
|
235428
|
+
( true ? "2.34.7" : 0);
|
|
233693
235429
|
return {
|
|
233694
235430
|
userAgent: `${osType} ${osRelease} ${arch} ${nodeVersion} CloudBase-MCP/${mcpVersion}`,
|
|
233695
235431
|
deviceId: this.deviceId,
|
|
@@ -234337,6 +236073,7 @@ const logger_js_1 = __webpack_require__(40781);
|
|
|
234337
236073
|
const telemetry_js_1 = __webpack_require__(5198);
|
|
234338
236074
|
const tool_result_js_1 = __webpack_require__(69645);
|
|
234339
236075
|
const repeat_error_guard_js_1 = __webpack_require__(13);
|
|
236076
|
+
const feedback_session_js_1 = __webpack_require__(23379);
|
|
234340
236077
|
const error_guidance_js_1 = __webpack_require__(81194);
|
|
234341
236078
|
/**
|
|
234342
236079
|
* Mirror annotations.category into _meta.category.
|
|
@@ -234412,7 +236149,7 @@ ${envIdSection}
|
|
|
234412
236149
|
## 环境信息
|
|
234413
236150
|
- 操作系统: ${os_1.default.type()} ${os_1.default.release()}
|
|
234414
236151
|
- Node.js版本: ${process.version}
|
|
234415
|
-
- MCP 版本:${( true ? "2.34.
|
|
236152
|
+
- MCP 版本:${( true ? "2.34.7" : 0) || 0 || 0}
|
|
234416
236153
|
- 系统架构: ${os_1.default.arch()}
|
|
234417
236154
|
- 时间: ${new Date().toISOString()}
|
|
234418
236155
|
- 请求ID: ${requestId}
|
|
@@ -234446,6 +236183,8 @@ function createWrappedHandler(name, handler, server) {
|
|
|
234446
236183
|
return async (args) => {
|
|
234447
236184
|
const startTime = Date.now();
|
|
234448
236185
|
let success = false;
|
|
236186
|
+
let businessFailed = false;
|
|
236187
|
+
let repeatCountSeen = 0;
|
|
234449
236188
|
let errorMessage;
|
|
234450
236189
|
let requestId;
|
|
234451
236190
|
try {
|
|
@@ -234457,7 +236196,11 @@ function createWrappedHandler(name, handler, server) {
|
|
|
234457
236196
|
}
|
|
234458
236197
|
// 执行原始处理函数
|
|
234459
236198
|
const result = await handler(args);
|
|
236199
|
+
// Returned { success: false } is a business failure for the local
|
|
236200
|
+
// session log. The telemetry flag below stays on the existing path.
|
|
236201
|
+
businessFailed = (0, tool_result_js_1.isBusinessFailureToolResult)(result);
|
|
234460
236202
|
success = true;
|
|
236203
|
+
repeatCountSeen = (0, repeat_error_guard_js_1.getRepeatGuardSnapshot)().consecutiveCount;
|
|
234461
236204
|
// 任一工具成功说明重复错误循环已被打破,清零连续错误计数
|
|
234462
236205
|
(0, repeat_error_guard_js_1.resetRepeatGuard)();
|
|
234463
236206
|
requestId = extractRequestIdFromToolResult(result);
|
|
@@ -234490,8 +236233,11 @@ function createWrappedHandler(name, handler, server) {
|
|
|
234490
236233
|
if ((0, tool_result_js_1.isToolPayloadError)(error)) {
|
|
234491
236234
|
// 连续相同结构化错误达到阈值时注入 repeat_guard 升级提示,
|
|
234492
236235
|
// 打断无头客户端的原样重试循环(不改写 message,保持遥测聚合稳定)
|
|
234493
|
-
|
|
236236
|
+
const payload = (0, repeat_error_guard_js_1.applyRepeatGuardToPayload)(error.payload);
|
|
236237
|
+
repeatCountSeen = (0, repeat_error_guard_js_1.getRepeatGuardSnapshot)().consecutiveCount;
|
|
236238
|
+
throw new tool_result_js_1.ToolPayloadError(payload);
|
|
234494
236239
|
}
|
|
236240
|
+
repeatCountSeen = (0, repeat_error_guard_js_1.getRepeatGuardSnapshot)().consecutiveCount;
|
|
234495
236241
|
// In tests, avoid any extra work that may block (envId lookup, issue link generation, etc.)
|
|
234496
236242
|
if (isTestEnvironment) {
|
|
234497
236243
|
throw error instanceof Error ? error : new Error(String(error));
|
|
@@ -234501,7 +236247,7 @@ function createWrappedHandler(name, handler, server) {
|
|
|
234501
236247
|
requestId,
|
|
234502
236248
|
ide: server.ide || process.env.INTEGRATION_IDE || ''
|
|
234503
236249
|
});
|
|
234504
|
-
const mcpVersion = true ? "2.34.
|
|
236250
|
+
const mcpVersion = true ? "2.34.7" : 0;
|
|
234505
236251
|
const requestIdSuffix = requestId ? `\n🆔 RequestId: ${requestId}` : '';
|
|
234506
236252
|
const enhancedErrorMessage = `${errorMessage}${requestIdSuffix}\n\n📦 CloudBase MCP v${mcpVersion}\n🔗 遇到问题?请复制以下链接到浏览器打开\n即可自动携带错误详情快速创建 GitHub Issue:\n${issueLink}`;
|
|
234507
236253
|
// 创建新的错误对象,保持原有的错误类型但更新消息
|
|
@@ -234517,6 +236263,20 @@ function createWrappedHandler(name, handler, server) {
|
|
|
234517
236263
|
throw enhancedError;
|
|
234518
236264
|
}
|
|
234519
236265
|
finally {
|
|
236266
|
+
try {
|
|
236267
|
+
(0, feedback_session_js_1.noteRepeatCount)(server, repeatCountSeen);
|
|
236268
|
+
(0, feedback_session_js_1.recordToolOutcome)(server, {
|
|
236269
|
+
toolName: name,
|
|
236270
|
+
durationMs: Date.now() - startTime,
|
|
236271
|
+
failed: Boolean(errorMessage) || businessFailed,
|
|
236272
|
+
});
|
|
236273
|
+
}
|
|
236274
|
+
catch (recordError) {
|
|
236275
|
+
(0, logger_js_1.debug)("feedback session record failed", {
|
|
236276
|
+
toolName: name,
|
|
236277
|
+
error: recordError instanceof Error ? recordError.message : String(recordError),
|
|
236278
|
+
});
|
|
236279
|
+
}
|
|
234520
236280
|
// 上报工具调用数据(测试环境中跳过,避免阻塞)
|
|
234521
236281
|
const isTestEnvironment = false || process.env.VITEST === "true";
|
|
234522
236282
|
if (!isTestEnvironment) {
|