@cloudbase/cloudbase-mcp 2.34.3 → 2.34.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -204165,9 +204165,9 @@ exports.permissions = void 0;
204165
204165
  const types_js_1 = __webpack_require__(89921);
204166
204166
  exports.permissions = (0, types_js_1.defineModule)({
204167
204167
  queryTitle: "查询 CloudBase 权限与用户配置",
204168
- queryDescription: "查询 CloudBase 权限与用户配置,支持查询资源权限(数据库/云函数/存储桶等)、角色列表/详情、应用用户列表/详情,以及网关 OPA 授权策略(对齐 CLI `tcb policy list/get`)。\n\n示例:\n- 查询存储桶权限:`action=\"getResourcePermission\", resourceType=\"storage\", resourceId=\"bucket-name\"`\n- 列出旧网关策略:`action=\"listPolicy\"`(PG / OPA 引擎环境返回空列表,与 CLI 一致)\n- 读取用户 Rego:`action=\"getPolicy\"`;平台扩展策略:`action=\"getPolicy\", extension=true`\n\n📌 跨后端边界提示:调用前先用 `envQuery(action=\"info\", envId=...)` 看 `EnvInfo.RuntimeBackends`。`resourceType=\"noSqlDatabase\"` 查询的是 CloudBase NoSQL 集合规则,与 CloudBase PostgreSQL(PG)表的行级安全(RLS)是两套独立机制——同一个 PG 环境里 NoSQL 集合若仍在使用,对那些集合查询本工具结果**仍然有效**。要查 PG 表 RLS,请改用 `queryPgDatabase(action=\"sql\", sql=\"SELECT * FROM pg_policies WHERE tablename=...\")`。本工具不涉及 MySQL 权限。\n\n⚠️ PostgreSQL 环境:平台 `DescribeResourcePermission` 对 PG 环境会直接拒绝。当 `resourceType=\"function\"` 时,本工具会自动回退到 Manager SDK `describeEnvAuthzConfig`(与 CLI `tcb policy get` 一致,读取 `authz.user.rego`)。显式 OPA 策略请用 `listPolicy` / `getPolicy`。\n\n⚠️ 角色类 action(`listRoles` / `getRole`)在 **PostgreSQL 类型环境**下平台侧一律拒绝(`The current API does not support PostgreSQL type environments.`)——这是平台能力边界,不是配置问题,**不要在 PG 环境反复重试**;PG 环境请改用 RLS(`managePgDatabase(action=\"execute\")` 跑 `CREATE POLICY`)或控制台管理权限。",
204168
+ queryDescription: "查询 CloudBase 权限与用户配置,支持查询资源权限(数据库/云函数/存储桶等)、角色列表/详情、应用用户列表/详情,以及网关 OPA 授权策略(对齐 CLI `tcb policy list/get`)。\n\n示例:\n- 查询存储桶权限:`action=\"getResourcePermission\", resourceType=\"storage\", resourceId=\"bucket-name\"`\n- 列出旧网关策略:`action=\"listPolicy\"`(PG / OPA 引擎环境返回空列表,与 CLI 一致)\n- 读取用户 Rego:`action=\"getPolicy\"`;平台扩展策略:`action=\"getPolicy\", extension=true`\n\n📌 跨后端边界提示:调用前先用 `queryEnv(action=\"info\", envId=...)` 看 `EnvInfo.RuntimeBackends`。`resourceType=\"noSqlDatabase\"` 查询的是 CloudBase NoSQL 集合规则,与 CloudBase PostgreSQL(PG)表的行级安全(RLS)是两套独立机制——同一个 PG 环境里 NoSQL 集合若仍在使用,对那些集合查询本工具结果**仍然有效**。要查 PG 表 RLS,请改用 `queryPgDatabase(action=\"sql\", sql=\"SELECT * FROM pg_policies WHERE tablename=...\")`。本工具不涉及 MySQL 权限。\n\n⚠️ PostgreSQL 环境:平台 `DescribeResourcePermission` 对 PG 环境会直接拒绝。当 `resourceType=\"function\"` 时,本工具会自动回退到 Manager SDK `describeEnvAuthzConfig`(与 CLI `tcb policy get` 一致,读取 `authz.user.rego`)。显式 OPA 策略请用 `listPolicy` / `getPolicy`。\n\n⚠️ 角色类 action(`listRoles` / `getRole`)在 **PostgreSQL 类型环境**下平台侧一律拒绝(`The current API does not support PostgreSQL type environments.`)——这是平台能力边界,不是配置问题,**不要在 PG 环境反复重试**;PG 环境请改用 RLS(`managePgDatabase(action=\"execute\")` 跑 `CREATE POLICY`)或控制台管理权限。",
204169
204169
  manageTitle: "管理 CloudBase 权限与用户配置",
204170
- manageDescription: "管理 CloudBase 权限与用户配置,支持修改资源权限(数据库/云函数/存储桶等)、角色管理、成员与策略增删、应用用户 CRUD,以及设置网关 OPA Rego 策略(对齐 CLI `tcb policy set`)。\n\n示例:\n- 设置存储桶为私有:`action=\"updateResourcePermission\", resourceType=\"storage\", resourceId=\"bucket-name\", permission=\"PRIVATE\"`\n- 创建角色:`action=\"createRole\", roleName=\"admin\", roleIdentity=\"admin\"`\n- 放开云函数匿名/未登录访问(PG 会走 OPA,对齐 CLI `tcb policy set`):`action=\"updateResourcePermission\", resourceType=\"function\", resourceId=\"myFn\", permission=\"CUSTOM\", securityRule='{\"invoke\":true}'`\n- 直接设置用户 Rego:`action=\"setPolicy\", regoContent=\"package authz.user\\n\\ndefault allow := false\\n\", confirm=true`(⚠️ 立即禁用旧网关鉴权)\n\n注意:`createUser` / `updateUser` 是环境侧应用用户管理能力,适合测试账号、管理员或预置用户,不应替代浏览器里的 Web SDK 注册表单;前端用户名密码注册应使用 `auth.signUp({ username, password })`,登录应使用 `auth.signInWithPassword({ username, password })`。直接在浏览器里用 `auth.signUp` 创建用户名密码用户取决于 SDK/provider 支持,使用前必须验证;不支持时应走后端或管理端边界,不能在浏览器暴露密钥。`securityRule` 的详细语义取决于 `resourceType`:`doc._openid`、`auth.openid`、查询条件子集校验,以及 `create` / `update` / `delete` JSON 模板仅适用于 `resourceType=\"noSqlDatabase\"` 的文档数据库安全规则;配置 `function` 或 `storage` 时,请参考各自官方安全规则文档,而不是复用 NoSQL 模板。\n\n📌 跨后端边界提示:调用前先用 `envQuery(action=\"info\", envId=...)` 看 `EnvInfo.RuntimeBackends`:\n- `resourceType=\"noSqlDatabase\"` 仅作用于 CloudBase NoSQL 文档数据库的集合;CloudBase PostgreSQL(PG)表的行级权限**不**受它控制——PG 表请改用 RLS:`managePgDatabase(action=\"execute\", confirm=true)` 跑 `ALTER TABLE ... ENABLE ROW LEVEL SECURITY` 与 `CREATE POLICY ...`。同一个 PG 环境里如果还有 NoSQL 集合在用,对那些**集合**继续使用 `noSqlDatabase` 规则是正确的——不是\"PG 环境就禁用本工具\"。\n- `resourceType=\"storage\"` 控制的是 NoSQL/COS 存储桶 ACL;PG 的 `pgstore` bucket 不在此 `resourceType` 覆盖范围内。\n- 本工具不涉及 MySQL;MySQL 数据库权限请走 MySQL 自身的 GRANT/REVOKE 语句(通过 `manageMysqlDatabase`)。\n\n⚠️ PostgreSQL 环境:平台 `ModifyResourcePermission` 对 PG 环境会直接拒绝。当 `resourceType=\"function\"` 时,本工具会自动回退到 Manager SDK `modifyEnvAuthzConfig`(与 CLI `tcb policy set` 一致,写入 `authz.user.rego`)。`securityRule` 可传完整 Rego(`package authz.user`)或 `'{\"invoke\":true}'`(自动生成放通 anonymous/unauthenticated 调 functions 的策略)。设置 Rego 后旧网关鉴权会失效,行为与 CLI 相同。显式 OPA 策略请优先用 `action=\"setPolicy\"`。\n\n⚠️ 角色类 action(`createRole` / `deleteRoles` / `updateRole`)在 **PostgreSQL 类型环境**下平台侧一律拒绝(`The current API does not support PostgreSQL type environments.`)——平台能力边界,不是配置问题,**不要在 PG 环境反复重试**;PG 环境请改用 RLS(`managePgDatabase(action=\"execute\")` 跑 `CREATE POLICY`)或控制台管理权限。",
204170
+ manageDescription: "管理 CloudBase 权限与用户配置,支持修改资源权限(数据库/云函数/存储桶等)、角色管理、成员与策略增删、应用用户 CRUD,以及设置网关 OPA Rego 策略(对齐 CLI `tcb policy set`)。\n\n示例:\n- 设置存储桶为私有:`action=\"updateResourcePermission\", resourceType=\"storage\", resourceId=\"bucket-name\", permission=\"PRIVATE\"`\n- 创建角色:`action=\"createRole\", roleName=\"admin\", roleIdentity=\"admin\"`\n- 放开云函数匿名/未登录访问(PG 会走 OPA,对齐 CLI `tcb policy set`):`action=\"updateResourcePermission\", resourceType=\"function\", resourceId=\"myFn\", permission=\"CUSTOM\", securityRule='{\"invoke\":true}'`\n- 直接设置用户 Rego:`action=\"setPolicy\", regoContent=\"package authz.user\\n\\ndefault allow := false\\n\", confirm=true`(⚠️ 立即禁用旧网关鉴权)\n\n注意:`createUser` / `updateUser` 是环境侧应用用户管理能力,适合测试账号、管理员或预置用户,不应替代浏览器里的 Web SDK 注册表单;前端用户名密码注册应使用 `auth.signUp({ username, password })`,登录应使用 `auth.signInWithPassword({ username, password })`。直接在浏览器里用 `auth.signUp` 创建用户名密码用户取决于 SDK/provider 支持,使用前必须验证;不支持时应走后端或管理端边界,不能在浏览器暴露密钥。`securityRule` 的详细语义取决于 `resourceType`:`doc._openid`、`auth.openid`、查询条件子集校验,以及 `create` / `update` / `delete` JSON 模板仅适用于 `resourceType=\"noSqlDatabase\"` 的文档数据库安全规则;配置 `function` 或 `storage` 时,请参考各自官方安全规则文档,而不是复用 NoSQL 模板。\n\n📌 跨后端边界提示:调用前先用 `queryEnv(action=\"info\", envId=...)` 看 `EnvInfo.RuntimeBackends`:\n- `resourceType=\"noSqlDatabase\"` 仅作用于 CloudBase NoSQL 文档数据库的集合;CloudBase PostgreSQL(PG)表的行级权限**不**受它控制——PG 表请改用 RLS:`managePgDatabase(action=\"execute\", confirm=true)` 跑 `ALTER TABLE ... ENABLE ROW LEVEL SECURITY` 与 `CREATE POLICY ...`。同一个 PG 环境里如果还有 NoSQL 集合在用,对那些**集合**继续使用 `noSqlDatabase` 规则是正确的——不是\"PG 环境就禁用本工具\"。\n- `resourceType=\"storage\"` 控制的是 NoSQL/COS 存储桶 ACL;PG 的 `pgstore` bucket 不在此 `resourceType` 覆盖范围内。\n- 本工具不涉及 MySQL;MySQL 数据库权限请走 MySQL 自身的 GRANT/REVOKE 语句(通过 `manageMysqlDatabase`)。\n\n⚠️ PostgreSQL 环境:平台 `ModifyResourcePermission` 对 PG 环境会直接拒绝。当 `resourceType=\"function\"` 时,本工具会自动回退到 Manager SDK `modifyEnvAuthzConfig`(与 CLI `tcb policy set` 一致,写入 `authz.user.rego`)。`securityRule` 可传完整 Rego(`package authz.user`)或 `'{\"invoke\":true}'`(自动生成放通 anonymous/unauthenticated 调 functions 的策略)。设置 Rego 后旧网关鉴权会失效,行为与 CLI 相同。显式 OPA 策略请优先用 `action=\"setPolicy\"`。\n\n⚠️ 角色类 action(`createRole` / `deleteRoles` / `updateRole`)在 **PostgreSQL 类型环境**下平台侧一律拒绝(`The current API does not support PostgreSQL type environments.`)——平台能力边界,不是配置问题,**不要在 PG 环境反复重试**;PG 环境请改用 RLS(`managePgDatabase(action=\"execute\")` 跑 `CREATE POLICY`)或控制台管理权限。",
204171
204171
  writeVerificationHint: "对于 {resourceId} 这类有后端权限控制的集合,前端调用 .doc(id).update() / .doc(id).remove() 后,不能只看是否没有抛异常。请显式检查返回结果中的 updated / deleted 是否大于 0;如果 result.code、result.message 存在,或 updated / deleted 为 0,要把它当作真实失败并向上抛错。",
204172
204172
  permissionPropagationHint: "刚更新完 {resourceId} 的安全规则时,后端权限通常在数秒到约 30 秒内生效。若紧接着的真实写操作仍返回 DATABASE_PERMISSION_DENIED,请先间隔数秒用同一登录态重试同一条 .doc(id).update() / .doc(id).remove();不要盲等数分钟,也不要立刻连续重写规则,更不要在短暂传播窗口里把旧拒绝直接当成规则表达式仍然错误。",
204173
204173
  validateRegoEmpty: "action=setPolicy 需要非空 regoContent(对齐 CLI `tcb policy set <regoContent>`)。",
@@ -204234,9 +204234,9 @@ exports.permissions = (0, types_js_1.defineModule)({
204234
204234
  setPolicySuccess: "用户 OPA Rego 策略设置成功(旧网关鉴权已失效)",
204235
204235
  }, {
204236
204236
  queryTitle: "Query CloudBase permissions and user config",
204237
- queryDescription: "Query CloudBase permissions and user config: resource permissions (database/functions/buckets etc.), role list/detail, app user list/detail, and gateway OPA authorization policies (aligned with CLI `tcb policy list/get`).\n\nExamples:\n- Query bucket permission: `action=\"getResourcePermission\", resourceType=\"storage\", resourceId=\"bucket-name\"`\n- List legacy gateway policies: `action=\"listPolicy\"` (returns an empty list on PG / OPA engine environments, consistent with the CLI)\n- Read user Rego: `action=\"getPolicy\"`; platform extension policy: `action=\"getPolicy\", extension=true`\n\n📌 Cross-backend boundary note: before calling, check `EnvInfo.RuntimeBackends` via `envQuery(action=\"info\", envId=...)`. `resourceType=\"noSqlDatabase\"` queries CloudBase NoSQL collection rules, which are a separate mechanism from row-level security (RLS) on CloudBase PostgreSQL (PG) tables — in the same PG environment, if NoSQL collections are still in use, querying them with this tool **remains valid**. To query PG table RLS, use `queryPgDatabase(action=\"sql\", sql=\"SELECT * FROM pg_policies WHERE tablename=...\")` instead. This tool does not cover MySQL permissions.\n\n⚠️ PostgreSQL environments: the platform `DescribeResourcePermission` API rejects PG environments outright. When `resourceType=\"function\"`, this tool automatically falls back to the Manager SDK `describeEnvAuthzConfig` (aligned with CLI `tcb policy get`, reading `authz.user.rego`). For explicit OPA policies use `listPolicy` / `getPolicy`.\n\n⚠️ Role actions (`listRoles` / `getRole`) are rejected outright by the platform on **PostgreSQL environments** (`The current API does not support PostgreSQL type environments.`). This is a platform capability boundary, not a configuration problem — **do not keep retrying on PG**; use RLS (`managePgDatabase(action=\"execute\")` with `CREATE POLICY`) or the console to manage permissions instead.",
204237
+ queryDescription: "Query CloudBase permissions and user config: resource permissions (database/functions/buckets etc.), role list/detail, app user list/detail, and gateway OPA authorization policies (aligned with CLI `tcb policy list/get`).\n\nExamples:\n- Query bucket permission: `action=\"getResourcePermission\", resourceType=\"storage\", resourceId=\"bucket-name\"`\n- List legacy gateway policies: `action=\"listPolicy\"` (returns an empty list on PG / OPA engine environments, consistent with the CLI)\n- Read user Rego: `action=\"getPolicy\"`; platform extension policy: `action=\"getPolicy\", extension=true`\n\n📌 Cross-backend boundary note: before calling, check `EnvInfo.RuntimeBackends` via `queryEnv(action=\"info\", envId=...)`. `resourceType=\"noSqlDatabase\"` queries CloudBase NoSQL collection rules, which are a separate mechanism from row-level security (RLS) on CloudBase PostgreSQL (PG) tables — in the same PG environment, if NoSQL collections are still in use, querying them with this tool **remains valid**. To query PG table RLS, use `queryPgDatabase(action=\"sql\", sql=\"SELECT * FROM pg_policies WHERE tablename=...\")` instead. This tool does not cover MySQL permissions.\n\n⚠️ PostgreSQL environments: the platform `DescribeResourcePermission` API rejects PG environments outright. When `resourceType=\"function\"`, this tool automatically falls back to the Manager SDK `describeEnvAuthzConfig` (aligned with CLI `tcb policy get`, reading `authz.user.rego`). For explicit OPA policies use `listPolicy` / `getPolicy`.\n\n⚠️ Role actions (`listRoles` / `getRole`) are rejected outright by the platform on **PostgreSQL environments** (`The current API does not support PostgreSQL type environments.`). This is a platform capability boundary, not a configuration problem — **do not keep retrying on PG**; use RLS (`managePgDatabase(action=\"execute\")` with `CREATE POLICY`) or the console to manage permissions instead.",
204238
204238
  manageTitle: "Manage CloudBase permissions and user config",
204239
- manageDescription: "Manage CloudBase permissions and user config: modify resource permissions (database/functions/buckets etc.), role management, member/policy add & remove, app user CRUD, and setting gateway OPA Rego policies (aligned with CLI `tcb policy set`).\n\nExamples:\n- Set a bucket to private: `action=\"updateResourcePermission\", resourceType=\"storage\", resourceId=\"bucket-name\", permission=\"PRIVATE\"`\n- Create a role: `action=\"createRole\", roleName=\"admin\", roleIdentity=\"admin\"`\n- Open a cloud function to anonymous/unauthenticated access (PG goes through OPA, aligned with CLI `tcb policy set`): `action=\"updateResourcePermission\", resourceType=\"function\", resourceId=\"myFn\", permission=\"CUSTOM\", securityRule='{\"invoke\":true}'`\n- Set user Rego directly: `action=\"setPolicy\", regoContent=\"package authz.user\\n\\ndefault allow := false\\n\", confirm=true` (⚠️ immediately disables legacy gateway authorization)\n\nNote: `createUser` / `updateUser` are environment-side app user management capabilities, suitable for test accounts, administrators, or pre-provisioned users; they should not replace the Web SDK signup form in the browser. For frontend username/password signup use `auth.signUp({ username, password })` and for login `auth.signInWithPassword({ username, password })`. Creating username/password users directly in the browser with `auth.signUp` depends on SDK/provider support and must be verified before use; if unsupported, go through a backend or management API boundary and never expose keys in the browser. The detailed semantics of `securityRule` depend on `resourceType`: `doc._openid`, `auth.openid`, query-condition subset validation, and the `create` / `update` / `delete` JSON templates only apply to document database security rules with `resourceType=\"noSqlDatabase\"`; when configuring `function` or `storage`, refer to their official security rule docs instead of reusing NoSQL templates.\n\n📌 Cross-backend boundary note: before calling, check `EnvInfo.RuntimeBackends` via `envQuery(action=\"info\", envId=...)`:\n- `resourceType=\"noSqlDatabase\"` only affects CloudBase NoSQL document database collections; row-level permissions of CloudBase PostgreSQL (PG) tables are **not** controlled by it — for PG tables use RLS instead: run `ALTER TABLE ... ENABLE ROW LEVEL SECURITY` and `CREATE POLICY ...` via `managePgDatabase(action=\"execute\", confirm=true)`. In the same PG environment, if NoSQL collections are still in use, continuing to use `noSqlDatabase` rules for those **collections** is correct — it does not mean \"this tool is disabled on PG environments\".\n- `resourceType=\"storage\"` controls NoSQL/COS bucket ACLs; PG `pgstore` buckets are not covered by this `resourceType`.\n- This tool does not cover MySQL; for MySQL database permissions use MySQL's own GRANT/REVOKE statements (via `manageMysqlDatabase`).\n\n⚠️ PostgreSQL environments: the platform `ModifyResourcePermission` API rejects PG environments outright. When `resourceType=\"function\"`, this tool automatically falls back to the Manager SDK `modifyEnvAuthzConfig` (aligned with CLI `tcb policy set`, writing `authz.user.rego`). `securityRule` accepts a full Rego document (`package authz.user`) or `'{\"invoke\":true}'` (auto-generates a policy allowing anonymous/unauthenticated calls to functions). Setting Rego disables legacy gateway authorization, same as the CLI. Prefer `action=\"setPolicy\"` for explicit OPA policies.\n\n⚠️ Role actions (`createRole` / `deleteRoles` / `updateRole`) are rejected outright by the platform on **PostgreSQL environments** (`The current API does not support PostgreSQL type environments.`). This is a platform capability boundary, not a configuration problem — **do not keep retrying on PG**; use RLS (`managePgDatabase(action=\"execute\")` with `CREATE POLICY`) or the console to manage permissions instead.",
204239
+ manageDescription: "Manage CloudBase permissions and user config: modify resource permissions (database/functions/buckets etc.), role management, member/policy add & remove, app user CRUD, and setting gateway OPA Rego policies (aligned with CLI `tcb policy set`).\n\nExamples:\n- Set a bucket to private: `action=\"updateResourcePermission\", resourceType=\"storage\", resourceId=\"bucket-name\", permission=\"PRIVATE\"`\n- Create a role: `action=\"createRole\", roleName=\"admin\", roleIdentity=\"admin\"`\n- Open a cloud function to anonymous/unauthenticated access (PG goes through OPA, aligned with CLI `tcb policy set`): `action=\"updateResourcePermission\", resourceType=\"function\", resourceId=\"myFn\", permission=\"CUSTOM\", securityRule='{\"invoke\":true}'`\n- Set user Rego directly: `action=\"setPolicy\", regoContent=\"package authz.user\\n\\ndefault allow := false\\n\", confirm=true` (⚠️ immediately disables legacy gateway authorization)\n\nNote: `createUser` / `updateUser` are environment-side app user management capabilities, suitable for test accounts, administrators, or pre-provisioned users; they should not replace the Web SDK signup form in the browser. For frontend username/password signup use `auth.signUp({ username, password })` and for login `auth.signInWithPassword({ username, password })`. Creating username/password users directly in the browser with `auth.signUp` depends on SDK/provider support and must be verified before use; if unsupported, go through a backend or management API boundary and never expose keys in the browser. The detailed semantics of `securityRule` depend on `resourceType`: `doc._openid`, `auth.openid`, query-condition subset validation, and the `create` / `update` / `delete` JSON templates only apply to document database security rules with `resourceType=\"noSqlDatabase\"`; when configuring `function` or `storage`, refer to their official security rule docs instead of reusing NoSQL templates.\n\n📌 Cross-backend boundary note: before calling, check `EnvInfo.RuntimeBackends` via `queryEnv(action=\"info\", envId=...)`:\n- `resourceType=\"noSqlDatabase\"` only affects CloudBase NoSQL document database collections; row-level permissions of CloudBase PostgreSQL (PG) tables are **not** controlled by it — for PG tables use RLS instead: run `ALTER TABLE ... ENABLE ROW LEVEL SECURITY` and `CREATE POLICY ...` via `managePgDatabase(action=\"execute\", confirm=true)`. In the same PG environment, if NoSQL collections are still in use, continuing to use `noSqlDatabase` rules for those **collections** is correct — it does not mean \"this tool is disabled on PG environments\".\n- `resourceType=\"storage\"` controls NoSQL/COS bucket ACLs; PG `pgstore` buckets are not covered by this `resourceType`.\n- This tool does not cover MySQL; for MySQL database permissions use MySQL's own GRANT/REVOKE statements (via `manageMysqlDatabase`).\n\n⚠️ PostgreSQL environments: the platform `ModifyResourcePermission` API rejects PG environments outright. When `resourceType=\"function\"`, this tool automatically falls back to the Manager SDK `modifyEnvAuthzConfig` (aligned with CLI `tcb policy set`, writing `authz.user.rego`). `securityRule` accepts a full Rego document (`package authz.user`) or `'{\"invoke\":true}'` (auto-generates a policy allowing anonymous/unauthenticated calls to functions). Setting Rego disables legacy gateway authorization, same as the CLI. Prefer `action=\"setPolicy\"` for explicit OPA policies.\n\n⚠️ Role actions (`createRole` / `deleteRoles` / `updateRole`) are rejected outright by the platform on **PostgreSQL environments** (`The current API does not support PostgreSQL type environments.`). This is a platform capability boundary, not a configuration problem — **do not keep retrying on PG**; use RLS (`managePgDatabase(action=\"execute\")` with `CREATE POLICY`) or the console to manage permissions instead.",
204240
204240
  writeVerificationHint: "For collections with backend permission control like {resourceId}, after the frontend calls .doc(id).update() / .doc(id).remove(), do not just check that no exception was thrown. Explicitly verify that updated / deleted in the result is greater than 0; if result.code or result.message exists, or updated / deleted is 0, treat it as a real failure and propagate the error.",
204241
204241
  permissionPropagationHint: "Right after updating security rules for {resourceId}, backend permissions usually take effect within a few seconds to about 30 seconds. If an immediate real write still returns DATABASE_PERMISSION_DENIED, wait a few seconds and retry the same .doc(id).update() / .doc(id).remove() with the same login state; do not wait blindly for minutes, do not immediately rewrite the rules repeatedly, and do not treat an old rejection during the short propagation window as evidence that the rule expression is still wrong.",
204242
204242
  validateRegoEmpty: "action=setPolicy requires non-empty regoContent (aligned with CLI `tcb policy set <regoContent>`).",
@@ -204334,11 +204334,11 @@ exports.rag = (0, types_js_1.defineModule)({
204334
204334
 
204335
204335
  返回内容包含该 skill 的 SKILL.md 全文,以及它在远端聚合仓(CNB raw)中的全部 .md 文件地址清单(SKILL.md 与 references/ 等,可直接 HTTP 抓取)。正文中代码栅栏之外的相对链接也会改写为绝对地址;若该 skill 在远端仓中不存在,则只返回内联内容并明确标注,不返回失效链接。
204336
204336
 
204337
- 固定技能文档 (skill) 查询当前支持 {skillCount} 个固定文档,分别是:
204338
- {skillList}
204337
+ 不确定该选哪个时:mode=skill 下不传 skillName、mode=openapi 下不传 apiName 直接调用,会返回当前可用清单及各自的适用场景 / 接口简介,再带上名称重新调用即可。可选名称也见本工具的 skillName / apiName 枚举(skill 共 {skillCount} 个,API 共 {openapiCount} 个)。
204339
204338
 
204340
- OpenAPI 文档 (openapi) 查询只需要传 mode="openapi" 和 apiName,不要传 action;action 仅用于 mode="docs"。当前支持 {openapiCount} 个 API 文档,分别是:
204341
- {openapiList}`,
204339
+ 注意:OpenAPI 文档 (openapi) 查询只需要传 mode="openapi" 和 apiName,不要传 action;action 仅用于 mode="docs"。`,
204340
+ skillCatalogHeader: "CloudBase 技能文档 (skill) 当前可用 {count} 个,用 mode=skill + skillName 读取其中一篇:",
204341
+ openapiCatalogHeader: "OpenAPI 文档 (openapi) 当前可用 {count} 个,用 mode=openapi + apiName 读取其中一篇:",
204342
204342
  skillListItem: "文档名:{name} 文档介绍:{description}",
204343
204343
  openapiListItem: "API名:{name} API介绍:{description}",
204344
204344
  paramRequired: "action={action} 时必须提供 {param}",
@@ -204382,11 +204382,11 @@ exports.rag = (0, types_js_1.defineModule)({
204382
204382
 
204383
204383
  The response contains the full SKILL.md of the skill plus the list of all its .md file URLs in the remote aggregate repo (CNB raw) — SKILL.md and references/ etc., fetchable over HTTP. Relative links outside code fences are rewritten to absolute URLs; when the skill is absent from the remote repo only the inline content is returned and that is stated explicitly, so no dead links are handed out.
204384
204384
 
204385
- Fixed skill doc (skill) queries currently support {skillCount} fixed docs:
204386
- {skillList}
204385
+ When unsure which one to pick: call with mode=skill and no skillName, or mode=openapi and no apiName, to get the current catalog with each entry's scenario / summary, then call again with the name. Available names are also listed in this tool's skillName / apiName enums (currently {skillCount} skills, {openapiCount} APIs).
204387
204386
 
204388
- OpenAPI doc (openapi) queries only need mode="openapi" and apiName; do not pass action — action is only for mode="docs". Currently {openapiCount} API docs are supported:
204389
- {openapiList}`,
204387
+ Note: OpenAPI doc (openapi) queries only need mode="openapi" and apiName; do not pass action — action is only for mode="docs".`,
204388
+ skillCatalogHeader: "CloudBase skill docs (skill), {count} available. Use mode=skill + skillName to read one:",
204389
+ openapiCatalogHeader: "OpenAPI docs (openapi), {count} available. Use mode=openapi + apiName to read one:",
204390
204390
  skillListItem: "Skill: {name} — Description: {description}",
204391
204391
  openapiListItem: "API: {name} — Description: {description}",
204392
204392
  paramRequired: "{param} is required when action={action}",
@@ -205226,7 +205226,8 @@ function registerAgentTools(server) {
205226
205226
  },
205227
205227
  annotations: {
205228
205228
  readOnlyHint: true,
205229
- openWorldHint: true,
205229
+ destructiveHint: false,
205230
+ openWorldHint: false,
205230
205231
  category: "agents",
205231
205232
  },
205232
205233
  }, async ({ action, agentId, pageNumber, pageSize, params, }) => {
@@ -205300,7 +205301,7 @@ function registerAgentTools(server) {
205300
205301
  readOnlyHint: false,
205301
205302
  destructiveHint: true,
205302
205303
  idempotentHint: false,
205303
- openWorldHint: true,
205304
+ openWorldHint: false,
205304
205305
  category: "agents",
205305
205306
  },
205306
205307
  }, async ({ action, agentId, name, description, runtime, timeout, memorySize, installDependency, zipFile, cosBucketRegion, tempCosObjectName, sessionConfig, cwd, params, }) => {
@@ -205755,7 +205756,8 @@ function registerAppAuthTools(server) {
205755
205756
  },
205756
205757
  annotations: {
205757
205758
  readOnlyHint: true,
205758
- openWorldHint: true,
205759
+ destructiveHint: false,
205760
+ openWorldHint: false,
205759
205761
  category: "auth",
205760
205762
  },
205761
205763
  }, async ({ action, providerId, clientId, keyType, pageNumber, pageSize, }) => withEnvelope(async () => {
@@ -205892,7 +205894,7 @@ function registerAppAuthTools(server) {
205892
205894
  readOnlyHint: false,
205893
205895
  destructiveHint: true,
205894
205896
  idempotentHint: false,
205895
- openWorldHint: true,
205897
+ openWorldHint: false,
205896
205898
  category: "auth",
205897
205899
  },
205898
205900
  }, async ({ action, patch, providerId, providerType, displayName, clientId, config, keyType, keyName, expireIn, keyId, }) => withEnvelope(async () => {
@@ -206204,7 +206206,8 @@ function registerAppTools(server) {
206204
206206
  },
206205
206207
  annotations: {
206206
206208
  readOnlyHint: true,
206207
- openWorldHint: true,
206209
+ destructiveHint: false,
206210
+ openWorldHint: false,
206208
206211
  category: "apps",
206209
206212
  },
206210
206213
  }, async ({ action, serviceName, searchKey, pageNo, pageSize, versionName, buildId, start, }) => {
@@ -206446,7 +206449,7 @@ function registerAppTools(server) {
206446
206449
  readOnlyHint: false,
206447
206450
  destructiveHint: true,
206448
206451
  idempotentHint: false,
206449
- openWorldHint: true,
206452
+ openWorldHint: false,
206450
206453
  category: "apps",
206451
206454
  },
206452
206455
  }, async ({ action, serviceName, filePath, cosTimestamp, appPath, buildPath, framework, nodeJsVersion, installCmd, buildCmd, deployCmd, ignore, versionName, }) => {
@@ -207122,7 +207125,7 @@ function registerCapiTools(server) {
207122
207125
  readOnlyHint: false,
207123
207126
  destructiveHint: true,
207124
207127
  idempotentHint: false,
207125
- openWorldHint: true,
207128
+ openWorldHint: false,
207126
207129
  category: CATEGORY,
207127
207130
  },
207128
207131
  }, async ({ service, action, params, version, region, }) => {
@@ -207525,7 +207528,7 @@ const ManageCloudRunInputSchema = {
207525
207528
  PolicyThreshold: zod_1.z.number().min(1).max(100).describe('扩缩容阈值,单位为百分比。如60表示当资源使用率达到60%时触发扩缩容')
207526
207529
  })).optional().describe('扩缩容配置数组,用于配置服务的自动扩缩容策略。可配置多个扩缩容策略'),
207527
207530
  CustomLogs: zod_1.z.string().optional().describe('自定义日志配置,用于配置服务的日志收集和存储策略'),
207528
- Port: zod_1.z.number().min(1).max(65535).optional().describe('服务监听端口配置。函数型服务固定为3000,容器型服务可自定义。服务代码必须监听此端口才能正常接收请求'),
207531
+ Port: zod_1.z.number().min(1).max(65535).optional().describe('服务监听端口配置。函数型服务固定为3000(函数框架自身监听该端口,业务代码不要自行 app.listen);容器型服务可自定义,业务代码必须监听此端口'),
207529
207532
  EnvParams: zod_1.z.string().optional().describe('环境变量配置,JSON字符串格式。用于传递配置信息给服务代码,如\'{"DATABASE_URL":"postgres://user:pass@10.x.x.x:5432/db","NODE_ENV":"production"}\'。SDK v5.6.1+ 会自动对传入的环境变量进行 AES-256-CBC 加密传输。⚠️ 若 EnvParams 含 DATABASE_URL / MYSQL_* / POSTGRES_* / REDIS_* 等传统 TCP 连库变量,必须同时配置 VpcConf,否则实例通常无法访问 VPC 内数据库'),
207530
207533
  Dockerfile: zod_1.z.string().optional().describe('Dockerfile文件名配置,仅容器型服务需要。指定用于构建容器镜像的Dockerfile文件路径,默认为项目根目录下的Dockerfile'),
207531
207534
  BuildDir: zod_1.z.string().optional().describe('构建目录配置,指定代码构建的目录路径。当代码结构与标准不同时使用,默认为项目根目录'),
@@ -208306,7 +208309,8 @@ function registerCloudRunTools(server) {
208306
208309
  inputSchema: queryCloudRunInputSchema,
208307
208310
  annotations: {
208308
208311
  readOnlyHint: true,
208309
- openWorldHint: true,
208312
+ destructiveHint: false,
208313
+ openWorldHint: false,
208310
208314
  category: "cloudrun"
208311
208315
  }
208312
208316
  }, async (args) => {
@@ -208765,7 +208769,7 @@ function registerCloudRunTools(server) {
208765
208769
  readOnlyHint: false,
208766
208770
  destructiveHint: true,
208767
208771
  idempotentHint: false,
208768
- openWorldHint: true,
208772
+ openWorldHint: false,
208769
208773
  category: "cloudrun"
208770
208774
  }
208771
208775
  }, async (args) => {
@@ -210383,7 +210387,8 @@ function registerDataModelTools(server) {
210383
210387
  },
210384
210388
  annotations: {
210385
210389
  readOnlyHint: true,
210386
- openWorldHint: true,
210390
+ destructiveHint: false,
210391
+ openWorldHint: false,
210387
210392
  category: "database",
210388
210393
  },
210389
210394
  }, async ({ action, name, names, }) => {
@@ -210722,7 +210727,7 @@ classDiagram
210722
210727
  readOnlyHint: false,
210723
210728
  destructiveHint: false,
210724
210729
  idempotentHint: false,
210725
- openWorldHint: true,
210730
+ openWorldHint: false,
210726
210731
  category: "database",
210727
210732
  },
210728
210733
  }, async ({ mermaidDiagram, action = "create", publish = false, dbInstanceType = "MYSQL", }) => {
@@ -211258,7 +211263,8 @@ checkIndex: 检查指定索引是否存在`),
211258
211263
  },
211259
211264
  annotations: {
211260
211265
  readOnlyHint: true,
211261
- openWorldHint: true,
211266
+ destructiveHint: false,
211267
+ openWorldHint: false,
211262
211268
  category: CATEGORY,
211263
211269
  },
211264
211270
  }, async ({ action, limit, offset, collectionName, indexName }) => {
@@ -211461,7 +211467,7 @@ deleteCollection: 删除集合`),
211461
211467
  readOnlyHint: false,
211462
211468
  destructiveHint: true,
211463
211469
  idempotentHint: false,
211464
- openWorldHint: true,
211470
+ openWorldHint: false,
211465
211471
  category: CATEGORY,
211466
211472
  },
211467
211473
  }, async ({ action, collectionName, updateOptions }) => {
@@ -211643,7 +211649,8 @@ deleteCollection: 删除集合`),
211643
211649
  },
211644
211650
  annotations: {
211645
211651
  readOnlyHint: true,
211646
- openWorldHint: true,
211652
+ destructiveHint: false,
211653
+ openWorldHint: false,
211647
211654
  category: CATEGORY,
211648
211655
  },
211649
211656
  }, async ({ collectionName, instanceId, query, projection, sort, limit, offset }) => {
@@ -211744,7 +211751,7 @@ deleteCollection: 删除集合`),
211744
211751
  readOnlyHint: false,
211745
211752
  destructiveHint: true,
211746
211753
  idempotentHint: false,
211747
- openWorldHint: true,
211754
+ openWorldHint: false,
211748
211755
  category: CATEGORY,
211749
211756
  },
211750
211757
  }, async ({ action, collectionName, instanceId, documents, query, update, isMulti, upsert, }) => {
@@ -214363,7 +214370,8 @@ function registerPGDatabaseTools(server, providedDeps) {
214363
214370
  },
214364
214371
  annotations: {
214365
214372
  readOnlyHint: true,
214366
- openWorldHint: true,
214373
+ destructiveHint: false,
214374
+ openWorldHint: false,
214367
214375
  category: CATEGORY,
214368
214376
  },
214369
214377
  }, async (args) => {
@@ -214522,7 +214530,7 @@ function registerPGDatabaseTools(server, providedDeps) {
214522
214530
  readOnlyHint: false,
214523
214531
  destructiveHint: true,
214524
214532
  idempotentHint: false,
214525
- openWorldHint: true,
214533
+ openWorldHint: false,
214526
214534
  category: CATEGORY,
214527
214535
  },
214528
214536
  }, async (args) => {
@@ -215532,7 +215540,8 @@ function registerSQLDatabaseTools(server) {
215532
215540
  },
215533
215541
  annotations: {
215534
215542
  readOnlyHint: true,
215535
- openWorldHint: true,
215543
+ destructiveHint: false,
215544
+ openWorldHint: false,
215536
215545
  category: CATEGORY,
215537
215546
  },
215538
215547
  }, async (args) => {
@@ -215601,7 +215610,7 @@ function registerSQLDatabaseTools(server) {
215601
215610
  readOnlyHint: false,
215602
215611
  destructiveHint: true,
215603
215612
  idempotentHint: false,
215604
- openWorldHint: true,
215613
+ openWorldHint: false,
215605
215614
  category: CATEGORY,
215606
215615
  },
215607
215616
  }, async (args) => {
@@ -215906,7 +215915,8 @@ function registerDeployTools(server) {
215906
215915
  annotations: {
215907
215916
  // 本地构建会执行 buildCommand 并写产物文件,不是 read-only;但不变更云端资源,非 destructive。
215908
215917
  readOnlyHint: false,
215909
- openWorldHint: true,
215918
+ destructiveHint: false,
215919
+ openWorldHint: false,
215910
215920
  category: "deploy",
215911
215921
  },
215912
215922
  }, async ({ cwd, mode }) => {
@@ -215978,7 +215988,8 @@ function registerDeployTools(server) {
215978
215988
  },
215979
215989
  annotations: {
215980
215990
  readOnlyHint: true,
215981
- openWorldHint: true,
215991
+ destructiveHint: false,
215992
+ openWorldHint: false,
215982
215993
  category: "deploy",
215983
215994
  },
215984
215995
  }, async ({ cwd, mode, envId: envIdInput, only, skip, yes, }) => {
@@ -216060,7 +216071,7 @@ function registerDeployTools(server) {
216060
216071
  annotations: {
216061
216072
  readOnlyHint: false,
216062
216073
  destructiveHint: true,
216063
- openWorldHint: true,
216074
+ openWorldHint: false,
216064
216075
  category: "deploy",
216065
216076
  },
216066
216077
  }, async ({ confirm, confirmDestructive, cwd, mode, envId: envIdInput, only, skip, yes, concurrency, continueOnError, }) => {
@@ -217825,7 +217836,7 @@ async function enrichEnvInfoWithMissingFields(manager, result, envId) {
217825
217836
  }
217826
217837
  }
217827
217838
  /**
217828
- * Project gateway Route.Enable onto envQuery(info) without mutating StaticDomain.
217839
+ * Project gateway Route.Enable onto queryEnv(info) without mutating StaticDomain.
217829
217840
  *
217830
217841
  * StaticStorages[].StaticDomain stays the cloud-API nominal hostname.
217831
217842
  * Sibling field staticDomainRouteEnabled (and EnvInfo-level mirrors for the
@@ -218384,7 +218395,7 @@ function registerEnvTools(server) {
218384
218395
  readOnlyHint: false,
218385
218396
  destructiveHint: false,
218386
218397
  idempotentHint: false,
218387
- openWorldHint: true,
218398
+ openWorldHint: false,
218388
218399
  category: "env",
218389
218400
  },
218390
218401
  }, async (rawArgs) => {
@@ -219352,7 +219363,8 @@ function registerEnvTools(server) {
219352
219363
  },
219353
219364
  annotations: {
219354
219365
  readOnlyHint: true,
219355
- openWorldHint: true,
219366
+ destructiveHint: false,
219367
+ openWorldHint: false,
219356
219368
  category: "env",
219357
219369
  },
219358
219370
  };
@@ -219384,9 +219396,9 @@ function registerEnvTools(server) {
219384
219396
  },
219385
219397
  annotations: {
219386
219398
  readOnlyHint: false,
219387
- destructiveHint: false, // 注意:delete操作虽然是破坏性的,但这里采用较宽松的标注
219399
+ destructiveHint: true,
219388
219400
  idempotentHint: false,
219389
- openWorldHint: true,
219401
+ openWorldHint: false,
219390
219402
  category: "env",
219391
219403
  },
219392
219404
  }, async ({ action, domains, }) => {
@@ -219470,7 +219482,7 @@ function registerEnvTools(server) {
219470
219482
  readOnlyHint: false,
219471
219483
  destructiveHint: true,
219472
219484
  idempotentHint: false,
219473
- openWorldHint: true,
219485
+ openWorldHint: false,
219474
219486
  category: "env",
219475
219487
  },
219476
219488
  }, async (rawArgs) => {
@@ -223106,7 +223118,8 @@ function registerFunctionTools(server) {
223106
223118
  },
223107
223119
  annotations: {
223108
223120
  readOnlyHint: true,
223109
- openWorldHint: true,
223121
+ destructiveHint: false,
223122
+ openWorldHint: false,
223110
223123
  category: "functions",
223111
223124
  },
223112
223125
  }, async (input) => withEnvelope(() => handleQueryFunctions(input)));
@@ -223191,7 +223204,7 @@ function registerFunctionTools(server) {
223191
223204
  readOnlyHint: false,
223192
223205
  destructiveHint: true,
223193
223206
  idempotentHint: false,
223194
- openWorldHint: true,
223207
+ openWorldHint: false,
223195
223208
  category: "functions",
223196
223209
  },
223197
223210
  }, async (input) => withEnvelope(() => handleManageFunctions(input)));
@@ -224397,7 +224410,8 @@ function registerGatewayTools(server) {
224397
224410
  },
224398
224411
  annotations: {
224399
224412
  readOnlyHint: true,
224400
- openWorldHint: true,
224413
+ destructiveHint: false,
224414
+ openWorldHint: false,
224401
224415
  category: "gateway",
224402
224416
  },
224403
224417
  }, async (input) => withEnvelope(() => handleQueryGateway(input)));
@@ -224515,7 +224529,7 @@ function registerGatewayTools(server) {
224515
224529
  readOnlyHint: false,
224516
224530
  destructiveHint: true,
224517
224531
  idempotentHint: false,
224518
- openWorldHint: true,
224532
+ openWorldHint: false,
224519
224533
  category: "gateway",
224520
224534
  },
224521
224535
  }, async (input) => withEnvelope(() => handleManageGateway(input)));
@@ -224959,6 +224973,15 @@ function buildWebsiteConfigNextStep() {
224959
224973
  },
224960
224974
  };
224961
224975
  }
224976
+ /**
224977
+ * 静态托管的对象 key 一律不带前导斜杠(`dir/f.txt` 而非 `/dir/f.txt`),但 agent
224978
+ * 从 URL 形态(`/index.html`)推路径时很自然带上斜杠。底层 SDK 的 `getCloudKey`
224979
+ * 只补尾部 `/`、不剥离前导 `/`,随后 `getBucket({ Prefix })` 做的是严格字节前缀
224980
+ * 匹配 ⇒ `/dir/` 匹配不到 `dir/f.txt`。因此所有对外传入的路径/前缀都先在此归一化。
224981
+ */
224982
+ function stripLeadingSlashes(value) {
224983
+ return value.replace(/^\/+/, '');
224984
+ }
224962
224985
  function buildFindFilesNextStep(prefix) {
224963
224986
  return {
224964
224987
  tool: 'queryHosting',
@@ -225187,7 +225210,8 @@ function registerHostingTools(server) {
225187
225210
  inputSchema: queryHostingInputSchema,
225188
225211
  annotations: {
225189
225212
  readOnlyHint: true,
225190
- openWorldHint: true,
225213
+ destructiveHint: false,
225214
+ openWorldHint: false,
225191
225215
  category: 'hosting',
225192
225216
  },
225193
225217
  }, async (args) => {
@@ -225230,8 +225254,11 @@ function registerHostingTools(server) {
225230
225254
  if (!input.prefix) {
225231
225255
  throw new Error((0, index_js_1.t)('hosting.findFilesPrefixRequired'));
225232
225256
  }
225257
+ // 读侧与 delete 侧同源:prefix 原样透传时,agent 按 URL 形态传的
225258
+ // `/assets/` 在 COS 侧严格前缀匹配命中 0 条,会被误读成「目录是空的」。
225259
+ const normalizedPrefix = stripLeadingSlashes(input.prefix);
225233
225260
  const result = await cloudbase.hosting.findFiles({
225234
- prefix: input.prefix,
225261
+ prefix: normalizedPrefix,
225235
225262
  marker: input.marker,
225236
225263
  maxKeys: input.maxKeys,
225237
225264
  });
@@ -225243,7 +225270,7 @@ function registerHostingTools(server) {
225243
225270
  success: true,
225244
225271
  data: {
225245
225272
  action: 'findFiles',
225246
- prefix: input.prefix,
225273
+ prefix: normalizedPrefix,
225247
225274
  marker: input.marker,
225248
225275
  maxKeys: input.maxKeys,
225249
225276
  files: normalizedFiles,
@@ -225252,7 +225279,7 @@ function registerHostingTools(server) {
225252
225279
  result,
225253
225280
  },
225254
225281
  message: (0, index_js_1.t)('hosting.findFilesSuccess', {
225255
- prefix: input.prefix,
225282
+ prefix: normalizedPrefix,
225256
225283
  count: normalizedFiles.length,
225257
225284
  more: nextMarker ? (0, index_js_1.t)('hosting.findFilesMore') : '',
225258
225285
  }),
@@ -225341,7 +225368,7 @@ function registerHostingTools(server) {
225341
225368
  readOnlyHint: false,
225342
225369
  destructiveHint: true,
225343
225370
  idempotentHint: false,
225344
- openWorldHint: true,
225371
+ openWorldHint: false,
225345
225372
  category: 'hosting',
225346
225373
  },
225347
225374
  }, async (args) => {
@@ -225503,10 +225530,18 @@ function registerHostingTools(server) {
225503
225530
  if (!input.confirm) {
225504
225531
  throw new Error((0, index_js_1.t)('hosting.deleteConfirmRequired'));
225505
225532
  }
225533
+ // 静态托管对象 key 不带前导斜杠。若不规范化,isDir=true 会走
225534
+ // storage.deleteDirectoryCustom,其前缀由 getCloudKey(cloudPath)
225535
+ // 生成且不做前导斜杠剥离,做严格字节前缀匹配时 `/dir/` 匹配不到
225536
+ // `dir/f.txt`,导致目录删除静默 no-op(Deleted:0,文件全在)。
225537
+ // 同时下面的回查 findFiles(prefix) 也是严格前缀匹配,带斜杠时
225538
+ // 同样命中 0 条,会把「没删到」误判成「删干净了 verified:true」。
225539
+ // 这里统一剥离前导斜杠,两种形态(/dir 与 dir)都按正确 key 处理。
225540
+ const normalizedCloudPath = stripLeadingSlashes(input.cloudPath);
225506
225541
  let result;
225507
225542
  try {
225508
225543
  result = await cloudbase.hosting.deleteFiles({
225509
- cloudPath: input.cloudPath,
225544
+ cloudPath: normalizedCloudPath,
225510
225545
  isDir: input.isDir ?? false,
225511
225546
  });
225512
225547
  }
@@ -225528,7 +225563,7 @@ function registerHostingTools(server) {
225528
225563
  }
225529
225564
  try {
225530
225565
  const checkResult = await cloudbase.hosting.findFiles({
225531
- prefix: input.cloudPath,
225566
+ prefix: normalizedCloudPath,
225532
225567
  maxKeys: 100,
225533
225568
  });
225534
225569
  // ⚠️ 回查有两个坑,都会让 verified 失真:
@@ -225539,8 +225574,7 @@ function registerHostingTools(server) {
225539
225574
  // /a/b.txt.bak 还在也会命中 → 把「已删成功」误判成未验证。
225540
225575
  // 单文件场景必须精确比对 Key(前缀场景见 normalizeFileFields 的 key 字段)。
225541
225576
  const remaining = normalizeFileFields(checkResult);
225542
- const stripLeadingSlash = (value) => value.replace(/^\/+/, '');
225543
- const targetPath = stripLeadingSlash(input.cloudPath ?? '');
225577
+ const targetPath = normalizedCloudPath;
225544
225578
  const stillExists = input.isDir
225545
225579
  ? remaining.length > 0
225546
225580
  : remaining.some((file) => {
@@ -225548,7 +225582,7 @@ function registerHostingTools(server) {
225548
225582
  // 拿不到 Key 时保守按「仍存在」处理,避免误报已验证
225549
225583
  if (!key)
225550
225584
  return true;
225551
- return stripLeadingSlash(key) === targetPath;
225585
+ return stripLeadingSlashes(key) === targetPath;
225552
225586
  });
225553
225587
  if (stillExists) {
225554
225588
  deleteVerified = false;
@@ -225574,7 +225608,11 @@ function registerHostingTools(server) {
225574
225608
  type: input.isDir ? (0, index_js_1.t)('hosting.typeDirectory') : (0, index_js_1.t)('hosting.typeFile'),
225575
225609
  cloudPath: input.cloudPath,
225576
225610
  })
225577
- : (0, index_js_1.t)('hosting.deleteUnverified', { cloudPath: input.cloudPath }),
225611
+ // 这里刻意插入规范化后的路径:该文案的 {cloudPath} 会被拼进
225612
+ // `queryHosting(action="findFiles", prefix="{cloudPath}")` 自查命令里,
225613
+ // 带前导斜杠的前缀在 COS 侧严格匹配不到任何对象,agent 照抄会得到
225614
+ // 「0 命中 ⇒ 看起来删干净了」的错误结论。
225615
+ : (0, index_js_1.t)('hosting.deleteUnverified', { cloudPath: normalizedCloudPath }),
225578
225616
  });
225579
225617
  }
225580
225618
  case 'setWebsiteDocument': {
@@ -225812,7 +225850,8 @@ function registerLogTools(server) {
225812
225850
  },
225813
225851
  annotations: {
225814
225852
  readOnlyHint: true,
225815
- openWorldHint: true,
225853
+ destructiveHint: false,
225854
+ openWorldHint: false,
225816
225855
  category: "logs",
225817
225856
  },
225818
225857
  }, async ({ action, queryString, service, startTime, endTime, limit, context, sort, }) => {
@@ -226361,7 +226400,8 @@ function registerMsgPushTools(server) {
226361
226400
  },
226362
226401
  annotations: {
226363
226402
  readOnlyHint: true,
226364
- openWorldHint: true,
226403
+ destructiveHint: false,
226404
+ openWorldHint: false,
226365
226405
  category: CATEGORY,
226366
226406
  },
226367
226407
  }, async ({ appid, env, action }) => {
@@ -226506,7 +226546,7 @@ function registerMsgPushTools(server) {
226506
226546
  readOnlyHint: false,
226507
226547
  destructiveHint: true,
226508
226548
  idempotentHint: true,
226509
- openWorldHint: true,
226549
+ openWorldHint: false,
226510
226550
  category: CATEGORY,
226511
226551
  },
226512
226552
  }, async ({ appid, env_id, function_name, action, msg_type, event_types, enable, qbase_container_path, qbase_env, text_mode, confirm, }) => {
@@ -227375,7 +227415,8 @@ function registerPermissionTools(server) {
227375
227415
  },
227376
227416
  annotations: {
227377
227417
  readOnlyHint: true,
227378
- openWorldHint: true,
227418
+ destructiveHint: false,
227419
+ openWorldHint: false,
227379
227420
  category: "permissions",
227380
227421
  },
227381
227422
  }, async ({ action, resourceType, resourceId, resourceIds, roleId, roleIdentity, roleName, uid, username, pageNo, pageSize, extension, policyResourceType, }) => withEnvelope(async () => {
@@ -227604,7 +227645,7 @@ function registerPermissionTools(server) {
227604
227645
  readOnlyHint: false,
227605
227646
  destructiveHint: true,
227606
227647
  idempotentHint: false,
227607
- openWorldHint: true,
227648
+ openWorldHint: false,
227608
227649
  category: "permissions",
227609
227650
  },
227610
227651
  }, async ({ action, resourceType, resourceId, permission, securityRule, roleId, roleIds, roleName, roleIdentity, description, memberUids, policies, policyIds, uid, uids, username, password, userStatus, regoContent, confirm, }) => withEnvelope(async () => {
@@ -228351,16 +228392,7 @@ async function registerRagTools(server) {
228351
228392
  title: "rag.title",
228352
228393
  description: (0, index_js_1.t)("rag.description", {
228353
228394
  skillCount: skills.length,
228354
- skillList: skills
228355
- .map((skill) => (0, index_js_1.t)("rag.skillListItem", {
228356
- name: path.basename(path.dirname(skill.absolutePath)),
228357
- description: skill.description,
228358
- }))
228359
- .join("\n"),
228360
228395
  openapiCount: openapis.length,
228361
- openapiList: openapis
228362
- .map((api) => (0, index_js_1.t)("rag.openapiListItem", { name: api.name, description: api.description }))
228363
- .join("\n"),
228364
228396
  }),
228365
228397
  inputSchema: {
228366
228398
  mode: SearchKnowledgeModeEnum,
@@ -228386,6 +228418,7 @@ async function registerRagTools(server) {
228386
228418
  },
228387
228419
  annotations: {
228388
228420
  readOnlyHint: true,
228421
+ destructiveHint: false,
228389
228422
  openWorldHint: true,
228390
228423
  category: "rag",
228391
228424
  },
@@ -228437,6 +228470,16 @@ async function registerRagTools(server) {
228437
228470
  }
228438
228471
  }
228439
228472
  if (mode === "skill") {
228473
+ // 不传 skillName:返回带适用场景的完整目录,让调用方按需发现后再取正文
228474
+ if (!skillName?.trim()) {
228475
+ return (0, json_content_js_1.jsonContent)([
228476
+ (0, index_js_1.t)("rag.skillCatalogHeader", { count: skillNames.length }),
228477
+ ...skills.map((item) => (0, index_js_1.t)("rag.skillListItem", {
228478
+ name: path.basename(path.dirname(item.absolutePath)),
228479
+ description: item.description,
228480
+ })),
228481
+ ].join("\n"));
228482
+ }
228440
228483
  const skill = skills.find((item) => item.absolutePath.includes(skillName));
228441
228484
  if (!skill) {
228442
228485
  const remoteHint = skillName?.trim()
@@ -228487,6 +228530,15 @@ async function registerRagTools(server) {
228487
228530
  return { content: [{ type: "text", text: sections.join("\n\n") }] };
228488
228531
  }
228489
228532
  if (mode === "openapi") {
228533
+ if (!apiName?.trim()) {
228534
+ return (0, json_content_js_1.jsonContent)([
228535
+ (0, index_js_1.t)("rag.openapiCatalogHeader", { count: openapiNames.length }),
228536
+ ...openapis.map((api) => (0, index_js_1.t)("rag.openapiListItem", {
228537
+ name: api.name,
228538
+ description: api.description,
228539
+ })),
228540
+ ].join("\n"));
228541
+ }
228490
228542
  const api = openapis.find((api) => api.name === apiName);
228491
228543
  if (!api) {
228492
228544
  return {
@@ -228543,7 +228595,7 @@ function extractDescriptionFromFrontMatter(content) {
228543
228595
  fm.push(lines[i]);
228544
228596
  const match = fm
228545
228597
  .join("\n")
228546
- .match(/^(?:decsription|description)\s*:\s*(.*)$/m);
228598
+ .match(/^description\s*:\s*(.*)$/m);
228547
228599
  return match ? match[1].trim() : null;
228548
228600
  }
228549
228601
  async function collectSkillDescriptions(rootDir) {
@@ -229511,7 +229563,8 @@ function registerStorageTools(server) {
229511
229563
  inputSchema: queryStorageInputSchema,
229512
229564
  annotations: {
229513
229565
  readOnlyHint: true,
229514
- openWorldHint: true,
229566
+ destructiveHint: false,
229567
+ openWorldHint: false,
229515
229568
  category: "storage"
229516
229569
  }
229517
229570
  }, async (args) => {
@@ -229691,7 +229744,7 @@ function registerStorageTools(server) {
229691
229744
  readOnlyHint: false,
229692
229745
  destructiveHint: true,
229693
229746
  idempotentHint: false,
229694
- openWorldHint: true,
229747
+ openWorldHint: false,
229695
229748
  category: "storage"
229696
229749
  }
229697
229750
  }, async (args) => {
@@ -230161,7 +230214,8 @@ function registerPGStorageTools(server) {
230161
230214
  },
230162
230215
  annotations: {
230163
230216
  readOnlyHint: true,
230164
- openWorldHint: true,
230217
+ destructiveHint: false,
230218
+ openWorldHint: false,
230165
230219
  category: CATEGORY,
230166
230220
  },
230167
230221
  }, async (args) => {
@@ -231411,7 +231465,7 @@ exports.SITE_REGION_MAP = {
231411
231465
  },
231412
231466
  };
231413
231467
  exports.SITE_IDS = Object.keys(exports.SITE_REGION_MAP);
231414
- /** Regions accepted by envQuery(list) / cross-region DescribeEnvs probes. */
231468
+ /** Regions accepted by queryEnv(list) / cross-region DescribeEnvs probes. */
231415
231469
  exports.TCB_QUERY_REGIONS = [
231416
231470
  "ap-shanghai",
231417
231471
  "ap-guangzhou",
@@ -231782,7 +231836,7 @@ class TelemetryReporter {
231782
231836
  const arch = os_1.default.arch(); // 系统架构
231783
231837
  // Build-time injected version; guard for vitest / non-webpack runtimes.
231784
231838
  const mcpVersion = process.env.npm_package_version ||
231785
- ( true ? "2.34.3" : 0);
231839
+ ( true ? "2.34.4" : 0);
231786
231840
  return {
231787
231841
  userAgent: `${osType} ${osRelease} ${arch} ${nodeVersion} CloudBase-MCP/${mcpVersion}`,
231788
231842
  deviceId: this.deviceId,
@@ -232401,7 +232455,7 @@ ${envIdSection}
232401
232455
  ## 环境信息
232402
232456
  - 操作系统: ${os_1.default.type()} ${os_1.default.release()}
232403
232457
  - Node.js版本: ${process.version}
232404
- - MCP 版本:${( true ? "2.34.3" : 0) || 0 || 0}
232458
+ - MCP 版本:${( true ? "2.34.4" : 0) || 0 || 0}
232405
232459
  - 系统架构: ${os_1.default.arch()}
232406
232460
  - 时间: ${new Date().toISOString()}
232407
232461
  - 请求ID: ${requestId}
@@ -232490,7 +232544,7 @@ function createWrappedHandler(name, handler, server) {
232490
232544
  requestId,
232491
232545
  ide: server.ide || process.env.INTEGRATION_IDE || ''
232492
232546
  });
232493
- const mcpVersion = true ? "2.34.3" : 0;
232547
+ const mcpVersion = true ? "2.34.4" : 0;
232494
232548
  const requestIdSuffix = requestId ? `\n🆔 RequestId: ${requestId}` : '';
232495
232549
  const enhancedErrorMessage = `${errorMessage}${requestIdSuffix}\n\n📦 CloudBase MCP v${mcpVersion}\n🔗 遇到问题?请复制以下链接到浏览器打开\n即可自动携带错误详情快速创建 GitHub Issue:\n${issueLink}`;
232496
232550
  // 创建新的错误对象,保持原有的错误类型但更新消息