Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions shortcuts/doc/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ func parseDocumentRef(input string) (documentRef, error) {
if token, ok := extractDocumentToken(raw, "/doc/"); ok {
return documentRef{Kind: "doc", Token: token}, nil
}
if _, ok := extractDocumentToken(raw, "/mindnote/"); ok {
return documentRef{}, errs.NewValidationError(errs.SubtypeInvalidArgument, "unsupported --doc input %q: Mind Note URLs are not Docx inputs and must not be routed to whiteboard; use `lark-cli mindnotes nodes list/create` for existing Mind Notes, or Drive operations for metadata, permissions, and file organization", raw).WithParam("--doc")
}
if strings.Contains(raw, "://") {
return documentRef{}, errs.NewValidationError(errs.SubtypeInvalidArgument, "unsupported --doc input %q: use a docx URL/token or a wiki URL that resolves to docx", raw).WithParam("--doc")
}
Expand Down
26 changes: 26 additions & 0 deletions shortcuts/doc/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
package doc

import (
"errors"
"reflect"
"strings"
"testing"

"github.com/larksuite/cli/errs"
)

func TestParseDocumentRef(t *testing.T) {
Expand All @@ -18,6 +21,7 @@ func TestParseDocumentRef(t *testing.T) {
wantKind string
wantToken string
wantErr string
wantParam string
}{
{
name: "docx url",
Expand Down Expand Up @@ -48,6 +52,12 @@ func TestParseDocumentRef(t *testing.T) {
input: "https://example.com/not-a-doc",
wantErr: "unsupported --doc input",
},
{
name: "native mindnote url",
input: "https://example.larksuite.com/mindnote/xxxxxx",
wantErr: "Mind Note URLs are not Docx inputs",
wantParam: "--doc",
},
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

for _, tt := range tests {
Expand All @@ -62,6 +72,22 @@ func TestParseDocumentRef(t *testing.T) {
if !strings.Contains(err.Error(), tt.wantErr) {
t.Fatalf("expected error containing %q, got %q", tt.wantErr, err.Error())
}
if tt.wantParam != "" {
p, ok := errs.ProblemOf(err)
if !ok {
t.Fatalf("expected typed problem, got err=%v", err)
}
if p.Category != errs.CategoryValidation || p.Subtype != errs.SubtypeInvalidArgument {
t.Fatalf("category/subtype=%s/%s want %s/%s", p.Category, p.Subtype, errs.CategoryValidation, errs.SubtypeInvalidArgument)
}
var ve *errs.ValidationError
if !errors.As(err, &ve) {
t.Fatalf("expected validation error, got %T: %v", err, err)
}
if ve.Param != tt.wantParam {
t.Fatalf("param=%q want %q", ve.Param, tt.wantParam)
}
}
return
}
if err != nil {
Expand Down
4 changes: 3 additions & 1 deletion skills/lark-doc/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: lark-doc
version: 2.0.0
description: "飞书云文档(Docx / Wiki 文档):读取和编辑飞书文档内容。当用户给出文档 URL 或 token,或需要查看、创建、编辑文档、插入或下载文档图片附件时使用。文档中嵌入的电子表格、多维表格、画板,先用本 skill 提取 token 再切到对应 skill。当用户给出 doubao.com 的 /docx/ 或 /wiki/ URL/token 时,也应直接使用本 skill;路由依据是 URL 路径模式和 token,而不是域名。不负责文档评论管理,也不负责表格或 Base 的数据操作。当用户明确要操作飞书思维笔记时,也使用本 skill。"
description: "飞书云文档(Docx / Wiki 文档 / Mind Note):读取和编辑飞书文档内容。当用户给出文档 URL 或 token,或需要查看、创建、编辑文档、插入或下载文档图片附件时使用。文档中嵌入的电子表格、多维表格、画板,先用本 skill 提取 token 再切到对应 skill。当用户给出 doubao.com 的 /docx/ 或 /wiki/ URL/token 时,也应直接使用本 skill;路由依据是 URL 路径模式和 token,而不是域名。当用户明确要操作飞书思维笔记时也使用本 skill,但不要把 /mindnote/ URL 路由到 whiteboard。不负责文档评论管理,也不负责表格或 Base 的数据操作。"
metadata:
requires:
bins: ["lark-cli"]
Expand Down Expand Up @@ -35,6 +35,7 @@ lark-cli docs +update --doc "文档URL或token" --command append --content '<p>
## 快速决策
- 用户要**复制文档 / 创建文档副本 / 另存为副本**时,切到 [`lark-drive`](../lark-drive/SKILL.md),按其中的复制指引使用 `lark-cli drive files copy`;不要用 `docs +fetch` + `docs +create` 重建正文,也不要走 `drive +export` / `drive +import`。
- 先判定任务路径:找文档 / 导入导出走 [`lark-drive`](../lark-drive/SKILL.md);只读 / 摘要用 `docs +fetch` 默认 `simple`;明确旧文本 → 新文本直接 `str_replace`;只有 block 链接、评论锚点、插入 / 替换 / 删除 / 移动才局部 fetch `with-ids`;保真改写已有内容才读 `full`
- `/mindnote/` URL 是原生 Mind Note,不是 Docx,也不是画板。已有思维笔记的节点读取/创建/更新走 [思维笔记链路](references/lark-doc-mindnote.md);只需要移动、权限、元数据等云空间操作时切到 [`lark-drive`](../lark-drive/SKILL.md);不要把 `/mindnote/` URL 路由到 `lark-whiteboard`
- block 直达链接格式:`文档基础 URL#block_id`;没有 block_id 时局部 fetch `with-ids`
- 连续执行多个文档写操作时,必须按 [`lark-doc-update.md`](references/lark-doc-update.md) 的「Block ID 生命周期」判断旧 block ID 是否还能复用;`overwrite` / `block_replace` / `block_delete` 后不要复用受影响的旧 ID,插入 / 复制后要重新 fetch 才能拿到新 block ID
- 用户需要在文档内**创建、复制或移动**资源块(画板、电子表格、多维表格等)时,必须先读取 [`lark-doc-xml.md`](references/lark-doc-xml.md) 的「三、资源块」章节
Expand Down Expand Up @@ -79,6 +80,7 @@ Shortcut 是对常用操作的高级封装(`lark-cli docs +<verb> [flags]`)

## 不在本 Skill 范围

- 把 `/mindnote/` URL 当成 whiteboard 处理;已有思维笔记应走 [思维笔记链路](references/lark-doc-mindnote.md)
- 文档评论管理 → [`lark-drive`](../lark-drive/SKILL.md)
- 电子表格或 Base 的数据操作 → [`lark-sheets`](../lark-sheets/SKILL.md) / [`lark-base`](../lark-base/SKILL.md)
- 云空间文件上传、下载、权限管理 → [`lark-drive`](../lark-drive/SKILL.md)
5 changes: 4 additions & 1 deletion skills/lark-drive/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: lark-drive
version: 1.0.0
description: "飞书云空间(云盘/云存储):管理 Drive 文件和文件夹,包含上传/下载、创建文件夹、复制/移动/删除、查看元数据、评论/权限/订阅、标题、版本和本地文件导入。用户需要整理云盘目录、处理云空间资源 URL/token、判断链接类型/真实 token/标题,或导入 Word/Markdown/Excel/CSV/PPTX/.base 为 docx/sheet/bitable/slides 时使用;doubao.com 云空间 URL/token 也按资源路径和 token 路由,不回退 WebFetch。不负责:文档内容编辑(走 lark-doc)、表格/Base 表内数据操作(走 lark-sheets/lark-base)、知识空间节点/成员管理(走 lark-wiki)、原生 Markdown 文件读写/patch/diff(走 lark-markdown)。"
description: "飞书云空间(云盘/云存储):管理 Drive 文件和文件夹,包含上传/下载、创建文件夹、复制/移动/删除、查看元数据、评论/权限/订阅、标题、版本和本地文件导入。用户需要整理云盘目录、处理云空间资源 URL/token、判断链接类型/真实 token/标题,或导入 Word/Markdown/Excel/CSV/PPTX/.base 为 docx/sheet/bitable/slides 时使用;doubao.com 云空间 URL/token 也按资源路径和 token 路由,不回退 WebFetch。Mind Note 在本 skill 中仅支持云空间层面的移动、权限、元数据等操作;Mind Note 节点读取/创建/更新走 lark-doc 的 mindnotes 链路。不负责:文档内容编辑(走 lark-doc)、表格/Base 表内数据操作(走 lark-sheets/lark-base)、知识空间节点/成员管理(走 lark-wiki)、原生 Markdown 文件读写/patch/diff(走 lark-markdown)。"
metadata:
requires:
bins: ["lark-cli"]
Expand All @@ -28,6 +28,7 @@ metadata:
- 用户要**搜文档 / Wiki / 电子表格 / 多维表格 / 云空间(云盘/云存储)对象**,优先使用 `lark-cli drive +search`。自然语言里"最近我编辑过的"、"我创建的"(→ `--created-by-me`,原始创建者语义)、"我负责/owner 的"(→ `--mine`,owner 语义)、"最近一周我打开过的 xxx"、"某人 owner 的 docx" 等直接映射到扁平 flag,避免手写嵌套 JSON。
- 用户要**根据文档评论定位正文位置**,例如 根据评论 review 文档、根据评论内容回看文档、区分多处相同引用文本时,对于 docx 类型(`file_type=docx`)的文档支持通过 `need_relation=true` 返回评论位置,其他类型暂不支持,具体用法需要先阅读 [`references/lark-drive-comment-location.md`](references/lark-drive-comment-location.md) 了解。
- 用户给出 doubao.com 的云空间资源 URL/token,或明确提到豆包里的 file/folder/docx/sheet/bitable/wiki 资源时,仍按资源类型、URL 路径和 token 路由到本 skill;不要因为域名不是飞书而回退到 WebFetch。
- 用户给出 `/mindnote/` URL 时,本 skill 只处理 Drive 层能力,例如移动、删除、权限、密级、标题、元数据、搜索或整理目录;已有 Mind Note 的节点读取/创建/更新切到 `lark-doc` 的 mindnotes 链路;不要切到 `lark-whiteboard`。
- 用户要把本地 `.xlsx` / `.csv` / `.base` 导入成 Base / 多维表格 / bitable,第一步必须使用 `lark-cli drive +import --type bitable`。
- 用户要把本地 `.md` / `.docx` / `.doc` / `.txt` / `.html` 导入成在线文档,使用 `lark-cli drive +import --type docx`。
- 用户要把本地 `.pptx` 导入成飞书幻灯片,使用 `lark-cli drive +import --type slides`;当前 PPTX 导入上限是 500MB。
Expand Down Expand Up @@ -60,6 +61,7 @@ metadata:
| `/docx/` | `https://example.larksuite.com/docx/doxcnxxxxxxxxx` | `file_token` | URL 路径中的 token 直接作为 `file_token` 使用 |
| `/doc/` | `https://example.larksuite.com/doc/doccnxxxxxxxxx` | `file_token` | URL 路径中的 token 直接作为 `file_token` 使用 |
| `/wiki/` | `https://example.larksuite.com/wiki/wikcnxxxxxxxxx` | `wiki_token` | 不能直接当底层 `file_token`;优先用 `drive +inspect` 解包获取 `obj_token` |
| `/mindnote/` | `https://example.larksuite.com/mindnote/mindcnxxxxxxxxx` | `file_token` | 本 skill 仅用于 Drive 层操作;节点读取/创建/更新走 `lark-doc` 的 mindnotes 链路 |
| `/sheets/` | `https://example.larksuite.com/sheets/shtcnxxxxxxxxx` | `file_token` | URL 路径中的 token 直接作为 `file_token` 使用 |
| `/drive/folder/` | `https://example.larksuite.com/drive/folder/fldcnxxxx` | `folder_token` | URL 路径中的 token 作为文件夹 token 使用 |

Expand Down Expand Up @@ -120,6 +122,7 @@ lark-cli drive +inspect --url 'https://xxx.feishu.cn/wiki/wikcnXXX'
- Base / 多维表格内部的表、字段、记录、视图、仪表盘等操作:使用 [`lark-base`](../lark-base/SKILL.md)。
- 知识空间、Wiki 节点层级、空间成员管理:使用 [`lark-wiki`](../lark-wiki/SKILL.md);上传本地文件到 wiki 节点仍用 `drive +upload --wiki-token`。
- 原生 Markdown 文件读取、写入、patch、diff:使用 [`lark-markdown`](../lark-markdown/SKILL.md);把 Markdown 导入成在线 docx 才用 `drive +import --type docx`。
- 原生 Mind Note 节点读取/创建/更新:使用 [`lark-doc`](../lark-doc/SKILL.md) 的 mindnotes 链路;Drive 只覆盖云空间层操作。

## Shortcuts(推荐优先使用)

Expand Down
5 changes: 4 additions & 1 deletion skills/lark-whiteboard/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: lark-whiteboard
version: 1.0.0
description: >
飞书画板:查询和编辑飞书云文档中的画板。支持导出画板为预览图片、导出原始节点结构、使用多种格式更新画板内容。
当用户需要查看画板内容、导出画板图片、编辑画板时使用此 skill。不负责:飞书云文档内容编辑(lark-doc)、文档内嵌电子表格/Base(lark-sheets / lark-base)。
当用户需要查看画板内容、导出画板图片、编辑画板时使用此 skill。不负责:原生 Mind Note 节点读取/创建/更新、飞书云文档内容编辑(lark-doc)、文档内嵌电子表格/Base(lark-sheets / lark-base)。
metadata:
requires:
bins: ["lark-cli"]
Expand All @@ -22,6 +22,8 @@ metadata:

**身份**:画板操作默认使用 `--as user`。仅当需要以应用身份上传时使用 `--as bot`。

`/mindnote/` URL 是原生 Mind Note,不是 whiteboard。已有 Mind Note 的节点读取/创建/更新走 `lark-doc` 的 mindnotes 链路;不要把 Mind Note URL 路由到本 skill。

| 用户需求 | 行动 |
|-----------------------------------------|-----------------------------------------------------------------------------------------------|
| 查看画板内容 / 导出图片 / 导出 SVG 矢量图 | [`+query --output_as image/svg`](references/lark-whiteboard-query.md) |
Expand All @@ -42,6 +44,7 @@ metadata:
---

## 不在本 skill 范围
- 原生 Mind Note 节点读取/创建/更新 → [lark-doc mindnotes 链路](../lark-doc/references/lark-doc-mindnote.md)
- 文档内容编辑 → lark-doc [lark-doc](../lark-doc/SKILL.md)
- 在文档中创建画板 → [lark-doc-whiteboard.md](../lark-doc/references/lark-doc-whiteboard.md)
- 表格 / Base 操作 → [lark-sheets](../lark-sheets/SKILL.md) / [lark-base](../lark-base/SKILL.md)
Loading