Compare commits

...
Author SHA1 Message Date
修雨 d2f87ff1dc test: run quality regressions in platform coverage 2026-07-16 09:33:22 +08:00
修雨 fcf795f17b Merge remote-tracking branch 'origin/main' into codex/fix-quality-eval-regressions
# Conflicts:
#	internal/cli/schema_agent_metadata/index.json
#	internal/cli/schema_agent_metadata_audit.json
#	internal/cli/schema_catalog.json
2026-07-16 09:20:58 +08:00
修雨 9daa95f2fd Merge origin/main into codex/fix-quality-eval-regressions 2026-07-16 00:08:24 +08:00
修雨 ec380b7e45 fix: make Windows helper coverage portable 2026-07-15 18:17:43 +08:00
修雨 44a3295aee Merge branch 'main' of https://github.com/DingTalk-Real-AI/dingtalk-workspace-cli into codex/fix-quality-eval-regressions
# Conflicts:
#	internal/cli/schema_agent_metadata/index.json
#	internal/cli/schema_agent_metadata_audit.json
#	internal/cli/schema_catalog.json
2026-07-15 17:33:41 +08:00
修雨 282c9154d6 fix: expose todo attachment listing schema 2026-07-15 17:15:43 +08:00
修雨 5e682ac381 docs: record invalid target fixes 2026-07-15 14:28:45 +08:00
修雨 1167c1cfab fix: surface invalid sheet and todo targets 2026-07-15 12:08:02 +08:00
17 changed files with 1037 additions and 72 deletions
+4
View File
@@ -12,6 +12,10 @@ The format is inspired by [Keep a Changelog](https://keepachangelog.com/) and th
- **Sheet imports and Aitable workflow writes** (#624) — adds `dws sheet import` / `sheet import create` for converting local xlsx/xls files into new online sheets, `sheet import get` for polling import tasks, and `dws aitable workflow create/update` for applying validated `workflow-dsl/v1` definitions, with matching reviewed Agent Schema and bundled Skill guidance.
- **Official multi-platform Homebrew channel** — stable `Formula/dingtalk-workspace-cli.rb` and keg-only `Formula/dingtalk-workspace-cli-beta.rb` live in this repository and select signed macOS Intel/Apple Silicon or Linux amd64/arm64 artifacts at install time. Stable and beta releases open isolated Formula update PRs after final artifact signing, so beta never replaces the stable Formula. Agent Skills stay under `pkgshare` without mutating the user's home directory, and both tracks are covered by the six-channel post-release verifier.
### Fixed
- **Sheet and Todo invalid-target failures** — `sheet range read/get` now rejects a null cell-info response instead of printing `null` and exiting successfully, while Todo completion and attachment listing verify that a task exists before calling lenient backend endpoints. Attachment listing is also published through Runtime Schema for schema-first Agent discovery.
## [1.0.52] - 2026-07-14
This release seals the `v1.0.52` line with personal event subscriptions, a deterministic 22-product Agent command catalog, local user-operation auditing, expanded Open product commands, safer macOS credentials and release signing, and more reliable Connect and IM delivery.
@@ -0,0 +1,56 @@
// Copyright 2026 Alibaba Group
// Licensed under the Apache License, Version 2.0 (the "License");
package app
import (
"bytes"
"encoding/json"
"testing"
)
func TestTodoListAttachmentDeliveredSchemaMatchesExecutableHelp(t *testing.T) {
const (
canonicalPath = "todo.list_todo_attachment"
cliPath = "todo task list-attachment"
)
root := NewRootCommand()
command := exactCommandForTest(root, cliPath)
if command == nil {
t.Fatalf("executable command %q is missing", cliPath)
}
var stdout, stderr bytes.Buffer
root.SetOut(&stdout)
root.SetErr(&stderr)
root.SetArgs([]string{"schema", cliPath, "--format", "json"})
if err := root.Execute(); err != nil {
t.Fatalf("execute embedded schema leaf: %v; stderr=%s", err, stderr.String())
}
var tool map[string]any
if err := json.Unmarshal(stdout.Bytes(), &tool); err != nil {
t.Fatalf("decode embedded schema leaf: %v", err)
}
if got := schemaContractString(tool["canonical_path"]); got != canonicalPath {
t.Fatalf("canonical_path = %q, want %q", got, canonicalPath)
}
if got := schemaContractString(tool["primary_cli_path"]); got != cliPath {
t.Fatalf("primary_cli_path = %q, want %q", got, cliPath)
}
if got := schemaContractString(tool["availability"]); got != "available" {
t.Fatalf("availability = %q, want available", got)
}
if problem := schemaHelpFlagCompletenessProblem(canonicalPath, cliPath, command, tool); problem != "" {
t.Fatal(problem)
}
taskID := schemaContractMap(tool["parameters"])["task-id"]
if taskID == nil {
t.Fatal("delivered Schema is missing --task-id")
}
if required, ok := taskID["required"].(bool); !ok || !required {
t.Fatalf("task-id required = %#v, want true", taskID["required"])
}
}
+10 -10
View File
@@ -1,18 +1,18 @@
{
"version": 1,
"source_hash": "sha256:53567141622d90e02ce50fe3bc1733357a25b9860a0795eb396d9361f43c41d1",
"surface_hash": "sha256:69e1f9fcd3768d49a2a197c40fb26c0bc07385e868753210761c3ea7f676eadb",
"source_hash": "sha256:d398f66780f4959874c4ffc48be5be08c716ba2daeed8ae3d8690504846a3906",
"surface_hash": "sha256:631b73b174f48cb0cca7c8449e80920739010d0db223dac2855101f4dbd0eda6",
"coverage": {
"surface_products": 22,
"products_with_metadata": 22,
"surface_tools": 568,
"tools_with_metadata": 568,
"tools_with_agent_summary": 568,
"tools_with_use_when": 568,
"tools_with_avoid_when": 568,
"tools_with_examples": 568,
"tools_with_interface_mode": 568,
"unmatched_skill_tools": 125,
"surface_tools": 569,
"tools_with_metadata": 569,
"tools_with_agent_summary": 569,
"tools_with_use_when": 569,
"tools_with_avoid_when": 569,
"tools_with_examples": 569,
"tools_with_interface_mode": 569,
"unmatched_skill_tools": 124,
"unreviewed_skill_tools": 7
},
"products": {
@@ -3439,6 +3439,265 @@
"需要按完成状态、优先级、角色或截止日期范围查询当前用户待办列表时"
]
},
"todo task list-attachment": {
"agent_summary": "查询待办附件列表",
"agent_summary_source": "dws-agent-selection/todo",
"availability": "available",
"avoid_when": [
"要上传附件时改用 dws todo task add-attachment",
"要删除附件时先用本命令确认 attachmentId,再改用 dws todo task remove-attachment"
],
"confirmation": "not_required",
"effect": "read",
"effect_source": "command-verb",
"examples": [
"dws todo task list-attachment --task-id \u003ctaskId\u003e",
"dws todo task list-attachment --task-id \u003ctaskId\u003e --format json"
],
"field_provenance": {
"agent_summary": {
"value": "查询待办附件列表",
"source": "internal/cli/schema_hints/selection/todo.json",
"precedence": "reviewed_explicit",
"resolution": "highest_precedence",
"review_reason": "依据当前 Cobra Help、Todo Skill 与 helper 中的 list_todo_attachment 调用手工审阅;当前 live leaf Schema 缺失,记录失败证据并以源码契约收口。",
"candidates": [
{
"value": "查询待办附件列表",
"source": "internal/cli/schema_hints/selection/todo.json",
"precedence": "reviewed_explicit",
"selected": true,
"review_reason": "依据当前 Cobra Help、Todo Skill 与 helper 中的 list_todo_attachment 调用手工审阅;当前 live leaf Schema 缺失,记录失败证据并以源码契约收口。"
}
]
},
"availability": {
"value": "available",
"source": "internal/cli/schema_hints/metadata/todo.json",
"precedence": "reviewed_explicit",
"resolution": "highest_precedence",
"review_reason": "dws-tool-metadata/todo marks this tool as reviewed",
"candidates": [
{
"value": "available",
"source": "internal/cli/schema_hints/metadata/todo.json",
"precedence": "reviewed_explicit",
"selected": true,
"review_reason": "dws-tool-metadata/todo marks this tool as reviewed"
}
]
},
"avoid_when": {
"value": [
"要上传附件时改用 dws todo task add-attachment",
"要删除附件时先用本命令确认 attachmentId,再改用 dws todo task remove-attachment"
],
"source": "internal/cli/schema_hints/selection/todo.json",
"precedence": "reviewed_explicit",
"resolution": "highest_precedence",
"review_reason": "依据当前 Cobra Help、Todo Skill 与 helper 中的 list_todo_attachment 调用手工审阅;当前 live leaf Schema 缺失,记录失败证据并以源码契约收口。",
"candidates": [
{
"value": [
"要上传附件时改用 dws todo task add-attachment",
"要删除附件时先用本命令确认 attachmentId,再改用 dws todo task remove-attachment"
],
"source": "internal/cli/schema_hints/selection/todo.json",
"precedence": "reviewed_explicit",
"selected": true,
"review_reason": "依据当前 Cobra Help、Todo Skill 与 helper 中的 list_todo_attachment 调用手工审阅;当前 live leaf Schema 缺失,记录失败证据并以源码契约收口。"
}
]
},
"confirmation": {
"value": "not_required",
"source": "risk-default",
"precedence": "inference_or_default",
"resolution": "highest_precedence",
"candidates": [
{
"value": "not_required",
"source": "risk-default",
"precedence": "inference_or_default",
"selected": true
}
]
},
"effect": {
"value": "read",
"source": "command-verb",
"precedence": "inference_or_default",
"resolution": "highest_precedence",
"candidates": [
{
"value": "read",
"source": "command-verb",
"precedence": "inference_or_default",
"selected": true
}
]
},
"examples": {
"value": [
"dws todo task list-attachment --task-id \u003ctaskId\u003e",
"dws todo task list-attachment --task-id \u003ctaskId\u003e --format json"
],
"source": "internal/cli/schema_hints/selection/todo.json",
"precedence": "reviewed_explicit",
"resolution": "highest_precedence",
"review_reason": "依据当前 Cobra Help、Todo Skill 与 helper 中的 list_todo_attachment 调用手工审阅;当前 live leaf Schema 缺失,记录失败证据并以源码契约收口。",
"candidates": [
{
"value": [
"dws todo task list-attachment --task-id \u003ctaskId\u003e",
"dws todo task list-attachment --task-id \u003ctaskId\u003e --format json"
],
"source": "internal/cli/schema_hints/selection/todo.json",
"precedence": "reviewed_explicit",
"selected": true,
"review_reason": "依据当前 Cobra Help、Todo Skill 与 helper 中的 list_todo_attachment 调用手工审阅;当前 live leaf Schema 缺失,记录失败证据并以源码契约收口。"
}
]
},
"idempotency": {
"value": "idempotent",
"source": "effect-default",
"precedence": "inference_or_default",
"resolution": "highest_precedence",
"candidates": [
{
"value": "idempotent",
"source": "effect-default",
"precedence": "inference_or_default",
"selected": true
}
]
},
"interface_mode": {
"value": "composite",
"source": "internal/cli/schema_hints/metadata/todo.json",
"precedence": "reviewed_explicit",
"resolution": "highest_precedence",
"review_reason": "dws-tool-metadata/todo marks this tool as reviewed",
"candidates": [
{
"value": "composite",
"source": "internal/cli/schema_hints/metadata/todo.json",
"precedence": "reviewed_explicit",
"selected": true,
"review_reason": "dws-tool-metadata/todo marks this tool as reviewed"
}
]
},
"interface_reason": {
"value": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
"source": "internal/cli/schema_hints/metadata/todo.json",
"precedence": "reviewed_explicit",
"resolution": "highest_precedence",
"review_reason": "dws-tool-metadata/todo marks this tool as reviewed",
"candidates": [
{
"value": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
"source": "internal/cli/schema_hints/metadata/todo.json",
"precedence": "reviewed_explicit",
"selected": true,
"review_reason": "dws-tool-metadata/todo marks this tool as reviewed"
}
]
},
"interface_ref": {
"value": null,
"source": "internal/cli/schema_hints/metadata/todo.json",
"precedence": "reviewed_explicit",
"resolution": "interface_disposition_matrix",
"review_reason": "final interface mode composite forbids a direct MCP interface_ref",
"candidates": [
{
"value": null,
"source": "internal/cli/schema_hints/metadata/todo.json",
"precedence": "reviewed_explicit",
"selected": true,
"review_reason": "final interface mode composite forbids a direct MCP interface_ref"
}
]
},
"reviewed": {
"value": true,
"source": "internal/cli/schema_hints/metadata/todo.json",
"precedence": "reviewed_explicit",
"resolution": "highest_precedence",
"review_reason": "dws-tool-metadata/todo marks this tool as reviewed",
"candidates": [
{
"value": true,
"source": "internal/cli/schema_hints/metadata/todo.json",
"precedence": "reviewed_explicit",
"selected": true,
"review_reason": "dws-tool-metadata/todo marks this tool as reviewed"
},
{
"value": true,
"source": "internal/cli/schema_hints/selection/todo.json",
"precedence": "reviewed_explicit",
"selected": false,
"review_reason": "依据当前 Cobra Help、Todo Skill 与 helper 中的 list_todo_attachment 调用手工审阅;当前 live leaf Schema 缺失,记录失败证据并以源码契约收口。"
}
]
},
"risk": {
"value": "low",
"source": "effect-default",
"precedence": "inference_or_default",
"resolution": "highest_precedence",
"candidates": [
{
"value": "low",
"source": "effect-default",
"precedence": "inference_or_default",
"selected": true
}
]
},
"use_when": {
"value": [
"已知 taskId,需要查看该待办当前附件及其 attachmentId、文件名和大小时"
],
"source": "internal/cli/schema_hints/selection/todo.json",
"precedence": "reviewed_explicit",
"resolution": "highest_precedence",
"review_reason": "依据当前 Cobra Help、Todo Skill 与 helper 中的 list_todo_attachment 调用手工审阅;当前 live leaf Schema 缺失,记录失败证据并以源码契约收口。",
"candidates": [
{
"value": [
"已知 taskId,需要查看该待办当前附件及其 attachmentId、文件名和大小时"
],
"source": "internal/cli/schema_hints/selection/todo.json",
"precedence": "reviewed_explicit",
"selected": true,
"review_reason": "依据当前 Cobra Help、Todo Skill 与 helper 中的 list_todo_attachment 调用手工审阅;当前 live leaf Schema 缺失,记录失败证据并以源码契约收口。"
}
]
}
},
"idempotency": "idempotent",
"interface_mode": "composite",
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
"reviewed": true,
"risk": "low",
"source_refs": [
"CommandRegistry:canonical_path=todo.list_todo_attachment",
"Skill:skills/mono/references/products/todo.md",
"cobra-help:dws todo task list-attachment",
"internal/cli/schema_hints/metadata/todo.json",
"internal/cli/schema_hints/selection/todo.json",
"live-dws-schema:todo.list_todo_attachment#FAILED",
"runtime-call:internal/helpers/todo.go#list_todo_attachment",
"skills/mono/references/products/todo.md"
],
"use_when": [
"已知 taskId,需要查看该待办当前附件及其 attachmentId、文件名和大小时"
]
},
"todo task remove-executor": {
"agent_summary": "移除待办执行人",
"agent_summary_source": "dws-agent-selection/todo",
+11 -39
View File
@@ -1,11 +1,11 @@
{
"version": 1,
"source_hash": "sha256:53567141622d90e02ce50fe3bc1733357a25b9860a0795eb396d9361f43c41d1",
"surface_hash": "sha256:69e1f9fcd3768d49a2a197c40fb26c0bc07385e868753210761c3ea7f676eadb",
"source_hash": "sha256:d398f66780f4959874c4ffc48be5be08c716ba2daeed8ae3d8690504846a3906",
"surface_hash": "sha256:631b73b174f48cb0cca7c8449e80920739010d0db223dac2855101f4dbd0eda6",
"source_files": 150,
"hint_files": 46,
"hint_products": 39,
"hint_tools": 1288,
"hint_tools": 1290,
"interface_metadata": {
"source": "mcp-tools-list+cli-registry",
"revision": "4574f7022c32cf4c033e9b7b4156e2fec815fed8",
@@ -29,14 +29,14 @@
"coverage": {
"surface_products": 22,
"products_with_metadata": 22,
"surface_tools": 568,
"tools_with_metadata": 568,
"tools_with_agent_summary": 568,
"tools_with_use_when": 568,
"tools_with_avoid_when": 568,
"tools_with_examples": 568,
"tools_with_interface_mode": 568,
"unmatched_skill_tools": 125,
"surface_tools": 569,
"tools_with_metadata": 569,
"tools_with_agent_summary": 569,
"tools_with_use_when": 569,
"tools_with_avoid_when": 569,
"tools_with_examples": 569,
"tools_with_interface_mode": 569,
"unmatched_skill_tools": 124,
"unreviewed_skill_tools": 7
},
"source_products": [
@@ -3944,20 +3944,6 @@
"reason": "旧版 Skill 或说明性引用,当前公开命令面无等价 leaf,禁止词法模糊映射"
}
},
{
"tool_path": "todo task list-attachment",
"source": "skills/mono/references/products/todo.md",
"line": 216,
"candidates": [
"todo task add-attachment",
"todo task add-executor",
"todo task add-participant"
],
"review": {
"status": "stale",
"reason": "旧版 Skill 或说明性引用,当前公开命令面无等价 leaf,禁止词法模糊映射"
}
},
{
"tool_path": "todo task remove-attachment",
"source": "skills/mono/references/products/todo.md",
@@ -3986,20 +3972,6 @@
"reason": "旧版 Skill 或说明性引用,当前公开命令面无等价 leaf,禁止词法模糊映射"
}
},
{
"tool_path": "todo task list-attachment",
"source": "skills/mono/references/products/todo.md",
"line": 375,
"candidates": [
"todo task add-attachment",
"todo task add-executor",
"todo task add-participant"
],
"review": {
"status": "stale",
"reason": "旧版 Skill 或说明性引用,当前公开命令面无等价 leaf,禁止词法模糊映射"
}
},
{
"tool_path": "todo task remove-attachment",
"source": "skills/mono/references/products/todo.md",
+456 -10
View File
@@ -1,18 +1,18 @@
{
"version": 1,
"source_hash": "sha256:9a907efbcea3339bcb3881aad578e77b15f4a3f4a8b53efe4c2791db894bb41a",
"surface_hash": "sha256:69e1f9fcd3768d49a2a197c40fb26c0bc07385e868753210761c3ea7f676eadb",
"source_hash": "sha256:8ad3b1c08185ecdae8bb7539017fd5b57ebb085508c8326149e241d95239af4a",
"surface_hash": "sha256:631b73b174f48cb0cca7c8449e80920739010d0db223dac2855101f4dbd0eda6",
"catalog": {
"agent_metadata": {
"products_with_metadata": 22,
"source": "embedded-skill-metadata",
"source_hash": "sha256:53567141622d90e02ce50fe3bc1733357a25b9860a0795eb396d9361f43c41d1",
"surface_hash": "sha256:69e1f9fcd3768d49a2a197c40fb26c0bc07385e868753210761c3ea7f676eadb",
"source_hash": "sha256:d398f66780f4959874c4ffc48be5be08c716ba2daeed8ae3d8690504846a3906",
"surface_hash": "sha256:631b73b174f48cb0cca7c8449e80920739010d0db223dac2855101f4dbd0eda6",
"surface_products": 22,
"surface_tools": 568,
"tools_with_agent_summary": 568,
"tools_with_metadata": 568,
"unmatched_skill_tools": 125,
"surface_tools": 569,
"tools_with_agent_summary": 569,
"tools_with_metadata": 569,
"unmatched_skill_tools": 124,
"version": 1
},
"count": 22,
@@ -17936,7 +17936,7 @@
"id": "todo",
"name": "待办任务管理",
"runtime": true,
"tool_count": 17,
"tool_count": 18,
"tools": [
{
"agent_metadata_source": "embedded-skill-metadata",
@@ -18294,6 +18294,34 @@
"需要按完成状态、优先级、角色或截止日期范围查询当前用户待办列表时"
]
},
{
"agent_metadata_source": "embedded-skill-metadata",
"agent_summary": "查询待办附件列表",
"agent_summary_source": "dws-agent-selection/todo",
"availability": "available",
"avoid_when": [
"要上传附件时改用 dws todo task add-attachment",
"要删除附件时先用本命令确认 attachmentId,再改用 dws todo task remove-attachment"
],
"canonical_path": "todo.list_todo_attachment",
"cli_name": "list-attachment",
"cli_path": "todo task list-attachment",
"confirmation": "not_required",
"description": "查询待办任务的附件列表",
"effect": "read",
"group": "task",
"idempotency": "idempotent",
"interface_mode": "composite",
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
"name": "list_todo_attachment",
"primary_cli_path": "todo task list-attachment",
"reviewed": true,
"risk": "low",
"title": "查询待办任务的附件列表",
"use_when": [
"已知 taskId,需要查看该待办当前附件及其 attachmentId、文件名和大小时"
]
},
{
"agent_metadata_source": "embedded-skill-metadata",
"agent_summary": "获取待办评论列表",
@@ -19042,7 +19070,7 @@
}
],
"source": "embedded-command-catalog",
"tool_count": 568
"tool_count": 569
},
"tools": {
"aisearch.enterprise_person_search": {
@@ -424437,6 +424465,424 @@
"需要按完成状态、优先级、角色或截止日期范围查询当前用户待办列表时"
]
},
"todo.list_todo_attachment": {
"agent_metadata_source": "embedded-skill-metadata",
"agent_source_refs": [
"CommandRegistry:canonical_path=todo.list_todo_attachment",
"Skill:skills/mono/references/products/todo.md",
"cobra-help:dws todo task list-attachment",
"internal/cli/schema_hints/metadata/todo.json",
"internal/cli/schema_hints/selection/todo.json",
"live-dws-schema:todo.list_todo_attachment#FAILED",
"runtime-call:internal/helpers/todo.go#list_todo_attachment",
"skills/mono/references/products/todo.md"
],
"agent_summary": "查询待办附件列表",
"agent_summary_source": "dws-agent-selection/todo",
"availability": "available",
"avoid_when": [
"要上传附件时改用 dws todo task add-attachment",
"要删除附件时先用本命令确认 attachmentId,再改用 dws todo task remove-attachment"
],
"canonical_path": "todo.list_todo_attachment",
"cli_name": "list-attachment",
"cli_path": "todo task list-attachment",
"confirmation": "not_required",
"description": "查询待办任务的附件列表",
"display": "待办任务管理",
"effect": "read",
"effect_source": "command-verb",
"examples": [
"dws todo task list-attachment --task-id \u003ctaskId\u003e",
"dws todo task list-attachment --task-id \u003ctaskId\u003e --format json"
],
"field_provenance": {
"agent_summary": {
"candidates": [
{
"precedence": "reviewed_explicit",
"review_reason": "依据当前 Cobra Help、Todo Skill 与 helper 中的 list_todo_attachment 调用手工审阅;当前 live leaf Schema 缺失,记录失败证据并以源码契约收口。",
"selected": true,
"source": "internal/cli/schema_hints/selection/todo.json",
"value": "查询待办附件列表"
}
],
"precedence": "reviewed_explicit",
"resolution": "highest_precedence",
"review_reason": "依据当前 Cobra Help、Todo Skill 与 helper 中的 list_todo_attachment 调用手工审阅;当前 live leaf Schema 缺失,记录失败证据并以源码契约收口。",
"source": "internal/cli/schema_hints/selection/todo.json",
"value": "查询待办附件列表"
},
"availability": {
"candidates": [
{
"precedence": "reviewed_explicit",
"review_reason": "dws-tool-metadata/todo marks this tool as reviewed",
"selected": true,
"source": "internal/cli/schema_hints/metadata/todo.json",
"value": "available"
}
],
"precedence": "reviewed_explicit",
"resolution": "highest_precedence",
"review_reason": "dws-tool-metadata/todo marks this tool as reviewed",
"source": "internal/cli/schema_hints/metadata/todo.json",
"value": "available"
},
"avoid_when": {
"candidates": [
{
"precedence": "reviewed_explicit",
"review_reason": "依据当前 Cobra Help、Todo Skill 与 helper 中的 list_todo_attachment 调用手工审阅;当前 live leaf Schema 缺失,记录失败证据并以源码契约收口。",
"selected": true,
"source": "internal/cli/schema_hints/selection/todo.json",
"value": [
"要上传附件时改用 dws todo task add-attachment",
"要删除附件时先用本命令确认 attachmentId,再改用 dws todo task remove-attachment"
]
}
],
"precedence": "reviewed_explicit",
"resolution": "highest_precedence",
"review_reason": "依据当前 Cobra Help、Todo Skill 与 helper 中的 list_todo_attachment 调用手工审阅;当前 live leaf Schema 缺失,记录失败证据并以源码契约收口。",
"source": "internal/cli/schema_hints/selection/todo.json",
"value": [
"要上传附件时改用 dws todo task add-attachment",
"要删除附件时先用本命令确认 attachmentId,再改用 dws todo task remove-attachment"
]
},
"canonical_path": {
"candidates": [
{
"precedence": "command_registry",
"selected": true,
"source": "reviewed_command_registry",
"source_ref": "todo task list-attachment",
"value": "todo.list_todo_attachment"
}
],
"precedence": "command_registry",
"resolution": "registry_identity",
"source": "reviewed_command_registry",
"source_ref": "todo task list-attachment",
"value": "todo.list_todo_attachment"
},
"confirmation": {
"candidates": [
{
"precedence": "inference_or_default",
"selected": true,
"source": "risk-default",
"value": "not_required"
}
],
"precedence": "inference_or_default",
"resolution": "highest_precedence",
"source": "risk-default",
"value": "not_required"
},
"description": {
"candidates": [
{
"precedence": "cobra_help",
"selected": true,
"source": "cobra_help",
"value": "查询待办任务的附件列表"
}
],
"precedence": "cobra_help",
"resolution": "highest_precedence",
"source": "cobra_help",
"value": "查询待办任务的附件列表"
},
"effect": {
"candidates": [
{
"precedence": "inference_or_default",
"selected": true,
"source": "command-verb",
"value": "read"
}
],
"precedence": "inference_or_default",
"resolution": "highest_precedence",
"source": "command-verb",
"value": "read"
},
"examples": {
"candidates": [
{
"precedence": "reviewed_explicit",
"review_reason": "依据当前 Cobra Help、Todo Skill 与 helper 中的 list_todo_attachment 调用手工审阅;当前 live leaf Schema 缺失,记录失败证据并以源码契约收口。",
"selected": true,
"source": "internal/cli/schema_hints/selection/todo.json",
"value": [
"dws todo task list-attachment --task-id \u003ctaskId\u003e",
"dws todo task list-attachment --task-id \u003ctaskId\u003e --format json"
]
}
],
"precedence": "reviewed_explicit",
"resolution": "highest_precedence",
"review_reason": "依据当前 Cobra Help、Todo Skill 与 helper 中的 list_todo_attachment 调用手工审阅;当前 live leaf Schema 缺失,记录失败证据并以源码契约收口。",
"source": "internal/cli/schema_hints/selection/todo.json",
"value": [
"dws todo task list-attachment --task-id \u003ctaskId\u003e",
"dws todo task list-attachment --task-id \u003ctaskId\u003e --format json"
]
},
"idempotency": {
"candidates": [
{
"precedence": "inference_or_default",
"selected": true,
"source": "effect-default",
"value": "idempotent"
}
],
"precedence": "inference_or_default",
"resolution": "highest_precedence",
"source": "effect-default",
"value": "idempotent"
},
"interface_mode": {
"candidates": [
{
"precedence": "reviewed_explicit",
"review_reason": "dws-tool-metadata/todo marks this tool as reviewed",
"selected": true,
"source": "internal/cli/schema_hints/metadata/todo.json",
"value": "composite"
}
],
"precedence": "reviewed_explicit",
"resolution": "highest_precedence",
"review_reason": "dws-tool-metadata/todo marks this tool as reviewed",
"source": "internal/cli/schema_hints/metadata/todo.json",
"value": "composite"
},
"interface_reason": {
"candidates": [
{
"precedence": "reviewed_explicit",
"review_reason": "dws-tool-metadata/todo marks this tool as reviewed",
"selected": true,
"source": "internal/cli/schema_hints/metadata/todo.json",
"value": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command."
}
],
"precedence": "reviewed_explicit",
"resolution": "highest_precedence",
"review_reason": "dws-tool-metadata/todo marks this tool as reviewed",
"source": "internal/cli/schema_hints/metadata/todo.json",
"value": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command."
},
"interface_ref": {
"candidates": [
{
"precedence": "reviewed_explicit",
"review_reason": "final interface mode composite forbids a direct MCP interface_ref",
"selected": true,
"source": "internal/cli/schema_hints/metadata/todo.json",
"value": null
}
],
"precedence": "reviewed_explicit",
"resolution": "interface_disposition_matrix",
"review_reason": "final interface mode composite forbids a direct MCP interface_ref",
"source": "internal/cli/schema_hints/metadata/todo.json",
"value": null
},
"reviewed": {
"candidates": [
{
"precedence": "reviewed_explicit",
"review_reason": "dws-tool-metadata/todo marks this tool as reviewed",
"selected": true,
"source": "internal/cli/schema_hints/metadata/todo.json",
"value": true
},
{
"precedence": "reviewed_explicit",
"review_reason": "依据当前 Cobra Help、Todo Skill 与 helper 中的 list_todo_attachment 调用手工审阅;当前 live leaf Schema 缺失,记录失败证据并以源码契约收口。",
"selected": false,
"source": "internal/cli/schema_hints/selection/todo.json",
"value": true
}
],
"precedence": "reviewed_explicit",
"resolution": "highest_precedence",
"review_reason": "dws-tool-metadata/todo marks this tool as reviewed",
"source": "internal/cli/schema_hints/metadata/todo.json",
"value": true
},
"risk": {
"candidates": [
{
"precedence": "inference_or_default",
"selected": true,
"source": "effect-default",
"value": "low"
}
],
"precedence": "inference_or_default",
"resolution": "highest_precedence",
"source": "effect-default",
"value": "low"
},
"title": {
"candidates": [
{
"precedence": "cobra_help",
"selected": true,
"source": "cobra_help",
"value": "查询待办任务的附件列表"
}
],
"precedence": "cobra_help",
"resolution": "highest_precedence",
"source": "cobra_help",
"value": "查询待办任务的附件列表"
},
"use_when": {
"candidates": [
{
"precedence": "reviewed_explicit",
"review_reason": "依据当前 Cobra Help、Todo Skill 与 helper 中的 list_todo_attachment 调用手工审阅;当前 live leaf Schema 缺失,记录失败证据并以源码契约收口。",
"selected": true,
"source": "internal/cli/schema_hints/selection/todo.json",
"value": [
"已知 taskId,需要查看该待办当前附件及其 attachmentId、文件名和大小时"
]
}
],
"precedence": "reviewed_explicit",
"resolution": "highest_precedence",
"review_reason": "依据当前 Cobra Help、Todo Skill 与 helper 中的 list_todo_attachment 调用手工审阅;当前 live leaf Schema 缺失,记录失败证据并以源码契约收口。",
"source": "internal/cli/schema_hints/selection/todo.json",
"value": [
"已知 taskId,需要查看该待办当前附件及其 attachmentId、文件名和大小时"
]
}
},
"group": "task",
"has_parameters": true,
"idempotency": "idempotent",
"interface_mode": "composite",
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
"is_alias": false,
"name": "list_todo_attachment",
"parameter_count": 1,
"parameters": {
"task-id": {
"description": "待办任务 ID (必填)",
"field_provenance": {
"description": {
"candidates": [
{
"precedence": "cobra_contract",
"selected": true,
"source": "cobra_usage",
"value": "待办任务 ID (必填)"
},
{
"precedence": "default",
"selected": false,
"source": "default",
"value": ""
}
],
"precedence": "cobra_contract",
"resolution": "highest_precedence",
"source": "cobra_usage",
"value": "待办任务 ID (必填)"
},
"property": {
"candidates": [
{
"precedence": "reviewed_mapping_exclusion",
"review_reason": "Reviewed unpinned adapter: --task-id is nested under todoAttachmentListRequest at runtime, while the immutable pinned MCP snapshot has no interface_ref for todo.list_todo_attachment.",
"selected": true,
"source": "reviewed_mapping_exclusion",
"value": ""
},
{
"precedence": "inference",
"selected": false,
"source": "flag_name_inference",
"value": "taskId"
}
],
"precedence": "reviewed_mapping_exclusion",
"resolution": "highest_precedence",
"review_reason": "Reviewed unpinned adapter: --task-id is nested under todoAttachmentListRequest at runtime, while the immutable pinned MCP snapshot has no interface_ref for todo.list_todo_attachment.",
"source": "reviewed_mapping_exclusion",
"value": ""
},
"required": {
"candidates": [
{
"precedence": "inference",
"selected": true,
"source": "usage_required_inference",
"value": true
},
{
"precedence": "default",
"selected": false,
"source": "default",
"value": false
}
],
"precedence": "inference",
"resolution": "highest_precedence",
"source": "usage_required_inference",
"value": true
},
"required_when": {
"candidates": [
{
"precedence": "default",
"selected": true,
"source": "default",
"value": ""
}
],
"precedence": "default",
"resolution": "highest_precedence",
"source": "default",
"value": ""
},
"type": {
"candidates": [
{
"precedence": "cobra_contract",
"selected": true,
"source": "cobra_flag_type",
"value": "string"
}
],
"precedence": "cobra_contract",
"resolution": "highest_precedence",
"source": "cobra_flag_type",
"value": "string"
}
},
"required": true,
"type": "string"
}
},
"path": "todo.list_todo_attachment",
"primary_cli_path": "todo task list-attachment",
"product_id": "todo",
"reviewed": true,
"risk": "low",
"source": "reviewed_command_registry",
"title": "查询待办任务的附件列表",
"use_when": [
"已知 taskId,需要查看该待办当前附件及其 attachmentId、文件名和大小时"
]
},
"todo.list_todo_comment": {
"agent_metadata_source": "embedded-skill-metadata",
"agent_source_refs": [
@@ -369,7 +369,6 @@
"oa approval revert-activities",
"oa approval revert-task",
"oa approval search-forms",
"todo task list-attachment",
"todo task list-sub",
"todo task remove-attachment"
]
@@ -2293,6 +2293,10 @@
"canonical_path": "todo.add_todo_attachment",
"cli_path": "todo task add-attachment"
},
{
"canonical_path": "todo.list_todo_attachment",
"cli_path": "todo task list-attachment"
},
{
"canonical_path": "todo.add_task_executors",
"cli_path": "todo task add-executor"
-4
View File
@@ -876,10 +876,6 @@
"status": "stale",
"reason": "旧版 Skill 或说明性引用,当前公开命令面无等价 leaf,禁止词法模糊映射"
},
"todo task list-attachment": {
"status": "stale",
"reason": "旧版 Skill 或说明性引用,当前公开命令面无等价 leaf,禁止词法模糊映射"
},
"todo task list-sub": {
"status": "stale",
"reason": "旧版 Skill 或说明性引用,当前公开命令面无等价 leaf,禁止词法模糊映射"
@@ -76,6 +76,12 @@
"availability": "available",
"reviewed": true
},
"todo.list_todo_attachment": {
"interface_mode": "composite",
"availability": "available",
"interface_reason": "Reviewed unpinned remote adapter: this executable CLI wrapper calls a remote helper that is absent from the pinned MCP metadata snapshot; no single pinned semantically equivalent interface_ref can represent the command.",
"reviewed": true
},
"todo.remove_task_executors": {
"effect": "write",
"risk": "medium",
@@ -825,10 +825,6 @@
"status": "stale",
"reason": "旧版 Skill 或说明性引用,当前公开命令面无等价 leaf,禁止词法模糊映射"
},
"todo task list-attachment": {
"status": "stale",
"reason": "旧版 Skill 或说明性引用,当前公开命令面无等价 leaf,禁止词法模糊映射"
},
"todo task list-sub": {
"status": "stale",
"reason": "旧版 Skill 或说明性引用,当前公开命令面无等价 leaf,禁止词法模糊映射"
@@ -7,7 +7,7 @@
"channel": "open-source"
},
"coverage": {
"source_tools": 568,
"source_tools": 569,
"matched_tools": 71
},
"tools": {
@@ -286,6 +286,29 @@
"live-dws-schema:todo.list_todo_comment"
]
},
"todo.list_todo_attachment": {
"agent_summary": "查询待办附件列表",
"use_when": [
"已知 taskId,需要查看该待办当前附件及其 attachmentId、文件名和大小时"
],
"avoid_when": [
"要上传附件时改用 dws todo task add-attachment",
"要删除附件时先用本命令确认 attachmentId,再改用 dws todo task remove-attachment"
],
"examples": [
"dws todo task list-attachment --task-id <taskId>",
"dws todo task list-attachment --task-id <taskId> --format json"
],
"reviewed": true,
"review_reason": "依据当前 Cobra Help、Todo Skill 与 helper 中的 list_todo_attachment 调用手工审阅;当前 live leaf Schema 缺失,记录失败证据并以源码契约收口。",
"source_refs": [
"CommandRegistry:canonical_path=todo.list_todo_attachment",
"cobra-help:dws todo task list-attachment",
"Skill:skills/mono/references/products/todo.md",
"runtime-call:internal/helpers/todo.go#list_todo_attachment",
"live-dws-schema:todo.list_todo_attachment#FAILED"
]
},
"todo.remove_task_executors": {
"agent_summary": "移除待办执行人",
"use_when": [
@@ -1874,6 +1874,7 @@
"sheet.write_image --mime-type": "local upload metadata",
"sheet.write_image --name": "local upload metadata",
"todo.add_todo_attachment --file-path": "local upload input used to construct attachmentList",
"todo.list_todo_attachment --task-id": "Reviewed unpinned adapter: --task-id is nested under todoAttachmentListRequest at runtime, while the immutable pinned MCP snapshot has no interface_ref for todo.list_todo_attachment.",
"wiki.create_wikiSpace --icon": "runtime extension sends icon, which is absent from the pinned create_wikiSpace metadata",
"wiki.delete_document --workspace": "local validation/authorization context; not sent to delete_document",
"wiki.list_wikiSpaces --cursor": "composite route maps to pageToken for wiki.list_wikiSpaces or nextToken for drive.list_spaces",
@@ -0,0 +1,158 @@
// Copyright 2026 Alibaba Group
// Licensed under the Apache License, Version 2.0 (the "License");
package helpers
import (
"context"
"errors"
"io"
"os"
"testing"
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/pkg/edition"
"github.com/spf13/cobra"
)
type qualityEvaluationCall struct {
productID string
toolName string
args map[string]any
}
type qualityEvaluationCaller struct {
calls []qualityEvaluationCall
dryRun bool
}
func (c *qualityEvaluationCaller) CallTool(_ context.Context, productID, toolName string, args map[string]any) (*edition.ToolResult, error) {
c.calls = append(c.calls, qualityEvaluationCall{productID: productID, toolName: toolName, args: args})
switch toolName {
case "get_cell_infos":
return qualityEvaluationTextResult("null"), nil
case "get_todo_detail":
taskID, _ := args["taskId"].(string)
if taskID == "INVALID" {
return nil, errors.New("task not found")
}
return qualityEvaluationTextResult(`{"success":true,"result":{"todoDetailModel":{"taskId":"` + taskID + `"}}}`), nil
case "update_todo_done_status":
return qualityEvaluationTextResult(`{"success":true}`), nil
case "list_todo_attachment":
return qualityEvaluationTextResult(`{"success":true,"attachments":[]}`), nil
default:
return qualityEvaluationTextResult(`{}`), nil
}
}
func (*qualityEvaluationCaller) Format() string { return "json" }
func (c *qualityEvaluationCaller) DryRun() bool { return c.dryRun }
func (*qualityEvaluationCaller) Fields() string { return "" }
func (*qualityEvaluationCaller) JQ() string { return "" }
func qualityEvaluationTextResult(text string) *edition.ToolResult {
return &edition.ToolResult{Content: []edition.ContentBlock{{Type: "text", Text: text}}}
}
func executeQualityEvaluationCommand(t *testing.T, product string, caller *qualityEvaluationCaller, cmd *cobra.Command, args ...string) error {
t.Helper()
previousDeps := deps
previousArgs := os.Args
t.Cleanup(func() {
deps = previousDeps
os.Args = previousArgs
})
InitDeps(caller)
deps.Out.w = io.Discard
os.Args = append([]string{"dws", product}, args...)
cmd.SilenceErrors = true
cmd.SilenceUsage = true
cmd.SetArgs(args)
return cmd.Execute()
}
func TestCrossPlatformCoverageSheetRangeReadRejectsNullToolResponse(t *testing.T) {
for _, command := range []string{"read", "get"} {
t.Run(command, func(t *testing.T) {
caller := &qualityEvaluationCaller{}
err := executeQualityEvaluationCommand(t, "sheet", caller, newSheetCommand(),
"range", command, "--node", "INVALID")
if err == nil {
t.Fatal("sheet range command accepted a null MCP response")
}
if len(caller.calls) != 1 || caller.calls[0].toolName != "get_cell_infos" {
t.Fatalf("calls = %#v, want one get_cell_infos call", caller.calls)
}
})
}
}
func TestCrossPlatformCoverageTodoCommandsRejectMissingTaskBeforeTargetCall(t *testing.T) {
tests := []struct {
name string
args []string
targetTool string
}{
{name: "done", args: []string{"task", "done", "--task-id", "INVALID", "--status", "true"}, targetTool: "update_todo_done_status"},
{name: "list attachment", args: []string{"task", "list-attachment", "--task-id", "INVALID"}, targetTool: "list_todo_attachment"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
caller := &qualityEvaluationCaller{}
err := executeQualityEvaluationCommand(t, "todo", caller, newTodoCommand(), tt.args...)
if err == nil {
t.Fatal("todo command accepted a missing task")
}
if len(caller.calls) != 1 || caller.calls[0].toolName != "get_todo_detail" {
t.Fatalf("calls = %#v, want only get_todo_detail preflight before %s", caller.calls, tt.targetTool)
}
})
}
}
func TestCrossPlatformCoverageTodoCommandsPreflightExistingTask(t *testing.T) {
tests := []struct {
name string
args []string
targetTool string
}{
{name: "done", args: []string{"task", "done", "--task-id", "12345", "--status", "true"}, targetTool: "update_todo_done_status"},
{name: "list attachment", args: []string{"task", "list-attachment", "--task-id", "12345"}, targetTool: "list_todo_attachment"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
caller := &qualityEvaluationCaller{}
if err := executeQualityEvaluationCommand(t, "todo", caller, newTodoCommand(), tt.args...); err != nil {
t.Fatalf("todo command returned error: %v", err)
}
if len(caller.calls) != 2 || caller.calls[0].toolName != "get_todo_detail" || caller.calls[1].toolName != tt.targetTool {
t.Fatalf("calls = %#v, want get_todo_detail then %s", caller.calls, tt.targetTool)
}
})
}
}
func TestCrossPlatformCoverageTodoTaskPreflightIsSkippedForDryRun(t *testing.T) {
tests := []struct {
name string
args []string
}{
{name: "done", args: []string{"task", "done", "--task-id", "12345", "--status", "true"}},
{name: "list attachment", args: []string{"task", "list-attachment", "--task-id", "12345"}},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
caller := &qualityEvaluationCaller{dryRun: true}
if err := executeQualityEvaluationCommand(t, "todo", caller, newTodoCommand(), tt.args...); err != nil {
t.Fatalf("todo dry-run returned error: %v", err)
}
if len(caller.calls) != 0 {
t.Fatalf("dry-run made remote calls: %#v", caller.calls)
}
})
}
}
+7
View File
@@ -146,6 +146,13 @@ func callMCPToolCellInfos(toolArgs map[string]any) error {
deps.Out.PrintRaw(text)
return nil
}
if parsed == nil {
return &CLIError{
Code: CodeMCPToolError,
Message: "get_cell_infos returned a null response",
Suggestion: "请确认 --node 指向当前用户可访问的钉钉在线表格",
}
}
// 清理空 dataValidation / hyperlink
if cells, ok := parsed["cells"].([]any); ok {
for _, row := range cells {
+41 -3
View File
@@ -22,6 +22,33 @@ import (
const todoListPageSizeMax = 20
func ensureTodoTaskExists(ctx context.Context, taskID string) error {
text, err := callMCPToolReturnTextOnServer(ctx, "todo", "get_todo_detail", map[string]any{
"taskId": taskID,
})
if err != nil {
return fmt.Errorf("待办任务 %q 不存在或不可访问: %w", taskID, err)
}
var body map[string]any
if err := json.Unmarshal([]byte(text), &body); err != nil {
return fmt.Errorf("校验待办任务 %q 时无法解析详情响应: %w", taskID, err)
}
result, ok := body["result"].(map[string]any)
if !ok {
return fmt.Errorf("待办任务 %q 不存在或详情响应缺少 result", taskID)
}
detail, ok := result["todoDetailModel"].(map[string]any)
if !ok {
return fmt.Errorf("待办任务 %q 不存在或详情响应缺少 todoDetailModel", taskID)
}
returnedTaskID := stringFromJSONScalar(detail["taskId"])
if returnedTaskID == "" || returnedTaskID != taskID {
return fmt.Errorf("待办任务 %q 不存在或详情响应中的 taskId 不匹配", taskID)
}
return nil
}
func newTodoCommand() *cobra.Command {
todoCmd := &cobra.Command{
Use: "todo",
@@ -231,8 +258,14 @@ func newTodoCommand() *cobra.Command {
if err := validateRequiredFlags(cmd, "task-id", "status"); err != nil {
return err
}
taskID := mustGetFlag(cmd, "task-id")
if !deps.Caller.DryRun() {
if err := ensureTodoTaskExists(cmd.Context(), taskID); err != nil {
return err
}
}
return callMCPTool("update_todo_done_status", map[string]any{
"taskId": mustGetFlag(cmd, "task-id"),
"taskId": taskID,
"isDone": mustGetFlag(cmd, "status"),
})
},
@@ -535,10 +568,15 @@ func newTodoCommand() *cobra.Command {
if err := validateRequiredFlags(cmd, "task-id"); err != nil {
return err
}
taskId := mustGetFlag(cmd, "task-id")
taskID := mustGetFlag(cmd, "task-id")
if !deps.Caller.DryRun() {
if err := ensureTodoTaskExists(cmd.Context(), taskID); err != nil {
return err
}
}
return callMCPTool("list_todo_attachment", map[string]any{
"todoAttachmentListRequest": map[string]any{
"taskId": taskId,
"taskId": taskID,
},
})
},