feat(cli): port drive list --depth and doc style, register all new commands in Schema
- Port drive list --depth N BFS recursive listing (pan + workspace routes, rate-limit requeue, SIGINT partial emit, --pattern/--quiet) - Port doc style cover set/clear, background set/clear, get with local image validation and attachment-upload subflow - Register all 26 newly ported commands in schema_command_registry with reviewed metadata/selection hints instead of exclusions (813->839 tools) - Review fixes: drive list --node usage text no longer implies required in agent schema; remove broken formula-verify --exit-on-error; error on --range without --sheet-id; portable stdin read; drop local --yes shadowing root -y on drive revert/transfer-owner; use confirmDangerousAction for non-delete confirms; explicit recursiveChange=false now transmitted; sheet version revert and comment delete moved into sheet confirmationGuards registry
This commit is contained in:
1 parent
e63a4bdf47
commit
68e1a78810
35 files changed
+25620
-396
No files matched your search
@@ -81,7 +81,7 @@ func TestEmbeddedShortcutProgressiveQueriesReturnCompleteContracts(t *testing.T)
|
||||
|
||||
product := executeShortcutSchemaQuery(t, "chat")
|
||||
productPayload, _ := product["product"].(map[string]any)
|
||||
if got, want := int(product["count"].(float64)), 120; got != want {
|
||||
if got, want := int(product["count"].(float64)), 124; got != want {
|
||||
t.Fatalf("schema chat count = %d, want %d", got, want)
|
||||
}
|
||||
summaries := schemaContractObjectSlice(productPayload["tools"])
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,17 +1,17 @@
|
||||
{
|
||||
"version": 1,
|
||||
"source_hash": "sha256:8852f8cb08fe6af6ee4f38b167f10c57ac83d49c1e57c6dce4358f38f6faa230",
|
||||
"surface_hash": "sha256:4cf8460240b19f896c3a330c69982cbb5f57aa8576cdf30373172082eea893ed",
|
||||
"source_hash": "sha256:39743700b9b19774144c8713202336165da669e0bd9ff07c35255b1fc94b30fd",
|
||||
"surface_hash": "sha256:674e6c00efb4d7f4c177ec0a1c4c097c8fb48b0045d1787c0ed001c32c51f20a",
|
||||
"coverage": {
|
||||
"surface_products": 26,
|
||||
"products_with_metadata": 26,
|
||||
"surface_tools": 813,
|
||||
"tools_with_metadata": 813,
|
||||
"tools_with_agent_summary": 813,
|
||||
"tools_with_use_when": 813,
|
||||
"tools_with_avoid_when": 813,
|
||||
"tools_with_examples": 813,
|
||||
"tools_with_interface_mode": 813,
|
||||
"surface_tools": 839,
|
||||
"tools_with_metadata": 839,
|
||||
"tools_with_agent_summary": 839,
|
||||
"tools_with_use_when": 839,
|
||||
"tools_with_avoid_when": 839,
|
||||
"tools_with_examples": 839,
|
||||
"tools_with_interface_mode": 839,
|
||||
"unmatched_skill_tools": 122,
|
||||
"unreviewed_skill_tools": 11
|
||||
},
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"version": 1,
|
||||
"source_hash": "sha256:8852f8cb08fe6af6ee4f38b167f10c57ac83d49c1e57c6dce4358f38f6faa230",
|
||||
"surface_hash": "sha256:4cf8460240b19f896c3a330c69982cbb5f57aa8576cdf30373172082eea893ed",
|
||||
"source_hash": "sha256:39743700b9b19774144c8713202336165da669e0bd9ff07c35255b1fc94b30fd",
|
||||
"surface_hash": "sha256:674e6c00efb4d7f4c177ec0a1c4c097c8fb48b0045d1787c0ed001c32c51f20a",
|
||||
"source_files": 160,
|
||||
"hint_files": 54,
|
||||
"hint_products": 43,
|
||||
"hint_tools": 1778,
|
||||
"hint_tools": 1830,
|
||||
"interface_metadata": {
|
||||
"source": "mcp-tools-list+cli-registry",
|
||||
"revision": "4574f7022c32cf4c033e9b7b4156e2fec815fed8",
|
||||
@@ -29,13 +29,13 @@
|
||||
"coverage": {
|
||||
"surface_products": 26,
|
||||
"products_with_metadata": 26,
|
||||
"surface_tools": 813,
|
||||
"tools_with_metadata": 813,
|
||||
"tools_with_agent_summary": 813,
|
||||
"tools_with_use_when": 813,
|
||||
"tools_with_avoid_when": 813,
|
||||
"tools_with_examples": 813,
|
||||
"tools_with_interface_mode": 813,
|
||||
"surface_tools": 839,
|
||||
"tools_with_metadata": 839,
|
||||
"tools_with_agent_summary": 839,
|
||||
"tools_with_use_when": 839,
|
||||
"tools_with_avoid_when": 839,
|
||||
"tools_with_examples": 839,
|
||||
"tools_with_interface_mode": 839,
|
||||
"unmatched_skill_tools": 122,
|
||||
"unreviewed_skill_tools": 11
|
||||
},
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
{
|
||||
"version": 1,
|
||||
"surface_hash": "sha256:4cf8460240b19f896c3a330c69982cbb5f57aa8576cdf30373172082eea893ed",
|
||||
"source_hash": "sha256:36bea2f435fe573c1226b98050096a2d39ba2cfd1731de5dd0c1aa2c11f36faf",
|
||||
"surface_hash": "sha256:674e6c00efb4d7f4c177ec0a1c4c097c8fb48b0045d1787c0ed001c32c51f20a",
|
||||
"source_hash": "sha256:a24d92ad8e5317fd466ec67aac0ddc760c86de6bb9d4d561e1c80d020657e613",
|
||||
"catalog": {
|
||||
"agent_metadata": {
|
||||
"products_with_metadata": 26,
|
||||
"source": "embedded-skill-metadata",
|
||||
"source_hash": "sha256:8852f8cb08fe6af6ee4f38b167f10c57ac83d49c1e57c6dce4358f38f6faa230",
|
||||
"surface_hash": "sha256:4cf8460240b19f896c3a330c69982cbb5f57aa8576cdf30373172082eea893ed",
|
||||
"source_hash": "sha256:39743700b9b19774144c8713202336165da669e0bd9ff07c35255b1fc94b30fd",
|
||||
"surface_hash": "sha256:674e6c00efb4d7f4c177ec0a1c4c097c8fb48b0045d1787c0ed001c32c51f20a",
|
||||
"surface_products": 26,
|
||||
"surface_tools": 813,
|
||||
"tools_with_agent_summary": 813,
|
||||
"tools_with_metadata": 813,
|
||||
"surface_tools": 839,
|
||||
"tools_with_agent_summary": 839,
|
||||
"tools_with_metadata": 839,
|
||||
"unmatched_skill_tools": 122,
|
||||
"version": 1
|
||||
},
|
||||
@@ -7722,7 +7722,7 @@
|
||||
"id": "chat",
|
||||
"name": "群聊 / 消息 / 机器人",
|
||||
"runtime": true,
|
||||
"tool_count": 120,
|
||||
"tool_count": 124,
|
||||
"tools": [
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
@@ -7907,6 +7907,60 @@
|
||||
"已有文字表情定义并要附加到消息时"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "批量查询当前用户自己的群会话设置(置顶/免打扰/群昵称/群备注)",
|
||||
"agent_summary_source": "dws-agent-selection/chat",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"管理员级群功能开关用 chat group update-settings"
|
||||
],
|
||||
"canonical_path": "chat.batch_query_group_chat_settings",
|
||||
"cli_name": "query",
|
||||
"cli_path": "chat group user-settings query",
|
||||
"confirmation": "not_required",
|
||||
"description": "批量查询当前用户的群会话设置",
|
||||
"effect": "read",
|
||||
"group": "group.user-settings",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "batch_query_group_chat_settings",
|
||||
"primary_cli_path": "chat group user-settings query",
|
||||
"reviewed": true,
|
||||
"risk": "low",
|
||||
"title": "批量查询当前用户的群会话设置",
|
||||
"use_when": [
|
||||
"用户说 看下这些群我的置顶和免打扰设置"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "批量更新当前用户自己的群会话设置(置顶/免打扰/群昵称/群备注)",
|
||||
"agent_summary_source": "dws-agent-selection/chat",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"单个群昵称优先 chat group update-nick"
|
||||
],
|
||||
"canonical_path": "chat.batch_update_group_chat_settings",
|
||||
"cli_name": "set",
|
||||
"cli_path": "chat group user-settings set",
|
||||
"confirmation": "not_required",
|
||||
"description": "批量更新当前用户的群会话设置",
|
||||
"effect": "write",
|
||||
"group": "group.user-settings",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "batch_update_group_chat_settings",
|
||||
"primary_cli_path": "chat group user-settings set",
|
||||
"reviewed": true,
|
||||
"risk": "low",
|
||||
"title": "批量更新当前用户的群会话设置",
|
||||
"use_when": [
|
||||
"用户说 把这些群都设为免打扰/置顶"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "把多条消息合并转发到目标会话",
|
||||
@@ -8332,6 +8386,33 @@
|
||||
"需要生成群邀请链接或设置有效期时"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "查询群用户禁言配置(禁言黑名单/全员禁言白名单)",
|
||||
"agent_summary_source": "dws-agent-selection/chat",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"设置全员禁言用 chat group-mute;禁言个人用 chat group-mute-member"
|
||||
],
|
||||
"canonical_path": "chat.get_group_mute_config",
|
||||
"cli_name": "get-mute-config",
|
||||
"cli_path": "chat group get-mute-config",
|
||||
"confirmation": "not_required",
|
||||
"description": "查询指定群的用户禁言配置,包括单独禁言黑名单、全员禁言白名单及相关操作时间。\n返回的是原始配置记录,不等同于当前被禁言成员列表;全员禁言开关也不在本命令的返回范围内。",
|
||||
"effect": "read",
|
||||
"group": "group",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "get_group_mute_config",
|
||||
"primary_cli_path": "chat group get-mute-config",
|
||||
"reviewed": true,
|
||||
"risk": "low",
|
||||
"title": "查询群用户禁言配置",
|
||||
"use_when": [
|
||||
"用户说 看下群里谁被禁言/禁言配置"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "查询指定会话所属的自定义会话分组",
|
||||
@@ -11166,6 +11247,33 @@
|
||||
"已有 bizId 并需要追加内容或结束流式输出时"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "更新消息上已有的文字表情回应",
|
||||
"agent_summary_source": "dws-agent-selection/chat",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"新增用 add-text-emotion;移除用 remove-text-emotion"
|
||||
],
|
||||
"canonical_path": "chat.update_text_emotion",
|
||||
"cli_name": "update-text-emotion",
|
||||
"cli_path": "chat message update-text-emotion",
|
||||
"confirmation": "not_required",
|
||||
"description": "更新消息的文字表情回应",
|
||||
"effect": "write",
|
||||
"group": "message",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "update_text_emotion",
|
||||
"primary_cli_path": "chat message update-text-emotion",
|
||||
"reviewed": true,
|
||||
"risk": "low",
|
||||
"title": "更新消息的文字表情回应",
|
||||
"use_when": [
|
||||
"用户说 改一下消息上的文字表情"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "不可逆地把已有普通群升级为外部群",
|
||||
@@ -14238,7 +14346,7 @@
|
||||
"id": "doc",
|
||||
"name": "钉钉文档管理",
|
||||
"runtime": true,
|
||||
"tool_count": 55,
|
||||
"tool_count": 60,
|
||||
"tools": [
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
@@ -14687,6 +14795,33 @@
|
||||
"准备读内容前必须先看 contentType/extension 以路由到 read/sheet/aitable/download 时"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "读取文档当前封面与背景配置(只读)",
|
||||
"agent_summary_source": "dws-agent-selection/doc",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"修改用 cover set / background set"
|
||||
],
|
||||
"canonical_path": "doc.get_document_style",
|
||||
"cli_name": "get",
|
||||
"cli_path": "doc style get",
|
||||
"confirmation": "not_required",
|
||||
"description": "读取钉钉文档当前的封面与背景配置(只读,单接口收口 get_document_style)。",
|
||||
"effect": "read",
|
||||
"group": "style",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "get_document_style",
|
||||
"primary_cli_path": "doc style get",
|
||||
"reviewed": true,
|
||||
"risk": "low",
|
||||
"title": "读取文档封面/背景 (只读)",
|
||||
"use_when": [
|
||||
"用户说 看下文档现在的封面/背景"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "根据 taskId 查询文档导入任务的执行结果",
|
||||
@@ -15536,6 +15671,114 @@
|
||||
"当你在做重大改动前后、想手动打一个可回滚的版本存档点时使用;输入 node,会实际为该文档保存一个当前内容的历史版本快照。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "清除钉钉文档背景",
|
||||
"agent_summary_source": "dws-agent-selection/doc",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"设置背景用 background set"
|
||||
],
|
||||
"canonical_path": "doc.style_background_clear",
|
||||
"cli_name": "clear",
|
||||
"cli_path": "doc style background clear",
|
||||
"confirmation": "not_required",
|
||||
"description": "清除文档背景",
|
||||
"effect": "write",
|
||||
"group": "style.background",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "style_background_clear",
|
||||
"primary_cli_path": "doc style background clear",
|
||||
"reviewed": true,
|
||||
"risk": "low",
|
||||
"title": "清除文档背景",
|
||||
"use_when": [
|
||||
"用户说 去掉文档背景色"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "设置钉钉文档背景纯色(#RRGGBB)",
|
||||
"agent_summary_source": "dws-agent-selection/doc",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"背景不支持图片;封面用 cover set"
|
||||
],
|
||||
"canonical_path": "doc.style_background_set",
|
||||
"cli_name": "set",
|
||||
"cli_path": "doc style background set",
|
||||
"confirmation": "not_required",
|
||||
"description": "为钉钉文档设置背景纯色(--color)。背景仅支持纯色,不支持背景图片上传(对齐前端能力)。",
|
||||
"effect": "write",
|
||||
"group": "style.background",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "style_background_set",
|
||||
"primary_cli_path": "doc style background set",
|
||||
"reviewed": true,
|
||||
"risk": "low",
|
||||
"title": "设置文档背景纯色",
|
||||
"use_when": [
|
||||
"用户说 给文档设置背景色"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "移除钉钉文档封面",
|
||||
"agent_summary_source": "dws-agent-selection/doc",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"设置封面用 cover set"
|
||||
],
|
||||
"canonical_path": "doc.style_cover_clear",
|
||||
"cli_name": "clear",
|
||||
"cli_path": "doc style cover clear",
|
||||
"confirmation": "not_required",
|
||||
"description": "移除文档封面",
|
||||
"effect": "write",
|
||||
"group": "style.cover",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "style_cover_clear",
|
||||
"primary_cli_path": "doc style cover clear",
|
||||
"reviewed": true,
|
||||
"risk": "low",
|
||||
"title": "移除文档封面",
|
||||
"use_when": [
|
||||
"用户说 去掉文档封面"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "设置钉钉文档顶部封面图(外链或本地图片上传)",
|
||||
"agent_summary_source": "dws-agent-selection/doc",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"读取当前封面用 doc style get;移除封面用 cover clear"
|
||||
],
|
||||
"canonical_path": "doc.style_cover_set",
|
||||
"cli_name": "set",
|
||||
"cli_path": "doc style cover set",
|
||||
"confirmation": "not_required",
|
||||
"description": "为钉钉文档设置顶部封面图,可指定竖直显示位置。图片来源二选一:--image 外链或 --file 本地文件。",
|
||||
"effect": "write",
|
||||
"group": "style.cover",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "style_cover_set",
|
||||
"primary_cli_path": "doc style cover set",
|
||||
"reviewed": true,
|
||||
"risk": "low",
|
||||
"title": "设置文档封面",
|
||||
"use_when": [
|
||||
"用户说 给文档设置封面/换个封面图"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "使用指定模板创建新文档",
|
||||
@@ -15929,7 +16172,7 @@
|
||||
"id": "drive",
|
||||
"name": "钉盘文件管理",
|
||||
"runtime": true,
|
||||
"tool_count": 32,
|
||||
"tool_count": 40,
|
||||
"tools": [
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
@@ -15965,6 +16208,33 @@
|
||||
"用户说把某篇文档分享给某人看/可编辑时(含「我的文档」下的节点)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "向审批人发起文档权限申请(会真实通知审批人)",
|
||||
"agent_summary_source": "dws-agent-selection/drive",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"先用 apply-info 查可申请角色与审批人;未经用户确认不得自行提交"
|
||||
],
|
||||
"canonical_path": "drive.apply_permission",
|
||||
"cli_name": "apply",
|
||||
"cli_path": "drive permission apply",
|
||||
"confirmation": "not_required",
|
||||
"description": "向指定节点的审批人发起权限申请。建议先用 apply-info 获取可申请角色与审批人。\n\n注意: 本命令会真实通知审批人,Agent 必须先获得用户明确同意后再执行。",
|
||||
"effect": "write",
|
||||
"group": "permission",
|
||||
"idempotency": "non_idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "apply_permission",
|
||||
"primary_cli_path": "drive permission apply",
|
||||
"reviewed": true,
|
||||
"risk": "medium",
|
||||
"title": "发起权限申请",
|
||||
"use_when": [
|
||||
"用户确认要为无权限文档发起权限申请"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "提交文件上传",
|
||||
@@ -16160,6 +16430,32 @@
|
||||
"已确认 contentType 非 ALIDOC,需要落盘本地查看时"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "获取节点封面图片地址(文档首图/图片缩略图/类型图标)",
|
||||
"agent_summary_source": "dws-agent-selection/drive",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"设置文档封面用 doc style cover set"
|
||||
],
|
||||
"canonical_path": "drive.get_cover",
|
||||
"cli_name": "cover",
|
||||
"cli_path": "drive cover",
|
||||
"confirmation": "not_required",
|
||||
"description": "获取节点封面地址",
|
||||
"effect": "read",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "get_cover",
|
||||
"primary_cli_path": "drive cover",
|
||||
"reviewed": true,
|
||||
"risk": "low",
|
||||
"title": "获取节点封面地址",
|
||||
"use_when": [
|
||||
"用户说 封面/封面图/缩略图/预览图"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "获取文件元数据信息",
|
||||
@@ -16220,6 +16516,33 @@
|
||||
"用户要查看节点阅读/编辑/评论/点赞/预览/下载等统计维度时"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "获取当前用户的收藏列表,支持分页与按内容类型筛选",
|
||||
"agent_summary_source": "dws-agent-selection/drive",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"操作单个收藏用 mark_star/unmark_star"
|
||||
],
|
||||
"canonical_path": "drive.get_star_list",
|
||||
"cli_name": "list",
|
||||
"cli_path": "drive star list",
|
||||
"confirmation": "not_required",
|
||||
"description": "获取收藏列表",
|
||||
"effect": "read",
|
||||
"group": "star",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "get_star_list",
|
||||
"primary_cli_path": "drive star list",
|
||||
"reviewed": true,
|
||||
"risk": "low",
|
||||
"title": "获取收藏列表",
|
||||
"use_when": [
|
||||
"用户说 我的收藏/收藏列表/收藏了哪些文档"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "获取文件上传信息",
|
||||
@@ -16345,6 +16668,33 @@
|
||||
"兼容入口:枚举钉盘企业空间或「我的文件」空间以拿 spaceId/rootFolderId 时"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "收藏文档/文件到当前用户收藏列表",
|
||||
"agent_summary_source": "dws-agent-selection/drive",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"取消收藏用 unmark_star;查看收藏列表用 get_star_list"
|
||||
],
|
||||
"canonical_path": "drive.mark_star",
|
||||
"cli_name": "add",
|
||||
"cli_path": "drive star add",
|
||||
"confirmation": "not_required",
|
||||
"description": "收藏文档",
|
||||
"effect": "write",
|
||||
"group": "star",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "mark_star",
|
||||
"primary_cli_path": "drive star add",
|
||||
"reviewed": true,
|
||||
"risk": "low",
|
||||
"title": "收藏文档",
|
||||
"use_when": [
|
||||
"用户说 收藏这个文档/加个收藏/标星"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "将文件或文档移动到目标文件夹或知识库(原位置不再保留)",
|
||||
@@ -16528,6 +16878,33 @@
|
||||
"用户明确要求关闭文件的互联网公开发布,使外部链接失效时"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "查询节点可申请的权限角色列表与审批人列表",
|
||||
"agent_summary_source": "dws-agent-selection/drive",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"实际发起申请用 apply_permission"
|
||||
],
|
||||
"canonical_path": "drive.query_permission_apply_info",
|
||||
"cli_name": "apply-info",
|
||||
"cli_path": "drive permission apply-info",
|
||||
"confirmation": "not_required",
|
||||
"description": "查询节点可申请的角色与审批人",
|
||||
"effect": "read",
|
||||
"group": "permission",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "query_permission_apply_info",
|
||||
"primary_cli_path": "drive permission apply-info",
|
||||
"reviewed": true,
|
||||
"risk": "low",
|
||||
"title": "查询节点可申请的角色与审批人",
|
||||
"use_when": [
|
||||
"无权限访问文档时,先查可申请角色与审批人"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "获取当前用户最近访问或编辑过的文档列表",
|
||||
@@ -16644,6 +17021,32 @@
|
||||
"用户要重命名钉盘/文档空间中的文件、文档或文件夹时;实际执行会读取节点类型和当前扩展名,仅去掉完全匹配的一层后缀"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "回滚普通文件到指定历史版本(生成新最新版本,历史不丢失)",
|
||||
"agent_summary_source": "dws-agent-selection/drive",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"在线文档回滚用 doc version revert;在线表格用 sheet version revert"
|
||||
],
|
||||
"canonical_path": "drive.revert_file_version",
|
||||
"cli_name": "revert",
|
||||
"cli_path": "drive revert",
|
||||
"confirmation": "user_required",
|
||||
"description": "将指定文件回滚到某个历史版本。仅支持普通文件(Word、Excel、PDF、图片等)。\n在线文档请用 dws doc version revert,在线表格请用 dws sheet version revert。",
|
||||
"effect": "write",
|
||||
"idempotency": "non_idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "revert_file_version",
|
||||
"primary_cli_path": "drive revert",
|
||||
"reviewed": true,
|
||||
"risk": "medium",
|
||||
"title": "[危险] 回滚文件到指定历史版本",
|
||||
"use_when": [
|
||||
"用户说 回滚版本/恢复到某个版本/版本回退,且目标是普通文件"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "全局搜索文件,默认同时搜索钉盘和文档空间,合并返回结果",
|
||||
@@ -16860,6 +17263,60 @@
|
||||
"当你只记得文档标题或关键词、想在文档空间/知识库中检索在线文档(区别于 +search 检索钉盘文件)时使用;输入 query 关键词,返回匹配的文档及其节点信息。"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "转交文档或知识库所有者给指定用户(不可逆)",
|
||||
"agent_summary_source": "dws-agent-selection/drive",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"普通协作权限变更用 permission add/update/remove"
|
||||
],
|
||||
"canonical_path": "drive.transfer_owner",
|
||||
"cli_name": "transfer-owner",
|
||||
"cli_path": "drive permission transfer-owner",
|
||||
"confirmation": "user_required",
|
||||
"description": "转交文档或知识库的所有者给指定用户。此操作不可逆,执行前需要确认。\n\n--node 和 --workspace 二选一。转交后原所有者保留角色由 --reserve-role 指定。\n使用 --yes 跳过确认时,--reserve-role 和 --recursive 必须显式指定。",
|
||||
"effect": "write",
|
||||
"group": "permission",
|
||||
"idempotency": "non_idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "transfer_owner",
|
||||
"primary_cli_path": "drive permission transfer-owner",
|
||||
"reviewed": true,
|
||||
"risk": "high",
|
||||
"title": "[危险] 转交所有者",
|
||||
"use_when": [
|
||||
"用户明确要求转交文档/知识库所有权"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "将文档/文件从当前用户收藏列表移除",
|
||||
"agent_summary_source": "dws-agent-selection/drive",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"添加收藏用 mark_star"
|
||||
],
|
||||
"canonical_path": "drive.unmark_star",
|
||||
"cli_name": "remove",
|
||||
"cli_path": "drive star remove",
|
||||
"confirmation": "not_required",
|
||||
"description": "取消收藏文档",
|
||||
"effect": "write",
|
||||
"group": "star",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "unmark_star",
|
||||
"primary_cli_path": "drive star remove",
|
||||
"reviewed": true,
|
||||
"risk": "low",
|
||||
"title": "取消收藏文档",
|
||||
"use_when": [
|
||||
"用户说 取消收藏/去掉收藏/不收藏了"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "上传本地文件到钉盘或文档空间,或按节点 ID 确认覆盖已有文件",
|
||||
@@ -21728,7 +22185,7 @@
|
||||
"id": "sheet",
|
||||
"name": "钉钉表格管理",
|
||||
"runtime": true,
|
||||
"tool_count": 81,
|
||||
"tool_count": 90,
|
||||
"tools": [
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
@@ -22165,6 +22622,33 @@
|
||||
"已有 axls 文档,需要新增一个工作表页签时"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "在指定单元格上创建评论,可 @ 用户",
|
||||
"agent_summary_source": "dws-agent-selection/sheet",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"回复已有评论用 comment reply;不要把评论写进单元格值"
|
||||
],
|
||||
"canonical_path": "sheet.create_sheet_comment",
|
||||
"cli_name": "create",
|
||||
"cli_path": "sheet comment create",
|
||||
"confirmation": "not_required",
|
||||
"description": "创建单元格评论",
|
||||
"effect": "write",
|
||||
"group": "comment",
|
||||
"idempotency": "non_idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "create_sheet_comment",
|
||||
"primary_cli_path": "sheet comment create",
|
||||
"reviewed": true,
|
||||
"risk": "low",
|
||||
"title": "创建单元格评论",
|
||||
"use_when": [
|
||||
"用户说 给单元格加评论/批注/@某人讨论这个数据"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "创建钉钉在线电子表格文档(axls),返回 nodeId。",
|
||||
@@ -22435,6 +22919,33 @@
|
||||
"用户明确要求永久删除某个工作表页签,且已确认目标 sheetId 时"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "删除单元格评论(不可恢复)",
|
||||
"agent_summary_source": "dws-agent-selection/sheet",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"标记解决不等于删除"
|
||||
],
|
||||
"canonical_path": "sheet.delete_sheet_comment",
|
||||
"cli_name": "delete",
|
||||
"cli_path": "sheet comment delete",
|
||||
"confirmation": "user_required",
|
||||
"description": "删除单元格评论",
|
||||
"effect": "write",
|
||||
"group": "comment",
|
||||
"idempotency": "non_idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "delete_sheet_comment",
|
||||
"primary_cli_path": "sheet comment delete",
|
||||
"reviewed": true,
|
||||
"risk": "medium",
|
||||
"title": "删除单元格评论",
|
||||
"use_when": [
|
||||
"用户明确要求删除某条评论"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "按源区域对目标区域做自动填充(复制或序列)。",
|
||||
@@ -22687,6 +23198,32 @@
|
||||
"要查找包含某文本或公式的单元格位置时,必须用服务端 find"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "扫描表格公式单元格并按错误类型聚合返回错误数量与位置",
|
||||
"agent_summary_source": "dws-agent-selection/sheet",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"读取公式文本用 range read --value-render-option formula"
|
||||
],
|
||||
"canonical_path": "sheet.formula_verify",
|
||||
"cli_name": "formula-verify",
|
||||
"cli_path": "sheet formula-verify",
|
||||
"confirmation": "not_required",
|
||||
"description": "扫描钉钉电子表格中已落表的公式单元格,按计算结果错误类型聚合返回错误数量、位置和样本。\n\n不指定 --sheet-id / --range / --targets 时默认扫描整本表格的全部工作表。",
|
||||
"effect": "read",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "formula_verify",
|
||||
"primary_cli_path": "sheet formula-verify",
|
||||
"reviewed": true,
|
||||
"risk": "low",
|
||||
"title": "校验表格公式错误",
|
||||
"use_when": [
|
||||
"用户说 校验公式/检查公式错误/公式错误扫描"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "列出电子表格文档内全部工作表的 ID 与名称。",
|
||||
@@ -23125,6 +23662,33 @@
|
||||
"需要查看工作表上有哪些透视表或某个透视表详情时"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "查询表格单元格评论列表,支持分页与按解决状态过滤",
|
||||
"agent_summary_source": "dws-agent-selection/sheet",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"新建评论用 comment create"
|
||||
],
|
||||
"canonical_path": "sheet.list_sheet_comments",
|
||||
"cli_name": "list",
|
||||
"cli_path": "sheet comment list",
|
||||
"confirmation": "not_required",
|
||||
"description": "查询表格评论列表",
|
||||
"effect": "read",
|
||||
"group": "comment",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "list_sheet_comments",
|
||||
"primary_cli_path": "sheet comment list",
|
||||
"reviewed": true,
|
||||
"risk": "low",
|
||||
"title": "查询表格评论列表",
|
||||
"use_when": [
|
||||
"用户说 看某格的评论/表格里有哪些批注"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "上传附件到表格并返回 resourceUrl(浮动图片前置步骤)。",
|
||||
@@ -23451,6 +24015,33 @@
|
||||
"要把工作表中匹配文本批量替换为另一文本时"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "回复指定单元格评论,支持表情贴图回复",
|
||||
"agent_summary_source": "dws-agent-selection/sheet",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"修改评论内容用 comment update"
|
||||
],
|
||||
"canonical_path": "sheet.reply_sheet_comment",
|
||||
"cli_name": "reply",
|
||||
"cli_path": "sheet comment reply",
|
||||
"confirmation": "not_required",
|
||||
"description": "回复单元格评论",
|
||||
"effect": "write",
|
||||
"group": "comment",
|
||||
"idempotency": "non_idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "reply_sheet_comment",
|
||||
"primary_cli_path": "sheet comment reply",
|
||||
"reviewed": true,
|
||||
"risk": "low",
|
||||
"title": "回复单元格评论",
|
||||
"use_when": [
|
||||
"用户说 回复这条评论"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "为指定范围设置下拉列表(可多选、可带颜色)。",
|
||||
@@ -24089,6 +24680,114 @@
|
||||
"要重命名工作表、调整页签顺序、隐藏/显示、冻结行列或改标签颜色时"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "更新单元格评论内容",
|
||||
"agent_summary_source": "dws-agent-selection/sheet",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"回复评论用 comment reply"
|
||||
],
|
||||
"canonical_path": "sheet.update_sheet_comment",
|
||||
"cli_name": "update",
|
||||
"cli_path": "sheet comment update",
|
||||
"confirmation": "not_required",
|
||||
"description": "更新单元格评论",
|
||||
"effect": "write",
|
||||
"group": "comment",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "update_sheet_comment",
|
||||
"primary_cli_path": "sheet comment update",
|
||||
"reviewed": true,
|
||||
"risk": "low",
|
||||
"title": "更新单元格评论",
|
||||
"use_when": [
|
||||
"用户说 改一下这条评论"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "查看表格历史版本列表",
|
||||
"agent_summary_source": "dws-agent-selection/sheet",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"回滚用 version revert"
|
||||
],
|
||||
"canonical_path": "sheet.version_list",
|
||||
"cli_name": "list",
|
||||
"cli_path": "sheet version list",
|
||||
"confirmation": "not_required",
|
||||
"description": "查看表格历史版本列表",
|
||||
"effect": "read",
|
||||
"group": "version",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "version_list",
|
||||
"primary_cli_path": "sheet version list",
|
||||
"reviewed": true,
|
||||
"risk": "low",
|
||||
"title": "查看表格历史版本列表",
|
||||
"use_when": [
|
||||
"用户说 看历史版本/版本列表,目标是在线表格"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "回滚表格到指定历史版本",
|
||||
"agent_summary_source": "dws-agent-selection/sheet",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"普通文件回滚用 drive revert;在线文档用 doc version revert"
|
||||
],
|
||||
"canonical_path": "sheet.version_revert",
|
||||
"cli_name": "revert",
|
||||
"cli_path": "sheet version revert",
|
||||
"confirmation": "user_required",
|
||||
"description": "[危险] 回滚表格到指定版本",
|
||||
"effect": "write",
|
||||
"group": "version",
|
||||
"idempotency": "non_idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "version_revert",
|
||||
"primary_cli_path": "sheet version revert",
|
||||
"reviewed": true,
|
||||
"risk": "medium",
|
||||
"title": "[危险] 回滚表格到指定版本",
|
||||
"use_when": [
|
||||
"用户说 回滚到某个版本/恢复到之前的表格"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "手动保存表格版本快照",
|
||||
"agent_summary_source": "dws-agent-selection/sheet",
|
||||
"availability": "available",
|
||||
"avoid_when": [
|
||||
"回滚用 version revert;查看历史用 version list"
|
||||
],
|
||||
"canonical_path": "sheet.version_save",
|
||||
"cli_name": "save",
|
||||
"cli_path": "sheet version save",
|
||||
"confirmation": "not_required",
|
||||
"description": "手动保存表格版本快照",
|
||||
"effect": "write",
|
||||
"group": "version",
|
||||
"idempotency": "non_idempotent",
|
||||
"interface_mode": "composite",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"name": "version_save",
|
||||
"primary_cli_path": "sheet version save",
|
||||
"reviewed": true,
|
||||
"risk": "low",
|
||||
"title": "手动保存表格版本快照",
|
||||
"use_when": [
|
||||
"用户说 保存版本/存个快照,目标是在线表格"
|
||||
]
|
||||
},
|
||||
{
|
||||
"agent_metadata_source": "embedded-skill-metadata",
|
||||
"agent_summary": "上传图片并写入指定单元格(占单元格内容)。",
|
||||
@@ -25785,6 +26484,6 @@
|
||||
}
|
||||
],
|
||||
"source": "embedded-command-catalog",
|
||||
"tool_count": 813
|
||||
"tool_count": 839
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -90,7 +90,6 @@
|
||||
"chat clear-red-point",
|
||||
"chat data-auth cross-org",
|
||||
"chat group audit-join-validation",
|
||||
"chat group get-mute-config",
|
||||
"chat group list-all",
|
||||
"chat group list-join-validations",
|
||||
"chat group members list-by-ids",
|
||||
@@ -100,8 +99,6 @@
|
||||
"chat group notice list",
|
||||
"chat group share-invite",
|
||||
"chat group update-alias",
|
||||
"chat group user-settings query",
|
||||
"chat group user-settings set",
|
||||
"chat hide",
|
||||
"chat list-all-conversations",
|
||||
"chat mark-read",
|
||||
@@ -109,7 +106,6 @@
|
||||
"chat message list-emotion-replies",
|
||||
"chat message set-top-msg",
|
||||
"chat message unset-top-msg",
|
||||
"chat message update-text-emotion",
|
||||
"chat mute-at-all",
|
||||
"chat mute-red-envelope",
|
||||
"chat text translate",
|
||||
@@ -122,14 +118,6 @@
|
||||
"ding message receiver-status",
|
||||
"ding message send-by-message",
|
||||
"ding message send-personal",
|
||||
"drive cover",
|
||||
"drive permission apply",
|
||||
"drive permission apply-info",
|
||||
"drive permission transfer-owner",
|
||||
"drive revert",
|
||||
"drive star add",
|
||||
"drive star list",
|
||||
"drive star remove",
|
||||
"mail allow-list add",
|
||||
"mail allow-list list",
|
||||
"mail allow-list remove",
|
||||
@@ -162,15 +150,6 @@
|
||||
"oa approval revert-activities",
|
||||
"oa approval revert-task",
|
||||
"oa approval search-forms",
|
||||
"sheet comment create",
|
||||
"sheet comment delete",
|
||||
"sheet comment list",
|
||||
"sheet comment reply",
|
||||
"sheet comment update",
|
||||
"sheet formula-verify",
|
||||
"sheet version list",
|
||||
"sheet version revert",
|
||||
"sheet version save",
|
||||
"todo task list-sub",
|
||||
"todo task remove-attachment"
|
||||
]
|
||||
|
||||
@@ -1,6 +1,174 @@
|
||||
{
|
||||
"id": "chat",
|
||||
"tools": [
|
||||
{
|
||||
"canonical_path": "chat.shortcut_at_me",
|
||||
"cli_path": "chat +at-me"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_bot_find",
|
||||
"cli_path": "chat +bot-find"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_bot_search",
|
||||
"cli_path": "chat +bot-search"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_broadcast",
|
||||
"cli_path": "chat +broadcast"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_category_create",
|
||||
"cli_path": "chat +category-create"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_category_delete",
|
||||
"cli_path": "chat +category-delete"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_category_list",
|
||||
"cli_path": "chat +category-list"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_category_rename",
|
||||
"cli_path": "chat +category-rename"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_bots",
|
||||
"cli_path": "chat +chat-bots"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_dismiss",
|
||||
"cli_path": "chat +chat-dismiss"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_invite_url",
|
||||
"cli_path": "chat +chat-invite-url"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_list_all",
|
||||
"cli_path": "chat +chat-list-all"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_list_join_requests",
|
||||
"cli_path": "chat +chat-list-join-requests"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_list_mine",
|
||||
"cli_path": "chat +chat-list-mine"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_mute",
|
||||
"cli_path": "chat +chat-mute"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_role_add",
|
||||
"cli_path": "chat +chat-role-add"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_role_list",
|
||||
"cli_path": "chat +chat-role-list"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_role_query_user",
|
||||
"cli_path": "chat +chat-role-query-user"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_role_set_user",
|
||||
"cli_path": "chat +chat-role-set-user"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_role_update",
|
||||
"cli_path": "chat +chat-role-update"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_search",
|
||||
"cli_path": "chat +chat-search"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_set_admin",
|
||||
"cli_path": "chat +chat-set-admin"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_set_history",
|
||||
"cli_path": "chat +chat-set-history"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_update_alias",
|
||||
"cli_path": "chat +chat-update-alias"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_update_nick",
|
||||
"cli_path": "chat +chat-update-nick"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_conversation_clear_all_red_point",
|
||||
"cli_path": "chat +conversation-clear-all-red-point"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_conversation_info",
|
||||
"cli_path": "chat +conversation-info"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_conversation_list",
|
||||
"cli_path": "chat +conversation-list"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_conversation_list_top",
|
||||
"cli_path": "chat +conversation-list-top"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_dm",
|
||||
"cli_path": "chat +dm"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_group_members",
|
||||
"cli_path": "chat +group-members"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_messages_list_direct",
|
||||
"cli_path": "chat +messages-list-direct"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_messages_list_pin",
|
||||
"cli_path": "chat +messages-list-pin"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_messages_list_unread_conversations",
|
||||
"cli_path": "chat +messages-list-unread-conversations"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_messages_mget",
|
||||
"cli_path": "chat +messages-mget"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_messages_query_send_status",
|
||||
"cli_path": "chat +messages-query-send-status"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_messages_read_status",
|
||||
"cli_path": "chat +messages-read-status"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_messages_send_by_webhook",
|
||||
"cli_path": "chat +messages-send-by-webhook"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_messages_update_card",
|
||||
"cli_path": "chat +messages-update-card"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_my_groups",
|
||||
"cli_path": "chat +my-groups"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_send_to_group",
|
||||
"cli_path": "chat +send-to-group"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_unread_chats",
|
||||
"cli_path": "chat +unread-chats"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.search_bots",
|
||||
"cli_path": "chat bot find"
|
||||
@@ -9,6 +177,10 @@
|
||||
"canonical_path": "chat.search_my_robots",
|
||||
"cli_path": "chat bot search"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.get_conv_categories_info",
|
||||
"cli_path": "chat category batch-info"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.create_smart_conv_category",
|
||||
"cli_path": "chat category create-smart"
|
||||
@@ -17,6 +189,10 @@
|
||||
"canonical_path": "chat.list_user_define_conv_categories",
|
||||
"cli_path": "chat category list"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.list_conv_categories_by_conv",
|
||||
"cli_path": "chat category list-by-conv"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.list_conversations_by_category",
|
||||
"cli_path": "chat category list-conversations"
|
||||
@@ -41,6 +217,10 @@
|
||||
"canonical_path": "chat.get_conv_info_by_group_id",
|
||||
"cli_path": "chat group get-by-group-id"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.get_group_mute_config",
|
||||
"cli_path": "chat group get-mute-config"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.get_group_invite_url",
|
||||
"cli_path": "chat group invite-url"
|
||||
@@ -89,10 +269,26 @@
|
||||
"canonical_path": "chat.update_group_icon",
|
||||
"cli_path": "chat group update-icon"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.update_group_nick",
|
||||
"cli_path": "chat group update-nick"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.update_group_settings",
|
||||
"cli_path": "chat group update-settings"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.upgrade_group_to_external",
|
||||
"cli_path": "chat group upgrade-to-external"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.batch_query_group_chat_settings",
|
||||
"cli_path": "chat group user-settings query"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.batch_update_group_chat_settings",
|
||||
"cli_path": "chat group user-settings set"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.set_group_mute",
|
||||
"cli_path": "chat group-mute"
|
||||
@@ -157,6 +353,10 @@
|
||||
"canonical_path": "chat.download_media",
|
||||
"cli_path": "chat message download-media"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.edit_message",
|
||||
"cli_path": "chat message edit"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.forward_message",
|
||||
"cli_path": "chat message forward"
|
||||
@@ -277,6 +477,10 @@
|
||||
"canonical_path": "chat.update_streaming_card",
|
||||
"cli_path": "chat message update-card"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.update_text_emotion",
|
||||
"cli_path": "chat message update-text-emotion"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.update_notification_off",
|
||||
"cli_path": "chat mute"
|
||||
@@ -292,194 +496,6 @@
|
||||
{
|
||||
"canonical_path": "chat.set_top_conversation",
|
||||
"cli_path": "chat set-top"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.edit_message",
|
||||
"cli_path": "chat message edit"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.get_conv_categories_info",
|
||||
"cli_path": "chat category batch-info"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.list_conv_categories_by_conv",
|
||||
"cli_path": "chat category list-by-conv"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.update_group_nick",
|
||||
"cli_path": "chat group update-nick"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.upgrade_group_to_external",
|
||||
"cli_path": "chat group upgrade-to-external"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_bot_search",
|
||||
"cli_path": "chat +bot-search"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_bot_find",
|
||||
"cli_path": "chat +bot-find"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_conversation_info",
|
||||
"cli_path": "chat +conversation-info"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_conversation_clear_all_red_point",
|
||||
"cli_path": "chat +conversation-clear-all-red-point"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_conversation_list",
|
||||
"cli_path": "chat +conversation-list"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_conversation_list_top",
|
||||
"cli_path": "chat +conversation-list-top"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_category_list",
|
||||
"cli_path": "chat +category-list"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_category_create",
|
||||
"cli_path": "chat +category-create"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_category_delete",
|
||||
"cli_path": "chat +category-delete"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_category_rename",
|
||||
"cli_path": "chat +category-rename"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_search",
|
||||
"cli_path": "chat +chat-search"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_invite_url",
|
||||
"cli_path": "chat +chat-invite-url"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_dismiss",
|
||||
"cli_path": "chat +chat-dismiss"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_set_history",
|
||||
"cli_path": "chat +chat-set-history"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_update_nick",
|
||||
"cli_path": "chat +chat-update-nick"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_update_alias",
|
||||
"cli_path": "chat +chat-update-alias"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_list_mine",
|
||||
"cli_path": "chat +chat-list-mine"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_list_all",
|
||||
"cli_path": "chat +chat-list-all"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_list_join_requests",
|
||||
"cli_path": "chat +chat-list-join-requests"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_bots",
|
||||
"cli_path": "chat +chat-bots"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_set_admin",
|
||||
"cli_path": "chat +chat-set-admin"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_mute",
|
||||
"cli_path": "chat +chat-mute"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_role_list",
|
||||
"cli_path": "chat +chat-role-list"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_role_add",
|
||||
"cli_path": "chat +chat-role-add"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_role_update",
|
||||
"cli_path": "chat +chat-role-update"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_role_set_user",
|
||||
"cli_path": "chat +chat-role-set-user"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_chat_role_query_user",
|
||||
"cli_path": "chat +chat-role-query-user"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_messages_send_by_webhook",
|
||||
"cli_path": "chat +messages-send-by-webhook"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_messages_list_direct",
|
||||
"cli_path": "chat +messages-list-direct"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_messages_list_unread_conversations",
|
||||
"cli_path": "chat +messages-list-unread-conversations"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_messages_mget",
|
||||
"cli_path": "chat +messages-mget"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_messages_query_send_status",
|
||||
"cli_path": "chat +messages-query-send-status"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_messages_read_status",
|
||||
"cli_path": "chat +messages-read-status"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_messages_update_card",
|
||||
"cli_path": "chat +messages-update-card"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_messages_list_pin",
|
||||
"cli_path": "chat +messages-list-pin"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_at_me",
|
||||
"cli_path": "chat +at-me"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_broadcast",
|
||||
"cli_path": "chat +broadcast"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_dm",
|
||||
"cli_path": "chat +dm"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_group_members",
|
||||
"cli_path": "chat +group-members"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_my_groups",
|
||||
"cli_path": "chat +my-groups"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_send_to_group",
|
||||
"cli_path": "chat +send-to-group"
|
||||
},
|
||||
{
|
||||
"canonical_path": "chat.shortcut_unread_chats",
|
||||
"cli_path": "chat +unread-chats"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,74 @@
|
||||
{
|
||||
"id": "doc",
|
||||
"tools": [
|
||||
{
|
||||
"canonical_path": "doc.shortcut_comment_create",
|
||||
"cli_path": "doc +comment-create"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_comment_list",
|
||||
"cli_path": "doc +comment-list"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_comment_reply",
|
||||
"cli_path": "doc +comment-reply"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_copy",
|
||||
"cli_path": "doc +copy"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_doc_append",
|
||||
"cli_path": "doc +doc-append"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_export_get",
|
||||
"cli_path": "doc +export-get"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_export_submit",
|
||||
"cli_path": "doc +export-submit"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_find_doc",
|
||||
"cli_path": "doc +find-doc"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_list",
|
||||
"cli_path": "doc +list"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_move",
|
||||
"cli_path": "doc +move"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_search",
|
||||
"cli_path": "doc +search"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_share_doc",
|
||||
"cli_path": "doc +share-doc"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_template_list",
|
||||
"cli_path": "doc +template-list"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_template_search",
|
||||
"cli_path": "doc +template-search"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_version_list",
|
||||
"cli_path": "doc +version-list"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_version_revert",
|
||||
"cli_path": "doc +version-revert"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_version_save",
|
||||
"cli_path": "doc +version-save"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.delete_document_block",
|
||||
"cli_path": "doc block delete"
|
||||
@@ -121,6 +189,26 @@
|
||||
"canonical_path": "doc.search_documents",
|
||||
"cli_path": "doc search"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.style_background_clear",
|
||||
"cli_path": "doc style background clear"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.style_background_set",
|
||||
"cli_path": "doc style background set"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.style_cover_clear",
|
||||
"cli_path": "doc style cover clear"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.style_cover_set",
|
||||
"cli_path": "doc style cover set"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.get_document_style",
|
||||
"cli_path": "doc style get"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.template_apply",
|
||||
"cli_path": "doc template apply"
|
||||
@@ -152,74 +240,6 @@
|
||||
{
|
||||
"canonical_path": "doc.version_save",
|
||||
"cli_path": "doc version save"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_search",
|
||||
"cli_path": "doc +search"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_list",
|
||||
"cli_path": "doc +list"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_copy",
|
||||
"cli_path": "doc +copy"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_move",
|
||||
"cli_path": "doc +move"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_comment_list",
|
||||
"cli_path": "doc +comment-list"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_comment_create",
|
||||
"cli_path": "doc +comment-create"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_comment_reply",
|
||||
"cli_path": "doc +comment-reply"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_export_submit",
|
||||
"cli_path": "doc +export-submit"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_export_get",
|
||||
"cli_path": "doc +export-get"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_version_save",
|
||||
"cli_path": "doc +version-save"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_version_list",
|
||||
"cli_path": "doc +version-list"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_version_revert",
|
||||
"cli_path": "doc +version-revert"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_template_list",
|
||||
"cli_path": "doc +template-list"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_template_search",
|
||||
"cli_path": "doc +template-search"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_doc_append",
|
||||
"cli_path": "doc +doc-append"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_find_doc",
|
||||
"cli_path": "doc +find-doc"
|
||||
},
|
||||
{
|
||||
"canonical_path": "doc.shortcut_share_doc",
|
||||
"cli_path": "doc +share-doc"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,34 @@
|
||||
{
|
||||
"id": "drive",
|
||||
"tools": [
|
||||
{
|
||||
"canonical_path": "drive.shortcut_copy",
|
||||
"cli_path": "drive +copy"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.shortcut_find_file",
|
||||
"cli_path": "drive +find-file"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.shortcut_info",
|
||||
"cli_path": "drive +info"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.shortcut_move",
|
||||
"cli_path": "drive +move"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.shortcut_recent",
|
||||
"cli_path": "drive +recent"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.shortcut_search",
|
||||
"cli_path": "drive +search"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.shortcut_search_docs",
|
||||
"cli_path": "drive +search-docs"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.commit_upload",
|
||||
"cli_path": "drive commit"
|
||||
@@ -9,6 +37,10 @@
|
||||
"canonical_path": "drive.copy_document",
|
||||
"cli_path": "drive copy"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.get_cover",
|
||||
"cli_path": "drive cover"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.delete_document",
|
||||
"cli_path": "drive delete"
|
||||
@@ -41,6 +73,14 @@
|
||||
"canonical_path": "drive.add_permission",
|
||||
"cli_path": "drive permission add"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.apply_permission",
|
||||
"cli_path": "drive permission apply"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.query_permission_apply_info",
|
||||
"cli_path": "drive permission apply-info"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.list_permission",
|
||||
"cli_path": "drive permission list"
|
||||
@@ -49,6 +89,10 @@
|
||||
"canonical_path": "drive.permission_remove",
|
||||
"cli_path": "drive permission remove"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.transfer_owner",
|
||||
"cli_path": "drive permission transfer-owner"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.permission_update",
|
||||
"cli_path": "drive permission update"
|
||||
@@ -81,6 +125,10 @@
|
||||
"canonical_path": "drive.rename_document",
|
||||
"cli_path": "drive rename"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.revert_file_version",
|
||||
"cli_path": "drive revert"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.search_files",
|
||||
"cli_path": "drive search"
|
||||
@@ -89,6 +137,18 @@
|
||||
"canonical_path": "drive.create_shortcut",
|
||||
"cli_path": "drive shortcut"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.mark_star",
|
||||
"cli_path": "drive star add"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.get_star_list",
|
||||
"cli_path": "drive star list"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.unmark_star",
|
||||
"cli_path": "drive star remove"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.get_node_stats",
|
||||
"cli_path": "drive stats"
|
||||
@@ -100,34 +160,6 @@
|
||||
{
|
||||
"canonical_path": "drive.get_upload_info",
|
||||
"cli_path": "drive upload-info"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.shortcut_info",
|
||||
"cli_path": "drive +info"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.shortcut_search",
|
||||
"cli_path": "drive +search"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.shortcut_search_docs",
|
||||
"cli_path": "drive +search-docs"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.shortcut_copy",
|
||||
"cli_path": "drive +copy"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.shortcut_move",
|
||||
"cli_path": "drive +move"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.shortcut_recent",
|
||||
"cli_path": "drive +recent"
|
||||
},
|
||||
{
|
||||
"canonical_path": "drive.shortcut_find_file",
|
||||
"cli_path": "drive +find-file"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,14 @@
|
||||
{
|
||||
"id": "sheet",
|
||||
"tools": [
|
||||
{
|
||||
"canonical_path": "sheet.shortcut_list_sheets",
|
||||
"cli_path": "sheet +list-sheets"
|
||||
},
|
||||
{
|
||||
"canonical_path": "sheet.shortcut_read",
|
||||
"cli_path": "sheet +read"
|
||||
},
|
||||
{
|
||||
"canonical_path": "sheet.add_dimension",
|
||||
"cli_path": "sheet add-dimension"
|
||||
@@ -29,6 +37,26 @@
|
||||
"canonical_path": "sheet.chart_update",
|
||||
"cli_path": "sheet chart update"
|
||||
},
|
||||
{
|
||||
"canonical_path": "sheet.create_sheet_comment",
|
||||
"cli_path": "sheet comment create"
|
||||
},
|
||||
{
|
||||
"canonical_path": "sheet.delete_sheet_comment",
|
||||
"cli_path": "sheet comment delete"
|
||||
},
|
||||
{
|
||||
"canonical_path": "sheet.list_sheet_comments",
|
||||
"cli_path": "sheet comment list"
|
||||
},
|
||||
{
|
||||
"canonical_path": "sheet.reply_sheet_comment",
|
||||
"cli_path": "sheet comment reply"
|
||||
},
|
||||
{
|
||||
"canonical_path": "sheet.update_sheet_comment",
|
||||
"cli_path": "sheet comment update"
|
||||
},
|
||||
{
|
||||
"canonical_path": "sheet.create_cond_format",
|
||||
"cli_path": "sheet cond-format create"
|
||||
@@ -149,6 +177,10 @@
|
||||
"canonical_path": "sheet.find_cells",
|
||||
"cli_path": "sheet find"
|
||||
},
|
||||
{
|
||||
"canonical_path": "sheet.formula_verify",
|
||||
"cli_path": "sheet formula-verify"
|
||||
},
|
||||
{
|
||||
"canonical_path": "sheet.get_dropdown_lists",
|
||||
"cli_path": "sheet get-dropdown"
|
||||
@@ -165,10 +197,6 @@
|
||||
"canonical_path": "sheet.hide_gridline",
|
||||
"cli_path": "sheet hide-gridline"
|
||||
},
|
||||
{
|
||||
"canonical_path": "sheet.info",
|
||||
"cli_path": "sheet info"
|
||||
},
|
||||
{
|
||||
"canonical_path": "sheet.import",
|
||||
"cli_path": "sheet import create"
|
||||
@@ -177,6 +205,10 @@
|
||||
"canonical_path": "sheet.import_get",
|
||||
"cli_path": "sheet import get"
|
||||
},
|
||||
{
|
||||
"canonical_path": "sheet.info",
|
||||
"cli_path": "sheet info"
|
||||
},
|
||||
{
|
||||
"canonical_path": "sheet.insert_dimension",
|
||||
"cli_path": "sheet insert-dimension"
|
||||
@@ -319,17 +351,21 @@
|
||||
"canonical_path": "sheet.update_float_image",
|
||||
"cli_path": "sheet update-float-image"
|
||||
},
|
||||
{
|
||||
"canonical_path": "sheet.version_list",
|
||||
"cli_path": "sheet version list"
|
||||
},
|
||||
{
|
||||
"canonical_path": "sheet.version_revert",
|
||||
"cli_path": "sheet version revert"
|
||||
},
|
||||
{
|
||||
"canonical_path": "sheet.version_save",
|
||||
"cli_path": "sheet version save"
|
||||
},
|
||||
{
|
||||
"canonical_path": "sheet.write_image",
|
||||
"cli_path": "sheet write-image"
|
||||
},
|
||||
{
|
||||
"canonical_path": "sheet.shortcut_list_sheets",
|
||||
"cli_path": "sheet +list-sheets"
|
||||
},
|
||||
{
|
||||
"canonical_path": "sheet.shortcut_read",
|
||||
"cli_path": "sheet +read"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1346,6 +1346,50 @@
|
||||
"review_reason": "Reviewed against the built-in Shortcut registry and mounted Cobra command: publishes the executable risk gate and composite interface without inventing a direct MCP identity.",
|
||||
"cli_path": "chat +unread-chats",
|
||||
"runtime_gate": "none"
|
||||
},
|
||||
"chat.update_text_emotion": {
|
||||
"effect": "write",
|
||||
"risk": "low",
|
||||
"confirmation": "not_required",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "none"
|
||||
},
|
||||
"chat.get_group_mute_config": {
|
||||
"effect": "read",
|
||||
"risk": "low",
|
||||
"confirmation": "not_required",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "none"
|
||||
},
|
||||
"chat.batch_query_group_chat_settings": {
|
||||
"effect": "read",
|
||||
"risk": "low",
|
||||
"confirmation": "not_required",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "none"
|
||||
},
|
||||
"chat.batch_update_group_chat_settings": {
|
||||
"effect": "write",
|
||||
"risk": "low",
|
||||
"confirmation": "not_required",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "none"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -587,6 +587,61 @@
|
||||
"review_reason": "Reviewed against the built-in Shortcut registry and mounted Cobra command: publishes the executable risk gate and composite interface without inventing a direct MCP identity.",
|
||||
"cli_path": "doc +share-doc",
|
||||
"runtime_gate": "typed_yes"
|
||||
},
|
||||
"doc.style_cover_set": {
|
||||
"effect": "write",
|
||||
"risk": "low",
|
||||
"confirmation": "not_required",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "none"
|
||||
},
|
||||
"doc.style_cover_clear": {
|
||||
"effect": "write",
|
||||
"risk": "low",
|
||||
"confirmation": "not_required",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "none"
|
||||
},
|
||||
"doc.style_background_set": {
|
||||
"effect": "write",
|
||||
"risk": "low",
|
||||
"confirmation": "not_required",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "none"
|
||||
},
|
||||
"doc.style_background_clear": {
|
||||
"effect": "write",
|
||||
"risk": "low",
|
||||
"confirmation": "not_required",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "none"
|
||||
},
|
||||
"doc.get_document_style": {
|
||||
"effect": "read",
|
||||
"risk": "low",
|
||||
"confirmation": "not_required",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "none"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -326,6 +326,94 @@
|
||||
"review_reason": "Reviewed against the built-in Shortcut registry and mounted Cobra command: publishes the executable risk gate and composite interface without inventing a direct MCP identity.",
|
||||
"cli_path": "drive +find-file",
|
||||
"runtime_gate": "none"
|
||||
},
|
||||
"drive.mark_star": {
|
||||
"effect": "write",
|
||||
"risk": "low",
|
||||
"confirmation": "not_required",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "none"
|
||||
},
|
||||
"drive.unmark_star": {
|
||||
"effect": "write",
|
||||
"risk": "low",
|
||||
"confirmation": "not_required",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "none"
|
||||
},
|
||||
"drive.get_star_list": {
|
||||
"effect": "read",
|
||||
"risk": "low",
|
||||
"confirmation": "not_required",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "none"
|
||||
},
|
||||
"drive.get_cover": {
|
||||
"effect": "read",
|
||||
"risk": "low",
|
||||
"confirmation": "not_required",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "none"
|
||||
},
|
||||
"drive.revert_file_version": {
|
||||
"effect": "write",
|
||||
"risk": "medium",
|
||||
"confirmation": "user_required",
|
||||
"idempotency": "non_idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "confirm_delete"
|
||||
},
|
||||
"drive.transfer_owner": {
|
||||
"effect": "write",
|
||||
"risk": "high",
|
||||
"confirmation": "user_required",
|
||||
"idempotency": "non_idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "confirm_delete"
|
||||
},
|
||||
"drive.query_permission_apply_info": {
|
||||
"effect": "read",
|
||||
"risk": "low",
|
||||
"confirmation": "not_required",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "none"
|
||||
},
|
||||
"drive.apply_permission": {
|
||||
"effect": "write",
|
||||
"risk": "medium",
|
||||
"confirmation": "not_required",
|
||||
"idempotency": "non_idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "none"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -734,6 +734,105 @@
|
||||
"review_reason": "Reviewed against the built-in Shortcut registry and mounted Cobra command: publishes the executable risk gate and composite interface without inventing a direct MCP identity.",
|
||||
"cli_path": "sheet +read",
|
||||
"runtime_gate": "none"
|
||||
},
|
||||
"sheet.version_save": {
|
||||
"effect": "write",
|
||||
"risk": "low",
|
||||
"confirmation": "not_required",
|
||||
"idempotency": "non_idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "none"
|
||||
},
|
||||
"sheet.version_list": {
|
||||
"effect": "read",
|
||||
"risk": "low",
|
||||
"confirmation": "not_required",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "none"
|
||||
},
|
||||
"sheet.version_revert": {
|
||||
"effect": "write",
|
||||
"risk": "medium",
|
||||
"confirmation": "user_required",
|
||||
"idempotency": "non_idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "confirm_delete"
|
||||
},
|
||||
"sheet.formula_verify": {
|
||||
"effect": "read",
|
||||
"risk": "low",
|
||||
"confirmation": "not_required",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "none"
|
||||
},
|
||||
"sheet.list_sheet_comments": {
|
||||
"effect": "read",
|
||||
"risk": "low",
|
||||
"confirmation": "not_required",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "none"
|
||||
},
|
||||
"sheet.create_sheet_comment": {
|
||||
"effect": "write",
|
||||
"risk": "low",
|
||||
"confirmation": "not_required",
|
||||
"idempotency": "non_idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "none"
|
||||
},
|
||||
"sheet.reply_sheet_comment": {
|
||||
"effect": "write",
|
||||
"risk": "low",
|
||||
"confirmation": "not_required",
|
||||
"idempotency": "non_idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "none"
|
||||
},
|
||||
"sheet.update_sheet_comment": {
|
||||
"effect": "write",
|
||||
"risk": "low",
|
||||
"confirmation": "not_required",
|
||||
"idempotency": "idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "none"
|
||||
},
|
||||
"sheet.delete_sheet_comment": {
|
||||
"effect": "write",
|
||||
"risk": "medium",
|
||||
"confirmation": "user_required",
|
||||
"idempotency": "non_idempotent",
|
||||
"interface_mode": "composite",
|
||||
"availability": "available",
|
||||
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
|
||||
"reviewed": true,
|
||||
"runtime_gate": "confirm_delete"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2396,6 +2396,82 @@
|
||||
"cobra-help:dws chat +unread-chats",
|
||||
"ShortcutRegistry:chat +unread-chats"
|
||||
]
|
||||
},
|
||||
"chat.update_text_emotion": {
|
||||
"agent_summary": "更新消息上已有的文字表情回应",
|
||||
"use_when": [
|
||||
"用户说 改一下消息上的文字表情"
|
||||
],
|
||||
"avoid_when": [
|
||||
"新增用 add-text-emotion;移除用 remove-text-emotion"
|
||||
],
|
||||
"examples": [
|
||||
"dws chat message update-text-emotion --conversation-id <cid> --msg-id <mid> --old-emotion-id <old> --emotion-id <new> --emotion-name \"赞\" --text \"nice\" --background-id im_bg_5 --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=chat.update_text_emotion",
|
||||
"cobra-help:dws chat message update-text-emotion",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
},
|
||||
"chat.get_group_mute_config": {
|
||||
"agent_summary": "查询群用户禁言配置(禁言黑名单/全员禁言白名单)",
|
||||
"use_when": [
|
||||
"用户说 看下群里谁被禁言/禁言配置"
|
||||
],
|
||||
"avoid_when": [
|
||||
"设置全员禁言用 chat group-mute;禁言个人用 chat group-mute-member"
|
||||
],
|
||||
"examples": [
|
||||
"dws chat group get-mute-config --group <openConversationId> --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=chat.get_group_mute_config",
|
||||
"cobra-help:dws chat group get-mute-config",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
},
|
||||
"chat.batch_query_group_chat_settings": {
|
||||
"agent_summary": "批量查询当前用户自己的群会话设置(置顶/免打扰/群昵称/群备注)",
|
||||
"use_when": [
|
||||
"用户说 看下这些群我的置顶和免打扰设置"
|
||||
],
|
||||
"avoid_when": [
|
||||
"管理员级群功能开关用 chat group update-settings"
|
||||
],
|
||||
"examples": [
|
||||
"dws chat group user-settings query --groups cid1,cid2 --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=chat.batch_query_group_chat_settings",
|
||||
"cobra-help:dws chat group user-settings query",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
},
|
||||
"chat.batch_update_group_chat_settings": {
|
||||
"agent_summary": "批量更新当前用户自己的群会话设置(置顶/免打扰/群昵称/群备注)",
|
||||
"use_when": [
|
||||
"用户说 把这些群都设为免打扰/置顶"
|
||||
],
|
||||
"avoid_when": [
|
||||
"单个群昵称优先 chat group update-nick"
|
||||
],
|
||||
"examples": [
|
||||
"dws chat group user-settings set --items '[{\"openConversationId\":\"cid1\",\"top\":true,\"mute\":false}]' --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=chat.batch_update_group_chat_settings",
|
||||
"cobra-help:dws chat group user-settings set",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
}
|
||||
},
|
||||
"products": {
|
||||
|
||||
@@ -1226,6 +1226,101 @@
|
||||
"cobra-help:dws doc +share-doc",
|
||||
"ShortcutRegistry:doc +share-doc"
|
||||
]
|
||||
},
|
||||
"doc.style_cover_set": {
|
||||
"agent_summary": "设置钉钉文档顶部封面图(外链或本地图片上传)",
|
||||
"use_when": [
|
||||
"用户说 给文档设置封面/换个封面图"
|
||||
],
|
||||
"avoid_when": [
|
||||
"读取当前封面用 doc style get;移除封面用 cover clear"
|
||||
],
|
||||
"examples": [
|
||||
"dws doc style cover set --node <DOC_ID> --image https://img.example.com/cover.png --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=doc.style_cover_set",
|
||||
"cobra-help:dws doc style cover set",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
},
|
||||
"doc.style_cover_clear": {
|
||||
"agent_summary": "移除钉钉文档封面",
|
||||
"use_when": [
|
||||
"用户说 去掉文档封面"
|
||||
],
|
||||
"avoid_when": [
|
||||
"设置封面用 cover set"
|
||||
],
|
||||
"examples": [
|
||||
"dws doc style cover clear --node <DOC_ID> --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=doc.style_cover_clear",
|
||||
"cobra-help:dws doc style cover clear",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
},
|
||||
"doc.style_background_set": {
|
||||
"agent_summary": "设置钉钉文档背景纯色(#RRGGBB)",
|
||||
"use_when": [
|
||||
"用户说 给文档设置背景色"
|
||||
],
|
||||
"avoid_when": [
|
||||
"背景不支持图片;封面用 cover set"
|
||||
],
|
||||
"examples": [
|
||||
"dws doc style background set --node <DOC_ID> --color \"#E8F2FE\" --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=doc.style_background_set",
|
||||
"cobra-help:dws doc style background set",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
},
|
||||
"doc.style_background_clear": {
|
||||
"agent_summary": "清除钉钉文档背景",
|
||||
"use_when": [
|
||||
"用户说 去掉文档背景色"
|
||||
],
|
||||
"avoid_when": [
|
||||
"设置背景用 background set"
|
||||
],
|
||||
"examples": [
|
||||
"dws doc style background clear --node <DOC_ID> --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=doc.style_background_clear",
|
||||
"cobra-help:dws doc style background clear",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
},
|
||||
"doc.get_document_style": {
|
||||
"agent_summary": "读取文档当前封面与背景配置(只读)",
|
||||
"use_when": [
|
||||
"用户说 看下文档现在的封面/背景"
|
||||
],
|
||||
"avoid_when": [
|
||||
"修改用 cover set / background set"
|
||||
],
|
||||
"examples": [
|
||||
"dws doc style get --node <DOC_ID> --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=doc.get_document_style",
|
||||
"cobra-help:dws doc style get",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
}
|
||||
},
|
||||
"products": {
|
||||
|
||||
@@ -758,6 +758,159 @@
|
||||
"cobra-help:dws drive +find-file",
|
||||
"ShortcutRegistry:drive +find-file"
|
||||
]
|
||||
},
|
||||
"drive.mark_star": {
|
||||
"agent_summary": "收藏文档/文件到当前用户收藏列表",
|
||||
"use_when": [
|
||||
"用户说 收藏这个文档/加个收藏/标星"
|
||||
],
|
||||
"avoid_when": [
|
||||
"取消收藏用 unmark_star;查看收藏列表用 get_star_list"
|
||||
],
|
||||
"examples": [
|
||||
"dws drive star add --node <nodeId> --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=drive.mark_star",
|
||||
"cobra-help:dws drive star add",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
},
|
||||
"drive.unmark_star": {
|
||||
"agent_summary": "将文档/文件从当前用户收藏列表移除",
|
||||
"use_when": [
|
||||
"用户说 取消收藏/去掉收藏/不收藏了"
|
||||
],
|
||||
"avoid_when": [
|
||||
"添加收藏用 mark_star"
|
||||
],
|
||||
"examples": [
|
||||
"dws drive star remove --node <nodeId> --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=drive.unmark_star",
|
||||
"cobra-help:dws drive star remove",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
},
|
||||
"drive.get_star_list": {
|
||||
"agent_summary": "获取当前用户的收藏列表,支持分页与按内容类型筛选",
|
||||
"use_when": [
|
||||
"用户说 我的收藏/收藏列表/收藏了哪些文档"
|
||||
],
|
||||
"avoid_when": [
|
||||
"操作单个收藏用 mark_star/unmark_star"
|
||||
],
|
||||
"examples": [
|
||||
"dws drive star list --format json",
|
||||
"dws drive star list --content-types doc,sheet --limit 10 --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=drive.get_star_list",
|
||||
"cobra-help:dws drive star list",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
},
|
||||
"drive.get_cover": {
|
||||
"agent_summary": "获取节点封面图片地址(文档首图/图片缩略图/类型图标)",
|
||||
"use_when": [
|
||||
"用户说 封面/封面图/缩略图/预览图"
|
||||
],
|
||||
"avoid_when": [
|
||||
"设置文档封面用 doc style cover set"
|
||||
],
|
||||
"examples": [
|
||||
"dws drive cover --node <dentryUuid> --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=drive.get_cover",
|
||||
"cobra-help:dws drive cover",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
},
|
||||
"drive.revert_file_version": {
|
||||
"agent_summary": "回滚普通文件到指定历史版本(生成新最新版本,历史不丢失)",
|
||||
"use_when": [
|
||||
"用户说 回滚版本/恢复到某个版本/版本回退,且目标是普通文件"
|
||||
],
|
||||
"avoid_when": [
|
||||
"在线文档回滚用 doc version revert;在线表格用 sheet version revert"
|
||||
],
|
||||
"examples": [
|
||||
"dws drive revert --node <dentryUuid> --version 3 --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=drive.revert_file_version",
|
||||
"cobra-help:dws drive revert",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
},
|
||||
"drive.transfer_owner": {
|
||||
"agent_summary": "转交文档或知识库所有者给指定用户(不可逆)",
|
||||
"use_when": [
|
||||
"用户明确要求转交文档/知识库所有权"
|
||||
],
|
||||
"avoid_when": [
|
||||
"普通协作权限变更用 permission add/update/remove"
|
||||
],
|
||||
"examples": [
|
||||
"dws drive permission transfer-owner --node <DOC_ID> --new-owner <userId> --reserve-role EDITOR --recursive=false --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=drive.transfer_owner",
|
||||
"cobra-help:dws drive permission transfer-owner",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
},
|
||||
"drive.query_permission_apply_info": {
|
||||
"agent_summary": "查询节点可申请的权限角色列表与审批人列表",
|
||||
"use_when": [
|
||||
"无权限访问文档时,先查可申请角色与审批人"
|
||||
],
|
||||
"avoid_when": [
|
||||
"实际发起申请用 apply_permission"
|
||||
],
|
||||
"examples": [
|
||||
"dws drive permission apply-info --node <DOC_ID> --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=drive.query_permission_apply_info",
|
||||
"cobra-help:dws drive permission apply-info",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
},
|
||||
"drive.apply_permission": {
|
||||
"agent_summary": "向审批人发起文档权限申请(会真实通知审批人)",
|
||||
"use_when": [
|
||||
"用户确认要为无权限文档发起权限申请"
|
||||
],
|
||||
"avoid_when": [
|
||||
"先用 apply-info 查可申请角色与审批人;未经用户确认不得自行提交"
|
||||
],
|
||||
"examples": [
|
||||
"dws drive permission apply --node <DOC_ID> --role READER --users <审批人userId> --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=drive.apply_permission",
|
||||
"cobra-help:dws drive permission apply",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
}
|
||||
},
|
||||
"products": {
|
||||
|
||||
@@ -1629,6 +1629,177 @@
|
||||
"cobra-help:dws sheet +read",
|
||||
"ShortcutRegistry:sheet +read"
|
||||
]
|
||||
},
|
||||
"sheet.version_save": {
|
||||
"agent_summary": "手动保存表格版本快照",
|
||||
"use_when": [
|
||||
"用户说 保存版本/存个快照,目标是在线表格"
|
||||
],
|
||||
"avoid_when": [
|
||||
"回滚用 version revert;查看历史用 version list"
|
||||
],
|
||||
"examples": [
|
||||
"dws sheet version save --node <SHEET_ID> --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=sheet.version_save",
|
||||
"cobra-help:dws sheet version save",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
},
|
||||
"sheet.version_list": {
|
||||
"agent_summary": "查看表格历史版本列表",
|
||||
"use_when": [
|
||||
"用户说 看历史版本/版本列表,目标是在线表格"
|
||||
],
|
||||
"avoid_when": [
|
||||
"回滚用 version revert"
|
||||
],
|
||||
"examples": [
|
||||
"dws sheet version list --node <SHEET_ID> --limit 10 --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=sheet.version_list",
|
||||
"cobra-help:dws sheet version list",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
},
|
||||
"sheet.version_revert": {
|
||||
"agent_summary": "回滚表格到指定历史版本",
|
||||
"use_when": [
|
||||
"用户说 回滚到某个版本/恢复到之前的表格"
|
||||
],
|
||||
"avoid_when": [
|
||||
"普通文件回滚用 drive revert;在线文档用 doc version revert"
|
||||
],
|
||||
"examples": [
|
||||
"dws sheet version revert --node <SHEET_ID> --version 3 --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=sheet.version_revert",
|
||||
"cobra-help:dws sheet version revert",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
},
|
||||
"sheet.formula_verify": {
|
||||
"agent_summary": "扫描表格公式单元格并按错误类型聚合返回错误数量与位置",
|
||||
"use_when": [
|
||||
"用户说 校验公式/检查公式错误/公式错误扫描"
|
||||
],
|
||||
"avoid_when": [
|
||||
"读取公式文本用 range read --value-render-option formula"
|
||||
],
|
||||
"examples": [
|
||||
"dws sheet formula-verify --node <NODE_ID> --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=sheet.formula_verify",
|
||||
"cobra-help:dws sheet formula-verify",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
},
|
||||
"sheet.list_sheet_comments": {
|
||||
"agent_summary": "查询表格单元格评论列表,支持分页与按解决状态过滤",
|
||||
"use_when": [
|
||||
"用户说 看某格的评论/表格里有哪些批注"
|
||||
],
|
||||
"avoid_when": [
|
||||
"新建评论用 comment create"
|
||||
],
|
||||
"examples": [
|
||||
"dws sheet comment list --node <SHEET_ID> --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=sheet.list_sheet_comments",
|
||||
"cobra-help:dws sheet comment list",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
},
|
||||
"sheet.create_sheet_comment": {
|
||||
"agent_summary": "在指定单元格上创建评论,可 @ 用户",
|
||||
"use_when": [
|
||||
"用户说 给单元格加评论/批注/@某人讨论这个数据"
|
||||
],
|
||||
"avoid_when": [
|
||||
"回复已有评论用 comment reply;不要把评论写进单元格值"
|
||||
],
|
||||
"examples": [
|
||||
"dws sheet comment create --node <SHEET_ID> --sheet-id Sheet1 --range A2 --content \"这个数字有问题\" --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=sheet.create_sheet_comment",
|
||||
"cobra-help:dws sheet comment create",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
},
|
||||
"sheet.reply_sheet_comment": {
|
||||
"agent_summary": "回复指定单元格评论,支持表情贴图回复",
|
||||
"use_when": [
|
||||
"用户说 回复这条评论"
|
||||
],
|
||||
"avoid_when": [
|
||||
"修改评论内容用 comment update"
|
||||
],
|
||||
"examples": [
|
||||
"dws sheet comment reply --node <SHEET_ID> --comment-key <COMMENT_KEY> --content \"已核实\" --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=sheet.reply_sheet_comment",
|
||||
"cobra-help:dws sheet comment reply",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
},
|
||||
"sheet.update_sheet_comment": {
|
||||
"agent_summary": "更新单元格评论内容",
|
||||
"use_when": [
|
||||
"用户说 改一下这条评论"
|
||||
],
|
||||
"avoid_when": [
|
||||
"回复评论用 comment reply"
|
||||
],
|
||||
"examples": [
|
||||
"dws sheet comment update --node <SHEET_ID> --comment-key <COMMENT_KEY> --content \"已修正\" --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=sheet.update_sheet_comment",
|
||||
"cobra-help:dws sheet comment update",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
},
|
||||
"sheet.delete_sheet_comment": {
|
||||
"agent_summary": "删除单元格评论(不可恢复)",
|
||||
"use_when": [
|
||||
"用户明确要求删除某条评论"
|
||||
],
|
||||
"avoid_when": [
|
||||
"标记解决不等于删除"
|
||||
],
|
||||
"examples": [
|
||||
"dws sheet comment delete --node <SHEET_ID> --comment-key <COMMENT_KEY> --format json"
|
||||
],
|
||||
"reviewed": true,
|
||||
"review_reason": "人工审阅:对照悟空 develop 同名命令实现、Cobra Long/Example 与 Runtime 确认门禁移植;不改变命令身份、参数契约或接口绑定。",
|
||||
"source_refs": [
|
||||
"CommandRegistry:canonical_path=sheet.delete_sheet_comment",
|
||||
"cobra-help:dws sheet comment delete",
|
||||
"wukong-develop:wukong/products"
|
||||
]
|
||||
}
|
||||
},
|
||||
"products": {
|
||||
|
||||
@@ -1893,6 +1893,83 @@
|
||||
"wiki.list_wikiSpaces --cursor": "composite route maps to pageToken for wiki.list_wikiSpaces or nextToken for drive.list_spaces",
|
||||
"wiki.list_wikiSpaces --limit": "composite route maps to pageSize for wiki.list_wikiSpaces or maxResults for drive.list_spaces",
|
||||
"wiki.list_wikiSpaces --type": "route selector maps to wikiSpaceType or spaceType on different composite branches",
|
||||
"wiki.search_wikiSpaces --type": "local route selector; myWikiSpace invokes list_wikiSpaces instead"
|
||||
"wiki.search_wikiSpaces --type": "local route selector; myWikiSpace invokes list_wikiSpaces instead",
|
||||
"chat.batch_query_group_chat_settings --groups": "Reviewed unpinned adapter: chat.batch_query_group_chat_settings has no singular pinned interface_ref; --groups is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"chat.batch_update_group_chat_settings --items": "Reviewed unpinned adapter: chat.batch_update_group_chat_settings has no singular pinned interface_ref; --items is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"chat.get_group_mute_config --group": "Reviewed unpinned adapter: chat.get_group_mute_config has no singular pinned interface_ref; --group is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"chat.update_text_emotion --background-id": "Reviewed unpinned adapter: chat.update_text_emotion has no singular pinned interface_ref; --background-id is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"chat.update_text_emotion --chat": "Reviewed unpinned adapter: chat.update_text_emotion has no singular pinned interface_ref; --chat is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"chat.update_text_emotion --conversation-id": "Reviewed unpinned adapter: chat.update_text_emotion has no singular pinned interface_ref; --conversation-id is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"chat.update_text_emotion --emotion-id": "Reviewed unpinned adapter: chat.update_text_emotion has no singular pinned interface_ref; --emotion-id is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"chat.update_text_emotion --emotion-name": "Reviewed unpinned adapter: chat.update_text_emotion has no singular pinned interface_ref; --emotion-name is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"chat.update_text_emotion --group": "Reviewed unpinned adapter: chat.update_text_emotion has no singular pinned interface_ref; --group is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"chat.update_text_emotion --id": "Reviewed unpinned adapter: chat.update_text_emotion has no singular pinned interface_ref; --id is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"chat.update_text_emotion --msg-id": "Reviewed unpinned adapter: chat.update_text_emotion has no singular pinned interface_ref; --msg-id is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"chat.update_text_emotion --old-emotion-id": "Reviewed unpinned adapter: chat.update_text_emotion has no singular pinned interface_ref; --old-emotion-id is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"chat.update_text_emotion --text": "Reviewed unpinned adapter: chat.update_text_emotion has no singular pinned interface_ref; --text is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"doc.get_document_style --node": "Reviewed unpinned adapter: doc.get_document_style has no singular pinned interface_ref; --node is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"doc.style_background_clear --node": "Reviewed unpinned adapter: doc.style_background_clear has no singular pinned interface_ref; --node is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"doc.style_background_set --color": "Reviewed unpinned adapter: doc.style_background_set has no singular pinned interface_ref; --color is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"doc.style_background_set --node": "Reviewed unpinned adapter: doc.style_background_set has no singular pinned interface_ref; --node is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"doc.style_cover_clear --node": "Reviewed unpinned adapter: doc.style_cover_clear has no singular pinned interface_ref; --node is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"doc.style_cover_set --file": "Reviewed unpinned adapter: doc.style_cover_set has no singular pinned interface_ref; --file is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"doc.style_cover_set --image": "Reviewed unpinned adapter: doc.style_cover_set has no singular pinned interface_ref; --image is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"doc.style_cover_set --node": "Reviewed unpinned adapter: doc.style_cover_set has no singular pinned interface_ref; --node is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"doc.style_cover_set --position": "Reviewed unpinned adapter: doc.style_cover_set has no singular pinned interface_ref; --position is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"drive.apply_permission --node": "Reviewed unpinned adapter: drive.apply_permission has no singular pinned interface_ref; --node is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"drive.apply_permission --notify-mode": "Reviewed unpinned adapter: drive.apply_permission has no singular pinned interface_ref; --notify-mode is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"drive.apply_permission --reason": "Reviewed unpinned adapter: drive.apply_permission has no singular pinned interface_ref; --reason is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"drive.apply_permission --role": "Reviewed unpinned adapter: drive.apply_permission has no singular pinned interface_ref; --role is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"drive.apply_permission --users": "Reviewed unpinned adapter: drive.apply_permission has no singular pinned interface_ref; --users is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"drive.get_cover --node": "Reviewed unpinned adapter: drive.get_cover has no singular pinned interface_ref; --node is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"drive.get_star_list --content-types": "Reviewed unpinned adapter: drive.get_star_list has no singular pinned interface_ref; --content-types is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"drive.get_star_list --cursor": "Reviewed unpinned adapter: drive.get_star_list has no singular pinned interface_ref; --cursor is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"drive.get_star_list --limit": "Reviewed unpinned adapter: drive.get_star_list has no singular pinned interface_ref; --limit is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"drive.get_star_list --order-by": "Reviewed unpinned adapter: drive.get_star_list has no singular pinned interface_ref; --order-by is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"drive.get_star_list --resource-types": "Reviewed unpinned adapter: drive.get_star_list has no singular pinned interface_ref; --resource-types is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"drive.get_star_list --sort": "Reviewed unpinned adapter: drive.get_star_list has no singular pinned interface_ref; --sort is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"drive.mark_star --node": "Reviewed unpinned adapter: drive.mark_star has no singular pinned interface_ref; --node is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"drive.query_permission_apply_info --node": "Reviewed unpinned adapter: drive.query_permission_apply_info has no singular pinned interface_ref; --node is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"drive.revert_file_version --node": "Reviewed unpinned adapter: drive.revert_file_version has no singular pinned interface_ref; --node is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"drive.revert_file_version --version": "Reviewed unpinned adapter: drive.revert_file_version has no singular pinned interface_ref; --version is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"drive.transfer_owner --new-owner": "Reviewed unpinned adapter: drive.transfer_owner has no singular pinned interface_ref; --new-owner is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"drive.transfer_owner --node": "Reviewed unpinned adapter: drive.transfer_owner has no singular pinned interface_ref; --node is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"drive.transfer_owner --recursive": "Reviewed unpinned adapter: drive.transfer_owner has no singular pinned interface_ref; --recursive is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"drive.transfer_owner --reserve-role": "Reviewed unpinned adapter: drive.transfer_owner has no singular pinned interface_ref; --reserve-role is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"drive.transfer_owner --workspace": "Reviewed unpinned adapter: drive.transfer_owner has no singular pinned interface_ref; --workspace is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"drive.unmark_star --node": "Reviewed unpinned adapter: drive.unmark_star has no singular pinned interface_ref; --node is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.create_sheet_comment --content": "Reviewed unpinned adapter: sheet.create_sheet_comment has no singular pinned interface_ref; --content is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.create_sheet_comment --mention": "Reviewed unpinned adapter: sheet.create_sheet_comment has no singular pinned interface_ref; --mention is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.create_sheet_comment --node": "Reviewed unpinned adapter: sheet.create_sheet_comment has no singular pinned interface_ref; --node is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.create_sheet_comment --range": "Reviewed unpinned adapter: sheet.create_sheet_comment has no singular pinned interface_ref; --range is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.create_sheet_comment --sheet-id": "Reviewed unpinned adapter: sheet.create_sheet_comment has no singular pinned interface_ref; --sheet-id is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.delete_sheet_comment --comment-key": "Reviewed unpinned adapter: sheet.delete_sheet_comment has no singular pinned interface_ref; --comment-key is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.delete_sheet_comment --node": "Reviewed unpinned adapter: sheet.delete_sheet_comment has no singular pinned interface_ref; --node is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.formula_verify --max-cells": "Reviewed unpinned adapter: sheet.formula_verify has no singular pinned interface_ref; --max-cells is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.formula_verify --max-locations-per-error": "Reviewed unpinned adapter: sheet.formula_verify has no singular pinned interface_ref; --max-locations-per-error is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.formula_verify --node": "Reviewed unpinned adapter: sheet.formula_verify has no singular pinned interface_ref; --node is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.formula_verify --range": "Reviewed unpinned adapter: sheet.formula_verify has no singular pinned interface_ref; --range is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.formula_verify --sheet-id": "Reviewed unpinned adapter: sheet.formula_verify has no singular pinned interface_ref; --sheet-id is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.formula_verify --targets": "Reviewed unpinned adapter: sheet.formula_verify has no singular pinned interface_ref; --targets is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.list_sheet_comments --cursor": "Reviewed unpinned adapter: sheet.list_sheet_comments has no singular pinned interface_ref; --cursor is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.list_sheet_comments --limit": "Reviewed unpinned adapter: sheet.list_sheet_comments has no singular pinned interface_ref; --limit is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.list_sheet_comments --node": "Reviewed unpinned adapter: sheet.list_sheet_comments has no singular pinned interface_ref; --node is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.list_sheet_comments --range": "Reviewed unpinned adapter: sheet.list_sheet_comments has no singular pinned interface_ref; --range is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.list_sheet_comments --resolve-status": "Reviewed unpinned adapter: sheet.list_sheet_comments has no singular pinned interface_ref; --resolve-status is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.list_sheet_comments --sheet-id": "Reviewed unpinned adapter: sheet.list_sheet_comments has no singular pinned interface_ref; --sheet-id is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.reply_sheet_comment --comment-key": "Reviewed unpinned adapter: sheet.reply_sheet_comment has no singular pinned interface_ref; --comment-key is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.reply_sheet_comment --content": "Reviewed unpinned adapter: sheet.reply_sheet_comment has no singular pinned interface_ref; --content is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.reply_sheet_comment --emoji": "Reviewed unpinned adapter: sheet.reply_sheet_comment has no singular pinned interface_ref; --emoji is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.reply_sheet_comment --mention": "Reviewed unpinned adapter: sheet.reply_sheet_comment has no singular pinned interface_ref; --mention is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.reply_sheet_comment --node": "Reviewed unpinned adapter: sheet.reply_sheet_comment has no singular pinned interface_ref; --node is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.update_sheet_comment --comment-key": "Reviewed unpinned adapter: sheet.update_sheet_comment has no singular pinned interface_ref; --comment-key is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.update_sheet_comment --content": "Reviewed unpinned adapter: sheet.update_sheet_comment has no singular pinned interface_ref; --content is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.update_sheet_comment --node": "Reviewed unpinned adapter: sheet.update_sheet_comment has no singular pinned interface_ref; --node is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.version_list --cursor": "Reviewed unpinned adapter: sheet.version_list has no singular pinned interface_ref; --cursor is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.version_list --limit": "Reviewed unpinned adapter: sheet.version_list has no singular pinned interface_ref; --limit is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.version_list --node": "Reviewed unpinned adapter: sheet.version_list has no singular pinned interface_ref; --node is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.version_revert --node": "Reviewed unpinned adapter: sheet.version_revert has no singular pinned interface_ref; --node is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.version_revert --version": "Reviewed unpinned adapter: sheet.version_revert has no singular pinned interface_ref; --version is a CLI wrapper input and does not publish a direct interface property.",
|
||||
"sheet.version_save --node": "Reviewed unpinned adapter: sheet.version_save has no singular pinned interface_ref; --node is a CLI wrapper input and does not publish a direct interface property."
|
||||
}
|
||||
}
|
||||
@@ -2901,7 +2901,7 @@ CLI 内部自动完成全部流程:
|
||||
folderCmd.Hidden = true
|
||||
permissionCmd.Hidden = true
|
||||
|
||||
root.AddCommand(searchCmd, listCmd, infoCmd, readCmd, createCmd, updateCmd, uploadCmd, downloadCmd, copyCmd, moveCmd, renameCmd, deleteCmd, fileCmd, folderCmd, blockCmd, commentCmd, mediaCmd, permissionCmd, exportCmd, importCmd, versionCmd, templateCmd)
|
||||
root.AddCommand(searchCmd, listCmd, infoCmd, readCmd, createCmd, updateCmd, uploadCmd, downloadCmd, copyCmd, moveCmd, renameCmd, deleteCmd, fileCmd, folderCmd, blockCmd, commentCmd, mediaCmd, permissionCmd, exportCmd, importCmd, versionCmd, templateCmd, newDocStyleCommand())
|
||||
|
||||
return root
|
||||
}
|
||||
|
||||
@@ -0,0 +1,312 @@
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// doc_style.go — `dws doc style`(文档封面/背景样式配置)。
|
||||
// 写入收口到 MCP 工具 update_document_style;读取用 get_document_style。
|
||||
|
||||
const docStyleToolName = "update_document_style"
|
||||
|
||||
const docStyleGetToolName = "get_document_style"
|
||||
|
||||
// newDocStyleCommand 构建 `dws doc style` 命令组:cover set|clear、background set|clear、get。
|
||||
func newDocStyleCommand() *cobra.Command {
|
||||
styleCmd := &cobra.Command{
|
||||
Use: "style",
|
||||
Short: "文档样式配置 (封面/背景)",
|
||||
Long: `配置钉钉文档的封面与背景(单接口收口 update_document_style)。
|
||||
|
||||
命令结构:
|
||||
dws doc style cover set 设置文档封面
|
||||
dws doc style cover clear 移除文档封面
|
||||
dws doc style background set 设置文档背景纯色
|
||||
dws doc style background clear 清除文档背景
|
||||
dws doc style get 读取文档封面/背景 (只读)
|
||||
|
||||
封面图片支持 --image 外链 (自动转存) 或 --file 本地文件上传,均会转存为公开读地址;背景仅支持 --color 纯色。`,
|
||||
RunE: groupRunE,
|
||||
}
|
||||
|
||||
coverCmd := &cobra.Command{
|
||||
Use: "cover",
|
||||
Short: "文档封面设置/移除",
|
||||
RunE: groupRunE,
|
||||
}
|
||||
coverSetCmd := &cobra.Command{
|
||||
Use: "set",
|
||||
Short: "设置文档封面",
|
||||
Long: `为钉钉文档设置顶部封面图,可指定竖直显示位置。图片来源二选一:--image 外链或 --file 本地文件。`,
|
||||
Example: ` dws doc style cover set --node DOC_ID --image https://img.example.com/cover.png
|
||||
dws doc style cover set --node DOC_ID --file ./cover.png --position 0.3`,
|
||||
RunE: runDocStyleCoverSet,
|
||||
}
|
||||
coverClearCmd := &cobra.Command{
|
||||
Use: "clear",
|
||||
Short: "移除文档封面",
|
||||
Example: ` dws doc style cover clear --node DOC_ID`,
|
||||
RunE: runDocStyleCoverClear,
|
||||
}
|
||||
|
||||
backgroundCmd := &cobra.Command{
|
||||
Use: "background",
|
||||
Short: "文档背景设置/清除",
|
||||
RunE: groupRunE,
|
||||
}
|
||||
backgroundSetCmd := &cobra.Command{
|
||||
Use: "set",
|
||||
Short: "设置文档背景纯色",
|
||||
Long: `为钉钉文档设置背景纯色(--color)。背景仅支持纯色,不支持背景图片上传(对齐前端能力)。`,
|
||||
Example: ` dws doc style background set --node DOC_ID --color "#E8F2FE"`,
|
||||
RunE: runDocStyleBackgroundSet,
|
||||
}
|
||||
backgroundClearCmd := &cobra.Command{
|
||||
Use: "clear",
|
||||
Short: "清除文档背景",
|
||||
Example: ` dws doc style background clear --node DOC_ID`,
|
||||
RunE: runDocStyleBackgroundClear,
|
||||
}
|
||||
getCmd := &cobra.Command{
|
||||
Use: "get",
|
||||
Short: "读取文档封面/背景 (只读)",
|
||||
Long: `读取钉钉文档当前的封面与背景配置(只读,单接口收口 get_document_style)。`,
|
||||
Example: ` dws doc style get --node DOC_ID`,
|
||||
RunE: runDocStyleGet,
|
||||
}
|
||||
|
||||
// cover set flags
|
||||
coverSetCmd.Flags().String("node", "", "目标文档标识,支持 URL 或 ID (必填)")
|
||||
coverSetCmd.Flags().String("image", "", "封面图片 URL (外链会自动转存为内部地址)")
|
||||
coverSetCmd.Flags().String("file", "", "本地图片文件路径 (与 --image 互斥)")
|
||||
coverSetCmd.Flags().Float64("position", 0.5, "封面竖直位置 [0,1],默认 0.5")
|
||||
coverSetCmd.MarkFlagsMutuallyExclusive("image", "file")
|
||||
|
||||
// cover clear flags
|
||||
coverClearCmd.Flags().String("node", "", "目标文档标识,支持 URL 或 ID (必填)")
|
||||
|
||||
// background set flags(仅纯色,对齐前端;不支持背景图片上传)
|
||||
backgroundSetCmd.Flags().String("node", "", "目标文档标识,支持 URL 或 ID (必填)")
|
||||
backgroundSetCmd.Flags().String("color", "", "背景纯色,如 #E8F2FE (必填)")
|
||||
|
||||
// background clear flags
|
||||
backgroundClearCmd.Flags().String("node", "", "目标文档标识,支持 URL 或 ID (必填)")
|
||||
|
||||
// get flags
|
||||
getCmd.Flags().String("node", "", "目标文档标识,支持 URL 或 ID (必填)")
|
||||
|
||||
// --node 隐藏别名 (--url/--id/--node-id/--doc-id/--file-id)
|
||||
for _, c := range []*cobra.Command{coverSetCmd, coverClearCmd, backgroundSetCmd, backgroundClearCmd, getCmd} {
|
||||
c.Flags().String("url", "", "--node 的别名")
|
||||
c.Flags().String("id", "", "--node 的别名")
|
||||
c.Flags().String("node-id", "", "--node 的别名")
|
||||
c.Flags().String("doc-id", "", "--node 的别名")
|
||||
c.Flags().String("file-id", "", "--node 的别名 (跨产品兼容 drive)")
|
||||
_ = c.Flags().MarkHidden("url")
|
||||
_ = c.Flags().MarkHidden("id")
|
||||
_ = c.Flags().MarkHidden("node-id")
|
||||
_ = c.Flags().MarkHidden("doc-id")
|
||||
_ = c.Flags().MarkHidden("file-id")
|
||||
}
|
||||
|
||||
coverCmd.AddCommand(coverSetCmd, coverClearCmd)
|
||||
backgroundCmd.AddCommand(backgroundSetCmd, backgroundClearCmd)
|
||||
styleCmd.AddCommand(coverCmd, backgroundCmd, getCmd)
|
||||
|
||||
// 递归注册跨产品别名,让 cover set 的 --file 获得统一别名 --file-path。
|
||||
registerCrossProductAliasesRecursive(styleCmd)
|
||||
return styleCmd
|
||||
}
|
||||
|
||||
// registerCrossProductAliasesRecursive 递归为 cmd 及其所有子命令注册跨产品别名。
|
||||
// 可正确处理多层分组(如 style 的 cover/background 组下还有 set/clear 叶子)。
|
||||
func registerCrossProductAliasesRecursive(cmd *cobra.Command) {
|
||||
RegisterCrossProductAliases(cmd)
|
||||
for _, sub := range cmd.Commands() {
|
||||
registerCrossProductAliasesRecursive(sub)
|
||||
}
|
||||
}
|
||||
|
||||
// docStyleNodeID 解析目标文档标识,支持 --node 及隐藏别名。
|
||||
func docStyleNodeID(cmd *cobra.Command) (string, error) {
|
||||
return mustFlagOrFallback(cmd, "node", "url", "id", "node-id", "doc-id", "file-id")
|
||||
}
|
||||
|
||||
func runDocStyleCoverSet(cmd *cobra.Command, _ []string) error {
|
||||
nodeID, err := docStyleNodeID(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 封面图片来源二选一:--image 外链(服务端转存公开)或 --file 本地上传(拿 resourceId 转存公开)。
|
||||
image, _ := cmd.Flags().GetString("image")
|
||||
filePath := flagOrFallback(cmd, "file", "file-path")
|
||||
// --image 与 --file/--file-path 互斥。cobra 的 MarkFlagsMutuallyExclusive 只认主名
|
||||
// image/file,拦不住别名 --file-path,故在此显式兜底。
|
||||
if image != "" && filePath != "" {
|
||||
return fmt.Errorf("--image and --file/--file-path are mutually exclusive; specify only one")
|
||||
}
|
||||
if image == "" && filePath == "" {
|
||||
return fmt.Errorf("flag --image or --file is required for `cover set`")
|
||||
}
|
||||
|
||||
cover := map[string]any{"action": "set"}
|
||||
// position 客户端校验:帮助文档承诺 [0,1],越界直接报错,避免触发上传/请求。
|
||||
if cmd.Flags().Changed("position") {
|
||||
pos, _ := cmd.Flags().GetFloat64("position")
|
||||
if pos < 0 || pos > 1 {
|
||||
return fmt.Errorf("--position must be within [0,1], got %v", pos)
|
||||
}
|
||||
cover["position"] = pos
|
||||
}
|
||||
|
||||
if image != "" {
|
||||
cover["imageUrl"] = image
|
||||
} else {
|
||||
// --file:先做本地校验(存在 + 必须为图片);dry-run 时在上传前短路,
|
||||
// 绝不读取/上传本地文件。
|
||||
mimeType, fileSize, err := validateCoverImageFile(filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if deps.Caller.DryRun() {
|
||||
cover["resourceId"] = fmt.Sprintf("(pending upload from --file %s)", filePath)
|
||||
} else {
|
||||
resourceID, err := uploadDocStyleImage(context.Background(), nodeID, filePath, filepath.Base(filePath), mimeType, fileSize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cover["resourceId"] = resourceID
|
||||
}
|
||||
}
|
||||
|
||||
return callMCPToolOnServer("doc", docStyleToolName, map[string]any{
|
||||
"nodeId": nodeID,
|
||||
"cover": cover,
|
||||
})
|
||||
}
|
||||
|
||||
func runDocStyleCoverClear(cmd *cobra.Command, _ []string) error {
|
||||
nodeID, err := docStyleNodeID(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return callMCPToolOnServer("doc", docStyleToolName, map[string]any{
|
||||
"nodeId": nodeID,
|
||||
"cover": map[string]any{"action": "clear"},
|
||||
})
|
||||
}
|
||||
|
||||
func runDocStyleBackgroundSet(cmd *cobra.Command, _ []string) error {
|
||||
nodeID, err := docStyleNodeID(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 背景仅支持纯色(对齐前端,不支持背景图片上传)。
|
||||
color, _ := cmd.Flags().GetString("color")
|
||||
if color == "" {
|
||||
return fmt.Errorf("flag --color is required for `background set`")
|
||||
}
|
||||
// 帮助文档承诺 #RRGGBB 十六进制纯色,非法值直接报错,不下发请求。
|
||||
if !isHexColor(color) {
|
||||
return fmt.Errorf("--color must be a hex color like #E8F2FE, got %q", color)
|
||||
}
|
||||
return callMCPToolOnServer("doc", docStyleToolName, map[string]any{
|
||||
"nodeId": nodeID,
|
||||
"background": map[string]any{
|
||||
"action": "set",
|
||||
"backgroundColor": color,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func runDocStyleBackgroundClear(cmd *cobra.Command, _ []string) error {
|
||||
nodeID, err := docStyleNodeID(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return callMCPToolOnServer("doc", docStyleToolName, map[string]any{
|
||||
"nodeId": nodeID,
|
||||
"background": map[string]any{"action": "clear"},
|
||||
})
|
||||
}
|
||||
|
||||
// runDocStyleGet 读取文档当前封面/背景(只读)。
|
||||
func runDocStyleGet(cmd *cobra.Command, _ []string) error {
|
||||
nodeID, err := docStyleNodeID(cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return callMCPToolOnServer("doc", docStyleGetToolName, map[string]any{
|
||||
"nodeId": nodeID,
|
||||
})
|
||||
}
|
||||
|
||||
// validateCoverImageFile 对 cover set --file 做本地校验(不上传/不读取文件内容):
|
||||
// 文件须存在、非目录,且按扩展名推断的 MIME 必须为 image/*。返回 mimeType 与文件大小,
|
||||
// 供 dry-run 预览与真实上传前 fail-fast,避免非法文件被先行上传。
|
||||
func validateCoverImageFile(filePath string) (mimeType string, fileSize int64, err error) {
|
||||
fileInfo, err := os.Stat(filePath)
|
||||
if err != nil {
|
||||
return "", 0, fmt.Errorf("cannot read file %s: %w", filePath, err)
|
||||
}
|
||||
if fileInfo.IsDir() {
|
||||
return "", 0, fmt.Errorf("%s is a directory, not a file", filePath)
|
||||
}
|
||||
mimeType = inferMimeType(filepath.Base(filePath))
|
||||
if !strings.HasPrefix(mimeType, "image/") {
|
||||
return "", 0, fmt.Errorf("cover --file must be an image (png/jpg/jpeg/gif/svg/webp), got %s", filepath.Base(filePath))
|
||||
}
|
||||
return mimeType, fileInfo.Size(), nil
|
||||
}
|
||||
|
||||
// isHexColor 校验 #RRGGBB 形式的十六进制颜色(大小写均可)。
|
||||
func isHexColor(s string) bool {
|
||||
if len(s) != 7 || s[0] != '#' {
|
||||
return false
|
||||
}
|
||||
for _, c := range s[1:] {
|
||||
switch {
|
||||
case c >= '0' && c <= '9', c >= 'a' && c <= 'f', c >= 'A' && c <= 'F':
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// uploadDocStyleImage 复用附件上传子流程(get_doc_attachment_upload_info + httpPutFile),
|
||||
// 上传本地文件为鉴权资源,返回其 resourceId(供封面在服务端转存为公开读地址)。
|
||||
// 入参 mimeType/fileSize 由调用方经 validateCoverImageFile 预校验得到;进度写 stderr,
|
||||
// 保证 --format json 时 stdout 只含合法 JSON。本函数一定发起网络请求,调用方须自行做 dry-run 短路。
|
||||
func uploadDocStyleImage(ctx context.Context, nodeID, filePath, fileName, mimeType string, fileSize int64) (string, error) {
|
||||
deps.Out.PrintProgress(fmt.Sprintf("[1/2] 获取图片上传凭证 (%s, %d bytes)...", fileName, fileSize))
|
||||
credText, err := callMCPToolReturnTextOnServer(ctx, "doc", "get_doc_attachment_upload_info", map[string]any{
|
||||
"nodeId": nodeID,
|
||||
"fileName": fileName,
|
||||
"fileSize": float64(fileSize),
|
||||
"mimeType": mimeType,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
uploadURL, resourceID, _, err := parseAttachmentUploadInfo(credText)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
deps.Out.PrintProgress("[2/2] 上传图片到 OSS...")
|
||||
ossHeaders := map[string]string{"Content-Type": mimeType}
|
||||
if err := httpPutFile(ctx, uploadURL, ossHeaders, filePath, fileSize); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if resourceID == "" {
|
||||
return "", fmt.Errorf("upload succeeded but no resourceId returned for %s", fileName)
|
||||
}
|
||||
return resourceID, nil
|
||||
}
|
||||
@@ -302,6 +302,15 @@ func newDriveCommand() *cobra.Command {
|
||||
dws drive list --workspace <workspaceId>
|
||||
dws drive list --workspace <workspaceId> --folder <folderId>`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
pattern, _ := cmd.Flags().GetString("pattern")
|
||||
|
||||
depth, _ := cmd.Flags().GetInt("depth")
|
||||
if cmd.Flags().Changed("depth") {
|
||||
if err := validateDriveListDepth(cmd, depth); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// --versions 模式:列出文件历史版本(仅普通文件)
|
||||
if cmd.Flags().Changed("versions") {
|
||||
nodeID, err := mustFlagOrFallback(cmd, "node", "url", "id", "node-id", "doc-id", "file-id")
|
||||
@@ -321,6 +330,25 @@ func newDriveCommand() *cobra.Command {
|
||||
// 如果指定了 --workspace,路由到文档空间(doc MCP server)
|
||||
workspaceID := flagOrFallback(cmd, "workspace", "workspace-id")
|
||||
if workspaceID != "" {
|
||||
// depth>1 时 --pattern 放开(先递归后过滤);--order-by/--space-id/--thumbnail
|
||||
// 知识库无对应参数,静默忽略。
|
||||
if depth > 1 {
|
||||
quiet, _ := cmd.Flags().GetBool("quiet")
|
||||
baseArgs := map[string]any{"workspaceId": workspaceID}
|
||||
rootFolder := docFolderFlag(cmd, "node", "file-id")
|
||||
if rootFolder != "" {
|
||||
if err := validateDocFolderID(rootFolder); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return runDriveListDepth(cmd, newDocDepthRoute(), baseArgs, rootFolder, depth, pattern, quiet)
|
||||
}
|
||||
if pattern != "" {
|
||||
return &CLIError{
|
||||
Code: CodeInvalidParam,
|
||||
Message: "--pattern 仅适用于钉盘文件列表,不能与 --workspace 同时使用",
|
||||
}
|
||||
}
|
||||
toolArgs := map[string]any{"workspaceId": workspaceID}
|
||||
if folder := docFolderFlag(cmd, "node", "file-id"); folder != "" {
|
||||
if err := validateDocFolderID(folder); err != nil {
|
||||
@@ -337,6 +365,30 @@ func newDriveCommand() *cobra.Command {
|
||||
return callMCPToolOnServer("doc", "list_nodes", toolArgs)
|
||||
}
|
||||
|
||||
if depth > 1 {
|
||||
quiet, _ := cmd.Flags().GetBool("quiet")
|
||||
baseArgs := map[string]any{}
|
||||
if v, _ := cmd.Flags().GetString("space-id"); v != "" {
|
||||
baseArgs["spaceId"] = v
|
||||
}
|
||||
if v, _ := cmd.Flags().GetString("order-by"); v != "" {
|
||||
baseArgs["orderBy"] = v
|
||||
}
|
||||
if v, _ := cmd.Flags().GetString("order"); v != "" {
|
||||
baseArgs["order"] = v
|
||||
}
|
||||
if v, _ := cmd.Flags().GetBool("thumbnail"); v {
|
||||
baseArgs["withThumbnail"] = true
|
||||
}
|
||||
rootFolder := flagOrFallback(cmd, "folder", "parent-id")
|
||||
if rootFolder != "" {
|
||||
if err := validateDriveParentID(rootFolder); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return runDriveListDepth(cmd, newDrivePanDepthRoute(), baseArgs, rootFolder, depth, pattern, quiet)
|
||||
}
|
||||
|
||||
// 默认路由:钉盘文件列表
|
||||
maxResults, _ := cmd.Flags().GetInt("limit")
|
||||
if !cmd.Flags().Changed("limit") {
|
||||
@@ -564,7 +616,10 @@ func newDriveCommand() *cobra.Command {
|
||||
driveListCmd.Flags().String("order", "", "排序方向: asc|desc,默认 desc (可选,仅钉盘)")
|
||||
driveListCmd.Flags().Bool("thumbnail", false, "是否返回缩略图信息 (可选,仅钉盘)")
|
||||
driveListCmd.Flags().Bool("versions", false, "列出文件历史版本而非文件列表 (需配合 --node)")
|
||||
driveListCmd.Flags().String("node", "", "文件 ID (dentryUuid) 或 URL (--versions 模式必填)")
|
||||
driveListCmd.Flags().String("node", "", "文件 ID (dentryUuid) 或 URL (--versions 模式下必填)")
|
||||
driveListCmd.Flags().String("pattern", "", "按名称通配过滤结果,如 \"*日报*\" (客户端过滤) (可选)")
|
||||
driveListCmd.Flags().Int("depth", 1, "递归列出子目录层级,默认 1(仅当前层),最大 5;与 --cursor/--limit 互斥;与 --workspace 组合时走知识库递归 (可选)")
|
||||
driveListCmd.Flags().Bool("quiet", false, "关闭递归进度输出(stderr),不影响 stdout JSON (仅 --depth>1 时有效) (可选)")
|
||||
|
||||
driveInfoCmd.Flags().String("node", "", "节点 ID (dentryUuid) (必填)")
|
||||
driveInfoCmd.Flags().String("space-id", "", "节点所属空间 ID (可选)")
|
||||
@@ -1180,7 +1235,11 @@ func newDriveCommand() *cobra.Command {
|
||||
reserveRole := mustGetFlag(cmd, "reserve-role")
|
||||
recursive, _ := cmd.Flags().GetBool("recursive")
|
||||
|
||||
if !yesMode && !confirmDelete("转交所有者", nodeID+workspaceID) {
|
||||
target := nodeID
|
||||
if target == "" {
|
||||
target = workspaceID
|
||||
}
|
||||
if !yesMode && !confirmDangerousAction(cmd, "转交所有者", target) {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1193,8 +1252,8 @@ func newDriveCommand() *cobra.Command {
|
||||
if reserveRole != "" {
|
||||
toolArgs["reserveOldOwnerRole"] = reserveRole
|
||||
}
|
||||
if recursive {
|
||||
toolArgs["recursiveChange"] = true
|
||||
if cmd.Flags().Changed("recursive") {
|
||||
toolArgs["recursiveChange"] = recursive
|
||||
}
|
||||
return callMCPToolOnServer("doc", "transfer_owner", toolArgs)
|
||||
},
|
||||
@@ -1204,7 +1263,6 @@ func newDriveCommand() *cobra.Command {
|
||||
drivePermTransferOwnerCmd.Flags().String("new-owner", "", "新所有者的用户 userId (必填)")
|
||||
drivePermTransferOwnerCmd.Flags().String("reserve-role", "", "转交后原所有者保留角色: MANAGER / EDITOR / DOWNLOADER / READER / NONE")
|
||||
drivePermTransferOwnerCmd.Flags().Bool("recursive", false, "是否递归变更所有子节点的所有者")
|
||||
drivePermTransferOwnerCmd.Flags().Bool("yes", false, "跳过确认提示")
|
||||
|
||||
drivePermApplyInfoCmd := &cobra.Command{
|
||||
Use: "apply-info",
|
||||
@@ -1635,7 +1693,7 @@ func newDriveCommand() *cobra.Command {
|
||||
if err != nil || versionNum <= 0 {
|
||||
return fmt.Errorf("flag --version is required and must be a positive integer")
|
||||
}
|
||||
if !commandDryRun(cmd) && !confirmDelete("回滚文件版本", fmt.Sprintf("节点 %s 回滚到版本 %d", nodeID, versionNum)) {
|
||||
if !commandDryRun(cmd) && !confirmDangerousAction(cmd, "回滚文件版本", fmt.Sprintf("节点 %s 回滚到版本 %d", nodeID, versionNum)) {
|
||||
return nil
|
||||
}
|
||||
return callMCPToolOnServer("drive", "revert_file_version", map[string]any{
|
||||
@@ -1646,7 +1704,6 @@ func newDriveCommand() *cobra.Command {
|
||||
}
|
||||
driveRevertCmd.Flags().String("node", "", "文件 ID (dentryUuid) 或 URL (必填)")
|
||||
driveRevertCmd.Flags().Int("version", 0, "要回滚到的历史版本号 (必填,正整数)")
|
||||
driveRevertCmd.Flags().Bool("yes", false, "跳过确认提示")
|
||||
|
||||
driveCmd.AddCommand(
|
||||
driveListCmd,
|
||||
|
||||
@@ -0,0 +1,557 @@
|
||||
package helpers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// ──────────────────────────────────────────────────────────
|
||||
// drive list --depth 递归编排(BFS + 限流补偿)
|
||||
//
|
||||
// 服务端无递归 API,CLI 侧 BFS 过渡方案;服务端递归 API 上线后本块整体退役。
|
||||
// 钉盘(list_files)与知识库(list_nodes)共用一份路由无关骨架,差异收敛在 driveDepthRoute。
|
||||
// ──────────────────────────────────────────────────────────
|
||||
|
||||
const (
|
||||
// 50 来源于服务端 MAX_PAGE_SIZE 硬校验(超限抛错不 clamp),服务端放宽后仅需修改此常量。
|
||||
driveDepthPageSize = 50
|
||||
// 来源与 driveDepthPageSize 不同(list_nodes pageSize 上限),数值碰巧相同但不合并。
|
||||
docDepthPageSize = 50
|
||||
// API 调用数随目录宽度指数增长,超过报错不 clamp。
|
||||
driveDepthMax = 5
|
||||
driveDepthMaxItems = 2000
|
||||
// Sentinel 限流以 HTTP 200 + body errorCode 返回,transport 层不会自动重试,补偿只能在 BFS 层做。
|
||||
driveDepthRateLimitedCode = "invalidRequest.rateLimited"
|
||||
driveDepthCancelledMsg = "cancelled by user, partial result emitted"
|
||||
)
|
||||
|
||||
type driveDepthFolder struct {
|
||||
id string // 钉盘 dentryUuid / 知识库 nodeId
|
||||
name string
|
||||
depth int
|
||||
relPath string
|
||||
retried bool // 已因 rate_limited 重新入队过一次,不二次补偿
|
||||
}
|
||||
|
||||
type driveDepthError struct {
|
||||
Depth int `json:"depth"`
|
||||
FolderID string `json:"folderId"`
|
||||
FolderName string `json:"folderName"`
|
||||
Reason string `json:"reason"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// 取消不是错误:不记 errors[]、不复用 1~6 退出码,固定 130(128+SIGINT)。
|
||||
type driveDepthCancelledError struct{}
|
||||
|
||||
func (e *driveDepthCancelledError) Error() string { return driveDepthCancelledMsg }
|
||||
func (e *driveDepthCancelledError) RawStderr() string { return driveDepthCancelledMsg }
|
||||
func (e *driveDepthCancelledError) ExitCode() int { return 130 }
|
||||
|
||||
// depth==1 走原有单层路径,仅做范围校验,不触发互斥检查。
|
||||
func validateDriveListDepth(cmd *cobra.Command, depth int) error {
|
||||
if depth < 1 {
|
||||
return &CLIError{
|
||||
Code: CodeInvalidParam,
|
||||
Message: fmt.Sprintf("--depth 必须为 1~%d 的整数,当前: %d", driveDepthMax, depth),
|
||||
}
|
||||
}
|
||||
if depth > driveDepthMax {
|
||||
// 不 clamp:静默 clamp 会让用户误以为拿到了完整树。
|
||||
return &CLIError{
|
||||
Code: CodeInvalidParam,
|
||||
Message: fmt.Sprintf("DEPTH_EXCEED_MAX: --depth 最大为 %d,当前: %d(API 调用数随目录宽度指数增长,不做静默 clamp)", driveDepthMax, depth),
|
||||
}
|
||||
}
|
||||
if depth == 1 {
|
||||
return nil
|
||||
}
|
||||
// --workspace 不互斥:depth>1 时作为路由开关切到知识库 BFS。
|
||||
if v := flagOrFallback(cmd, "cursor", "next-token"); v != "" {
|
||||
return driveDepthExclusiveError("cursor", "depth>1 时多文件夹合成一份清单,无连续游标")
|
||||
}
|
||||
if cmd.Flags().Changed("limit") || cmd.Flags().Changed("max") {
|
||||
return driveDepthExclusiveError("limit", "递归模式数据量由全局上限 2000 与 --depth 层数控制")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func driveDepthExclusiveError(flag, reason string) error {
|
||||
return &CLIError{
|
||||
Code: CodeInvalidParam,
|
||||
Message: fmt.Sprintf("--depth 不能与 --%s 同时使用:%s", flag, reason),
|
||||
}
|
||||
}
|
||||
|
||||
// 路由绑定差异全部收敛在此,BFS 主循环保持路由无关。
|
||||
type driveDepthRoute struct {
|
||||
serverID string // ""=钉盘自动路由 / "doc"=知识库
|
||||
toolName string
|
||||
pageSize int
|
||||
// 钉盘契约无 hasMore 字段,只信空 nextToken;知识库契约含 hasMore,显式 false 即停。
|
||||
// 钉盘的 hasMore 仅用于「hasMore=true 但 token 为空」异常检测。
|
||||
hasMoreAuthoritative bool
|
||||
buildArgs func(base map[string]any, folderID, pageToken string) map[string]any
|
||||
parsePage func(text string) (items []map[string]any, nextToken string, hasMore bool)
|
||||
isFolder func(item map[string]any) bool
|
||||
itemID func(item map[string]any) string
|
||||
}
|
||||
|
||||
func (r driveDepthRoute) fetchPage(ctx context.Context, args map[string]any) (string, error) {
|
||||
if r.serverID == "" {
|
||||
return callMCPToolReturnText(ctx, r.toolName, args)
|
||||
}
|
||||
return callMCPToolReturnTextOnServer(ctx, r.serverID, r.toolName, args)
|
||||
}
|
||||
|
||||
func newDrivePanDepthRoute() driveDepthRoute {
|
||||
return driveDepthRoute{
|
||||
serverID: "",
|
||||
toolName: "list_files",
|
||||
pageSize: driveDepthPageSize,
|
||||
hasMoreAuthoritative: false,
|
||||
buildArgs: func(base map[string]any, folderID, pageToken string) map[string]any {
|
||||
args := map[string]any{"maxResults": float64(driveDepthPageSize)}
|
||||
for k, v := range base {
|
||||
args[k] = v
|
||||
}
|
||||
if folderID != "" {
|
||||
args["parentId"] = folderID
|
||||
}
|
||||
if pageToken != "" {
|
||||
args["nextToken"] = pageToken
|
||||
}
|
||||
return args
|
||||
},
|
||||
parsePage: parseDriveDepthPage,
|
||||
isFolder: isDriveDepthFolder,
|
||||
itemID: func(item map[string]any) string {
|
||||
id, _ := item["fileId"].(string)
|
||||
return id
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// folderId 为空 = 知识库根。
|
||||
func newDocDepthRoute() driveDepthRoute {
|
||||
return driveDepthRoute{
|
||||
serverID: "doc",
|
||||
toolName: "list_nodes",
|
||||
pageSize: docDepthPageSize,
|
||||
// 字段缺失(契约违背)时按停处理——保守方向,宁可少翻页不空转。
|
||||
hasMoreAuthoritative: true,
|
||||
buildArgs: func(base map[string]any, folderID, pageToken string) map[string]any {
|
||||
args := map[string]any{"pageSize": float64(docDepthPageSize)}
|
||||
for k, v := range base {
|
||||
args[k] = v
|
||||
}
|
||||
if folderID != "" {
|
||||
args["folderId"] = folderID
|
||||
}
|
||||
if pageToken != "" {
|
||||
args["pageToken"] = pageToken
|
||||
}
|
||||
return args
|
||||
},
|
||||
parsePage: parseDocDepthPage,
|
||||
isFolder: isDocDepthFolder,
|
||||
itemID: func(item map[string]any) string {
|
||||
id, _ := item["nodeId"].(string)
|
||||
return id
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// SIGINT 检查两点(出队后发首页前 + 翻页循环发每页前),入队是纯内存操作不检查。
|
||||
func runDriveListDepth(cmd *cobra.Command, route driveDepthRoute, baseArgs map[string]any, rootFolderID string, maxDepth int, pattern string, quiet bool) error {
|
||||
if deps.Caller.DryRun() {
|
||||
return printDriveDepthDryRun(route, baseArgs, maxDepth)
|
||||
}
|
||||
|
||||
parent := cmd.Context()
|
||||
if parent == nil {
|
||||
parent = context.Background()
|
||||
}
|
||||
ctx, stop := signal.NotifyContext(parent, os.Interrupt)
|
||||
defer stop()
|
||||
|
||||
// 兜底服务端「空页 + 非空游标」类 bug:该形态下条目不增长、全局 2000 永不触发。
|
||||
// 不用「token 不推进即停」:兜不住每页 token 都不同的空页流。
|
||||
maxPagesPerFolder := driveDepthMaxItems/route.pageSize + 1
|
||||
|
||||
traceID := fmt.Sprintf("drive-depth-%d", time.Now().UnixNano())
|
||||
var (
|
||||
collected []map[string]any
|
||||
errs = make([]driveDepthError, 0)
|
||||
truncated bool
|
||||
visited = map[string]bool{}
|
||||
)
|
||||
queue := []driveDepthFolder{{id: rootFolderID, depth: 0}}
|
||||
if rootFolderID != "" {
|
||||
visited[rootFolderID] = true
|
||||
}
|
||||
|
||||
bfs:
|
||||
for len(queue) > 0 {
|
||||
if ctx.Err() != nil {
|
||||
return emitDriveDepthCancelled(collected, errs, pattern)
|
||||
}
|
||||
folder := queue[0]
|
||||
queue = queue[1:]
|
||||
|
||||
start := time.Now()
|
||||
var folderErr error
|
||||
pageToken := ""
|
||||
pages := 0
|
||||
for {
|
||||
if ctx.Err() != nil {
|
||||
return emitDriveDepthCancelled(collected, errs, pattern)
|
||||
}
|
||||
pages++
|
||||
if pages > maxPagesPerFolder {
|
||||
folderErr = &CLIError{
|
||||
Code: CodeMCPToolError,
|
||||
Message: fmt.Sprintf("pagination anomaly: folder exceeded %d pages with non-empty nextToken, cursor loop suspected, directory may be truncated", maxPagesPerFolder),
|
||||
}
|
||||
break
|
||||
}
|
||||
args := route.buildArgs(baseArgs, folder.id, pageToken)
|
||||
text, err := route.fetchPage(ctx, args)
|
||||
if ctx.Err() != nil {
|
||||
return emitDriveDepthCancelled(collected, errs, pattern)
|
||||
}
|
||||
if err != nil {
|
||||
folderErr = err
|
||||
break
|
||||
}
|
||||
items, next, hasMore := route.parsePage(text)
|
||||
for _, item := range items {
|
||||
name, _ := item["name"].(string)
|
||||
rel := name
|
||||
if folder.relPath != "" {
|
||||
rel = folder.relPath + "/" + name
|
||||
}
|
||||
item["depth"] = folder.depth + 1
|
||||
item["parentId"] = folder.id // 根级为空串
|
||||
item["rel_path"] = rel // 不保证唯一,组树以 parentId 为准
|
||||
collected = append(collected, item)
|
||||
if len(collected) >= driveDepthMaxItems {
|
||||
// 未访问目录不记 errors[](没失败只是没扫),避免 errors 数组被淹没
|
||||
truncated = true
|
||||
break
|
||||
}
|
||||
if route.isFolder(item) && folder.depth+1 < maxDepth {
|
||||
if id := route.itemID(item); id != "" && !visited[id] {
|
||||
// 重复条目静默丢弃
|
||||
visited[id] = true
|
||||
queue = append(queue, driveDepthFolder{id: id, name: name, depth: folder.depth + 1, relPath: rel})
|
||||
}
|
||||
}
|
||||
}
|
||||
if truncated {
|
||||
break bfs
|
||||
}
|
||||
if hasMore && next == "" {
|
||||
// 不静默截断——显式落 api_error,让消费方感知数据不完整。
|
||||
folderErr = &CLIError{
|
||||
Code: CodeMCPToolError,
|
||||
Message: "pagination anomaly: hasMore=true but nextToken is empty, directory may be truncated",
|
||||
}
|
||||
break
|
||||
}
|
||||
if next == "" {
|
||||
break
|
||||
}
|
||||
if route.hasMoreAuthoritative && !hasMore {
|
||||
break
|
||||
}
|
||||
pageToken = next
|
||||
}
|
||||
|
||||
slog.Info("drive list depth folder done",
|
||||
"traceId", traceID, "depth", folder.depth, "folderId", folder.id,
|
||||
"latency", time.Since(start).Milliseconds(), "failed", folderErr != nil)
|
||||
|
||||
if folderErr != nil {
|
||||
if driveDepthUnrecoverable(folderErr) {
|
||||
// partial 照吐 stdout,错误详情走 stderr,非零退出
|
||||
errs = append(errs, newDriveDepthError(folder, folderErr))
|
||||
if emitErr := emitDriveDepthResult(collected, errs, truncated, pattern); emitErr != nil {
|
||||
return emitErr
|
||||
}
|
||||
return folderErr
|
||||
}
|
||||
if driveDepthErrorCode(folderErr) == driveDepthRateLimitedCode && !folder.retried {
|
||||
// 限流命中在入口处、业务逻辑未执行,重试零副作用;不加 sleep/退避。
|
||||
folder.retried = true
|
||||
queue = append(queue, folder)
|
||||
continue
|
||||
}
|
||||
if folder.depth == 0 && len(collected) == 0 {
|
||||
return folderErr
|
||||
}
|
||||
// 403 / transport 重试耗尽 / 限流重入队仍失败:记 errors[] 跳过
|
||||
errs = append(errs, newDriveDepthError(folder, folderErr))
|
||||
continue
|
||||
}
|
||||
|
||||
if !quiet {
|
||||
display := folder.name
|
||||
if display == "" {
|
||||
display = folder.id
|
||||
}
|
||||
if display == "" {
|
||||
display = "<root>"
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "[drive-list] depth=%d folder=%s done\n", folder.depth, display)
|
||||
}
|
||||
}
|
||||
|
||||
return emitDriveDepthResult(collected, errs, truncated, pattern)
|
||||
}
|
||||
|
||||
func emitDriveDepthCancelled(items []map[string]any, errs []driveDepthError, pattern string) error {
|
||||
if err := emitDriveDepthResult(items, errs, true, pattern); err != nil {
|
||||
return err
|
||||
}
|
||||
return &driveDepthCancelledError{}
|
||||
}
|
||||
|
||||
// depth>1 不输出 nextToken。
|
||||
func emitDriveDepthResult(items []map[string]any, errs []driveDepthError, truncated bool, pattern string) error {
|
||||
if pattern != "" {
|
||||
// 先递归后过滤,过滤仅作用于输出项,不阻止文件夹下钻
|
||||
filtered := make([]map[string]any, 0, len(items))
|
||||
for _, item := range items {
|
||||
name, _ := item["name"].(string)
|
||||
if name == "" {
|
||||
name, _ = item["fileName"].(string)
|
||||
}
|
||||
if matchDriveNamePattern(name, pattern) {
|
||||
filtered = append(filtered, item)
|
||||
}
|
||||
}
|
||||
items = filtered
|
||||
}
|
||||
// 排列为 rel_path 树序:BFS 只决定截断时哪些条目入选,树序决定呈现顺序。
|
||||
sort.SliceStable(items, func(i, j int) bool {
|
||||
ri, _ := items[i]["rel_path"].(string)
|
||||
rj, _ := items[j]["rel_path"].(string)
|
||||
if ri != rj {
|
||||
return ri < rj
|
||||
}
|
||||
return driveDepthItemID(items[i]) < driveDepthItemID(items[j])
|
||||
})
|
||||
maxDepth := 0
|
||||
for _, item := range items {
|
||||
if d, ok := item["depth"].(int); ok && d > maxDepth {
|
||||
maxDepth = d
|
||||
}
|
||||
}
|
||||
if items == nil {
|
||||
items = []map[string]any{}
|
||||
}
|
||||
return deps.Out.PrintJSON(map[string]any{
|
||||
"items": items,
|
||||
"maxDepth": maxDepth,
|
||||
"truncated": truncated,
|
||||
"errors": errs,
|
||||
})
|
||||
}
|
||||
|
||||
// 不输出预估调用次数:零调用下平均子文件夹数不可知,硬编码上界会被误读为真实估算。
|
||||
func printDriveDepthDryRun(route driveDepthRoute, baseArgs map[string]any, maxDepth int) error {
|
||||
if deps.Caller.Format() == "json" {
|
||||
return deps.Out.PrintJSON(map[string]any{
|
||||
"dry_run": true,
|
||||
"executed": false,
|
||||
"tool": route.toolName,
|
||||
"baseArgs": baseArgs,
|
||||
"maxDepth": maxDepth,
|
||||
"pageSize": route.pageSize,
|
||||
"totalLimit": driveDepthMaxItems,
|
||||
"warning": "调用数随目录宽度指数增长",
|
||||
})
|
||||
}
|
||||
bold := color.New(color.FgYellow, color.Bold)
|
||||
bold.Println("[DRY-RUN] Preview only, not executed:")
|
||||
deps.Out.PrintKeyValue("Tool", route.toolName)
|
||||
argsJSON, _ := json.MarshalIndent(baseArgs, " ", " ")
|
||||
deps.Out.PrintKeyValue("baseArgs", "\n "+string(argsJSON))
|
||||
deps.Out.PrintKeyValue("maxDepth", fmt.Sprintf("%d", maxDepth))
|
||||
deps.Out.PrintKeyValue("每页条数", fmt.Sprintf("%d", route.pageSize))
|
||||
deps.Out.PrintKeyValue("全局上限", fmt.Sprintf("%d", driveDepthMaxItems))
|
||||
deps.Out.PrintWarning("调用数随目录宽度指数增长")
|
||||
return nil
|
||||
}
|
||||
|
||||
// 钉盘契约无 hasMore 字段,hasMoreExplicit 仅供「hasMore=true 但 token 为空」异常检测。
|
||||
func parseDriveDepthPage(text string) (items []map[string]any, nextToken string, hasMoreExplicit bool) {
|
||||
var body map[string]any
|
||||
if json.Unmarshal([]byte(text), &body) != nil {
|
||||
return nil, "", false
|
||||
}
|
||||
target := body
|
||||
if inner, ok := body["result"].(map[string]any); ok && driveDepthListItemsKey(inner) != "" {
|
||||
target = inner
|
||||
}
|
||||
key := driveDepthListItemsKey(target)
|
||||
if key == "" {
|
||||
return nil, "", false
|
||||
}
|
||||
arr, _ := target[key].([]any)
|
||||
for _, it := range arr {
|
||||
if m, ok := it.(map[string]any); ok {
|
||||
items = append(items, m)
|
||||
}
|
||||
}
|
||||
nextToken, _ = target["nextToken"].(string)
|
||||
hasMoreExplicit, _ = target["hasMore"].(bool)
|
||||
return items, nextToken, hasMoreExplicit
|
||||
}
|
||||
|
||||
func driveDepthListItemsKey(m map[string]any) string {
|
||||
for _, k := range []string{"items", "dentryList"} {
|
||||
if arr, ok := m[k].([]any); ok && arr != nil {
|
||||
return k
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// 非法通配符降级为子串匹配,避免 filepath.Match 报错导致过滤静默失效。
|
||||
func matchDriveNamePattern(name, pattern string) bool {
|
||||
if pattern == "" {
|
||||
return true
|
||||
}
|
||||
p := pattern
|
||||
if !strings.ContainsAny(p, "*?[") {
|
||||
p = "*" + p + "*"
|
||||
}
|
||||
ok, err := filepath.Match(p, name)
|
||||
if err != nil {
|
||||
return strings.Contains(name, pattern)
|
||||
}
|
||||
return ok
|
||||
}
|
||||
|
||||
func isDriveDepthFolder(item map[string]any) bool {
|
||||
for _, key := range []string{"type", "dentryType"} {
|
||||
if v, ok := item[key].(string); ok && strings.EqualFold(v, "FOLDER") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// list_nodes 游标字段叫 nextPageToken,与钉盘的 nextToken 不同名。
|
||||
func parseDocDepthPage(text string) (items []map[string]any, nextToken string, hasMore bool) {
|
||||
var body map[string]any
|
||||
if json.Unmarshal([]byte(text), &body) != nil {
|
||||
return nil, "", false
|
||||
}
|
||||
arr, _ := body["nodes"].([]any)
|
||||
for _, it := range arr {
|
||||
if m, ok := it.(map[string]any); ok {
|
||||
items = append(items, m)
|
||||
}
|
||||
}
|
||||
nextToken, _ = body["nextPageToken"].(string)
|
||||
hasMore, _ = body["hasMore"].(bool)
|
||||
return items, nextToken, hasMore
|
||||
}
|
||||
|
||||
func isDocDepthFolder(item map[string]any) bool {
|
||||
v, _ := item["nodeType"].(string)
|
||||
return strings.EqualFold(v, "folder")
|
||||
}
|
||||
|
||||
func driveDepthItemID(item map[string]any) string {
|
||||
for _, key := range []string{"fileId", "nodeId"} {
|
||||
if s, ok := item[key].(string); ok && s != "" {
|
||||
return s
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func driveDepthUnrecoverable(err error) bool {
|
||||
var cliErr *CLIError
|
||||
if errors.As(err, &cliErr) {
|
||||
switch cliErr.Code {
|
||||
case CodeAuthTokenExpired, CodeAuthNotConfigured, CodeNetworkTimeout, CodeNetworkUnreachable:
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// CLIError.Message 保留了原始响应 JSON。
|
||||
func driveDepthErrorCode(err error) string {
|
||||
var cliErr *CLIError
|
||||
if !errors.As(err, &cliErr) {
|
||||
return ""
|
||||
}
|
||||
var body map[string]any
|
||||
if json.Unmarshal([]byte(cliErr.Message), &body) != nil {
|
||||
return ""
|
||||
}
|
||||
for _, key := range []string{"errorCode", "error_code", "code"} {
|
||||
if s, ok := body[key].(string); ok && s != "" {
|
||||
return s
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// 匹配顺序是硬约束:invalidRequest.rateLimited 自带 "invalidRequest." 前缀,
|
||||
// 若先做 invalidRequest.* 前缀分类,限流会被吞进参数错误类。必须先精确匹配限流,
|
||||
// 再 forbidden.* 前缀,最后兜底 api_error。未知 reason 按 api_error 兼容。
|
||||
func classifyDriveDepthReason(errorCode string) string {
|
||||
switch {
|
||||
case errorCode == driveDepthRateLimitedCode:
|
||||
return "rate_limited"
|
||||
case strings.HasPrefix(errorCode, "forbidden."):
|
||||
return "permission_denied"
|
||||
default:
|
||||
return "api_error"
|
||||
}
|
||||
}
|
||||
|
||||
func newDriveDepthError(folder driveDepthFolder, err error) driveDepthError {
|
||||
return driveDepthError{
|
||||
Depth: folder.depth,
|
||||
FolderID: folder.id,
|
||||
FolderName: folder.name,
|
||||
Reason: classifyDriveDepthReason(driveDepthErrorCode(err)),
|
||||
Message: driveDepthErrorMessage(err),
|
||||
}
|
||||
}
|
||||
|
||||
func driveDepthErrorMessage(err error) string {
|
||||
var cliErr *CLIError
|
||||
if errors.As(err, &cliErr) {
|
||||
var body map[string]any
|
||||
if json.Unmarshal([]byte(cliErr.Message), &body) == nil {
|
||||
for _, key := range []string{"errorMsg", "message"} {
|
||||
if s, ok := body[key].(string); ok && s != "" {
|
||||
return s
|
||||
}
|
||||
}
|
||||
}
|
||||
return cliErr.Message
|
||||
}
|
||||
return err.Error()
|
||||
}
|
||||
@@ -148,6 +148,7 @@ func (f *Formatter) PrintSuccess(msg string) { fmt.Fprintf(f.w, "[OK] %s\n", msg
|
||||
func (f *Formatter) PrintError(msg string) { fmt.Fprintf(f.w, "[ERROR] %s\n", msg) }
|
||||
func (f *Formatter) PrintWarning(msg string) { fmt.Fprintf(f.errW, "[WARN] %s\n", msg) }
|
||||
func (f *Formatter) PrintInfo(msg string) { fmt.Fprintf(f.w, "[INFO] %s\n", msg) }
|
||||
func (f *Formatter) PrintProgress(msg string) { fmt.Fprintf(f.errW, "%s\n", msg) }
|
||||
func (f *Formatter) PrintDim(msg string) { fmt.Fprintf(f.w, " %s\n", msg) }
|
||||
|
||||
func (f *Formatter) PrintKeyValue(key, value string) {
|
||||
|
||||
@@ -176,6 +176,8 @@ func newSheetCommand() *cobra.Command {
|
||||
{path: "filter-view delete-criteria", operation: "删除筛选视图列条件", targetHint: "文档、工作表、筛选视图和列"},
|
||||
{path: "range batch-clear", operation: "批量清除工作表区域", targetHint: "文档、工作表、清除范围和清除类型"},
|
||||
{path: "range move-to", operation: "移动工作表区域", targetHint: "源工作表范围和目标位置"},
|
||||
{path: "version revert", operation: "回滚表格版本", targetHint: "文档和目标版本号"},
|
||||
{path: "comment delete", operation: "删除单元格评论", targetHint: "文档和评论 commentKey"},
|
||||
}
|
||||
for _, guard := range confirmationGuards {
|
||||
attachSheetConfirmationGuard(root, guard.path, guard.operation, guard.targetHint)
|
||||
|
||||
@@ -149,9 +149,6 @@ func newSheetCommentCmd() *cobra.Command {
|
||||
return err
|
||||
}
|
||||
commentKey := mustGetFlag(cmd, "comment-key")
|
||||
if !confirmDelete("表格评论", commentKey) {
|
||||
return nil
|
||||
}
|
||||
return callMCPToolOnServer("doc-comment", "delete_comment", map[string]any{
|
||||
"nodeId": nodeID,
|
||||
"commentKey": commentKey,
|
||||
|
||||
@@ -3,6 +3,7 @@ package helpers
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
@@ -18,7 +19,7 @@ func newSheetFormulaVerifyCmd() *cobra.Command {
|
||||
不指定 --sheet-id / --range / --targets 时默认扫描整本表格的全部工作表。`,
|
||||
Example: ` dws sheet formula-verify --node NODE_ID
|
||||
dws sheet formula-verify --node NODE_ID --sheet-id Sheet1 --range A1:D100
|
||||
dws sheet formula-verify --node NODE_ID --exit-on-error`,
|
||||
dws sheet formula-verify --node NODE_ID --targets '[{"sheetId":"Sheet1","range":"A1:D100"}]'`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
if err := validateRequiredFlags(cmd, "node"); err != nil {
|
||||
return err
|
||||
@@ -47,32 +48,27 @@ func newSheetFormulaVerifyCmd() *cobra.Command {
|
||||
}
|
||||
toolArgs["maxCells"] = v
|
||||
}
|
||||
exitOnError, _ := cmd.Flags().GetBool("exit-on-error")
|
||||
if err := callMCPToolOnServer("sheet", "formula_verify", toolArgs); err != nil {
|
||||
return err
|
||||
}
|
||||
if exitOnError {
|
||||
return fmt.Errorf("formula errors detected (--exit-on-error)")
|
||||
}
|
||||
return nil
|
||||
return callMCPToolOnServer("sheet", "formula_verify", toolArgs)
|
||||
},
|
||||
}
|
||||
cmd.Flags().String("node", "", "表格文档 ID 或 URL (必填)")
|
||||
cmd.Flags().String("sheet-id", "", "工作表 ID 或名称")
|
||||
cmd.Flags().String("range", "", "A1 范围(需与 --sheet-id 配合)")
|
||||
cmd.Flags().String("targets", "", `扫描目标 JSON 数组或 @文件路径;每项 {"sheetId":"Sheet1","range":"A1:D100"}`)
|
||||
cmd.Flags().String("sheet-id", "", "工作表 ID 或名称;与 --range 组成单个扫描目标")
|
||||
cmd.Flags().String("range", "", "A1 范围;需与 --sheet-id 配合使用")
|
||||
cmd.Flags().String("targets", "", `扫描目标 JSON 数组、@文件路径 或 - 表示 stdin;每项 {"sheetId":"Sheet1","range":"A1:D100"}`)
|
||||
cmd.Flags().Int("max-locations-per-error", 0, "每种错误类型最多返回的位置数")
|
||||
cmd.Flags().Int("max-cells", 0, "最多扫描的单元格数")
|
||||
cmd.Flags().Bool("exit-on-error", false, "发现公式错误时返回非 0 退出码")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func formulaVerifyTargetsFromFlags(cmd *cobra.Command) ([]map[string]any, error) {
|
||||
if v, _ := cmd.Flags().GetString("targets"); v != "" {
|
||||
return parseFormulaVerifyTargets(v)
|
||||
return parseFormulaVerifyTargets(cmd, v)
|
||||
}
|
||||
sheetID, _ := cmd.Flags().GetString("sheet-id")
|
||||
rangeStr, _ := cmd.Flags().GetString("range")
|
||||
if sheetID == "" && rangeStr != "" {
|
||||
return nil, fmt.Errorf("--range 必须与 --sheet-id 配合使用")
|
||||
}
|
||||
if sheetID != "" {
|
||||
t := map[string]any{"sheetId": sheetID}
|
||||
if rangeStr != "" {
|
||||
@@ -83,7 +79,7 @@ func formulaVerifyTargetsFromFlags(cmd *cobra.Command) ([]map[string]any, error)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func parseFormulaVerifyTargets(raw string) ([]map[string]any, error) {
|
||||
func parseFormulaVerifyTargets(cmd *cobra.Command, raw string) ([]map[string]any, error) {
|
||||
data := raw
|
||||
if strings.HasPrefix(raw, "@") {
|
||||
filePath := strings.TrimPrefix(raw, "@")
|
||||
@@ -93,7 +89,7 @@ func parseFormulaVerifyTargets(raw string) ([]map[string]any, error) {
|
||||
}
|
||||
data = string(content)
|
||||
} else if raw == "-" {
|
||||
content, err := os.ReadFile("/dev/stdin")
|
||||
content, err := io.ReadAll(cmd.InOrStdin())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("读取 stdin 失败: %w", err)
|
||||
}
|
||||
|
||||
@@ -68,9 +68,6 @@ func newSheetVersionCmd() *cobra.Command {
|
||||
return fmt.Errorf("flag --version is required")
|
||||
}
|
||||
version, _ := cmd.Flags().GetInt("version")
|
||||
if !commandDryRun(cmd) && !confirmDelete("表格版本回滚", nodeID) {
|
||||
return nil
|
||||
}
|
||||
return callMCPToolOnServer("doc", "revert_doc_version", map[string]any{
|
||||
"nodeId": nodeID,
|
||||
"version": version,
|
||||
|
||||
Reference in new issue
Block a user