From d9330b7ab3dcd6de2fd2944517cc5758cc47f55c Mon Sep 17 00:00:00 2001 From: SunPeiYang996 Date: Fri, 26 Jun 2026 14:32:09 +0800 Subject: [PATCH] fix(docs): hide docs api-version compat flag (#1580) --- README.md | 2 +- README.zh.md | 2 +- shortcuts/doc/docs_create_test.go | 9 +--- shortcuts/doc/docs_fetch_v2_test.go | 4 +- shortcuts/doc/docs_update_test.go | 4 +- shortcuts/doc/v2_only.go | 14 ++--- shortcuts/doc/v2_only_test.go | 26 +--------- shortcuts/note/note_transcript.go | 2 +- shortcuts/note/note_transcript_test.go | 2 +- shortcuts/register_test.go | 27 +++------- skill-template/domains/doc.md | 4 +- skill-template/domains/drive.md | 2 +- skills/lark-doc/SKILL.md | 18 +++---- skills/lark-doc/references/lark-doc-create.md | 5 +- skills/lark-doc/references/lark-doc-fetch.md | 17 +++--- skills/lark-doc/references/lark-doc-md.md | 6 +-- .../references/lark-doc-media-insert.md | 2 +- skills/lark-doc/references/lark-doc-update.md | 39 +++++++------- .../references/lark-doc-whiteboard.md | 4 +- .../style/lark-doc-create-workflow.md | 4 +- .../style/lark-doc-update-workflow.md | 10 ++-- skills/lark-drive/SKILL.md | 2 +- .../references/lark-drive-add-comment.md | 6 +-- .../references/lark-drive-comment-location.md | 4 +- .../references/lark-drive-files-list.md | 2 +- skills/lark-note/SKILL.md | 14 ++--- .../lark-note/references/lark-note-detail.md | 4 +- .../references/lark-note-transcript.md | 6 +-- skills/lark-vc/SKILL.md | 6 +-- .../references/vc-domain-boundaries.md | 14 ++--- .../references/lark-whiteboard-workflow.md | 4 +- skills/lark-workflow-meeting-summary/SKILL.md | 4 +- tests/cli_e2e/doc/docs_dryrun_test.go | 52 +++++++++++++++++++ 33 files changed, 160 insertions(+), 161 deletions(-) create mode 100644 tests/cli_e2e/doc/docs_dryrun_test.go diff --git a/README.md b/README.md index 5ea47838..e0f371f6 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,7 @@ Prefixed with `+`, designed to be friendly for both humans and AI, with smart de ```bash lark-cli calendar +agenda lark-cli im +messages-send --chat-id "oc_xxx" --text "Hello" -lark-cli docs +create --api-version v2 --doc-format markdown --content $'Weekly Report\n# Progress\n- Completed feature X' +lark-cli docs +create --doc-format markdown --content $'Weekly Report\n# Progress\n- Completed feature X' ``` Run `lark-cli --help` to see all shortcut commands. diff --git a/README.zh.md b/README.zh.md index f597ca68..6d8221f2 100644 --- a/README.zh.md +++ b/README.zh.md @@ -199,7 +199,7 @@ CLI 提供三种粒度的调用方式,覆盖从快速操作到完全自定义 ```bash lark-cli calendar +agenda lark-cli im +messages-send --chat-id "oc_xxx" --text "Hello" -lark-cli docs +create --api-version v2 --doc-format markdown --content $'周报\n# 本周进展\n- 完成了 X 功能' +lark-cli docs +create --doc-format markdown --content $'周报\n# 本周进展\n- 完成了 X 功能' ``` 运行 `lark-cli --help` 查看所有快捷命令。 diff --git a/shortcuts/doc/docs_create_test.go b/shortcuts/doc/docs_create_test.go index 20d484aa..089a0c3f 100644 --- a/shortcuts/doc/docs_create_test.go +++ b/shortcuts/doc/docs_create_test.go @@ -90,7 +90,6 @@ func TestDocsCreateV2BotAutoGrantSkippedWithoutCurrentUser(t *testing.T) { err := runDocsCreateShortcut(t, f, stdout, []string{ "+create", - "--api-version", "v2", "--content", "内容

正文

", "--as", "bot", }) @@ -125,7 +124,6 @@ func TestDocsCreateV2UserSkipsPermissionGrantAugmentation(t *testing.T) { err := runDocsCreateShortcut(t, f, stdout, []string{ "+create", - "--api-version", "v2", "--content", "内容

正文

", "--as", "user", }) @@ -163,7 +161,6 @@ func TestDocsCreateV2BotAutoGrantFailureDoesNotFailCreate(t *testing.T) { err := runDocsCreateShortcut(t, f, stdout, []string{ "+create", - "--api-version", "v2", "--content", "内容

正文

", "--as", "bot", }) @@ -201,7 +198,6 @@ func TestDocsCreateV2FallbackURLWhenBackendOmitsIt(t *testing.T) { err := runDocsCreateShortcut(t, f, stdout, []string{ "+create", - "--api-version", "v2", "--content", "内容

正文

", "--as", "user", }) @@ -233,7 +229,6 @@ func TestDocsCreateV2PreservesBackendURL(t *testing.T) { err := runDocsCreateShortcut(t, f, stdout, []string{ "+create", - "--api-version", "v2", "--content", "内容

正文

", "--as", "user", }) @@ -248,7 +243,7 @@ func TestDocsCreateV2PreservesBackendURL(t *testing.T) { } } -func TestDocsCreateAPIVersionV1StillUsesV2Endpoint(t *testing.T) { +func TestDocsCreateAPIVersionCompatFlagIsIgnored(t *testing.T) { t.Parallel() f, stdout, _, reg := cmdutil.TestFactory(t, docsCreateTestConfig(t, "")) @@ -262,7 +257,7 @@ func TestDocsCreateAPIVersionV1StillUsesV2Endpoint(t *testing.T) { err := runDocsCreateShortcut(t, f, stdout, []string{ "+create", - "--api-version", "v1", + "--api-version", "legacy", "--content", "项目计划", "--as", "user", }) diff --git a/shortcuts/doc/docs_fetch_v2_test.go b/shortcuts/doc/docs_fetch_v2_test.go index 6aa3296b..63aba4a7 100644 --- a/shortcuts/doc/docs_fetch_v2_test.go +++ b/shortcuts/doc/docs_fetch_v2_test.go @@ -507,10 +507,10 @@ func TestDocsFetchDryRunDefaultsToV2Endpoint(t *testing.T) { } } -func TestDocsFetchAPIVersionV1StillUsesV2Endpoint(t *testing.T) { +func TestDocsFetchAPIVersionCompatFlagIsIgnored(t *testing.T) { t.Parallel() - runtime := newFetchShortcutTestRuntime(t, "v1", nil) + runtime := newFetchShortcutTestRuntime(t, "legacy", nil) if err := validateFetchV2(context.Background(), runtime); err != nil { t.Fatalf("validateFetchV2() error = %v", err) } diff --git a/shortcuts/doc/docs_update_test.go b/shortcuts/doc/docs_update_test.go index dd856188..b6b757cb 100644 --- a/shortcuts/doc/docs_update_test.go +++ b/shortcuts/doc/docs_update_test.go @@ -34,8 +34,8 @@ func TestValidCommandsV2(t *testing.T) { } } -func TestDocsUpdateDryRunAcceptsDeprecatedAPIVersionValues(t *testing.T) { - for _, apiVersion := range []string{"v1", "v2"} { +func TestDocsUpdateDryRunIgnoresAPIVersionCompatFlag(t *testing.T) { + for _, apiVersion := range []string{"v1", "v2", "legacy"} { t.Run(apiVersion, func(t *testing.T) { t.Parallel() diff --git a/shortcuts/doc/v2_only.go b/shortcuts/doc/v2_only.go index 8e124983..cb49ea62 100644 --- a/shortcuts/doc/v2_only.go +++ b/shortcuts/doc/v2_only.go @@ -17,9 +17,9 @@ type docsLegacyFlag struct { func docsAPIVersionCompatFlag() common.Flag { return common.Flag{ - Name: "api-version", - Desc: "deprecated compatibility flag; docs shortcuts always use v2, and both v1/v2 are accepted for rollback-safe skill examples", - Default: "v2", + Name: "api-version", + Desc: "deprecated compatibility flag; ignored by docs shortcuts", + Hidden: true, } } @@ -54,7 +54,7 @@ func docsLegacyFlagDefinitions(flags []docsLegacyFlag) []common.Flag { for _, flag := range flags { out = append(out, common.Flag{ Name: flag.Name, - Desc: "deprecated v1 compatibility flag; run `lark-cli skills read lark-doc` for the v2 CLI skill", + Desc: "deprecated compatibility flag; run `lark-cli skills read lark-doc` for the current CLI skill", Hidden: true, }) } @@ -62,12 +62,6 @@ func docsLegacyFlagDefinitions(flags []docsLegacyFlag) []common.Flag { } func validateDocsV2Only(runtime *common.RuntimeContext, shortcut string, legacyFlags []docsLegacyFlag) error { - switch apiVersion := strings.TrimSpace(runtime.Str("api-version")); apiVersion { - case "", "v1", "v2": - default: - return docsV2OnlyError(shortcut, "--api-version is deprecated and only accepts v1 or v2; both values execute the v2 API", "--api-version") - } - var used []string var replacements []string for _, flag := range legacyFlags { diff --git a/shortcuts/doc/v2_only_test.go b/shortcuts/doc/v2_only_test.go index ce216c8a..2ebd6dab 100644 --- a/shortcuts/doc/v2_only_test.go +++ b/shortcuts/doc/v2_only_test.go @@ -11,8 +11,8 @@ import ( "github.com/spf13/cobra" ) -func TestValidateDocsV2OnlyAllowsDefaultAndDeprecatedAPIVersionValues(t *testing.T) { - for _, apiVersion := range []string{"", "v1", "v2"} { +func TestValidateDocsV2OnlyIgnoresAPIVersionValues(t *testing.T) { + for _, apiVersion := range []string{"", "v1", "v2", "v0", "legacy"} { t.Run(apiVersion, func(t *testing.T) { runtime := docsV2OnlyTestRuntime(t, apiVersion, false) if err := validateDocsV2Only(runtime, "+update", []docsLegacyFlag{{Name: "mode", Replacement: "use --command"}}); err != nil { @@ -22,28 +22,6 @@ func TestValidateDocsV2OnlyAllowsDefaultAndDeprecatedAPIVersionValues(t *testing } } -func TestValidateDocsV2OnlyRejectsUnknownAPIVersion(t *testing.T) { - runtime := docsV2OnlyTestRuntime(t, "v0", false) - err := validateDocsV2Only(runtime, "+fetch", nil) - if err == nil { - t.Fatal("expected unknown --api-version to be rejected") - } - for _, want := range []string{ - "docs +fetch is v2-only", - "--api-version is deprecated and only accepts v1 or v2", - "both values execute the v2 API", - "lark-cli skills read lark-doc references/lark-doc-fetch.md", - "lark-cli skills read lark-doc references/lark-doc-xml.md", - "lark-cli skills read lark-doc references/lark-doc-md.md", - "MUST NOT grep/open local SKILL.md files", - "lark-cli docs +fetch --help", - } { - if !strings.Contains(err.Error(), want) { - t.Fatalf("error missing %q: %v", want, err) - } - } -} - func TestValidateDocsV2OnlyRejectsChangedLegacyFlags(t *testing.T) { runtime := docsV2OnlyTestRuntime(t, "", true) err := validateDocsV2Only(runtime, "+update", []docsLegacyFlag{{Name: "mode", Replacement: "use --command"}}) diff --git a/shortcuts/note/note_transcript.go b/shortcuts/note/note_transcript.go index 6810afe6..fe84f057 100644 --- a/shortcuts/note/note_transcript.go +++ b/shortcuts/note/note_transcript.go @@ -153,7 +153,7 @@ func ensureUnifiedNote(ctx context.Context, runtime *common.RuntimeContext, note if detail.DisplayType != "unified" { if detail.VerbatimDocToken != "" { return errs.NewValidationError(errs.SubtypeFailedPrecondition, "note %s is not a unified note (note_display_type=%s, verbatim_doc_token=%s)", noteID, detail.DisplayType, detail.VerbatimDocToken). - WithHint("Use docs +fetch --api-version v2 --doc %s for normal note transcripts", detail.VerbatimDocToken) + WithHint("Use docs +fetch --doc %s for normal note transcripts", detail.VerbatimDocToken) } return errs.NewValidationError(errs.SubtypeFailedPrecondition, "note %s is not a unified note (note_display_type=%s, verbatim_doc_token=)", noteID, detail.DisplayType). WithHint("Use note +detail to inspect document tokens") diff --git a/shortcuts/note/note_transcript_test.go b/shortcuts/note/note_transcript_test.go index d6979414..f9914ec7 100644 --- a/shortcuts/note/note_transcript_test.go +++ b/shortcuts/note/note_transcript_test.go @@ -39,7 +39,7 @@ func TestNoteTranscriptRequiresUnifiedNote(t *testing.T) { if problem.Subtype != errs.SubtypeFailedPrecondition { t.Fatalf("subtype = %v, want FailedPrecondition", problem.Subtype) } - if !strings.Contains(problem.Hint, "docs +fetch --api-version v2 --doc doc_verbatim") { + if !strings.Contains(problem.Hint, "docs +fetch --doc doc_verbatim") { t.Fatalf("hint = %q, want docs +fetch guidance", problem.Hint) } if stdout.Len() != 0 { diff --git a/shortcuts/register_test.go b/shortcuts/register_test.go index 2864bf5a..5137584b 100644 --- a/shortcuts/register_test.go +++ b/shortcuts/register_test.go @@ -246,7 +246,7 @@ func TestRegisterShortcutsDocsShortcutHelpIsV2Only(t *testing.T) { shortcutHelp: "Create a Lark document", visibleFlag: "--content", skillCommand: "lark-cli skills read lark-doc references/lark-doc-create.md", - hiddenFlags: []string{"markdown", "folder-token", "wiki-node", "wiki-space"}, + hiddenFlags: []string{"api-version", "markdown", "folder-token", "wiki-node", "wiki-space"}, contentHelp: []string{ "--title", "AI agents MUST read", @@ -258,7 +258,7 @@ func TestRegisterShortcutsDocsShortcutHelpIsV2Only(t *testing.T) { "MUST NOT grep/open local SKILL.md files", "use --help for the latest command flags", }, - unwanted: []string{"--markdown", "--folder-token", "--wiki-node", "--wiki-space"}, + unwanted: []string{"--api-version", "--markdown", "--folder-token", "--wiki-node", "--wiki-space"}, }, { name: "fetch", @@ -266,8 +266,8 @@ func TestRegisterShortcutsDocsShortcutHelpIsV2Only(t *testing.T) { shortcutHelp: "Fetch Lark document content", visibleFlag: "read scope", skillCommand: "lark-cli skills read lark-doc references/lark-doc-fetch.md", - hiddenFlags: []string{"offset", "limit"}, - unwanted: []string{"--offset", "--limit"}, + hiddenFlags: []string{"api-version", "offset", "limit"}, + unwanted: []string{"--api-version", "--offset", "--limit"}, }, { name: "update", @@ -275,7 +275,7 @@ func TestRegisterShortcutsDocsShortcutHelpIsV2Only(t *testing.T) { shortcutHelp: "Update a Lark document", visibleFlag: "--command", skillCommand: "lark-cli skills read lark-doc references/lark-doc-update.md", - hiddenFlags: []string{"mode", "markdown", "selection-with-ellipsis", "selection-by-title", "new-title"}, + hiddenFlags: []string{"api-version", "mode", "markdown", "selection-with-ellipsis", "selection-by-title", "new-title"}, contentHelp: []string{ "AI agents MUST read", "lark-cli skills read lark-doc references/lark-doc-xml.md", @@ -286,7 +286,7 @@ func TestRegisterShortcutsDocsShortcutHelpIsV2Only(t *testing.T) { "MUST NOT grep/open local SKILL.md files", "use --help for the latest command flags", }, - unwanted: []string{"--mode", "--markdown", "--selection-with-ellipsis", "--selection-by-title", "--new-title"}, + unwanted: []string{"--api-version", "--mode", "--markdown", "--selection-with-ellipsis", "--selection-by-title", "--new-title"}, }, } @@ -312,17 +312,6 @@ func TestRegisterShortcutsDocsShortcutHelpIsV2Only(t *testing.T) { t.Fatalf("docs %s flag %q should be hidden", tt.shortcut, flagName) } } - apiVersionFlag := cmd.Flags().Lookup("api-version") - if apiVersionFlag == nil { - t.Fatalf("docs %s missing --api-version flag", tt.shortcut) - } - if apiVersionFlag.Hidden { - t.Fatalf("docs %s --api-version should be visible", tt.shortcut) - } - if apiVersionFlag.DefValue != "v2" { - t.Fatalf("docs %s --api-version default = %q, want v2", tt.shortcut, apiVersionFlag.DefValue) - } - var out bytes.Buffer cmd.SetOut(&out) if err := cmd.Help(); err != nil { @@ -332,10 +321,6 @@ func TestRegisterShortcutsDocsShortcutHelpIsV2Only(t *testing.T) { for _, want := range []string{ tt.shortcutHelp, tt.visibleFlag, - "--api-version", - "deprecated compatibility flag; docs shortcuts always use v2", - "both v1/v2 are accepted", - "(default \"v2\")", "Start here (required for AI agents):", "AI agents MUST read the matching embedded skill", "Do not skip this step", diff --git a/skill-template/domains/doc.md b/skill-template/domains/doc.md index 9d8b42af..17cf03d0 100644 --- a/skill-template/domains/doc.md +++ b/skill-template/domains/doc.md @@ -86,8 +86,8 @@ Drive Folder (云空间文件夹) ## 重要说明:画板编辑 > **⚠️ lark-doc skill 不能直接编辑已有画板内容,但 `docs +update` 可以新建空白画板** -### 场景 1:已通过 docs +fetch --api-version v2 获取到文档内容和画板 token -如果用户已经通过 `docs +fetch --api-version v2` 拉取了文档内容,并且文档中已有画板(返回的 markdown 中包含 `` 标签),请引导用户: +### 场景 1:已通过 docs +fetch 获取到文档内容和画板 token +如果用户已经通过 `docs +fetch` 拉取了文档内容,并且文档中已有画板(返回的 markdown 中包含 `` 标签),请引导用户: 1. 记录画板的 token 2. 查看 [`../lark-whiteboard/SKILL.md`](../lark-whiteboard/SKILL.md) 了解如何编辑画板内容 ### 场景 2:刚创建画板,需要编辑 diff --git a/skill-template/domains/drive.md b/skill-template/domains/drive.md index fbaf4e8b..99fbabce 100644 --- a/skill-template/domains/drive.md +++ b/skill-template/domains/drive.md @@ -111,7 +111,7 @@ Drive Folder (云空间文件夹) | 操作 | 需要的 Token | 说明 | |------|-------------|------| -| 读取文档内容 | `file_token` / 通过 `docs +fetch --api-version v2` 自动处理 | `docs +fetch --api-version v2` 支持直接传入 URL | +| 读取文档内容 | `file_token` / 通过 `docs +fetch` 自动处理 | `docs +fetch` 支持直接传入 URL | | 添加局部评论(划词评论) | `file_token` | 传 `--block-id` 时,`drive +add-comment` 会创建局部评论;`docx` 支持文本定位或 block_id,`sheet` 使用 `!`,`slides` 使用 `!`;Base / bitable 只有记录局部评论,定位为 file_token(base token) + `--block-id !!` | | 添加全文评论 | `file_token` | 不传 `--block-id` 时,`drive +add-comment` 默认创建全文评论;支持 `docx`、旧版 `doc` URL、白名单扩展名的 Drive file,以及最终解析为 `doc`/`docx`/`file` 的 wiki URL | | 下载文件 | `file_token` | 从文件 URL 中直接提取 | diff --git a/skills/lark-doc/SKILL.md b/skills/lark-doc/SKILL.md index 9018ddb4..de803512 100644 --- a/skills/lark-doc/SKILL.md +++ b/skills/lark-doc/SKILL.md @@ -1,31 +1,29 @@ --- name: lark-doc version: 2.0.0 -description: "飞书云文档(Docx / Wiki 文档,v2 API):读取和编辑飞书文档内容。当用户给出文档 URL 或 token,或需要查看、创建、编辑文档、插入或下载文档图片附件时使用。文档中嵌入的电子表格、多维表格、画板,先用本 skill 提取 token 再切到对应 skill。当用户给出 doubao.com 的 /docx/ 或 /wiki/ URL/token 时,也应直接使用本 skill;路由依据是 URL 路径模式和 token,而不是域名。不负责文档评论管理,也不负责表格或 Base 的数据操作。" +description: "飞书云文档(Docx / Wiki 文档):读取和编辑飞书文档内容。当用户给出文档 URL 或 token,或需要查看、创建、编辑文档、插入或下载文档图片附件时使用。文档中嵌入的电子表格、多维表格、画板,先用本 skill 提取 token 再切到对应 skill。当用户给出 doubao.com 的 /docx/ 或 /wiki/ URL/token 时,也应直接使用本 skill;路由依据是 URL 路径模式和 token,而不是域名。不负责文档评论管理,也不负责表格或 Base 的数据操作。" metadata: requires: bins: ["lark-cli"] - cliHelp: "lark-cli docs --api-version v2 --help; lark-cli docs +create --api-version v2 --help; lark-cli docs +fetch --api-version v2 --help; lark-cli docs +update --api-version v2 --help; lark-cli docs +resource-download --help; lark-cli docs +resource-update --help; lark-cli docs +resource-delete --help" + cliHelp: "lark-cli docs --help; lark-cli docs +create --help; lark-cli docs +fetch --help; lark-cli docs +update --help; lark-cli docs +resource-download --help; lark-cli docs +resource-update --help; lark-cli docs +resource-delete --help" --- -# docs (v2) +# docs **身份:文档操作默认使用 `--as user`。首次使用前执行 `lark-cli auth login`。** -> **CRITICAL — API 版本:本 skill 使用 v2 API。执行 `docs +create`、`docs +fetch`、`docs +update` 时必须显式传入 `--api-version v2`。** - ```bash # 常用示例 -lark-cli docs +fetch --api-version v2 --doc "文档URL或token" -lark-cli docs +create --api-version v2 --content '标题

内容

' -lark-cli docs +update --api-version v2 --doc "文档URL或token" --command append --content '

内容

' +lark-cli docs +fetch --doc "文档URL或token" +lark-cli docs +create --content '标题

内容

' +lark-cli docs +update --doc "文档URL或token" --command append --content '

内容

' ``` ## 前置条件 — 执行操作前必读 **CRITICAL — 执行对应操作前,MUST 先用 Read 工具读取以下文件,缺一不可:** 1. [`../lark-shared/SKILL.md`](../lark-shared/SKILL.md) — 认证、权限处理、全局参数(所有操作通用) -2. **读取文档(`docs +fetch --api-version v2`)** → 必读 [`lark-doc-fetch.md`](references/lark-doc-fetch.md)(`--scope` / `--detail` 选择、局部读取策略、`` / `` 输出结构) +2. **读取文档(`docs +fetch`)** → 必读 [`lark-doc-fetch.md`](references/lark-doc-fetch.md)(`--scope` / `--detail` 选择、局部读取策略、`` / `` 输出结构) 3. **创建或编辑文档内容** → 必读 [`lark-doc-xml.md`](references/lark-doc-xml.md)(XML 语法规则,仅当用户明确要求 Markdown 时改读 [`lark-doc-md.md`](references/lark-doc-md.md))和 [`lark-doc-style.md`](references/style/lark-doc-style.md)(元素选择、丰富度规则、颜色语义);从零创建时加读 [`lark-doc-create-workflow.md`](references/style/lark-doc-create-workflow.md);编辑已有文档时加读 [`lark-doc-update.md`](references/lark-doc-update.md) 和 [`lark-doc-update-workflow.md`](references/style/lark-doc-update-workflow.md) **未读完以上文件就执行相应操作会导致参数选择错误或格式错误。** @@ -57,7 +55,7 @@ lark-cli docs +update --api-version v2 --doc "文档URL或token" --command appen | `` | 同 `` | [`lark-sheets`](../lark-sheets/SKILL.md) | | `` | 同 `` | [`lark-base`](../lark-base/SKILL.md) | | `` | `vc-node-id` -> note_id | [`lark-note`](../lark-note/SKILL.md):先 `note +detail --note-id ` | -| `` | `src-token` -> doc_token, `src-block-id` -> block_id | 用 `docs +fetch --api-version v2` 读取 src-token 文档,定位 block | +| `` | `src-token` -> doc_token, `src-block-id` -> block_id | 用 `docs +fetch` 读取 src-token 文档,定位 block | ## Shortcuts(推荐优先使用) diff --git a/skills/lark-doc/references/lark-doc-create.md b/skills/lark-doc/references/lark-doc-create.md index 749fcb7a..17fa6bc2 100644 --- a/skills/lark-doc/references/lark-doc-create.md +++ b/skills/lark-doc/references/lark-doc-create.md @@ -15,10 +15,10 @@ ```bash # 创建 XML 文档(默认格式,推荐) -lark-cli docs +create --api-version v2 --content '项目计划

目标

记录本周重点。

' +lark-cli docs +create --content '项目计划

目标

记录本周重点。

' # 仅当用户明确要求导入 Markdown 时才使用;文档标题用 --title,正文标题按内容自然组织 -lark-cli docs +create --api-version v2 --doc-format markdown --title "项目计划" --content $'## 目标\n\n- 明确重点\n- 记录待办' +lark-cli docs +create --doc-format markdown --title "项目计划" --content $'## 目标\n\n- 明确重点\n- 记录待办' ``` ## 返回值 @@ -58,7 +58,6 @@ lark-cli docs +create --api-version v2 --doc-format markdown --title "项目计 | 参数 | 必填 | 说明 | | ------------------- | -- |---------------------------------------------| -| `--api-version` | 是 | 固定传 `v2` | | `--title` | 否 | 文档标题,Markdown 导入时使用;XML 创建推荐在 `--content` 开头写 `...`;多个标题仅保留第一个并在 `warnings` / `degrade_details` 提示 | | `--content` | 视情况 | 文档内容(XML 或 Markdown 格式);不传 `--content` 时必须传 `--title` | | `--doc-format` | 否 | 内容格式:`xml`(默认,始终优先使用)\| `markdown`(仅用户明确要求时) | diff --git a/skills/lark-doc/references/lark-doc-fetch.md b/skills/lark-doc/references/lark-doc-fetch.md index c4661f71..b0ffc87e 100644 --- a/skills/lark-doc/references/lark-doc-fetch.md +++ b/skills/lark-doc/references/lark-doc-fetch.md @@ -5,27 +5,27 @@ ```bash # 获取文档(默认 XML,simple) -lark-cli docs +fetch --api-version v2 --doc "https://xxx.feishu.cn/docx/Z1Fj...tnAc" +lark-cli docs +fetch --doc "https://xxx.feishu.cn/docx/Z1Fj...tnAc" # Markdown 格式 -lark-cli docs +fetch --api-version v2 --doc Z1Fj...tnAc --doc-format markdown +lark-cli docs +fetch --doc Z1Fj...tnAc --doc-format markdown # 带 block ID(用于后续 block 级更新) -lark-cli docs +fetch --api-version v2 --doc Z1Fj...tnAc --detail with-ids +lark-cli docs +fetch --doc Z1Fj...tnAc --detail with-ids # 只拿目录 -lark-cli docs +fetch --api-version v2 --doc Z1Fj...tnAc --scope outline --max-depth 3 +lark-cli docs +fetch --doc Z1Fj...tnAc --scope outline --max-depth 3 # 按 block id 区间精读 -lark-cli docs +fetch --api-version v2 --doc Z1Fj...tnAc \ +lark-cli docs +fetch --doc Z1Fj...tnAc \ --scope range --start-block-id blkA --end-block-id blkB --detail with-ids # 读整个章节(以标题 id 为锚点,自动展开到下一个同级/更高级标题前) -lark-cli docs +fetch --api-version v2 --doc Z1Fj...tnAc \ +lark-cli docs +fetch --doc Z1Fj...tnAc \ --scope section --start-block-id <标题id> --detail with-ids # 按关键词定位(多关键词用 | 分隔,任一命中即返回) -lark-cli docs +fetch --api-version v2 --doc Z1Fj...tnAc \ +lark-cli docs +fetch --doc Z1Fj...tnAc \ --scope keyword --keyword "部署|发布|上线" ``` @@ -97,7 +97,6 @@ lark-cli docs +fetch --api-version v2 --doc Z1Fj...tnAc \ | 参数 | 必填 | 说明 | |------|------|------| -| `--api-version` | 是 | 固定传 `v2` | | `--doc` | 是 | 文档 URL 或 token(支持 `/docx/` 和 `/wiki/`) | | `--doc-format` | 否 | `xml`(默认)\| `markdown` \| `im-markdown`(仅用于获取内容后在 `lark-im` 场景下使用) | | `--detail` | 否 | `simple`(默认)\| `with-ids` \| `full` | @@ -128,7 +127,7 @@ lark-cli docs +fetch --api-version v2 --doc Z1Fj...tnAc \ ## 嵌入电子表格 / 多维表格 -返回中可能含 ``、``、``。内部数据无法通过 `docs +fetch --api-version v2` 获取,提取 `token` 等属性后切到 [`lark-sheets`](../../lark-sheets/SKILL.md) / [`lark-base`](../../lark-base/SKILL.md) 下钻,详见 [SKILL.md 快速决策](../SKILL.md) 路由表。 +返回中可能含 ``、``、``。内部数据无法通过 `docs +fetch` 获取,提取 `token` 等属性后切到 [`lark-sheets`](../../lark-sheets/SKILL.md) / [`lark-base`](../../lark-base/SKILL.md) 下钻,详见 [SKILL.md 快速决策](../SKILL.md) 路由表。 ## 参考 diff --git a/skills/lark-doc/references/lark-doc-md.md b/skills/lark-doc/references/lark-doc-md.md index f43ab060..b8ae2d0a 100644 --- a/skills/lark-doc/references/lark-doc-md.md +++ b/skills/lark-doc/references/lark-doc-md.md @@ -1,6 +1,6 @@ # Markdown 格式参考 -`docs +fetch --api-version v2` / `docs +create --api-version v2` / `docs +update --api-version v2` 使用 `--doc-format markdown` 时适用;fetch 的 `--doc-format im-markdown` 仅用于获取内容后在 `lark-im` 场景下使用,不作为 create/update 写入格式。 +`docs +fetch` / `docs +create` / `docs +update` 使用 `--doc-format markdown` 时适用;fetch 的 `--doc-format im-markdown` 仅用于获取内容后在 `lark-im` 场景下使用,不作为 create/update 写入格式。 ## 转义规则 @@ -34,14 +34,14 @@ - `$...$` 数学公式内部,符号为 LaTeX 语法,不受 Markdown 转义影响 **导出已转义,不要反转义:** -`docs +fetch --api-version v2 --doc-format markdown` 导出的内容中,特殊字符**已经被转义过了**(例如 `\[`、`\|`、`\\` 等)。这些 `\` 是有意义的——去掉会导致后续写入时字符被 Markdown 语法吞掉。**不要反转义或去掉 `\`。** +`docs +fetch --doc-format markdown` 导出的内容中,特殊字符**已经被转义过了**(例如 `\[`、`\|`、`\\` 等)。这些 `\` 是有意义的——去掉会导致后续写入时字符被 Markdown 语法吞掉。**不要反转义或去掉 `\`。** **写入时必须转义:** 使用 `docs +create` 或 `docs +update` 的 `--doc-format markdown` 写入内容时,字面文本中的特殊字符同样必须转义。`--pattern` 参数中也必须使用转义形式才能正确匹配。 **导出 → 更新 工作流示例:** -1. `docs +fetch --api-version v2` 导出得到 `C:\\Users\\test\[1\]` +1. `docs +fetch` 导出得到 `C:\\Users\\test\[1\]` 2. 用 `str_replace --pattern 'C:\\Users\\test\[1\]'` 匹配(直接使用导出的转义形式) 3. `--content` 中的替换内容也要保持转义:`C:\\Users\\prod\[2\]` diff --git a/skills/lark-doc/references/lark-doc-media-insert.md b/skills/lark-doc/references/lark-doc-media-insert.md index 9b557b70..ca541300 100644 --- a/skills/lark-doc/references/lark-doc-media-insert.md +++ b/skills/lark-doc/references/lark-doc-media-insert.md @@ -48,7 +48,7 @@ lark-cli docs +media-insert --doc doxcnXXX --from-clipboard # 从本地文件插入 # 除了上传本地文件,还可以在 `docs +update` 时直接通过网络 URL 插入图片,无需先下载到本地: -lark-cli docs +update --api-version v2 --doc "" --command block_insert_after \ +lark-cli docs +update --doc "" --command block_insert_after \ --block-id "目标 block_id" \ --content '' diff --git a/skills/lark-doc/references/lark-doc-update.md b/skills/lark-doc/references/lark-doc-update.md index bf5402a3..62fc467a 100644 --- a/skills/lark-doc/references/lark-doc-update.md +++ b/skills/lark-doc/references/lark-doc-update.md @@ -14,13 +14,12 @@ > - **局部精修**(`str_replace` / `block_insert_after` / `block_replace` / `block_delete` / `block_move_after`):优先使用 XML(默认)。XML 能稳定表达 block 结构和样式,精准编辑更可控;不要因为 Markdown 写起来更简单就自行切换。 > - **整段写入**(`append` / `overwrite`):XML 和 Markdown 都可以。用户提供 `.md` 本地文件或明确要求 Markdown 时直接用 Markdown;否则默认 XML。 > -> **Markdown 局限 & block ID 前提:** Markdown 不携带 block ID,也无样式(颜色、对齐、callout 等)。需要按 block ID 定位(`block_*` 指令的 `--block-id`)时,先 `docs +fetch --api-version v2 --detail with-ids` **配合 `--scope`(`outline` / `range` / `keyword` / `section`)局部获取**目标段落,不要全量 fetch。拿到 block ID 后 `--content` 仍可用 Markdown,只是写入内容不带样式。 +> **Markdown 局限 & block ID 前提:** Markdown 不携带 block ID,也无样式(颜色、对齐、callout 等)。需要按 block ID 定位(`block_*` 指令的 `--block-id`)时,先 `docs +fetch --detail with-ids` **配合 `--scope`(`outline` / `range` / `keyword` / `section`)局部获取**目标段落,不要全量 fetch。拿到 block ID 后 `--content` 仍可用 Markdown,只是写入内容不带样式。 ## 参数 | 参数 | 必填 | 说明 | |------|------|------| -| `--api-version` | 是 | 固定传 `v2` | | `--doc` | 是 | 文档 URL 或 token | | `--command` | 是 | 操作指令(见下方指令速查表) | | `--doc-format` | 否 | 内容格式:`xml`(默认,始终优先使用)\| `markdown`(仅用户明确要求时) | @@ -64,20 +63,20 @@ ```bash # 简单文本替换 -lark-cli docs +update --api-version v2 --doc "" --command str_replace \ +lark-cli docs +update --doc "" --command str_replace \ --pattern "张三" --content "李四" # 替换为富文本(加粗 + 链接) -lark-cli docs +update --api-version v2 --doc "" --command str_replace \ +lark-cli docs +update --doc "" --command str_replace \ --pattern "旧链接" --content '新链接 点击查看' # 仅当用户明确要求时才使用 Markdown -lark-cli docs +update --api-version v2 --doc "" --command str_replace \ +lark-cli docs +update --doc "" --command str_replace \ --doc-format markdown --pattern "旧内容" --content "新内容" # Markdown 模式下支持跨行匹配(--pattern 与 --content 都需要真实换行;"..."/'...' 里的 \n 是字面量) # 多行内容推荐 heredoc 或 --content @file.md,避免 shell 转义踩坑 -lark-cli docs +update --api-version v2 --doc "" --command str_replace \ +lark-cli docs +update --doc "" --command str_replace \ --doc-format markdown \ --pattern "$(printf '## 旧标题\n\n第一段原文\n\n第二段原文')" \ --content - <<'EOF' @@ -90,7 +89,7 @@ EOF # Markdown 模式下使用 `前缀...后缀` 省略号匹配首尾特征明显的大段内容 # 下例会把「## 旧标题」到「结束语。」之间的所有内容整体替换 -lark-cli docs +update --api-version v2 --doc "" --command str_replace \ +lark-cli docs +update --doc "" --command str_replace \ --doc-format markdown \ --pattern "## 旧标题...结束语。" \ --content - <<'EOF' @@ -102,14 +101,14 @@ lark-cli docs +update --api-version v2 --doc "" --command str_replace \ EOF # 删除文本:--content 传空字符串即可 -lark-cli docs +update --api-version v2 --doc "" --command str_replace \ +lark-cli docs +update --doc "" --command str_replace \ --pattern "废弃的内容" --content "" ``` ### block_insert_after — 在指定 block 之后插入 ```bash -lark-cli docs +update --api-version v2 --doc "" --command block_insert_after \ +lark-cli docs +update --doc "" --command block_insert_after \ --block-id "目标 block_id" \ --content '

新章节

  • 要点 1
  • 要点 2
' ``` @@ -117,7 +116,7 @@ lark-cli docs +update --api-version v2 --doc "" --command block_insert_a ### block_replace — 替换指定 block ```bash -lark-cli docs +update --api-version v2 --doc "" --command block_replace \ +lark-cli docs +update --doc "" --command block_replace \ --block-id "目标 block_id" \ --content '

替换后的段落内容

' ``` @@ -126,14 +125,14 @@ lark-cli docs +update --api-version v2 --doc "" --command block_replace ```bash # 删除多个块时用逗号 "," 分隔 -lark-cli docs +update --api-version v2 --doc "" --command block_delete \ +lark-cli docs +update --doc "" --command block_delete \ --block-id "block_id_1,block_id_2,block_id_3" ``` ### overwrite — 全文覆盖 ```bash -lark-cli docs +update --api-version v2 --doc "" --command overwrite \ +lark-cli docs +update --doc "" --command overwrite \ --content '全新文档

概述

新的内容

' ``` @@ -142,7 +141,7 @@ lark-cli docs +update --api-version v2 --doc "" --command overwrite \ ### append — 在文档末尾追加 ```bash -lark-cli docs +update --api-version v2 --doc "" --command append \ +lark-cli docs +update --doc "" --command append \ --content '

新增章节

追加的内容

' ``` @@ -154,7 +153,7 @@ lark-cli docs +update --api-version v2 --doc "" --command append \ ```bash # 复制多个块(按顺序插入:anchor → a → b → c) -lark-cli docs +update --api-version v2 --doc "" --command block_copy_insert_after \ +lark-cli docs +update --doc "" --command block_copy_insert_after \ --block-id "锚点 block_id" \ --src-block-ids "block_a,block_b,block_c" ``` @@ -165,7 +164,7 @@ lark-cli docs +update --api-version v2 --doc "" --command block_copy_ins ```bash # 移动到页面末尾 -lark-cli docs +update --api-version v2 --doc "" --command block_move_after \ +lark-cli docs +update --doc "" --command block_move_after \ --block-id "-1表示末尾,page_id表示开头,blk" \ --src-block-ids "block_a,block_b" ``` @@ -203,7 +202,7 @@ lark-cli docs +update --api-version v2 --doc "" --command block_move_aft 1. **获取文档内容和 block ID**: ```bash - lark-cli docs +fetch --api-version v2 --doc "" --detail with-ids + lark-cli docs +fetch --doc "" --detail with-ids ``` 2. **定位目标 block**:从返回的 XML 中找到要修改的 block 及其 `id` 属性 @@ -211,11 +210,11 @@ lark-cli docs +update --api-version v2 --doc "" --command block_move_aft 3. **执行更新**: ```bash # 替换特定 block - lark-cli docs +update --api-version v2 --doc "" --command block_replace \ + lark-cli docs +update --doc "" --command block_replace \ --block-id "blkcnXXXX" --content "

新内容

" # 在某 block 后插入 - lark-cli docs +update --api-version v2 --doc "" --command block_insert_after \ + lark-cli docs +update --doc "" --command block_insert_after \ --block-id "blkcnXXXX" --content "

追加的章节

" ``` @@ -224,13 +223,13 @@ lark-cli docs +update --api-version v2 --doc "" --command block_move_aft 不需要 block ID,直接匹配替换: ```bash -lark-cli docs +update --api-version v2 --doc "" --command str_replace \ +lark-cli docs +update --doc "" --command str_replace \ --pattern "v1.0" --content "v2.0" ``` ## 画板处理 -> **`docs +update` 不能直接编辑已有画板的内容。** 本命令只能**新增**画板块;要修改已有画板,先用 `docs +fetch --api-version v2` 取到 ``,再按 [`lark-doc-whiteboard.md`](lark-doc-whiteboard.md) 启动 SubAgent 读取 [`lark-whiteboard`](../../lark-whiteboard/SKILL.md) 并写入。 +> **`docs +update` 不能直接编辑已有画板的内容。** 本命令只能**新增**画板块;要修改已有画板,先用 `docs +fetch` 取到 ``,再按 [`lark-doc-whiteboard.md`](lark-doc-whiteboard.md) 启动 SubAgent 读取 [`lark-whiteboard`](../../lark-whiteboard/SKILL.md) 并写入。 画板的语法选型与插入示例见 [`lark-doc-style.md`](style/lark-doc-style.md) 的「画板语法与插入」章节。 diff --git a/skills/lark-doc/references/lark-doc-whiteboard.md b/skills/lark-doc/references/lark-doc-whiteboard.md index 1048cd95..6d16b74a 100644 --- a/skills/lark-doc/references/lark-doc-whiteboard.md +++ b/skills/lark-doc/references/lark-doc-whiteboard.md @@ -23,7 +23,7 @@ |-------------------------|-----------------------------------------------------------| | 文档中需要思维导图、时序图、类图、饼图、甘特图 | 步骤 2A:使用 mermaid 插入图表 | | 文档中需要插入其他图表/自定义图形 | 步骤 2B: 使用 SVG 插入图表 | -| 已有画板需要更新内容 | 先 `docs +fetch --api-version v2` 获取 `board_token`,跳至步骤 3B | +| 已有画板需要更新内容 | 先 `docs +fetch` 获取 `board_token`,跳至步骤 3B | | 只查看 / 下载已有画板 | 切换至 `lark-whiteboard`,不走本流程 | > [!IMPORTANT] @@ -46,7 +46,7 @@ SubAgent 插入 SVG。 ### 步骤 2B: SubAgent 使用 SVG 插入图表 -主 Agent 启动 SubAgent,让它用 `docs +create --api-version v2` / `docs +update --api-version v2` 插入: +主 Agent 启动 SubAgent,让它用 `docs +create` / `docs +update` 插入: ```xml diff --git a/skills/lark-doc/references/style/lark-doc-create-workflow.md b/skills/lark-doc/references/style/lark-doc-create-workflow.md index 26a8c872..d845e91c 100644 --- a/skills/lark-doc/references/style/lark-doc-create-workflow.md +++ b/skills/lark-doc/references/style/lark-doc-create-workflow.md @@ -20,7 +20,7 @@ 1. 分析用户需求:受众、目的、范围 2. 设计大纲:根据任务自然选择结构。可以是短文、纪要、FAQ、方案、报告、清单或其他形式;不要默认套固定章节、固定开头或固定富 block 配比 -3. `docs +create --api-version v2` 创建文档。长文档可**只建骨架**:标题 + 各级标题 + 每节一句占位摘要;短文档可以一次写入完整内容 +3. `docs +create` 创建文档。长文档可**只建骨架**:标题 + 各级标题 + 每节一句占位摘要;短文档可以一次写入完整内容 - ⚠️ 创建较长文档时,**不要**一次性把完整章节内容塞进 `--content`。超长 `--content` 容易触发字符/参数限制。 - 完整内容留到步骤二,由各 Agent 用 `block_insert_after --block-id <章节标题 block_id>` 分段写入。 - ⚠️ **`@file` 路径限制**:`--content @file` 只接受当前工作目录下的相对路径,传绝对路径(如 `@/tmp/xxx.md`)会报 `unsafe file path`。需要落盘时,将文件写在 cwd 下,用完自行清理。 @@ -34,7 +34,7 @@ ### 步骤三:整合审查与画板识别(串行) -5. `docs +fetch --api-version v2 --detail with-ids` 获取文档,审查整体效果 +5. `docs +fetch --detail with-ids` 获取文档,审查整体效果 6. 评估内容是否满足用户目标:事实是否完整、结构是否清楚、语气是否匹配、是否保留必要素材 7. **画板意图识别**:逐章节扫描,按 `lark-doc-style.md`「画板意图识别」表判断是否有段落适合用图表达。重要信息优先画板化,记录需要插图的章节、推荐画板类型、mermaid/SVG 路径和用于画图的源内容 diff --git a/skills/lark-doc/references/style/lark-doc-update-workflow.md b/skills/lark-doc/references/style/lark-doc-update-workflow.md index ca28d467..9ff07c4d 100644 --- a/skills/lark-doc/references/style/lark-doc-update-workflow.md +++ b/skills/lark-doc/references/style/lark-doc-update-workflow.md @@ -19,10 +19,10 @@ ### 步骤一:分析与画板识别(串行) 1. **选择读取范围**(节省上下文的关键): - - 用户只改某一节 / 文档较大 → 先 `docs +fetch --api-version v2 --scope outline --max-depth 2` 拿目录,再 `docs +fetch --api-version v2 --scope section --start-block-id <目标标题id> --detail with-ids` 精读该节(`section` 会自动展开到下一个同级/更高级标题前,不用手动算结束 block id) - - 需要精确跨节区间 → `docs +fetch --api-version v2 --scope range --start-block-id xxx --end-block-id yyy`(或 `--end-block-id -1` 读到末尾) - - 用户只给了模糊关键词 → `docs +fetch --api-version v2 --scope keyword --keyword xxx --context-before 1 --context-after 1 --detail with-ids` - - 用户明确要改整篇 → `docs +fetch --api-version v2 --detail with-ids` + - 用户只改某一节 / 文档较大 → 先 `docs +fetch --scope outline --max-depth 2` 拿目录,再 `docs +fetch --scope section --start-block-id <目标标题id> --detail with-ids` 精读该节(`section` 会自动展开到下一个同级/更高级标题前,不用手动算结束 block id) + - 需要精确跨节区间 → `docs +fetch --scope range --start-block-id xxx --end-block-id yyy`(或 `--end-block-id -1` 读到末尾) + - 用户只给了模糊关键词 → `docs +fetch --scope keyword --keyword xxx --context-before 1 --context-after 1 --detail with-ids` + - 用户明确要改整篇 → `docs +fetch --detail with-ids` - 详见 [`lark-doc-fetch.md`](../lark-doc-fetch.md) "意图引导:选择正确的 --scope" 2. 系统性评估:用户想改什么、现有文档风格是什么、哪些内容需要保留、哪些问题影响理解 3. **画板意图识别**:逐章节扫描,按 `lark-doc-style.md`「画板意图识别」表判断哪些段落的信息适合用图表达。重要信息优先画板化,记录需要插图的章节(block ID)、推荐画板类型、mermaid/SVG路径和源内容片段 @@ -52,4 +52,4 @@ SVG SubAgent 必须收到:文档 token、插入位置(标题/block ID)、 已有画板更新 SubAgent 必须收到:board_token、图表目标、推荐画板类型、源内容片段、[`../../../lark-whiteboard/SKILL.md`](../../../lark-whiteboard/SKILL.md) 路径。它只负责写入画板,不改文档正文。 -**上下文节省提示**:Agent 如需在自己负责的章节内重新读取内容,优先用 `docs +fetch --api-version v2 --scope section --start-block-id <章节标题id>`(自动覆盖整节),或 `--scope range --start-block-id xxx --end-block-id yyy` 精确区间,只拉自己的章节,不要重复拉全文。 +**上下文节省提示**:Agent 如需在自己负责的章节内重新读取内容,优先用 `docs +fetch --scope section --start-block-id <章节标题id>`(自动覆盖整节),或 `--scope range --start-block-id xxx --end-block-id yyy` 精确区间,只拉自己的章节,不要重复拉全文。 diff --git a/skills/lark-drive/SKILL.md b/skills/lark-drive/SKILL.md index 90491a1c..393e1381 100644 --- a/skills/lark-drive/SKILL.md +++ b/skills/lark-drive/SKILL.md @@ -69,7 +69,7 @@ lark-cli drive +inspect --url 'https://xxx.feishu.cn/wiki/wikcnXXX' | 操作 | 需要的 Token | 说明 | |------|-------------|------| -| 读取文档内容 | `file_token` / 通过 `docs +fetch --api-version v2` 自动处理 | `docs +fetch --api-version v2` 支持直接传入 URL | +| 读取文档内容 | `file_token` / 通过 `docs +fetch` 自动处理 | `docs +fetch` 支持直接传入 URL | | 添加局部评论(划词评论) | `file_token` | 传 `--block-id` 时,`drive +add-comment` 会创建局部评论;`docx` 支持文本定位或 block_id,`sheet` 使用 `!`,`slides` 使用 `!`;Base 只有记录局部评论,定位为 file_token(base_token) + `--block-id !!` | | 添加全文评论 | `file_token` | 不传 `--block-id` 时,`drive +add-comment` 默认创建全文评论;支持 `docx`、旧版 `doc` URL、白名单扩展名的 Drive file,以及最终解析为 `doc`/`docx`/`file` 的 wiki URL | | 下载文件 | `file_token` | 从文件 URL 中直接提取 | diff --git a/skills/lark-drive/references/lark-drive-add-comment.md b/skills/lark-drive/references/lark-drive-add-comment.md index 8de1982c..17dc2d9f 100644 --- a/skills/lark-drive/references/lark-drive-add-comment.md +++ b/skills/lark-drive/references/lark-drive-add-comment.md @@ -35,7 +35,7 @@ lark-cli drive +add-comment \ --doc "" --type file \ --content '[{"type":"text","text":"请补充目录说明"}]' -# 给 docx 文档的指定 block 添加局部评论(block_id 可通过 docs +fetch --api-version v2 --detail with-ids 获取) +# 给 docx 文档的指定 block 添加局部评论(block_id 可通过 docs +fetch --detail with-ids 获取) lark-cli drive +add-comment \ --doc "https://example.larksuite.com/docx/" \ --block-id "" \ @@ -155,11 +155,11 @@ lark-cli drive +add-comment \ | `--type` | 裸 token 时必填 | 文档类型:`doc`、`docx`、`file`、`sheet`、`slides`、`bitable`、`base`;评论 Base 文档推荐传 `bitable`,`base` 仅作为兼容别名兜底。URL 输入时自动识别,无需传 | | `--content` | 是 | `reply_elements` JSON 数组字符串。示例:`'[{"type":"text","text":"文本"},{"type":"mention_user","text":"ou_xxx"},{"type":"link","text":"https://example.com"}]'` | | `--full-comment` | 否 | 显式指定创建全文评论;未传 `--block-id` 时也会默认走全文评论(仅适用于 doc/docx、白名单 Drive file,以及解析为这些类型的 wiki;不适用于 sheet、slides、Base / bitable) | -| `--block-id` | 局部评论时必填 | 目标块 ID,可通过 `docs +fetch --api-version v2 --detail with-ids` 获取;sheet 用 `!`,slides 用 `!`,Base 用 `!!` | +| `--block-id` | 局部评论时必填 | 目标块 ID,可通过 `docs +fetch --detail with-ids` 获取;sheet 用 `!`,slides 用 `!`,Base 用 `!!` | ## 行为说明 -- **局部评论需要先获取 block ID**:先调用 `docs +fetch --api-version v2 --doc --detail with-ids` 获取带有 block ID 的文档内容,然后使用 `--block-id` 指定目标块。 +- **局部评论需要先获取 block ID**:先调用 `docs +fetch --doc --detail with-ids` 获取带有 block ID 的文档内容,然后使用 `--block-id` 指定目标块。 - **Review 场景优先局部评论**:审阅、校对、逐条指出问题时,必须先尝试定位到具体 block / 单元格 / slide 元素,并逐问题创建局部评论;不要把所有问题合并成一条全文评论。 - 未传 `--block-id` 时,shortcut 默认创建**全文评论**;也可以显式传 `--full-comment`。全文评论支持 `docx`、旧版 `doc` URL、白名单扩展名的 Drive file,以及最终可解析为 `doc`/`docx`/`file` 的 wiki URL。 - **Drive file 评论**:仅支持白名单扩展名的普通文件。当前支持:`.md`、`.txt`、`.json`、`.csv`、`.go`、`.js`、`.py`、`.pptx`、`.png`、`.jpg`、`.jpeg`、`.zip`、`.mp3`、`.mp4`。 diff --git a/skills/lark-drive/references/lark-drive-comment-location.md b/skills/lark-drive/references/lark-drive-comment-location.md index bd6d1353..cbb5a6b6 100644 --- a/skills/lark-drive/references/lark-drive-comment-location.md +++ b/skills/lark-drive/references/lark-drive-comment-location.md @@ -27,7 +27,7 @@ lark-cli drive file.comments batch_query \ 同时获取文档内容,并要求返回 block id: ```bash -lark-cli docs +fetch --api-version v2 --doc '' --detail with-ids +lark-cli docs +fetch --doc '' --detail with-ids ``` ## 字段含义 @@ -127,7 +127,7 @@ lark-cli docs +fetch --api-version v2 --doc '' --detail with-i 1. 确认目标是 `file_type=docx`;只有 docx 文档支持通过 `need_relation` 查询评论位置。 2. 用 `drive file.comments list` 或 `drive file.comments batch_query` 获取评论,并带 `need_relation=true`。 -3. 用 `docs +fetch --api-version v2 --detail with-ids` 获取文档内容。 +3. 用 `docs +fetch --detail with-ids` 获取文档内容。 4. 对每条评论先看 `relation`: - 如果存在 `relation.relation`,解析这个 JSON 字符串。 - 从解析结果里取 `positionInfo.blockID`。 diff --git a/skills/lark-drive/references/lark-drive-files-list.md b/skills/lark-drive/references/lark-drive-files-list.md index 4af0c3f4..e3f5ec8f 100644 --- a/skills/lark-drive/references/lark-drive-files-list.md +++ b/skills/lark-drive/references/lark-drive-files-list.md @@ -10,7 +10,7 @@ | 盘点用户明确确认的 Drive 根目录 | 使用 | 第一层用空 `folder_token`,子文件夹继续按普通文件夹递归 | | 验证移动 / 创建后的实际位置 | 使用 | 读取目标目录直接子项,再按需递归验证 | | 根据关键词、标题、时间、owner 找资源 | 不使用 | 优先用 `drive +search` | -| 读取 Docx 正文内容 | 不使用 | 用 `docs +fetch --api-version v2` | +| 读取 Docx 正文内容 | 不使用 | 用 `docs +fetch` | | 读取 Sheet / Base 内部数据 | 不使用 | 切到 `lark-sheets` / `lark-base` | ## 标准命令模板 diff --git a/skills/lark-note/SKILL.md b/skills/lark-note/SKILL.md index 95df4752..dd9ac331 100644 --- a/skills/lark-note/SKILL.md +++ b/skills/lark-note/SKILL.md @@ -17,18 +17,18 @@ metadata: > 2. 了解会议产物(妙记和纪要)之间的关联关系,例如:**妙记和纪要产生条件相互独立** > 3. 了解不同会议产物的组成部分,以便根据需求决策使用哪种产物的数据 -Note 域只接受显式 `note_id`:用户直接提供,或 `docs +fetch --api-version v2` 返回的 `` 中的 `vc-node-id`。不要从 `doc_token`、标题、正文或 backlink 反推 `note_id`。 +Note 域只接受显式 `note_id`:用户直接提供,或 `docs +fetch` 返回的 `` 中的 `vc-node-id`。不要从 `doc_token`、标题、正文或 backlink 反推 `note_id`。 ## 命令路由 | 用户表达 / 上下文 | 路由 | |---------|------| | 已知 `note_id`,查纪要类型 / 文档 token | `note +detail --note-id NOTE_ID` | -| `docs +fetch --api-version v2` 返回 `` | 取 `vc-node-id` 作为 `NOTE_ID`,先 `note +detail --note-id NOTE_ID` | +| `docs +fetch` 返回 `` | 取 `vc-node-id` 作为 `NOTE_ID`,先 `note +detail --note-id NOTE_ID` | | 只持有 `meeting_id` | 先 `vc +detail --meeting-ids ` 拿 `note_id`,再 `note +detail --note-id NOTE_ID` | | 只持有 `minute_token`(妙记 URL) | 先 `minutes +detail --minute-tokens ` 顶层取 `note_id`,再 `note +detail --note-id NOTE_ID`(不要把 `minute_token` 当 `note_id`) | | 只持有日程 `event_id` | 先 `calendar +meeting --event-ids ` 拿 `meeting_id`,再按上一行继续 | -| 已知 `note_id`,读纪要正文 | `note +detail` → `docs +fetch --api-version v2 --doc ` | +| 已知 `note_id`,读纪要正文 | `note +detail` → `docs +fetch --doc ` | | 已知 `note_id`,查 unified 原始记录 / 逐字稿 | `note +transcript --note-id NOTE_ID` | | 只有自然语言纪要标题,用户要逐字稿 / 原始记录 / 谁说了什么 | 不进本 skill;先走文档搜索与 `docs +fetch`,拿到 `vc-node-id` 后再回来 | @@ -36,7 +36,7 @@ Note 域只接受显式 `note_id`:用户直接提供,或 `docs +fetch --api- | `note +detail` 结果 | 用户要逐字稿 / 原始记录时 | |------|---------------| -| `normal` + `verbatim_doc_token` 非空 | `docs +fetch --api-version v2 --doc ` | +| `normal` + `verbatim_doc_token` 非空 | `docs +fetch --doc ` | | `unknown` + `verbatim_doc_token` 非空 | 先按独立文档处理;不要猜成 unified | | `unknown` + 无逐字稿 token | 停止重试并说明无法确定逐字稿入口 | | `unified` | `note +transcript --note-id ` | @@ -80,7 +80,7 @@ Note 域只接受显式 `note_id`:用户直接提供,或 `docs +fetch --api- 1. 当用户已有 `note_id`,需要获取对应的 `note_doc_token`、`verbatim_doc_token` 或 `shared_doc_tokens` 时,使用 `note +detail`。 2. `note_id` 通常来自 `vc +detail` 的返回结果。 -3. 获取到文档 Token 后,可使用 `docs +fetch --api-version v2` 读取文档内容,或使用 `drive metas batch_query` 获取文档元信息。 +3. 获取到文档 Token 后,可使用 `docs +fetch` 读取文档内容,或使用 `drive metas batch_query` 获取文档元信息。 ```bash # 1. 从会议获取 note_id @@ -90,5 +90,5 @@ lark-cli vc +detail --meeting-ids lark-cli note +detail --note-id # 3. 读取纪要文档内容 -lark-cli docs +fetch --api-version v2 --doc --doc-format markdown -``` \ No newline at end of file +lark-cli docs +fetch --doc --doc-format markdown +``` diff --git a/skills/lark-note/references/lark-note-detail.md b/skills/lark-note/references/lark-note-detail.md index aa2db394..b0d352d1 100644 --- a/skills/lark-note/references/lark-note-detail.md +++ b/skills/lark-note/references/lark-note-detail.md @@ -18,8 +18,8 @@ lark-cli note +detail --note-id | detail 字段 | 后续动作 | |---------|---------| -| `note_doc_token` | 读纪要正文 / 总结 / 待办 / 章节:`docs +fetch --api-version v2 --doc ` | -| `note_display_type=normal` + `verbatim_doc_token` | 读逐字稿:`docs +fetch --api-version v2 --doc ` | +| `note_doc_token` | 读纪要正文 / 总结 / 待办 / 章节:`docs +fetch --doc ` | +| `note_display_type=normal` + `verbatim_doc_token` | 读逐字稿:`docs +fetch --doc ` | | `note_display_type=unknown` + `verbatim_doc_token` | 先按普通独立逐字稿文档读取;不要猜成 unified | | `note_display_type=unified` | 读逐字稿 / 原始记录:转 [`note +transcript`](lark-note-transcript.md) | diff --git a/skills/lark-note/references/lark-note-transcript.md b/skills/lark-note/references/lark-note-transcript.md index dcffaec8..5d334acf 100644 --- a/skills/lark-note/references/lark-note-transcript.md +++ b/skills/lark-note/references/lark-note-transcript.md @@ -17,7 +17,7 @@ lark-cli note +transcript --note-id NOTE_ID | 场景 | 正确路由 | |------|---------| -| 只有纪要文档标题 | 先文档搜索,再 `docs +fetch --api-version v2`;有 `vc-node-id` 才回 Note 域 | -| 只有 Docx URL / `doc_token` | 先 `docs +fetch --api-version v2`;不要从 `doc_token` 反推 `note_id` | -| `note_display_type=normal` | `docs +fetch --api-version v2 --doc ` | +| 只有纪要文档标题 | 先文档搜索,再 `docs +fetch`;有 `vc-node-id` 才回 Note 域 | +| 只有 Docx URL / `doc_token` | 先 `docs +fetch`;不要从 `doc_token` 反推 `note_id` | +| `note_display_type=normal` | `docs +fetch --doc ` | | `note_display_type=unknown` 且 `verbatim_doc_token` 非空 | 先按独立逐字稿文档读取 | diff --git a/skills/lark-vc/SKILL.md b/skills/lark-vc/SKILL.md index e8fe316d..9b1230d9 100644 --- a/skills/lark-vc/SKILL.md +++ b/skills/lark-vc/SKILL.md @@ -93,7 +93,7 @@ lark-cli vc +search --query "站会" --start --end ```bash # 1. 读取纪要内容 -lark-cli docs +fetch --api-version v2 --doc --doc-format markdown +lark-cli docs +fetch --doc --doc-format markdown # 2. 从返回的 markdown 中提取第一个 的 token # 3. 下载封面图到聚合目录(和逐字稿、录像同目录,保持产物归拢) # 并非所有纪要都有封面画板,没有 标签时跳过即可 @@ -119,10 +119,10 @@ lark-cli schema drive.metas.batch_query # 批量获取文档基本信息: 一次最多查询 10 个文档 lark-cli drive metas batch_query --data '{"request_docs": [{"doc_type": "docx", "doc_token": ""}], "with_url": true}' ``` -3. 需要获取文档内容时,使用 `lark-cli docs +fetch --api-version v2`。 +3. 需要获取文档内容时,使用 `lark-cli docs +fetch`。 ```bash # 获取文档内容 -lark-cli docs +fetch --api-version v2 --doc --doc-format markdown +lark-cli docs +fetch --doc --doc-format markdown ``` ### 4. 查询参会人快照(读操作) diff --git a/skills/lark-vc/references/vc-domain-boundaries.md b/skills/lark-vc/references/vc-domain-boundaries.md index 2f71b5ab..380c10ca 100644 --- a/skills/lark-vc/references/vc-domain-boundaries.md +++ b/skills/lark-vc/references/vc-domain-boundaries.md @@ -81,7 +81,7 @@ 根据关键字、组织者、参与人、会议室等条件搜索会议,获取会议列表。 -> **不要把纪要标题当会议线索:** 如果用户说“查询 xx 纪要的逐字稿 / 原始记录 / 谁说了什么”,且没有 `meeting_id`、`calendar_event_id`、会议号、参会人或时间范围,先用 `drive +search --query <标题>` 搜索纪要文档,拿到 Docx URL/token 后再 `docs +fetch --api-version v2`。若返回 ``,提取 `note_id` 后进入 Note 域判断 `normal` / `unified`;若没有该 block,但有“文字记录/逐字稿” Docx 链接,直接用 `docs +fetch --api-version v2` 读取该链接。 +> **不要把纪要标题当会议线索:** 如果用户说“查询 xx 纪要的逐字稿 / 原始记录 / 谁说了什么”,且没有 `meeting_id`、`calendar_event_id`、会议号、参会人或时间范围,先用 `drive +search --query <标题>` 搜索纪要文档,拿到 Docx URL/token 后再 `docs +fetch`。若返回 ``,提取 `note_id` 后进入 Note 域判断 `normal` / `unified`;若没有该 block,但有“文字记录/逐字稿” Docx 链接,直接用 `docs +fetch` 读取该链接。 ```bash lark-cli vc +search --start "" --end "" --format json @@ -131,14 +131,14 @@ lark-cli minutes +detail --minute-tokens ',' \ #### Step 3: 按 `note_display_type` 拉取正文 / 逐字稿 -智能纪要(`note_doc_token`)是飞书文档,使用 `docs +fetch --api-version v2` 读取正文内容;**逐字稿的读取方式由 `note_display_type` 决定**: +智能纪要(`note_doc_token`)是飞书文档,使用 `docs +fetch` 读取正文内容;**逐字稿的读取方式由 `note_display_type` 决定**: ```bash # 纪要正文(两种展示类型都适用) -lark-cli docs +fetch --api-version v2 --doc --doc-format markdown +lark-cli docs +fetch --doc --doc-format markdown # note_display_type=normal:逐字稿是独立文档 -lark-cli docs +fetch --api-version v2 --doc --doc-format markdown +lark-cli docs +fetch --doc --doc-format markdown # note_display_type=unified:逐字稿不是独立文档,按 note_id 拉取 lark-cli note +transcript --note-id @@ -157,14 +157,14 @@ lark-cli note +transcript --note-id - 已知 `note_id` 后切到 [lark-note](../../lark-note/SKILL.md);逐字稿路由以 `lark-note` 的 `note_display_type` 规则为准。 - 已知 `minute_token` 时,[`minutes +detail`](../../lark-minutes/references/lark-minutes-detail.md) 顶层会一并返回该妙记关联的 `note_id`(如有);可直接传给 `note +detail` 取纪要文档 token,无需绕回 VC。 - 仅有日程 `event_id` 时,先走 [`calendar +meeting`](../../lark-calendar/references/lark-calendar-meeting.md) 拿到 `meeting_id` 或用户绑定的 `meeting_note`,再按上述路径继续。 -- 只有自然语言纪要标题时,先走文档搜索与 `docs +fetch --api-version v2`;只有 `` 的 `vc-node-id` 可以进入 Note 域。 +- 只有自然语言纪要标题时,先走文档搜索与 `docs +fetch`;只有 `` 的 `vc-node-id` 可以进入 Note 域。 - `doc_token` / Docx URL 不是 `note_id`。没有 `vc-node-id` 时不要反推 Note,继续按 Doc 域读取正文或正文中明确给出的逐字稿文档。 ## Doc 域 - **lark-doc skill** 负责飞书云文档管理,包括获取文档元信息、读取文档内容、创建和编辑文档等操作。 -- **会议产物的文档本质**:智能纪要(`note_doc_token`)和 `normal` 纪要的逐字稿(`verbatim_doc_token`)都是飞书文档,需要通过 `lark-doc` 的 API(如 `docs +fetch --api-version v2`)查询其内容和元信息;`unified` 纪要的逐字稿不是独立文档,用 `note +transcript` 拉取([lark-note](../../lark-note/SKILL.md))。 -- **文档元信息查询**:获取文档名称、URL 等基本信息时,使用 `drive metas batch_query`;获取文档正文内容时,使用 `docs +fetch --api-version v2`。 +- **会议产物的文档本质**:智能纪要(`note_doc_token`)和 `normal` 纪要的逐字稿(`verbatim_doc_token`)都是飞书文档,需要通过 `lark-doc` 的 API(如 `docs +fetch`)查询其内容和元信息;`unified` 纪要的逐字稿不是独立文档,用 `note +transcript` 拉取([lark-note](../../lark-note/SKILL.md))。 +- **文档元信息查询**:获取文档名称、URL 等基本信息时,使用 `drive metas batch_query`;获取文档正文内容时,使用 `docs +fetch`。 ## 三域关联总览 diff --git a/skills/lark-whiteboard/references/lark-whiteboard-workflow.md b/skills/lark-whiteboard/references/lark-whiteboard-workflow.md index a3665e2d..c0ce702b 100644 --- a/skills/lark-whiteboard/references/lark-whiteboard-workflow.md +++ b/skills/lark-whiteboard/references/lark-whiteboard-workflow.md @@ -10,8 +10,8 @@ | 用户给了什么 | 怎么获取 | |---|---| | 直接给了 whiteboard token(`wbcnXXX`)| 直接使用 | -| 文档 URL 或 doc_id,文档中已有画板 | `lark-cli docs +fetch --api-version v2 --doc --as user`,从返回的 `` 提取 | -| 文档 URL 或 doc_id,需要新建画板 | `lark-cli docs +update --api-version v2 --doc --command append --content '' --as user`,从响应 `data.new_blocks[0].block_token` 取得(`block_type == "whiteboard"` 的那条;参数详见 lark-doc SKILL.md)| +| 文档 URL 或 doc_id,文档中已有画板 | `lark-cli docs +fetch --doc --as user`,从返回的 `` 提取 | +| 文档 URL 或 doc_id,需要新建画板 | `lark-cli docs +update --doc --command append --content '' --as user`,从响应 `data.new_blocks[0].block_token` 取得(`block_type == "whiteboard"` 的那条;参数详见 lark-doc SKILL.md)| **Step 2:渲染 & 写入** diff --git a/skills/lark-workflow-meeting-summary/SKILL.md b/skills/lark-workflow-meeting-summary/SKILL.md index eb931c2c..7f377ea2 100644 --- a/skills/lark-workflow-meeting-summary/SKILL.md +++ b/skills/lark-workflow-meeting-summary/SKILL.md @@ -109,9 +109,9 @@ lark-cli drive metas batch_query --data '{"request_docs": [{"doc_type": "docx", 阅读 [`../lark-doc/SKILL.md`](../lark-doc/SKILL.md) 学习云文档技能。 ```bash -lark-cli docs +create --api-version v2 --doc-format markdown --content $'会议纪要汇总 (<start> - <end>)\n<内容>' +lark-cli docs +create --doc-format markdown --content $'会议纪要汇总 (<start> - <end>)\n<内容>' # 或追加到已有文档 -lark-cli docs +update --api-version v2 --doc "" --command append --doc-format markdown --content $'<内容>' +lark-cli docs +update --doc "" --command append --doc-format markdown --content $'<内容>' ``` ## 参考 diff --git a/tests/cli_e2e/doc/docs_dryrun_test.go b/tests/cli_e2e/doc/docs_dryrun_test.go new file mode 100644 index 00000000..02fb0ac2 --- /dev/null +++ b/tests/cli_e2e/doc/docs_dryrun_test.go @@ -0,0 +1,52 @@ +// Copyright (c) 2026 Lark Technologies Pte. Ltd. +// SPDX-License-Identifier: MIT + +package doc + +import ( + "context" + "testing" + "time" + + clie2e "github.com/larksuite/cli/tests/cli_e2e" + "github.com/stretchr/testify/require" + "github.com/tidwall/gjson" +) + +func TestDocsFetchDryRunIgnoresAPIVersionCompatFlag(t *testing.T) { + setDocsDryRunEnv(t) + + ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) + t.Cleanup(cancel) + + result, err := clie2e.RunCmd(ctx, clie2e.Request{ + Args: []string{ + "docs", "+fetch", + "--doc", "doxcnDryRunCompat", + "--api-version", "legacy", + "--dry-run", + }, + DefaultAs: "bot", + }) + require.NoError(t, err) + result.AssertExitCode(t, 0) + + out := result.Stdout + if got := gjson.Get(out, "api.0.method").String(); got != "POST" { + t.Fatalf("method=%q, want POST\nstdout:\n%s", got, out) + } + if got := gjson.Get(out, "api.0.url").String(); got != "/open-apis/docs_ai/v1/documents/doxcnDryRunCompat/fetch" { + t.Fatalf("url=%q, want docs fetch endpoint\nstdout:\n%s", got, out) + } + if got := gjson.Get(out, "api.0.body.format").String(); got != "xml" { + t.Fatalf("format=%q, want xml\nstdout:\n%s", got, out) + } +} + +func setDocsDryRunEnv(t *testing.T) { + t.Helper() + t.Setenv("LARKSUITE_CLI_CONFIG_DIR", t.TempDir()) + t.Setenv("LARKSUITE_CLI_APP_ID", "docs_dryrun_test") + t.Setenv("LARKSUITE_CLI_APP_SECRET", "docs_dryrun_secret") + t.Setenv("LARKSUITE_CLI_BRAND", "feishu") +}