fix(im): resolve direct recipients via contact search

This commit is contained in:
Dennis committed 2026-07-30 10:29:39 +08:00
1 parent f9e3476d42
commit cffc48406c
16 files changed
+250 -202

No files matched your search

+62 -62
View File
@@ -9836,14 +9836,14 @@
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Agent-authored from the verified identity/content capability matrix, userId resolution, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.", "review_reason": "Agent-authored from the verified identity/content capability matrix, live-compatible contact search with exact userId matching, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.",
"candidates": [ "candidates": [
{ {
"value": "统一发送文本、Markdown、当前用户文件或已有 mediaId 图片", "value": "统一发送文本、Markdown、当前用户文件或已有 mediaId 图片",
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Agent-authored from the verified identity/content capability matrix, userId resolution, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media." "review_reason": "Agent-authored from the verified identity/content capability matrix, live-compatible contact search with exact userId matching, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media."
} }
] ]
}, },
@@ -9852,14 +9852,14 @@
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"candidates": [ "candidates": [
{ {
"value": "available", "value": "available",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists." "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists."
} }
] ]
}, },
@@ -9870,7 +9870,7 @@
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Agent-authored from the verified identity/content capability matrix, userId resolution, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.", "review_reason": "Agent-authored from the verified identity/content capability matrix, live-compatible contact search with exact userId matching, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.",
"candidates": [ "candidates": [
{ {
"value": [ "value": [
@@ -9879,7 +9879,7 @@
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Agent-authored from the verified identity/content capability matrix, userId resolution, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media." "review_reason": "Agent-authored from the verified identity/content capability matrix, live-compatible contact search with exact userId matching, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media."
} }
] ]
}, },
@@ -9888,14 +9888,14 @@
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"candidates": [ "candidates": [
{ {
"value": "user_required", "value": "user_required",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists." "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists."
}, },
{ {
"value": "not_required", "value": "not_required",
@@ -9910,14 +9910,14 @@
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"candidates": [ "candidates": [
{ {
"value": "write", "value": "write",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists." "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists."
}, },
{ {
"value": "write", "value": "write",
@@ -9935,7 +9935,7 @@
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Agent-authored from the verified identity/content capability matrix, userId resolution, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.", "review_reason": "Agent-authored from the verified identity/content capability matrix, live-compatible contact search with exact userId matching, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.",
"candidates": [ "candidates": [
{ {
"value": [ "value": [
@@ -9945,7 +9945,7 @@
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Agent-authored from the verified identity/content capability matrix, userId resolution, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media." "review_reason": "Agent-authored from the verified identity/content capability matrix, live-compatible contact search with exact userId matching, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media."
} }
] ]
}, },
@@ -9954,14 +9954,14 @@
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"candidates": [ "candidates": [
{ {
"value": "unknown", "value": "unknown",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists." "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists."
}, },
{ {
"value": "unknown", "value": "unknown",
@@ -9976,30 +9976,30 @@
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"candidates": [ "candidates": [
{ {
"value": "composite", "value": "composite",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists." "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists."
} }
] ]
}, },
"interface_reason": { "interface_reason": {
"value": "Reviewed composite send adapter: it selects current-user, bot, or webhook transport; current-user additionally supports userId resolution, mediaId images, and the native init/upload/commit local-file flow.", "value": "Reviewed composite send adapter: it selects current-user, bot, or webhook transport; current-user additionally supports live-compatible contact search with exact userId matching, mediaId images, and the native init/upload/commit local-file flow.",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"candidates": [ "candidates": [
{ {
"value": "Reviewed composite send adapter: it selects current-user, bot, or webhook transport; current-user additionally supports userId resolution, mediaId images, and the native init/upload/commit local-file flow.", "value": "Reviewed composite send adapter: it selects current-user, bot, or webhook transport; current-user additionally supports live-compatible contact search with exact userId matching, mediaId images, and the native init/upload/commit local-file flow.",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists." "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists."
} }
] ]
}, },
@@ -10024,21 +10024,21 @@
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"candidates": [ "candidates": [
{ {
"value": true, "value": true,
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists." "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists."
}, },
{ {
"value": true, "value": true,
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": false, "selected": false,
"review_reason": "Agent-authored from the verified identity/content capability matrix, userId resolution, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media." "review_reason": "Agent-authored from the verified identity/content capability matrix, live-compatible contact search with exact userId matching, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media."
} }
] ]
}, },
@@ -10047,14 +10047,14 @@
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"candidates": [ "candidates": [
{ {
"value": "medium", "value": "medium",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists." "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists."
}, },
{ {
"value": "medium", "value": "medium",
@@ -10066,28 +10066,28 @@
}, },
"use_when": { "use_when": {
"value": [ "value": [
"当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先只读解析为 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。" "当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先通过通讯录关键词搜索并按 userId 精确匹配 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。"
], ],
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Agent-authored from the verified identity/content capability matrix, userId resolution, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.", "review_reason": "Agent-authored from the verified identity/content capability matrix, live-compatible contact search with exact userId matching, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.",
"candidates": [ "candidates": [
{ {
"value": [ "value": [
"当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先只读解析为 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。" "当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先通过通讯录关键词搜索并按 userId 精确匹配 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。"
], ],
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Agent-authored from the verified identity/content capability matrix, userId resolution, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media." "review_reason": "Agent-authored from the verified identity/content capability matrix, live-compatible contact search with exact userId matching, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media."
} }
] ]
} }
}, },
"idempotency": "unknown", "idempotency": "unknown",
"interface_mode": "composite", "interface_mode": "composite",
"interface_reason": "Reviewed composite send adapter: it selects current-user, bot, or webhook transport; current-user additionally supports userId resolution, mediaId images, and the native init/upload/commit local-file flow.", "interface_reason": "Reviewed composite send adapter: it selects current-user, bot, or webhook transport; current-user additionally supports live-compatible contact search with exact userId matching, mediaId images, and the native init/upload/commit local-file flow.",
"reviewed": true, "reviewed": true,
"risk": "medium", "risk": "medium",
"source_refs": [ "source_refs": [
@@ -10099,7 +10099,7 @@
"skills/mono/references/intent-guide.md" "skills/mono/references/intent-guide.md"
], ],
"use_when": [ "use_when": [
"当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先只读解析为 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。" "当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先通过通讯录关键词搜索并按 userId 精确匹配 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。"
] ]
}, },
"chat +messages-send-by-webhook": { "chat +messages-send-by-webhook": {
@@ -10380,14 +10380,14 @@
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.", "review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, live-compatible contact search with exact userId matching, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.",
"candidates": [ "candidates": [
{ {
"value": "创建流式卡片,可在同一次调用中写入内容并结束", "value": "创建流式卡片,可在同一次调用中写入内容并结束",
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting." "review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, live-compatible contact search with exact userId matching, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting."
} }
] ]
}, },
@@ -10396,14 +10396,14 @@
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"candidates": [ "candidates": [
{ {
"value": "available", "value": "available",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property." "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property."
} }
] ]
}, },
@@ -10414,7 +10414,7 @@
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.", "review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, live-compatible contact search with exact userId matching, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.",
"candidates": [ "candidates": [
{ {
"value": [ "value": [
@@ -10423,7 +10423,7 @@
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting." "review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, live-compatible contact search with exact userId matching, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting."
} }
] ]
}, },
@@ -10432,14 +10432,14 @@
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"candidates": [ "candidates": [
{ {
"value": "user_required", "value": "user_required",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property." "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property."
} }
] ]
}, },
@@ -10448,14 +10448,14 @@
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"candidates": [ "candidates": [
{ {
"value": "write", "value": "write",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property." "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property."
} }
] ]
}, },
@@ -10467,7 +10467,7 @@
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.", "review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, live-compatible contact search with exact userId matching, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.",
"candidates": [ "candidates": [
{ {
"value": [ "value": [
@@ -10477,7 +10477,7 @@
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting." "review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, live-compatible contact search with exact userId matching, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting."
} }
] ]
}, },
@@ -10486,14 +10486,14 @@
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"candidates": [ "candidates": [
{ {
"value": "unknown", "value": "unknown",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property." "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property."
} }
] ]
}, },
@@ -10502,30 +10502,30 @@
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"candidates": [ "candidates": [
{ {
"value": "composite", "value": "composite",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property." "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property."
} }
] ]
}, },
"interface_reason": { "interface_reason": {
"value": "Reviewed card lifecycle adapter: it can call create_and_send_card alone or compose it with update_streaming_card after extracting the returned bizId.", "value": "Reviewed card lifecycle adapter: it can resolve a userId through contact search with exact matching, call create_and_send_card alone, or compose creation with update_streaming_card after extracting the returned bizId.",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"candidates": [ "candidates": [
{ {
"value": "Reviewed card lifecycle adapter: it can call create_and_send_card alone or compose it with update_streaming_card after extracting the returned bizId.", "value": "Reviewed card lifecycle adapter: it can resolve a userId through contact search with exact matching, call create_and_send_card alone, or compose creation with update_streaming_card after extracting the returned bizId.",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property." "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property."
} }
] ]
}, },
@@ -10550,21 +10550,21 @@
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"candidates": [ "candidates": [
{ {
"value": true, "value": true,
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property." "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property."
}, },
{ {
"value": true, "value": true,
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": false, "selected": false,
"review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting." "review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, live-compatible contact search with exact userId matching, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting."
} }
] ]
}, },
@@ -10573,41 +10573,41 @@
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"candidates": [ "candidates": [
{ {
"value": "medium", "value": "medium",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property." "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property."
} }
] ]
}, },
"use_when": { "use_when": {
"value": [ "value": [
"当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 做只读通讯录解析,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。" "当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 通过通讯录关键词搜索做精确匹配,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。"
], ],
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.", "review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, live-compatible contact search with exact userId matching, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.",
"candidates": [ "candidates": [
{ {
"value": [ "value": [
"当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 做只读通讯录解析,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。" "当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 通过通讯录关键词搜索做精确匹配,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。"
], ],
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"selected": true, "selected": true,
"review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting." "review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, live-compatible contact search with exact userId matching, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting."
} }
] ]
} }
}, },
"idempotency": "unknown", "idempotency": "unknown",
"interface_mode": "composite", "interface_mode": "composite",
"interface_reason": "Reviewed card lifecycle adapter: it can call create_and_send_card alone or compose it with update_streaming_card after extracting the returned bizId.", "interface_reason": "Reviewed card lifecycle adapter: it can resolve a userId through contact search with exact matching, call create_and_send_card alone, or compose creation with update_streaming_card after extracting the returned bizId.",
"reviewed": true, "reviewed": true,
"risk": "medium", "risk": "medium",
"source_refs": [ "source_refs": [
@@ -10618,7 +10618,7 @@
"internal/cli/schema_hints/selection/chat.json" "internal/cli/schema_hints/selection/chat.json"
], ],
"use_when": [ "use_when": [
"当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 做只读通讯录解析,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。" "当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 通过通讯录关键词搜索做精确匹配,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。"
] ]
}, },
"chat +messages-update-card": { "chat +messages-update-card": {
@@ -1,6 +1,6 @@
{ {
"version": 1, "version": 1,
"source_hash": "sha256:f7afa1d0abaa0c3d4ead4c6262948b7565787abb0860bb724276d1d3fe52178b", "source_hash": "sha256:f8cb29bdbeaceae6f04cbac8a93ea77f2a84f93f8304d25878c827b959bc0ba0",
"surface_hash": "sha256:60eee8e2f37d6d9d60689efce85082798eb9ad38b7ba7c0b471c3de676a85a16", "surface_hash": "sha256:60eee8e2f37d6d9d60689efce85082798eb9ad38b7ba7c0b471c3de676a85a16",
"coverage": { "coverage": {
"surface_products": 26, "surface_products": 26,
@@ -1,6 +1,6 @@
{ {
"version": 1, "version": 1,
"source_hash": "sha256:f7afa1d0abaa0c3d4ead4c6262948b7565787abb0860bb724276d1d3fe52178b", "source_hash": "sha256:f8cb29bdbeaceae6f04cbac8a93ea77f2a84f93f8304d25878c827b959bc0ba0",
"surface_hash": "sha256:60eee8e2f37d6d9d60689efce85082798eb9ad38b7ba7c0b471c3de676a85a16", "surface_hash": "sha256:60eee8e2f37d6d9d60689efce85082798eb9ad38b7ba7c0b471c3de676a85a16",
"source_files": 160, "source_files": 160,
"hint_files": 54, "hint_files": 54,
+8 -8
View File
@@ -1,12 +1,12 @@
{ {
"version": 1, "version": 1,
"surface_hash": "sha256:60eee8e2f37d6d9d60689efce85082798eb9ad38b7ba7c0b471c3de676a85a16", "surface_hash": "sha256:60eee8e2f37d6d9d60689efce85082798eb9ad38b7ba7c0b471c3de676a85a16",
"source_hash": "sha256:8fcebd5100f2727898290118b2b381cc3edc325bc1c8526e61036da5482e025b", "source_hash": "sha256:735bbf8e04cfc44db741e9b14ffe1698f80aac5d2662d2c1c41b0aadcee9098d",
"catalog": { "catalog": {
"agent_metadata": { "agent_metadata": {
"products_with_metadata": 26, "products_with_metadata": 26,
"source": "embedded-skill-metadata", "source": "embedded-skill-metadata",
"source_hash": "sha256:f7afa1d0abaa0c3d4ead4c6262948b7565787abb0860bb724276d1d3fe52178b", "source_hash": "sha256:f8cb29bdbeaceae6f04cbac8a93ea77f2a84f93f8304d25878c827b959bc0ba0",
"surface_hash": "sha256:60eee8e2f37d6d9d60689efce85082798eb9ad38b7ba7c0b471c3de676a85a16", "surface_hash": "sha256:60eee8e2f37d6d9d60689efce85082798eb9ad38b7ba7c0b471c3de676a85a16",
"surface_products": 26, "surface_products": 26,
"surface_tools": 845, "surface_tools": 845,
@@ -10788,18 +10788,18 @@
"cli_name": "+messages-send", "cli_name": "+messages-send",
"cli_path": "chat +messages-send", "cli_path": "chat +messages-send",
"confirmation": "user_required", "confirmation": "user_required",
"description": "当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先只读解析为 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。\n\n参数约束:\n - --text、--markdown、--media-id、--file、--file-path 至少指定一个\n - --text、--markdown、--media-id、--file、--file-path 互斥,最多指定一个\n - --identity、--as 互斥,最多指定一个\n - --group、--chat-id 互斥,最多指定一个\n - --user、--open-dingtalk-id 互斥,最多指定一个\n - --uuid、--idempotency-key 互斥,最多指定一个\n - 目标、凭据和幂等参数受发送身份能力矩阵约束:user 必须指定一个群聊或单聊目标;bot 必须指定 robot-code 和一类目标;webhook 必须指定 webhook-token;幂等键仅 user 支持", "description": "当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先通过通讯录关键词搜索并按 userId 精确匹配 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。\n\n参数约束:\n - --text、--markdown、--media-id、--file、--file-path 至少指定一个\n - --text、--markdown、--media-id、--file、--file-path 互斥,最多指定一个\n - --identity、--as 互斥,最多指定一个\n - --group、--chat-id 互斥,最多指定一个\n - --user、--open-dingtalk-id 互斥,最多指定一个\n - --uuid、--idempotency-key 互斥,最多指定一个\n - 目标、凭据和幂等参数受发送身份能力矩阵约束:user 必须指定一个群聊或单聊目标;bot 必须指定 robot-code 和一类目标;webhook 必须指定 webhook-token;幂等键仅 user 支持",
"effect": "write", "effect": "write",
"idempotency": "unknown", "idempotency": "unknown",
"interface_mode": "composite", "interface_mode": "composite",
"interface_reason": "Reviewed composite send adapter: it selects current-user, bot, or webhook transport; current-user additionally supports userId resolution, mediaId images, and the native init/upload/commit local-file flow.", "interface_reason": "Reviewed composite send adapter: it selects current-user, bot, or webhook transport; current-user additionally supports live-compatible contact search with exact userId matching, mediaId images, and the native init/upload/commit local-file flow.",
"name": "shortcut_messages_send", "name": "shortcut_messages_send",
"primary_cli_path": "chat +messages-send", "primary_cli_path": "chat +messages-send",
"reviewed": true, "reviewed": true,
"risk": "medium", "risk": "medium",
"title": "统一发送文本、Markdown、当前用户文件或已有 mediaId 图片", "title": "统一发送文本、Markdown、当前用户文件或已有 mediaId 图片",
"use_when": [ "use_when": [
"当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先只读解析为 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。" "当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先通过通讯录关键词搜索并按 userId 精确匹配 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。"
] ]
}, },
{ {
@@ -10840,18 +10840,18 @@
"cli_name": "+messages-send-card", "cli_name": "+messages-send-card",
"cli_path": "chat +messages-send-card", "cli_path": "chat +messages-send-card",
"confirmation": "user_required", "confirmation": "user_required",
"description": "当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 做只读通讯录解析,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。\n\n参数约束:\n - --group、--receiver、--receiver-open-dingtalk-id 必须且只能指定一个\n - --flow-status 必须在 1-5 之间,且显式指定时必须同时提供 --content", "description": "当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 通过通讯录关键词搜索做精确匹配,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。\n\n参数约束:\n - --group、--receiver、--receiver-open-dingtalk-id 必须且只能指定一个\n - --flow-status 必须在 1-5 之间,且显式指定时必须同时提供 --content",
"effect": "write", "effect": "write",
"idempotency": "unknown", "idempotency": "unknown",
"interface_mode": "composite", "interface_mode": "composite",
"interface_reason": "Reviewed card lifecycle adapter: it can call create_and_send_card alone or compose it with update_streaming_card after extracting the returned bizId.", "interface_reason": "Reviewed card lifecycle adapter: it can resolve a userId through contact search with exact matching, call create_and_send_card alone, or compose creation with update_streaming_card after extracting the returned bizId.",
"name": "shortcut_messages_send_card", "name": "shortcut_messages_send_card",
"primary_cli_path": "chat +messages-send-card", "primary_cli_path": "chat +messages-send-card",
"reviewed": true, "reviewed": true,
"risk": "medium", "risk": "medium",
"title": "创建流式卡片,可在同一次调用中写入内容并结束", "title": "创建流式卡片,可在同一次调用中写入内容并结束",
"use_when": [ "use_when": [
"当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 做只读通讯录解析,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。" "当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 通过通讯录关键词搜索做精确匹配,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。"
] ]
}, },
{ {
+79 -79
View File
@@ -73972,7 +73972,7 @@
] ]
] ]
}, },
"description": "当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先只读解析为 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。\n\n参数约束:\n - --text、--markdown、--media-id、--file、--file-path 至少指定一个\n - --text、--markdown、--media-id、--file、--file-path 互斥,最多指定一个\n - --identity、--as 互斥,最多指定一个\n - --group、--chat-id 互斥,最多指定一个\n - --user、--open-dingtalk-id 互斥,最多指定一个\n - --uuid、--idempotency-key 互斥,最多指定一个\n - 目标、凭据和幂等参数受发送身份能力矩阵约束:user 必须指定一个群聊或单聊目标;bot 必须指定 robot-code 和一类目标;webhook 必须指定 webhook-token;幂等键仅 user 支持", "description": "当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先通过通讯录关键词搜索并按 userId 精确匹配 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。\n\n参数约束:\n - --text、--markdown、--media-id、--file、--file-path 至少指定一个\n - --text、--markdown、--media-id、--file、--file-path 互斥,最多指定一个\n - --identity、--as 互斥,最多指定一个\n - --group、--chat-id 互斥,最多指定一个\n - --user、--open-dingtalk-id 互斥,最多指定一个\n - --uuid、--idempotency-key 互斥,最多指定一个\n - 目标、凭据和幂等参数受发送身份能力矩阵约束:user 必须指定一个群聊或单聊目标;bot 必须指定 robot-code 和一类目标;webhook 必须指定 webhook-token;幂等键仅 user 支持",
"display": "群聊 / 消息 / 机器人", "display": "群聊 / 消息 / 机器人",
"effect": "write", "effect": "write",
"effect_source": "agent-hint", "effect_source": "agent-hint",
@@ -73985,7 +73985,7 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Agent-authored from the verified identity/content capability matrix, userId resolution, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.", "review_reason": "Agent-authored from the verified identity/content capability matrix, live-compatible contact search with exact userId matching, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"value": "统一发送文本、Markdown、当前用户文件或已有 mediaId 图片" "value": "统一发送文本、Markdown、当前用户文件或已有 mediaId 图片"
@@ -73993,7 +73993,7 @@
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Agent-authored from the verified identity/content capability matrix, userId resolution, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.", "review_reason": "Agent-authored from the verified identity/content capability matrix, live-compatible contact search with exact userId matching, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.",
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"value": "统一发送文本、Markdown、当前用户文件或已有 mediaId 图片" "value": "统一发送文本、Markdown、当前用户文件或已有 mediaId 图片"
}, },
@@ -74001,7 +74001,7 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "available" "value": "available"
@@ -74009,7 +74009,7 @@
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "available" "value": "available"
}, },
@@ -74017,7 +74017,7 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Agent-authored from the verified identity/content capability matrix, userId resolution, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.", "review_reason": "Agent-authored from the verified identity/content capability matrix, live-compatible contact search with exact userId matching, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"value": [ "value": [
@@ -74027,7 +74027,7 @@
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Agent-authored from the verified identity/content capability matrix, userId resolution, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.", "review_reason": "Agent-authored from the verified identity/content capability matrix, live-compatible contact search with exact userId matching, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.",
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"value": [ "value": [
"需要 bot/webhook 发送媒体、卡片或 thread 回复时不要假设等价支持;改用真实存在的专用下层命令,缺少下层能力时停止" "需要 bot/webhook 发送媒体、卡片或 thread 回复时不要假设等价支持;改用真实存在的专用下层命令,缺少下层能力时停止"
@@ -74053,7 +74053,7 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "user_required" "value": "user_required"
@@ -74067,7 +74067,7 @@
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "user_required" "value": "user_required"
}, },
@@ -74077,19 +74077,19 @@
"precedence": "cobra_help", "precedence": "cobra_help",
"selected": true, "selected": true,
"source": "cobra_help", "source": "cobra_help",
"value": "当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先只读解析为 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。\n\n参数约束:\n - --text、--markdown、--media-id、--file、--file-path 至少指定一个\n - --text、--markdown、--media-id、--file、--file-path 互斥,最多指定一个\n - --identity、--as 互斥,最多指定一个\n - --group、--chat-id 互斥,最多指定一个\n - --user、--open-dingtalk-id 互斥,最多指定一个\n - --uuid、--idempotency-key 互斥,最多指定一个\n - 目标、凭据和幂等参数受发送身份能力矩阵约束:user 必须指定一个群聊或单聊目标;bot 必须指定 robot-code 和一类目标;webhook 必须指定 webhook-token;幂等键仅 user 支持" "value": "当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先通过通讯录关键词搜索并按 userId 精确匹配 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。\n\n参数约束:\n - --text、--markdown、--media-id、--file、--file-path 至少指定一个\n - --text、--markdown、--media-id、--file、--file-path 互斥,最多指定一个\n - --identity、--as 互斥,最多指定一个\n - --group、--chat-id 互斥,最多指定一个\n - --user、--open-dingtalk-id 互斥,最多指定一个\n - --uuid、--idempotency-key 互斥,最多指定一个\n - 目标、凭据和幂等参数受发送身份能力矩阵约束:user 必须指定一个群聊或单聊目标;bot 必须指定 robot-code 和一类目标;webhook 必须指定 webhook-token;幂等键仅 user 支持"
} }
], ],
"precedence": "cobra_help", "precedence": "cobra_help",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"source": "cobra_help", "source": "cobra_help",
"value": "当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先只读解析为 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。\n\n参数约束:\n - --text、--markdown、--media-id、--file、--file-path 至少指定一个\n - --text、--markdown、--media-id、--file、--file-path 互斥,最多指定一个\n - --identity、--as 互斥,最多指定一个\n - --group、--chat-id 互斥,最多指定一个\n - --user、--open-dingtalk-id 互斥,最多指定一个\n - --uuid、--idempotency-key 互斥,最多指定一个\n - 目标、凭据和幂等参数受发送身份能力矩阵约束:user 必须指定一个群聊或单聊目标;bot 必须指定 robot-code 和一类目标;webhook 必须指定 webhook-token;幂等键仅 user 支持" "value": "当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先通过通讯录关键词搜索并按 userId 精确匹配 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。\n\n参数约束:\n - --text、--markdown、--media-id、--file、--file-path 至少指定一个\n - --text、--markdown、--media-id、--file、--file-path 互斥,最多指定一个\n - --identity、--as 互斥,最多指定一个\n - --group、--chat-id 互斥,最多指定一个\n - --user、--open-dingtalk-id 互斥,最多指定一个\n - --uuid、--idempotency-key 互斥,最多指定一个\n - 目标、凭据和幂等参数受发送身份能力矩阵约束:user 必须指定一个群聊或单聊目标;bot 必须指定 robot-code 和一类目标;webhook 必须指定 webhook-token;幂等键仅 user 支持"
}, },
"effect": { "effect": {
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "write" "value": "write"
@@ -74103,7 +74103,7 @@
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "write" "value": "write"
}, },
@@ -74111,7 +74111,7 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Agent-authored from the verified identity/content capability matrix, userId resolution, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.", "review_reason": "Agent-authored from the verified identity/content capability matrix, live-compatible contact search with exact userId matching, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"value": [ "value": [
@@ -74122,7 +74122,7 @@
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Agent-authored from the verified identity/content capability matrix, userId resolution, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.", "review_reason": "Agent-authored from the verified identity/content capability matrix, live-compatible contact search with exact userId matching, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.",
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"value": [ "value": [
"dws chat +messages-send --as user --chat-id \u003copenConversationId\u003e --markdown \"## 周报\" --idempotency-key \u003ckey\u003e", "dws chat +messages-send --as user --chat-id \u003copenConversationId\u003e --markdown \"## 周报\" --idempotency-key \u003ckey\u003e",
@@ -74133,7 +74133,7 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "unknown" "value": "unknown"
@@ -74147,7 +74147,7 @@
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "unknown" "value": "unknown"
}, },
@@ -74155,7 +74155,7 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "composite" "value": "composite"
@@ -74163,7 +74163,7 @@
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "composite" "value": "composite"
}, },
@@ -74171,17 +74171,17 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "Reviewed composite send adapter: it selects current-user, bot, or webhook transport; current-user additionally supports userId resolution, mediaId images, and the native init/upload/commit local-file flow." "value": "Reviewed composite send adapter: it selects current-user, bot, or webhook transport; current-user additionally supports live-compatible contact search with exact userId matching, mediaId images, and the native init/upload/commit local-file flow."
} }
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "Reviewed composite send adapter: it selects current-user, bot, or webhook transport; current-user additionally supports userId resolution, mediaId images, and the native init/upload/commit local-file flow." "value": "Reviewed composite send adapter: it selects current-user, bot, or webhook transport; current-user additionally supports live-compatible contact search with exact userId matching, mediaId images, and the native init/upload/commit local-file flow."
}, },
"interface_ref": { "interface_ref": {
"candidates": [ "candidates": [
@@ -74203,14 +74203,14 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": true "value": true
}, },
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Agent-authored from the verified identity/content capability matrix, userId resolution, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.", "review_reason": "Agent-authored from the verified identity/content capability matrix, live-compatible contact search with exact userId matching, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.",
"selected": false, "selected": false,
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"value": true "value": true
@@ -74218,7 +74218,7 @@
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": true "value": true
}, },
@@ -74226,7 +74226,7 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "medium" "value": "medium"
@@ -74240,7 +74240,7 @@
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "medium" "value": "medium"
}, },
@@ -74262,27 +74262,27 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Agent-authored from the verified identity/content capability matrix, userId resolution, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.", "review_reason": "Agent-authored from the verified identity/content capability matrix, live-compatible contact search with exact userId matching, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"value": [ "value": [
"当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先只读解析为 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。" "当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先通过通讯录关键词搜索并按 userId 精确匹配 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。"
] ]
} }
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Agent-authored from the verified identity/content capability matrix, userId resolution, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.", "review_reason": "Agent-authored from the verified identity/content capability matrix, live-compatible contact search with exact userId matching, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.",
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"value": [ "value": [
"当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先只读解析为 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。" "当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先通过通讯录关键词搜索并按 userId 精确匹配 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。"
] ]
} }
}, },
"has_parameters": true, "has_parameters": true,
"idempotency": "unknown", "idempotency": "unknown",
"interface_mode": "composite", "interface_mode": "composite",
"interface_reason": "Reviewed composite send adapter: it selects current-user, bot, or webhook transport; current-user additionally supports userId resolution, mediaId images, and the native init/upload/commit local-file flow.", "interface_reason": "Reviewed composite send adapter: it selects current-user, bot, or webhook transport; current-user additionally supports live-compatible contact search with exact userId matching, mediaId images, and the native init/upload/commit local-file flow.",
"is_alias": false, "is_alias": false,
"name": "shortcut_messages_send", "name": "shortcut_messages_send",
"parameter_count": 24, "parameter_count": 24,
@@ -76120,7 +76120,7 @@
"type": "string" "type": "string"
}, },
"user": { "user": {
"description": "单聊接收者 userId(user;包括 --dry-run 也会先只读解析 openDingTalkId);受发送身份能力矩阵约束", "description": "单聊接收者 userId(user;包括 --dry-run 也会先通过通讯录搜索精确匹配 openDingTalkId);受发送身份能力矩阵约束",
"field_provenance": { "field_provenance": {
"description": { "description": {
"candidates": [ "candidates": [
@@ -76128,7 +76128,7 @@
"precedence": "cobra_contract", "precedence": "cobra_contract",
"selected": true, "selected": true,
"source": "cobra_usage", "source": "cobra_usage",
"value": "单聊接收者 userId(user;包括 --dry-run 也会先只读解析 openDingTalkId);受发送身份能力矩阵约束" "value": "单聊接收者 userId(user;包括 --dry-run 也会先通过通讯录搜索精确匹配 openDingTalkId);受发送身份能力矩阵约束"
}, },
{ {
"precedence": "default", "precedence": "default",
@@ -76140,7 +76140,7 @@
"precedence": "cobra_contract", "precedence": "cobra_contract",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"source": "cobra_usage", "source": "cobra_usage",
"value": "单聊接收者 userId(user;包括 --dry-run 也会先只读解析 openDingTalkId);受发送身份能力矩阵约束" "value": "单聊接收者 userId(user;包括 --dry-run 也会先通过通讯录搜索精确匹配 openDingTalkId);受发送身份能力矩阵约束"
}, },
"property": { "property": {
"candidates": [ "candidates": [
@@ -76464,7 +76464,7 @@
"source": "reviewed_command_registry", "source": "reviewed_command_registry",
"title": "统一发送文本、Markdown、当前用户文件或已有 mediaId 图片", "title": "统一发送文本、Markdown、当前用户文件或已有 mediaId 图片",
"use_when": [ "use_when": [
"当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先只读解析为 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。" "当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先通过通讯录关键词搜索并按 userId 精确匹配 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。"
] ]
}, },
"chat.shortcut_messages_send_by_webhook": { "chat.shortcut_messages_send_by_webhook": {
@@ -77361,7 +77361,7 @@
] ]
] ]
}, },
"description": "当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 做只读通讯录解析,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。\n\n参数约束:\n - --group、--receiver、--receiver-open-dingtalk-id 必须且只能指定一个\n - --flow-status 必须在 1-5 之间,且显式指定时必须同时提供 --content", "description": "当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 通过通讯录关键词搜索做精确匹配,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。\n\n参数约束:\n - --group、--receiver、--receiver-open-dingtalk-id 必须且只能指定一个\n - --flow-status 必须在 1-5 之间,且显式指定时必须同时提供 --content",
"display": "群聊 / 消息 / 机器人", "display": "群聊 / 消息 / 机器人",
"effect": "write", "effect": "write",
"effect_source": "agent-hint", "effect_source": "agent-hint",
@@ -77374,7 +77374,7 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.", "review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, live-compatible contact search with exact userId matching, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"value": "创建流式卡片,可在同一次调用中写入内容并结束" "value": "创建流式卡片,可在同一次调用中写入内容并结束"
@@ -77382,7 +77382,7 @@
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.", "review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, live-compatible contact search with exact userId matching, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.",
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"value": "创建流式卡片,可在同一次调用中写入内容并结束" "value": "创建流式卡片,可在同一次调用中写入内容并结束"
}, },
@@ -77390,7 +77390,7 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "available" "value": "available"
@@ -77398,7 +77398,7 @@
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "available" "value": "available"
}, },
@@ -77406,7 +77406,7 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.", "review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, live-compatible contact search with exact userId matching, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"value": [ "value": [
@@ -77416,7 +77416,7 @@
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.", "review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, live-compatible contact search with exact userId matching, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.",
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"value": [ "value": [
"已有 bizId、只需要追加或更新现有卡片内容时使用 +messages-update-card" "已有 bizId、只需要追加或更新现有卡片内容时使用 +messages-update-card"
@@ -77433,7 +77433,7 @@
}, },
{ {
"precedence": "reviewed_manual", "precedence": "reviewed_manual",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"selected": false, "selected": false,
"source": "reviewed_manual_hint", "source": "reviewed_manual_hint",
"source_ref": "chat +messages-send-card", "source_ref": "chat +messages-send-card",
@@ -77450,7 +77450,7 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "user_required" "value": "user_required"
@@ -77458,7 +77458,7 @@
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "user_required" "value": "user_required"
}, },
@@ -77468,19 +77468,19 @@
"precedence": "cobra_help", "precedence": "cobra_help",
"selected": true, "selected": true,
"source": "cobra_help", "source": "cobra_help",
"value": "当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 做只读通讯录解析,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。\n\n参数约束:\n - --group、--receiver、--receiver-open-dingtalk-id 必须且只能指定一个\n - --flow-status 必须在 1-5 之间,且显式指定时必须同时提供 --content" "value": "当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 通过通讯录关键词搜索做精确匹配,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。\n\n参数约束:\n - --group、--receiver、--receiver-open-dingtalk-id 必须且只能指定一个\n - --flow-status 必须在 1-5 之间,且显式指定时必须同时提供 --content"
} }
], ],
"precedence": "cobra_help", "precedence": "cobra_help",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"source": "cobra_help", "source": "cobra_help",
"value": "当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 做只读通讯录解析,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。\n\n参数约束:\n - --group、--receiver、--receiver-open-dingtalk-id 必须且只能指定一个\n - --flow-status 必须在 1-5 之间,且显式指定时必须同时提供 --content" "value": "当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 通过通讯录关键词搜索做精确匹配,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。\n\n参数约束:\n - --group、--receiver、--receiver-open-dingtalk-id 必须且只能指定一个\n - --flow-status 必须在 1-5 之间,且显式指定时必须同时提供 --content"
}, },
"effect": { "effect": {
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "write" "value": "write"
@@ -77488,7 +77488,7 @@
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "write" "value": "write"
}, },
@@ -77496,7 +77496,7 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.", "review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, live-compatible contact search with exact userId matching, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"value": [ "value": [
@@ -77507,7 +77507,7 @@
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.", "review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, live-compatible contact search with exact userId matching, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.",
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"value": [ "value": [
"dws chat +messages-send-card --group \u003copenConversationId\u003e --content \"任务已完成\"", "dws chat +messages-send-card --group \u003copenConversationId\u003e --content \"任务已完成\"",
@@ -77518,7 +77518,7 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "unknown" "value": "unknown"
@@ -77526,7 +77526,7 @@
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "unknown" "value": "unknown"
}, },
@@ -77534,7 +77534,7 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "composite" "value": "composite"
@@ -77542,7 +77542,7 @@
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "composite" "value": "composite"
}, },
@@ -77550,17 +77550,17 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "Reviewed card lifecycle adapter: it can call create_and_send_card alone or compose it with update_streaming_card after extracting the returned bizId." "value": "Reviewed card lifecycle adapter: it can resolve a userId through contact search with exact matching, call create_and_send_card alone, or compose creation with update_streaming_card after extracting the returned bizId."
} }
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "Reviewed card lifecycle adapter: it can call create_and_send_card alone or compose it with update_streaming_card after extracting the returned bizId." "value": "Reviewed card lifecycle adapter: it can resolve a userId through contact search with exact matching, call create_and_send_card alone, or compose creation with update_streaming_card after extracting the returned bizId."
}, },
"interface_ref": { "interface_ref": {
"candidates": [ "candidates": [
@@ -77582,14 +77582,14 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": true "value": true
}, },
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.", "review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, live-compatible contact search with exact userId matching, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.",
"selected": false, "selected": false,
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"value": true "value": true
@@ -77597,7 +77597,7 @@
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": true "value": true
}, },
@@ -77605,7 +77605,7 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "medium" "value": "medium"
@@ -77613,7 +77613,7 @@
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"source": "internal/cli/schema_hints/metadata/chat.json", "source": "internal/cli/schema_hints/metadata/chat.json",
"value": "medium" "value": "medium"
}, },
@@ -77635,27 +77635,27 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.", "review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, live-compatible contact search with exact userId matching, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.",
"selected": true, "selected": true,
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"value": [ "value": [
"当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 做只读通讯录解析,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。" "当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 通过通讯录关键词搜索做精确匹配,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。"
] ]
} }
], ],
"precedence": "reviewed_explicit", "precedence": "reviewed_explicit",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.", "review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, live-compatible contact search with exact userId matching, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.",
"source": "internal/cli/schema_hints/selection/chat.json", "source": "internal/cli/schema_hints/selection/chat.json",
"value": [ "value": [
"当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 做只读通讯录解析,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。" "当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 通过通讯录关键词搜索做精确匹配,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。"
] ]
} }
}, },
"has_parameters": true, "has_parameters": true,
"idempotency": "unknown", "idempotency": "unknown",
"interface_mode": "composite", "interface_mode": "composite",
"interface_reason": "Reviewed card lifecycle adapter: it can call create_and_send_card alone or compose it with update_streaming_card after extracting the returned bizId.", "interface_reason": "Reviewed card lifecycle adapter: it can resolve a userId through contact search with exact matching, call create_and_send_card alone, or compose creation with update_streaming_card after extracting the returned bizId.",
"is_alias": false, "is_alias": false,
"name": "shortcut_messages_send_card", "name": "shortcut_messages_send_card",
"parameter_count": 5, "parameter_count": 5,
@@ -77926,7 +77926,7 @@
"type": "string" "type": "string"
}, },
"receiver": { "receiver": {
"description": "单聊接收者 userId(与 --group/--receiver-open-dingtalk-id 互斥);始终只读解析为 openDingTalkId,包括 --dry-run 和 D/d 开头的 userId", "description": "单聊接收者 userId(与 --group/--receiver-open-dingtalk-id 互斥);始终通过通讯录搜索精确匹配 openDingTalkId,包括 --dry-run 和 D/d 开头的 userId",
"field_provenance": { "field_provenance": {
"description": { "description": {
"candidates": [ "candidates": [
@@ -77934,7 +77934,7 @@
"precedence": "cobra_contract", "precedence": "cobra_contract",
"selected": true, "selected": true,
"source": "cobra_usage", "source": "cobra_usage",
"value": "单聊接收者 userId(与 --group/--receiver-open-dingtalk-id 互斥);始终只读解析为 openDingTalkId,包括 --dry-run 和 D/d 开头的 userId" "value": "单聊接收者 userId(与 --group/--receiver-open-dingtalk-id 互斥);始终通过通讯录搜索精确匹配 openDingTalkId,包括 --dry-run 和 D/d 开头的 userId"
}, },
{ {
"precedence": "default", "precedence": "default",
@@ -77946,7 +77946,7 @@
"precedence": "cobra_contract", "precedence": "cobra_contract",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"source": "cobra_usage", "source": "cobra_usage",
"value": "单聊接收者 userId(与 --group/--receiver-open-dingtalk-id 互斥);始终只读解析为 openDingTalkId,包括 --dry-run 和 D/d 开头的 userId" "value": "单聊接收者 userId(与 --group/--receiver-open-dingtalk-id 互斥);始终通过通讯录搜索精确匹配 openDingTalkId,包括 --dry-run 和 D/d 开头的 userId"
}, },
"property": { "property": {
"candidates": [ "candidates": [
@@ -78042,7 +78042,7 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_manual", "precedence": "reviewed_manual",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"selected": true, "selected": true,
"source": "reviewed_manual_hint", "source": "reviewed_manual_hint",
"value": "receiverOpenDingTalkId" "value": "receiverOpenDingTalkId"
@@ -78056,7 +78056,7 @@
], ],
"precedence": "reviewed_manual", "precedence": "reviewed_manual",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"source": "reviewed_manual_hint", "source": "reviewed_manual_hint",
"value": "receiverOpenDingTalkId" "value": "receiverOpenDingTalkId"
}, },
@@ -78064,7 +78064,7 @@
"candidates": [ "candidates": [
{ {
"precedence": "reviewed_manual", "precedence": "reviewed_manual",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"selected": true, "selected": true,
"source": "reviewed_manual_hint", "source": "reviewed_manual_hint",
"value": false "value": false
@@ -78084,7 +78084,7 @@
], ],
"precedence": "reviewed_manual", "precedence": "reviewed_manual",
"resolution": "highest_precedence", "resolution": "highest_precedence",
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"source": "reviewed_manual_hint", "source": "reviewed_manual_hint",
"value": false "value": false
}, },
@@ -78130,7 +78130,7 @@
"source": "reviewed_command_registry", "source": "reviewed_command_registry",
"title": "创建流式卡片,可在同一次调用中写入内容并结束", "title": "创建流式卡片,可在同一次调用中写入内容并结束",
"use_when": [ "use_when": [
"当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 做只读通讯录解析,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。" "当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 通过通讯录关键词搜索做精确匹配,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。"
] ]
}, },
"chat.shortcut_messages_update_card": { "chat.shortcut_messages_update_card": {
+4 -4
View File
@@ -1172,9 +1172,9 @@
"idempotency": "unknown", "idempotency": "unknown",
"interface_mode": "composite", "interface_mode": "composite",
"availability": "available", "availability": "available",
"interface_reason": "Reviewed composite send adapter: it selects current-user, bot, or webhook transport; current-user additionally supports userId resolution, mediaId images, and the native init/upload/commit local-file flow.", "interface_reason": "Reviewed composite send adapter: it selects current-user, bot, or webhook transport; current-user additionally supports live-compatible contact search with exact userId matching, mediaId images, and the native init/upload/commit local-file flow.",
"reviewed": true, "reviewed": true,
"review_reason": "Reviewed against every executable identity/content/target validation branch and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.", "review_reason": "Reviewed against every executable identity/content/target validation branch, authenticated contact-search response shape, and the real lower tool mappings; bot and webhook media are intentionally rejected because no equivalent lower capability exists.",
"cli_path": "chat +messages-send", "cli_path": "chat +messages-send",
"runtime_gate": "typed_yes" "runtime_gate": "typed_yes"
}, },
@@ -1198,7 +1198,7 @@
"idempotency": "unknown", "idempotency": "unknown",
"interface_mode": "composite", "interface_mode": "composite",
"availability": "available", "availability": "available",
"interface_reason": "Reviewed card lifecycle adapter: it can call create_and_send_card alone or compose it with update_streaming_card after extracting the returned bizId.", "interface_reason": "Reviewed card lifecycle adapter: it can resolve a userId through contact search with exact matching, call create_and_send_card alone, or compose creation with update_streaming_card after extracting the returned bizId.",
"parameters": { "parameters": {
"receiver-open-dingtalk-id": { "receiver-open-dingtalk-id": {
"property": "receiverOpenDingTalkId", "property": "receiverOpenDingTalkId",
@@ -1206,7 +1206,7 @@
} }
}, },
"reviewed": true, "reviewed": true,
"review_reason": "Reviewed against create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.", "review_reason": "Reviewed against authenticated contact-search resolution, create-only, two-action dry-run, create/update success, missing bizId, and partial-failure behavior that preserves the created bizId; the explicit openDingTalkId flag is bound to the lower interface's exact receiverOpenDingTalkId property.",
"cli_path": "chat +messages-send-card", "cli_path": "chat +messages-send-card",
"runtime_gate": "typed_yes" "runtime_gate": "typed_yes"
}, },
@@ -2133,7 +2133,7 @@
"chat.shortcut_messages_send": { "chat.shortcut_messages_send": {
"agent_summary": "统一发送文本、Markdown、当前用户文件或已有 mediaId 图片", "agent_summary": "统一发送文本、Markdown、当前用户文件或已有 mediaId 图片",
"use_when": [ "use_when": [
"当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先只读解析为 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。" "当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先通过通讯录关键词搜索并按 userId 精确匹配 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。"
], ],
"avoid_when": [ "avoid_when": [
"需要 bot/webhook 发送媒体、卡片或 thread 回复时不要假设等价支持;改用真实存在的专用下层命令,缺少下层能力时停止" "需要 bot/webhook 发送媒体、卡片或 thread 回复时不要假设等价支持;改用真实存在的专用下层命令,缺少下层能力时停止"
@@ -2143,7 +2143,7 @@
"dws chat +messages-send --as user --user <userId> --msg-type file --file ./report.pdf" "dws chat +messages-send --as user --user <userId> --msg-type file --file ./report.pdf"
], ],
"reviewed": true, "reviewed": true,
"review_reason": "Agent-authored from the verified identity/content capability matrix, userId resolution, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.", "review_reason": "Agent-authored from the verified identity/content capability matrix, live-compatible contact search with exact userId matching, native local-file upload flow, and fail-closed rejection of unsupported bot/webhook media.",
"source_refs": [ "source_refs": [
"internal/cli/schema_command_registry.json#chat.shortcut_messages_send", "internal/cli/schema_command_registry.json#chat.shortcut_messages_send",
"cobra-help:dws chat +messages-send", "cobra-help:dws chat +messages-send",
@@ -2172,7 +2172,7 @@
"chat.shortcut_messages_send_card": { "chat.shortcut_messages_send_card": {
"agent_summary": "创建流式卡片,可在同一次调用中写入内容并结束", "agent_summary": "创建流式卡片,可在同一次调用中写入内容并结束",
"use_when": [ "use_when": [
"当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 做只读通讯录解析,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。" "当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 通过通讯录关键词搜索做精确匹配,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。"
], ],
"avoid_when": [ "avoid_when": [
"已有 bizId、只需要追加或更新现有卡片内容时使用 +messages-update-card" "已有 bizId、只需要追加或更新现有卡片内容时使用 +messages-update-card"
@@ -2182,7 +2182,7 @@
"dws chat +messages-send-card --receiver <userId>" "dws chat +messages-send-card --receiver <userId>"
], ],
"reviewed": true, "reviewed": true,
"review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.", "review_reason": "Agent-authored from the verified create-only and create-then-update lifecycle, live-compatible contact search with exact userId matching, explicit userId/openDingTalkId routing, two-action dry-run, bizId extraction, and partial-failure reporting.",
"source_refs": [ "source_refs": [
"internal/cli/schema_command_registry.json#chat.shortcut_messages_send_card", "internal/cli/schema_command_registry.json#chat.shortcut_messages_send_card",
"cobra-help:dws chat +messages-send-card", "cobra-help:dws chat +messages-send-card",
+2 -2
View File
@@ -1015,11 +1015,11 @@ var MessagesSendCard = shortcut.Shortcut{
Command: "+messages-send-card", Command: "+messages-send-card",
Product: "im", Product: "im",
Description: "创建流式卡片,可在同一次调用中写入内容并结束", Description: "创建流式卡片,可在同一次调用中写入内容并结束",
Intent: "当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 做只读通讯录解析,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。", Intent: "当你要发送一张流式卡片消息时使用;群 openConversationId、单聊 userId、单聊 openDingTalkId 严格三选一,分别使用 --group、--receiver、--receiver-open-dingtalk-id。--receiver 始终按 userId 通过通讯录关键词搜索做精确匹配,即使值以 D/d 开头也不会猜成 openDingTalkId;已有 openDingTalkId 时必须用显式参数直传。userId 包括在 --dry-run 时也会先解析。只传目标时创建卡片并返回 bizId,供后续 messages-update-card 流式更新;同时传 --content 时会自动串联创建和更新,默认以 flowStatus=3 完成,避免卡片停留在加载中。",
Risk: shortcut.RiskWrite, Risk: shortcut.RiskWrite,
Flags: []shortcut.Flag{ Flags: []shortcut.Flag{
{Name: "group", Type: shortcut.FlagString, Desc: "群 openConversationId(与两个单聊接收者参数互斥)"}, {Name: "group", Type: shortcut.FlagString, Desc: "群 openConversationId(与两个单聊接收者参数互斥)"},
{Name: "receiver", Type: shortcut.FlagString, Desc: "单聊接收者 userId(与 --group/--receiver-open-dingtalk-id 互斥);始终只读解析为 openDingTalkId,包括 --dry-run 和 D/d 开头的 userId"}, {Name: "receiver", Type: shortcut.FlagString, Desc: "单聊接收者 userId(与 --group/--receiver-open-dingtalk-id 互斥);始终通过通讯录搜索精确匹配 openDingTalkId,包括 --dry-run 和 D/d 开头的 userId"},
{Name: "receiver-open-dingtalk-id", Type: shortcut.FlagString, Desc: "单聊接收者 openDingTalkId(与 --group/--receiver 互斥);显式直传且不做通讯录解析"}, {Name: "receiver-open-dingtalk-id", Type: shortcut.FlagString, Desc: "单聊接收者 openDingTalkId(与 --group/--receiver 互斥);显式直传且不做通讯录解析"},
{Name: "content", Type: shortcut.FlagString, Desc: "创建后立即写入的卡片内容;省略时仅创建并返回 bizId"}, {Name: "content", Type: shortcut.FlagString, Desc: "创建后立即写入的卡片内容;省略时仅创建并返回 bizId"},
{Name: "flow-status", Type: shortcut.FlagInt, Default: "3", Desc: "自动更新状态:1处理中/2输入中/3完成/4执行中/5错误;--flow-status 必须在 1-5 之间,且显式指定时必须同时提供 --content"}, {Name: "flow-status", Type: shortcut.FlagInt, Default: "3", Desc: "自动更新状态:1处理中/2输入中/3完成/4执行中/5错误;--flow-status 必须在 1-5 之间,且显式指定时必须同时提供 --content"},
@@ -120,17 +120,17 @@ func TestCrossPlatformCoverageChatCreateAndReplyFailures(t *testing.T) {
}, },
{ {
name: "explicit sender lookup", name: "explicit sender lookup",
caller: &larkAlignmentCaller{failProductTool: "contact/get_user_info_by_user_ids"}, caller: &larkAlignmentCaller{failProductTool: "contact/search_contact_by_key_word"},
args: []string{"chat", "+messages-reply", "--conversation-id", "cid", "--message-id", "msg", "--ref-sender", "user-id", "--text", "收到", "--yes"}, args: []string{"chat", "+messages-reply", "--conversation-id", "cid", "--message-id", "msg", "--ref-sender", "user-id", "--text", "收到", "--yes"},
wantError: "解析为 openDingTalkId", wantError: "解析为 openDingTalkId",
}, },
{ {
name: "explicit sender unresolved", name: "explicit sender unresolved",
caller: &larkAlignmentCaller{responses: map[string]string{ caller: &larkAlignmentCaller{responses: map[string]string{
"contact/get_user_info_by_user_ids": `{"result":[]}`, "contact/search_contact_by_key_word": `{"result":[]}`,
}}, }},
args: []string{"chat", "+messages-reply", "--conversation-id", "cid", "--message-id", "msg", "--ref-sender", "user-id", "--text", "收到", "--yes"}, args: []string{"chat", "+messages-reply", "--conversation-id", "cid", "--message-id", "msg", "--ref-sender", "user-id", "--text", "收到", "--yes"},
wantError: "无法把 --ref-sender", wantError: "没有精确匹配",
}, },
{ {
name: "referenced message lookup", name: "referenced message lookup",
+17 -8
View File
@@ -80,9 +80,12 @@ func TestCrossPlatformCoverageMessagesSendCurrentUserImageAndUserResolution(t *t
if len(fake.calls) != 2 { if len(fake.calls) != 2 {
t.Fatalf("calls = %#v, want contact resolution + send", fake.calls) t.Fatalf("calls = %#v, want contact resolution + send", fake.calls)
} }
if fake.calls[0].product != "contact" || fake.calls[0].tool != "get_user_info_by_user_ids" { if fake.calls[0].product != "contact" || fake.calls[0].tool != "search_contact_by_key_word" {
t.Fatalf("resolution call = %#v", fake.calls[0]) t.Fatalf("resolution call = %#v", fake.calls[0])
} }
if got := fake.calls[0].args["keyword"]; got != "user-id" {
t.Fatalf("resolution keyword = %#v, want user-id", got)
}
send := fake.calls[1] send := fake.calls[1]
if send.product != "chat" || send.tool != "send_personal_message" { if send.product != "chat" || send.tool != "send_personal_message" {
t.Fatalf("send call = %#v", send) t.Fatalf("send call = %#v", send)
@@ -284,9 +287,15 @@ func TestCrossPlatformCoverageMessagesSendUserResolutionFailures(t *testing.T) {
name string name string
fake *larkAlignmentCaller fake *larkAlignmentCaller
}{ }{
{"lookup error", &larkAlignmentCaller{failProductTool: "contact/get_user_info_by_user_ids"}}, {"lookup error", &larkAlignmentCaller{failProductTool: "contact/search_contact_by_key_word"}},
{"no exact user id", &larkAlignmentCaller{responses: map[string]string{
"contact/search_contact_by_key_word": `{"result":[{"userId":"other-user","openDingTalkId":"D-other"}]}`,
}}},
{"missing open id", &larkAlignmentCaller{responses: map[string]string{ {"missing open id", &larkAlignmentCaller{responses: map[string]string{
"contact/get_user_info_by_user_ids": `{"result":[]}`, "contact/search_contact_by_key_word": `{"result":[{"userId":"user-id","name":"Resolved User"}]}`,
}}},
{"ambiguous open id", &larkAlignmentCaller{responses: map[string]string{
"contact/search_contact_by_key_word": `{"result":[{"userId":"user-id","openDingTalkId":"D-one"},{"userId":"user-id","openDingTalkId":"D-two"}]}`,
}}}, }}},
} { } {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
@@ -394,7 +403,7 @@ func TestCrossPlatformCoverageMessagesSendCardResolvesReceiverForLowerTool(t *te
} }
if len(fake.calls) != 2 || if len(fake.calls) != 2 ||
fake.calls[0].product != "contact" || fake.calls[0].product != "contact" ||
fake.calls[0].tool != "get_user_info_by_user_ids" || fake.calls[0].tool != "search_contact_by_key_word" ||
fake.calls[1].product != "im" || fake.calls[1].product != "im" ||
fake.calls[1].tool != "create_and_send_card" { fake.calls[1].tool != "create_and_send_card" {
t.Fatalf("card receiver calls = %#v", fake.calls) t.Fatalf("card receiver calls = %#v", fake.calls)
@@ -402,7 +411,7 @@ func TestCrossPlatformCoverageMessagesSendCardResolvesReceiverForLowerTool(t *te
if got := fake.calls[1].args["receiverOpenDingTalkId"]; got != "D-resolved" { if got := fake.calls[1].args["receiverOpenDingTalkId"]; got != "D-resolved" {
t.Fatalf("receiverOpenDingTalkId = %#v, want D-resolved", got) t.Fatalf("receiverOpenDingTalkId = %#v, want D-resolved", got)
} }
if got := fake.calls[0].args["user_id_list"]; !reflect.DeepEqual(got, []string{"d-user-id"}) { if got := fake.calls[0].args["keyword"]; got != "d-user-id" {
t.Fatalf("D/d-prefixed userId resolution args = %#v", fake.calls[0].args) t.Fatalf("D/d-prefixed userId resolution args = %#v", fake.calls[0].args)
} }
if _, exists := fake.calls[1].args["receiverUid"]; exists { if _, exists := fake.calls[1].args["receiverUid"]; exists {
@@ -469,7 +478,7 @@ func TestCrossPlatformCoverageMessagesSendCardDryRunAndFailureBoundaries(t *test
} }
if len(fake.calls) != 1 || if len(fake.calls) != 1 ||
fake.calls[0].product != "contact" || fake.calls[0].product != "contact" ||
fake.calls[0].tool != "get_user_info_by_user_ids" { fake.calls[0].tool != "search_contact_by_key_word" {
t.Fatalf("card dry-run receiver resolution calls = %#v", fake.calls) t.Fatalf("card dry-run receiver resolution calls = %#v", fake.calls)
} }
var payload map[string]any var payload map[string]any
@@ -486,7 +495,7 @@ func TestCrossPlatformCoverageMessagesSendCardDryRunAndFailureBoundaries(t *test
}) })
t.Run("receiver resolution error", func(t *testing.T) { t.Run("receiver resolution error", func(t *testing.T) {
fake := &larkAlignmentCaller{failProductTool: "contact/get_user_info_by_user_ids"} fake := &larkAlignmentCaller{failProductTool: "contact/search_contact_by_key_word"}
helpers.InitDeps(fake) helpers.InitDeps(fake)
root := newPlatformCoverageRoot() root := newPlatformCoverageRoot()
root.SetArgs([]string{ root.SetArgs([]string{
@@ -498,7 +507,7 @@ func TestCrossPlatformCoverageMessagesSendCardDryRunAndFailureBoundaries(t *test
if err == nil || !strings.Contains(err.Error(), "解析为 openDingTalkId 失败") { if err == nil || !strings.Contains(err.Error(), "解析为 openDingTalkId 失败") {
t.Fatalf("receiver resolution error = %v", err) t.Fatalf("receiver resolution error = %v", err)
} }
if len(fake.calls) != 1 || fake.calls[0].tool != "get_user_info_by_user_ids" { if len(fake.calls) != 1 || fake.calls[0].tool != "search_contact_by_key_word" {
t.Fatalf("receiver resolution calls = %#v", fake.calls) t.Fatalf("receiver resolution calls = %#v", fake.calls)
} }
}) })
+4 -9
View File
@@ -139,13 +139,13 @@ var MessagesReply = shortcut.Shortcut{
Command: "+messages-reply", Command: "+messages-reply",
Product: "chat", Product: "chat",
Description: "以当前用户身份引用回复消息(自动补全原发送者)", Description: "以当前用户身份引用回复消息(自动补全原发送者)",
Intent: "当你要以当前用户身份对已有消息发送纯文本引用回复时使用;提供会话和被引用消息即可,默认通过 mget 自动读取原发送者,也可显式传 openDingTalkId/userId。它不支持 bot 身份、富媒体、卡片或 thread 内回复。", Intent: "当你要以当前用户身份对已有消息发送纯文本引用回复时使用;提供会话和被引用消息即可,默认通过 mget 自动读取原发送者,也可显式传 openDingTalkId/userId;userId 会通过通讯录搜索精确匹配 openDingTalkId。它不支持 bot 身份、富媒体、卡片或 thread 内回复。",
Risk: shortcut.RiskWrite, Risk: shortcut.RiskWrite,
Flags: []shortcut.Flag{ Flags: []shortcut.Flag{
{Name: "conversation-id", Type: shortcut.FlagString, Desc: "会话 openConversationId", Required: true}, {Name: "conversation-id", Type: shortcut.FlagString, Desc: "会话 openConversationId", Required: true},
{Name: "ref-msg-id", Type: shortcut.FlagString, Desc: "被引用消息 openMessageId"}, {Name: "ref-msg-id", Type: shortcut.FlagString, Desc: "被引用消息 openMessageId"},
{Name: "message-id", Type: shortcut.FlagString, Desc: "--ref-msg-id 的 lark-cli 对齐别名"}, {Name: "message-id", Type: shortcut.FlagString, Desc: "--ref-msg-id 的 lark-cli 对齐别名"},
{Name: "ref-sender", Type: shortcut.FlagString, Desc: "原消息发送者 openDingTalkId/userId(不传则自动读取)"}, {Name: "ref-sender", Type: shortcut.FlagString, Desc: "原消息发送者 openDingTalkId/userId(userId 通过通讯录搜索精确匹配;不传则自动读取)"},
{Name: "text", Type: shortcut.FlagString, Desc: "纯文本回复内容", Required: true}, {Name: "text", Type: shortcut.FlagString, Desc: "纯文本回复内容", Required: true},
{Name: "uuid", Type: shortcut.FlagString, Desc: "幂等键(可选)"}, {Name: "uuid", Type: shortcut.FlagString, Desc: "幂等键(可选)"},
{Name: "idempotency-key", Type: shortcut.FlagString, Desc: "--uuid 的 lark-cli 对齐别名"}, {Name: "idempotency-key", Type: shortcut.FlagString, Desc: "--uuid 的 lark-cli 对齐别名"},
@@ -184,16 +184,11 @@ func resolveReplySender(rt *shortcut.RuntimeContext) (string, error) {
if isOpenID(value) { if isOpenID(value) {
return value, nil return value, nil
} }
data, err := rt.CallMCPData("contact", "get_user_info_by_user_ids", map[string]any{ openID, err := resolveUserOpenDingTalkID(rt, value)
"user_id_list": []string{value},
})
if err != nil { if err != nil {
return "", fmt.Errorf("把 --ref-sender userId 解析为 openDingTalkId 失败: %w", err) return "", fmt.Errorf("把 --ref-sender userId 解析为 openDingTalkId 失败: %w", err)
} }
if openID := findOpenDingTalkID(data); openID != "" { return openID, nil
return openID, nil
}
return "", apperrors.NewValidation("无法把 --ref-sender 解析为 openDingTalkId")
} }
messageID := replyMessageID(rt) messageID := replyMessageID(rt)
+20 -3
View File
@@ -44,7 +44,24 @@ func (f *larkAlignmentCaller) CallTool(_ context.Context, product, tool string,
case "contact/get_current_user_profile": case "contact/get_current_user_profile":
text = `{"result":[{"orgEmployeeModel":{"userId":"self-user"}}]}` text = `{"result":[{"orgEmployeeModel":{"userId":"self-user"}}]}`
case "contact/get_user_info_by_user_ids": case "contact/get_user_info_by_user_ids":
text = `{"result":[{"userId":"user-id","openDingTalkId":"D-resolved"}]}` text = `{"result":[{"orgEmployeeModel":{"orgUserId":"user-id","orgUserName":"Resolved User"}}]}`
case "contact/search_contact_by_key_word":
keyword, _ := args["keyword"].(string)
payload, _ := json.Marshal(map[string]any{
"result": []map[string]any{
{
"name": "Fuzzy Neighbor",
"userId": keyword + "-other",
"openDingTalkId": "D-other",
},
{
"name": "Resolved User",
"userId": keyword,
"openDingTalkId": "D-resolved",
},
},
})
text = string(payload)
case "im/create_group_conversation": case "im/create_group_conversation":
text = `{"result":{"cid":"internal-cid","openCid":"open-cid"}}` text = `{"result":{"cid":"internal-cid","openCid":"open-cid"}}`
case "im/list_messages_by_ids": case "im/list_messages_by_ids":
@@ -403,7 +420,7 @@ func TestMessagesMgetDryRunPublishesMultiResourceDownloadPlan(t *testing.T) {
} }
} }
func TestMessagesReplyResolvesUserIDBeforeExecution(t *testing.T) { func TestCrossPlatformCoverageMessagesReplyResolvesUserIDBeforeExecution(t *testing.T) {
fake := &larkAlignmentCaller{} fake := &larkAlignmentCaller{}
helpers.InitDeps(fake) helpers.InitDeps(fake)
root := newPlatformCoverageRoot() root := newPlatformCoverageRoot()
@@ -420,7 +437,7 @@ func TestMessagesReplyResolvesUserIDBeforeExecution(t *testing.T) {
} }
if len(fake.calls) != 2 || if len(fake.calls) != 2 ||
fake.calls[0].product != "contact" || fake.calls[0].product != "contact" ||
fake.calls[0].tool != "get_user_info_by_user_ids" || fake.calls[0].tool != "search_contact_by_key_word" ||
fake.calls[1].tool != "send_personal_message" { fake.calls[1].tool != "send_personal_message" {
t.Fatalf("calls = %#v", fake.calls) t.Fatalf("calls = %#v", fake.calls)
} }
+35 -9
View File
@@ -28,14 +28,14 @@ var MessagesSend = shortcut.Shortcut{
Command: "+messages-send", Command: "+messages-send",
Product: "chat", Product: "chat",
Description: "统一发送文本、Markdown、当前用户文件或已有 mediaId 图片", Description: "统一发送文本、Markdown、当前用户文件或已有 mediaId 图片",
Intent: "当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先只读解析为 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。", Intent: "当你希望用同一个入口选择 current-user、bot 或 webhook 身份发送消息时使用;命令会按身份校验目标、内容和凭据并路由到真实下层。current-user 支持文本/Markdown、已有 mediaId 图片、安全相对路径文件上传和幂等键;--user 传 userId 时包括在 --dry-run 中也会先通过通讯录关键词搜索并按 userId 精确匹配 openDingTalkId。bot 支持群聊或批量单聊文本/Markdown;webhook 的目标由 token 所在群决定。不会把 user 文件能力伪装成 bot/webhook 等价能力。",
Risk: shortcut.RiskWrite, Risk: shortcut.RiskWrite,
Flags: []shortcut.Flag{ Flags: []shortcut.Flag{
{Name: "identity", Type: shortcut.FlagString, Default: "user", Enum: []string{"user", "bot", "webhook"}, Desc: "发送身份;目标、凭据和幂等参数受发送身份能力矩阵约束"}, {Name: "identity", Type: shortcut.FlagString, Default: "user", Enum: []string{"user", "bot", "webhook"}, Desc: "发送身份;目标、凭据和幂等参数受发送身份能力矩阵约束"},
{Name: "as", Type: shortcut.FlagString, Enum: []string{"user", "bot", "webhook"}, Desc: "--identity 的 lark-cli 对齐别名;受发送身份能力矩阵约束"}, {Name: "as", Type: shortcut.FlagString, Enum: []string{"user", "bot", "webhook"}, Desc: "--identity 的 lark-cli 对齐别名;受发送身份能力矩阵约束"},
{Name: "group", Type: shortcut.FlagString, Desc: "群 openConversationId(user/bot 群聊);受发送身份能力矩阵约束"}, {Name: "group", Type: shortcut.FlagString, Desc: "群 openConversationId(user/bot 群聊);受发送身份能力矩阵约束"},
{Name: "chat-id", Type: shortcut.FlagString, Desc: "--group 的 lark-cli 对齐别名;受发送身份能力矩阵约束"}, {Name: "chat-id", Type: shortcut.FlagString, Desc: "--group 的 lark-cli 对齐别名;受发送身份能力矩阵约束"},
{Name: "user", Type: shortcut.FlagString, Desc: "单聊接收者 userId(user;包括 --dry-run 也会先只读解析 openDingTalkId);受发送身份能力矩阵约束"}, {Name: "user", Type: shortcut.FlagString, Desc: "单聊接收者 userId(user;包括 --dry-run 也会先通过通讯录搜索精确匹配 openDingTalkId);受发送身份能力矩阵约束"},
{Name: "open-dingtalk-id", Type: shortcut.FlagString, Desc: "单聊接收者 openDingTalkId(user);受发送身份能力矩阵约束"}, {Name: "open-dingtalk-id", Type: shortcut.FlagString, Desc: "单聊接收者 openDingTalkId(user);受发送身份能力矩阵约束"},
{Name: "users", Type: shortcut.FlagStringSlice, Desc: "批量单聊接收者 userId(bot);受发送身份能力矩阵约束"}, {Name: "users", Type: shortcut.FlagStringSlice, Desc: "批量单聊接收者 userId(bot);受发送身份能力矩阵约束"},
{Name: "open-dingtalk-ids", Type: shortcut.FlagStringSlice, Desc: "批量单聊接收者 openDingTalkId(bot);受发送身份能力矩阵约束"}, {Name: "open-dingtalk-ids", Type: shortcut.FlagStringSlice, Desc: "批量单聊接收者 openDingTalkId(bot);受发送身份能力矩阵约束"},
@@ -368,17 +368,43 @@ func messagesSendUserTarget(rt *shortcut.RuntimeContext) (group, openID string,
func resolveUserOpenDingTalkID(rt *shortcut.RuntimeContext, userID string) (string, error) { func resolveUserOpenDingTalkID(rt *shortcut.RuntimeContext, userID string) (string, error) {
userID = strings.TrimSpace(userID) userID = strings.TrimSpace(userID)
data, err := rt.CallMCPData("contact", "get_user_info_by_user_ids", map[string]any{ data, err := rt.CallMCPData("contact", "search_contact_by_key_word", map[string]any{
"user_id_list": []string{userID}, "keyword": userID,
}) })
if err != nil { if err != nil {
return "", fmt.Errorf("把 userId 解析为 openDingTalkId 失败: %w", err) return "", fmt.Errorf("通过通讯录搜索把 userId %q 解析为 openDingTalkId 失败: %w", userID, err)
} }
openID := findOpenDingTalkID(data)
if openID == "" { exactRows := 0
return "", apperrors.NewValidation("无法把 userId 解析为 openDingTalkId;请改用当前命令提供的显式 openDingTalkId 参数") openIDs := make([]string, 0, 1)
for _, user := range shortcutMapSlice(data["result"]) {
if shortcutString(user, "userId", "userID") != userID {
continue
}
exactRows++
if openID := shortcutString(user, "openDingTalkId", "openDingtalkId"); openID != "" {
openIDs = appendUniqueShortcutString(openIDs, openID)
}
}
switch {
case len(openIDs) == 1:
return openIDs[0], nil
case len(openIDs) > 1:
return "", apperrors.NewValidation(fmt.Sprintf(
"通讯录中 userId %q 精确匹配到多个不同的 openDingTalkId,无法安全选择",
userID,
))
case exactRows > 0:
return "", apperrors.NewValidation(fmt.Sprintf(
"通讯录已精确匹配 userId %q,但结果未返回 openDingTalkId",
userID,
))
default:
return "", apperrors.NewValidation(fmt.Sprintf(
"通讯录搜索结果中没有精确匹配的 userId %q",
userID,
))
} }
return openID, nil
} }
func executeMessagesSendUserFile( func executeMessagesSendUserFile(
+4 -4
View File
@@ -273,8 +273,8 @@ alidocs 链接表面长得一样(`https://alidocs.dingtalk.com/i/nodes/{id}`
- "帮我在群里发个消息提醒大家" — **个人身份**发群消息 - "帮我在群里发个消息提醒大家" — **个人身份**发群消息
- "发个单聊消息给某人" — 个人身份发单聊: - "发个单聊消息给某人" — 个人身份发单聊:
- 已有 userId 时直接使用 `--user`;已有 openDingTalkId 时使用 `--open-dingtalk-id` - 已有 userId 时直接使用 `--user`;已有 openDingTalkId 时使用 `--open-dingtalk-id`
- 纯文本/Markdown 单聊传 `--user` 时直接走 userId 发送能力,不需要先手动查询 openDingTalkId - `+messages-send --user` 对所有内容类型都会通过通讯录关键词搜索并按 userId 精确匹配 openDingTalkId;无需手动预查,`--dry-run` 也会执行这次只读解析
- 富媒体消息(image/file)单聊优先使用 `--open-dingtalk-id`;传 `--user` 时 CLI 会尝试解析为 openDingTalkId 后发送 - 已持有 openDingTalkId 时优先使用显式 `--open-dingtalk-id`,避免额外解析
- "发本地图片/文件/语音/视频到群里" — `dws chat message send ... --msg-type file --file-path <本地路径>`,CLI 内部自动上传并发送;png/jpg/pdf/mp4/zip 等任意扩展名都走这条,接收方看到的是可下载的文件附件。图片不会内联渲染,也不会生成 mediaId - "发本地图片/文件/语音/视频到群里" — `dws chat message send ... --msg-type file --file-path <本地路径>`,CLI 内部自动上传并发送;png/jpg/pdf/mp4/zip 等任意扩展名都走这条,接收方看到的是可下载的文件附件。图片不会内联渲染,也不会生成 mediaId
- "用已有 mediaId 发内联图片" — 仅当上游已经提供有效 mediaId 时,使用 `dws chat message send ... --msg-type image --media-id <mediaId>`;DWS CLI 不能把本地图片转换成 mediaId - "用已有 mediaId 发内联图片" — 仅当上游已经提供有效 mediaId 时,使用 `dws chat message send ... --msg-type image --media-id <mediaId>`;DWS CLI 不能把本地图片转换成 mediaId
- "发图片+文字说明" — 不要硬塞进一条命令;先发图片/文件消息再补一条 `--text "..."` 即可 - "发图片+文字说明" — 不要硬塞进一条命令;先发图片/文件消息再补一条 `--text "..."` 即可
@@ -285,13 +285,13 @@ dws chat +messages-send --as user --open-dingtalk-id <openDingTalkId> --msg-type
``` ```
> ❌ 反模式:先把本地文件转换成 mediaId,或先经钉盘上传再拼装聊天消息。本地图片/文件一律用 `--msg-type file --file` 直发;`--msg-type image --media-id` 只接受上游已经提供的有效 mediaId。 > ❌ 反模式:先把本地文件转换成 mediaId,或先经钉盘上传再拼装聊天消息。本地图片/文件一律用 `--msg-type file --file` 直发;`--msg-type image --media-id` 只接受上游已经提供的有效 mediaId。
> 富媒体消息单聊优先使用 `--open-dingtalk-id`;传 `--user` 时 CLI 会尝试解析为 openDingTalkId 后发送。 > 单聊已持有 openDingTalkId 时优先使用 `--open-dingtalk-id`;传 `--user` 时 CLI 会通过通讯录关键词搜索做 userId 精确匹配后发送。
`+messages-send` 的 @ 占位符按身份自动规范化并补齐:user 使用 `<@id>` / `<@all>`;bot/webhook 使用 `@id` / `@手机号` / `@all`。声明 `--at-*` / `--at-all` 即可,不要再手工拼 `@10`。 `+messages-send` 的 @ 占位符按身份自动规范化并补齐:user 使用 `<@id>` / `<@all>`;bot/webhook 使用 `@id` / `@手机号` / `@all`。声明 `--at-*` / `--at-all` 即可,不要再手工拼 `@10`。
**用 `chat +messages-send-card` 的场景**: **用 `chat +messages-send-card` 的场景**:
- 群聊流式卡片使用 `--group <openConversationId>`。 - 群聊流式卡片使用 `--group <openConversationId>`。
- 单聊已有 userId 时使用 `--receiver <userId>`,CLI 始终先只读解析为 openDingTalkId;即使 userId 以 D/d 开头也不会猜测类型,`--dry-run` 也会执行该解析。 - 单聊已有 userId 时使用 `--receiver <userId>`,CLI 始终通过通讯录关键词搜索并按 userId 精确匹配 openDingTalkId;即使 userId 以 D/d 开头也不会猜测类型,`--dry-run` 也会执行该解析。
- 单聊已有 openDingTalkId 时必须显式使用 `--receiver-open-dingtalk-id <openDingTalkId>`,避免与 userId 混淆。 - 单聊已有 openDingTalkId 时必须显式使用 `--receiver-open-dingtalk-id <openDingTalkId>`,避免与 userId 混淆。
- `--group`、`--receiver`、`--receiver-open-dingtalk-id` 严格三选一;传 `--content` 可在同一次调用中创建并结束卡片。 - `--group`、`--receiver`、`--receiver-open-dingtalk-id` 严格三选一;传 `--content` 可在同一次调用中创建并结束卡片。
+2 -1
View File
@@ -130,7 +130,8 @@ metadata:
- 查询结果中的 `resourceRefs` 是可继续执行的资源上下文。引用、回复或合并转发中的子消息必须使用该子消息返回的 `messageId`;子消息缺会话 ID 时才继承父消息的 `openConversationId`。 - 查询结果中的 `resourceRefs` 是可继续执行的资源上下文。引用、回复或合并转发中的子消息必须使用该子消息返回的 `messageId`;子消息缺会话 ID 时才继承父消息的 `openConversationId`。
- 上述五个查询 Shortcut 与 `+messages-resource-download` 都沿用安全本地下载的 `read/not_required` 契约,不应添加 `--yes` 或触发交互确认。下载只允许工作目录内相对路径、默认不覆盖并原子落盘;需要覆盖时必须由用户显式传 `--overwrite`。 - 上述五个查询 Shortcut 与 `+messages-resource-download` 都沿用安全本地下载的 `read/not_required` 契约,不应添加 `--yes` 或触发交互确认。下载只允许工作目录内相对路径、默认不覆盖并原子落盘;需要覆盖时必须由用户显式传 `--overwrite`。
- `+messages-send` 会按身份规范化 @ 占位符:user 使用 `<@id>` / `<@all>`,bot/webhook 使用 `@id` / `@手机号` / `@all`;只需声明 `--at-*` / `--at-all`,缺失占位符会自动补齐。 - `+messages-send` 会按身份规范化 @ 占位符:user 使用 `<@id>` / `<@all>`,bot/webhook 使用 `@id` / `@手机号` / `@all`;只需声明 `--at-*` / `--at-all`,缺失占位符会自动补齐。
- 流式卡片优先用 `+messages-send-card`:群聊传 `--group`,单聊 userId 传 `--receiver` 并由 CLI 只读解析,已有 openDingTalkId 则必须显式传 `--receiver-open-dingtalk-id`;三者严格三选一,禁止根据首字母猜身份类型。 - `+messages-send --as user --user <userId>` 会通过通讯录关键词搜索并按 userId 精确匹配 openDingTalkId,所有内容类型与 `--dry-run` 都使用同一只读解析链路;已有 openDingTalkId 时直接传 `--open-dingtalk-id`。
- 流式卡片优先用 `+messages-send-card`:群聊传 `--group`,单聊 userId 传 `--receiver` 并由 CLI 通过通讯录关键词搜索做 userId 精确匹配,已有 openDingTalkId 则必须显式传 `--receiver-open-dingtalk-id`;三者严格三选一,禁止根据首字母猜身份类型。
## 意图表 ## 意图表
@@ -288,8 +288,8 @@ alidocs 链接表面长得一样(`https://alidocs.dingtalk.com/i/nodes/{id}`
- "帮我在群里发个消息提醒大家" — **个人身份**发群消息 - "帮我在群里发个消息提醒大家" — **个人身份**发群消息
- "发个单聊消息给某人" — 个人身份发单聊: - "发个单聊消息给某人" — 个人身份发单聊:
- 已有 userId 时直接使用 `--user`;已有 openDingTalkId 时使用 `--open-dingtalk-id` - 已有 userId 时直接使用 `--user`;已有 openDingTalkId 时使用 `--open-dingtalk-id`
- 纯文本/Markdown 单聊传 `--user` 时直接走 userId 发送能力,不需要先手动查询 openDingTalkId - `+messages-send --user` 对所有内容类型都会通过通讯录关键词搜索并按 userId 精确匹配 openDingTalkId;无需手动预查,`--dry-run` 也会执行这次只读解析
- 富媒体消息(image/file)单聊优先使用 `--open-dingtalk-id`;传 `--user` 时 CLI 会尝试解析为 openDingTalkId 后发送 - 已持有 openDingTalkId 时优先使用显式 `--open-dingtalk-id`,避免额外解析
- "发张图片/截图/语音/视频/文件到群里" / "发张图给某某" — **统一一条命令**:`dws chat message send ... --msg-type file --file-path <本地路径>`,CLI 内部自动上传并发送,**任意扩展名(png/jpg/pdf/mp4/zip…)都走这条** - "发张图片/截图/语音/视频/文件到群里" / "发张图给某某" — **统一一条命令**:`dws chat message send ... --msg-type file --file-path <本地路径>`,CLI 内部自动上传并发送,**任意扩展名(png/jpg/pdf/mp4/zip…)都走这条**
- "发图片+文字说明" — 不要硬塞进一条命令;先发文件消息再补一条 `--text "..."` 即可 - "发图片+文字说明" — 不要硬塞进一条命令;先发文件消息再补一条 `--text "..."` 即可
@@ -299,11 +299,11 @@ dws chat message send --open-dingtalk-id <openDingTalkId> --msg-type file --file
``` ```
> ❌ 反模式:调 `dt_media_upload` / `extract_media_id.py` / `drive upload` / `drive download` 等前置工具再 `--msg-type image --media-id`。这是**旧链路**,仅当上游已持有 mediaId 才用;新场景一律 `--file-path` 直发,避免长链路与“空白图”现象。 > ❌ 反模式:调 `dt_media_upload` / `extract_media_id.py` / `drive upload` / `drive download` 等前置工具再 `--msg-type image --media-id`。这是**旧链路**,仅当上游已持有 mediaId 才用;新场景一律 `--file-path` 直发,避免长链路与“空白图”现象。
> 富媒体消息单聊优先使用 `--open-dingtalk-id`;传 `--user` 时 CLI 会尝试解析为 openDingTalkId 后发送。 > 单聊已持有 openDingTalkId 时优先使用 `--open-dingtalk-id`;传 `--user` 时 CLI 会通过通讯录关键词搜索做 userId 精确匹配后发送。
**用 `chat +messages-send-card` 的场景**: **用 `chat +messages-send-card` 的场景**:
- 群聊流式卡片使用 `--group <openConversationId>`。 - 群聊流式卡片使用 `--group <openConversationId>`。
- 单聊已有 userId 时使用 `--receiver <userId>`,CLI 始终先只读解析为 openDingTalkId;即使 userId 以 D/d 开头也不会猜测类型,`--dry-run` 也会执行该解析。 - 单聊已有 userId 时使用 `--receiver <userId>`,CLI 始终通过通讯录关键词搜索并按 userId 精确匹配 openDingTalkId;即使 userId 以 D/d 开头也不会猜测类型,`--dry-run` 也会执行该解析。
- 单聊已有 openDingTalkId 时必须显式使用 `--receiver-open-dingtalk-id <openDingTalkId>`,避免与 userId 混淆。 - 单聊已有 openDingTalkId 时必须显式使用 `--receiver-open-dingtalk-id <openDingTalkId>`,避免与 userId 混淆。
- `--group`、`--receiver`、`--receiver-open-dingtalk-id` 严格三选一;传 `--content` 可在同一次调用中创建并结束卡片。 - `--group`、`--receiver`、`--receiver-open-dingtalk-id` 严格三选一;传 `--content` 可在同一次调用中创建并结束卡片。