125 lines
6.1 KiB
Go
125 lines
6.1 KiB
Go
// Copyright 2026 Alibaba Group
|
||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||
// you may not use this file except in compliance with the License.
|
||
// You may obtain a copy of the License at
|
||
//
|
||
// http://www.apache.org/licenses/LICENSE-2.0
|
||
//
|
||
// Unless required by applicable law or agreed to in writing, software
|
||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
// See the License for the specific language governing permissions and
|
||
// limitations under the License.
|
||
|
||
package smart
|
||
|
||
import (
|
||
"encoding/json"
|
||
|
||
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/corecmd"
|
||
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/corecmd/contract"
|
||
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/output"
|
||
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/shortcut"
|
||
)
|
||
|
||
// CreatedTodos: list the todos I created (rather than the ones assigned to me
|
||
// to execute) in one step.
|
||
//
|
||
// Steps:
|
||
//
|
||
// 1. list my todos via get_user_todos_in_current_org (pageNum / pageSize as
|
||
// strings, mirroring helpers.todo list) but with roleTypes=["creator"] so
|
||
// the server returns todos where I am the creator. "creator" is one of the
|
||
// three enum values accepted by helpers.parseRoleTypes
|
||
// (creator / executor / participant), so this is a supported role value.
|
||
//
|
||
// 2. project each todoCards[] entry to {subject, taskId, dueTime} with
|
||
// defensive field parsing (reusing shortcutTodoCards / shortcutTodoTaskID /
|
||
// shortcutOverdueDueTime), and print via rt.Output so it honours
|
||
// --format/--jq/--fields.
|
||
//
|
||
// Read-only: it only lists and projects, it never creates or mutates any todo.
|
||
//
|
||
// dws todo +created-todos
|
||
var CreatedTodos = shortcut.Shortcut{
|
||
OutputRollout: output.RolloutUnifiedActive,
|
||
Service: "todo",
|
||
Command: "+created-todos",
|
||
Product: "todo",
|
||
Description: "列出我创建的待办(我作为创建人 creator 发起的待办,而非分配给我执行的)",
|
||
Intent: "当你想快速看清『哪些待办是我自己创建/发起的』,而不是别人指派给我执行的待办时使用;" +
|
||
"内部拉取你当前组织下角色为创建人(creator)的待办列表(roleTypes=[\"creator\"]," +
|
||
"creator 是待办列表支持的角色枚举之一),再在本地把每条待办投影成标题(subject)、" +
|
||
"任务 ID(taskId) 和截止时间(dueTime) 打印出来。这是纯只读操作,只做列表与投影," +
|
||
"不会创建或修改任何待办;若没有你创建的待办则返回空列表。",
|
||
Risk: shortcut.RiskRead,
|
||
Safety: contract.SafetySpec{
|
||
Effect: "read", Risk: "low",
|
||
Confirmation: "not_required", Idempotency: "idempotent",
|
||
},
|
||
Contract: corecmd.ContractDecl{
|
||
Identity: contract.ToolIdentitySpec{
|
||
ProductID: "todo",
|
||
Name: "shortcut_created_todos",
|
||
CanonicalPath: "todo.shortcut_created_todos",
|
||
CLIPath: "todo +created-todos",
|
||
PrimaryCLIPath: "todo +created-todos",
|
||
},
|
||
Description: "列出我创建的待办(我作为创建人 creator 发起的待办,而非分配给我执行的)",
|
||
Result: &contract.ResultSpec{Outcomes: []contract.ResultOutcome{contract.ResultOutcomeSuccess}, DataSchema: json.RawMessage(`{"type":"object","description":"我创建的全部待办","properties":{"created":{"type":"array","description":"创建人角色待办","items":{"type":"object","description":"待办条目","additionalProperties":true}}},"required":["created"],"additionalProperties":false}`)},
|
||
Interface: &contract.InterfaceSpec{
|
||
Mode: "composite",
|
||
Availability: "available",
|
||
Reason: "Reviewed built-in shortcut adapter: the executable CLI owns validation, optional multi-step orchestration, output projection, and confirmation; the complete command contract is not represented by one pinned MCP interface_ref.",
|
||
},
|
||
Selection: contract.SelectionSpec{
|
||
AgentSummary: "列出我创建的待办(我作为创建人 creator 发起的待办,而非分配给我执行的)",
|
||
UseWhen: []string{"当你想快速看清『哪些待办是我自己创建/发起的』,而不是别人指派给我执行的待办时使用;内部拉取你当前组织下角色为创建人(creator)的待办列表(roleTypes=[\"creator\"],creator 是待办列表支持的角色枚举之一),再在本地把每条待办投影成标题(subject)、任务 ID(taskId) 和截止时间(dueTime) 打印出来。这是纯只读操作,只做列表与投影,不会创建或修改任何待办;若没有你创建的待办则返回空列表。"},
|
||
AvoidWhen: []string{"需要该 Shortcut 未公开的底层参数、原始响应或不同执行语义时,改用对应原子命令"},
|
||
Examples: []string{"dws todo +created-todos"},
|
||
},
|
||
},
|
||
Flags: []shortcut.Flag{
|
||
// No required flags: "my created todos" is fully derived from the
|
||
// current identity plus roleTypes=["creator"].
|
||
},
|
||
Tips: []string{
|
||
`dws todo +created-todos`,
|
||
},
|
||
Execute: func(rt *shortcut.RuntimeContext) error {
|
||
// Step 1 — list my todos as creator via the shared pager. This keeps
|
||
// pageSize at todoPageSize(=20): the backend silently returns an empty
|
||
// page for pageSize>20, so the previous hard-coded pageSize=50 made this
|
||
// command always return empty even when the creator had todos. The pager
|
||
// also merges every page instead of only the first.
|
||
cards, err := shortcutListAllTodoCards(rt, map[string]any{
|
||
"roleTypes": []string{"creator"},
|
||
})
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
// Step 2 — project each card to {subject, taskId, dueTime}, parsing
|
||
// fields defensively (helpers reused from todo_done.go / overdue.go).
|
||
created := make([]map[string]any, 0, len(cards))
|
||
for _, m := range cards {
|
||
subject, _ := m["subject"].(string)
|
||
item := map[string]any{
|
||
"subject": subject,
|
||
"taskId": shortcutTodoTaskID(m),
|
||
}
|
||
if due, ok := shortcutOverdueDueTime(m); ok {
|
||
item["dueTime"] = due
|
||
}
|
||
created = append(created, item)
|
||
}
|
||
|
||
// Step 3 — print the projected list of todos I created.
|
||
return rt.Output(map[string]any{"created": created})
|
||
},
|
||
}
|
||
|
||
func init() {
|
||
shortcut.Register(CreatedTodos)
|
||
}
|