110 lines
5.3 KiB
Go
110 lines
5.3 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 (
|
||
"strings"
|
||
|
||
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/corecmd"
|
||
|
||
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/corecmd/contract"
|
||
apperrors "github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/errors"
|
||
"github.com/DingTalk-Real-AI/dingtalk-workspace-cli/internal/shortcut"
|
||
)
|
||
|
||
// DocAppend: append a chunk of text to the END of a document in one command.
|
||
//
|
||
// Instead of asking you to first list the document blocks, figure out the
|
||
// child count / last-block index, then hand-build an insert_document_block
|
||
// element payload, this shortcut leans on update_document's built-in
|
||
// "append" mode — the helper documents mode=append as "追加 (在末尾追加,最安全)",
|
||
// i.e. it appends the given markdown to the document tail safely without
|
||
// touching existing content. Params (nodeId/markdown/mode) are copied verbatim
|
||
// from the update_document append call site in internal/helpers/doc.go.
|
||
//
|
||
// dws doc +doc-append --doc DOC_ID --content "今天的会议结论:下周一上线。"
|
||
var DocAppend = shortcut.Shortcut{
|
||
Service: "doc",
|
||
Command: "+doc-append",
|
||
Product: "doc",
|
||
Description: "在文档末尾追加一段文本(安全追加,不改动原有内容)",
|
||
Intent: "当你只想往一篇钉钉文档的最后面补一段文字、又不想动原有内容时使用;" +
|
||
"内部用文档更新的“追加(append)”模式,把你给的文本安全地拼到文档末尾," +
|
||
"不需要你先去查文档块列表、算末尾位置或手工拼块结构。" +
|
||
"会真实写入文档内容。",
|
||
Risk: shortcut.RiskWrite,
|
||
Safety: contract.SafetySpec{
|
||
Effect: "write", Risk: "medium",
|
||
Confirmation: "user_required", Idempotency: "unknown",
|
||
},
|
||
Contract: corecmd.ContractDecl{
|
||
Identity: contract.ToolIdentitySpec{
|
||
ProductID: "doc",
|
||
Name: "shortcut_doc_append",
|
||
CanonicalPath: "doc.shortcut_doc_append",
|
||
CLIPath: "doc +doc-append",
|
||
PrimaryCLIPath: "doc +doc-append",
|
||
},
|
||
Description: "在文档末尾追加一段文本(安全追加,不改动原有内容)",
|
||
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: "在文档末尾追加一段文本(安全追加,不改动原有内容)",
|
||
UseWhen: []string{"当你只想往一篇钉钉文档的最后面补一段文字、又不想动原有内容时使用;内部用文档更新的“追加(append)”模式,把你给的文本安全地拼到文档末尾,不需要你先去查文档块列表、算末尾位置或手工拼块结构。会真实写入文档内容。"},
|
||
AvoidWhen: []string{"需要该 Shortcut 未公开的底层参数、原始响应或不同执行语义时,改用对应原子命令"},
|
||
Examples: []string{
|
||
"dws doc +doc-append --doc DOC_ID --content \"补充说明:本方案已评审通过。\"",
|
||
"dws doc +doc-append --doc \"https://alidocs.dingtalk.com/i/nodes/<DOC_UUID>\" --content \"追加一行备注\"",
|
||
},
|
||
},
|
||
Parameters: []contract.ParamDecl{renamedRequiredParam("content", "text")},
|
||
},
|
||
Flags: []shortcut.Flag{
|
||
{Name: "doc", Type: shortcut.FlagString, Desc: "文档 documentId / nodeId(或文档 URL/token)", Required: true},
|
||
{Name: "content", Type: shortcut.FlagString, Desc: "要追加到文档末尾的文本", Required: true, Aliases: []string{"text"}},
|
||
},
|
||
Tips: []string{
|
||
`dws doc +doc-append --doc DOC_ID --content "补充说明:本方案已评审通过。"`,
|
||
`dws doc +doc-append --doc "https://alidocs.dingtalk.com/i/nodes/<DOC_UUID>" --content "追加一行备注"`,
|
||
},
|
||
Execute: func(rt *shortcut.RuntimeContext) error {
|
||
nodeID := strings.TrimSpace(rt.Str("doc"))
|
||
if nodeID == "" {
|
||
return apperrors.NewValidation("--doc 不能为空,请提供文档 documentId/nodeId 或文档 URL")
|
||
}
|
||
text := rt.StrFirst("text", "content")
|
||
if strings.TrimSpace(text) == "" {
|
||
return apperrors.NewValidation("--content 不能为空,请提供要追加的文本")
|
||
}
|
||
|
||
// update_document append: params copied verbatim from the helper's
|
||
// `doc update --mode append` call site — nodeId + markdown + mode.
|
||
// mode=append 追加到文档末尾(最安全,不清空原内容)。
|
||
return rt.CallMCP("update_document", map[string]any{
|
||
"nodeId": nodeID,
|
||
"markdown": text,
|
||
"mode": "append",
|
||
})
|
||
},
|
||
}
|
||
|
||
func init() {
|
||
// Keep the historical command and Schema identity alongside the richer
|
||
// canonical doc +update surface for backwards compatibility.
|
||
shortcut.Register(DocAppend)
|
||
}
|