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
250 changes: 53 additions & 197 deletions skill-template/domains/drive.md

Large diffs are not rendered by default.

6 changes: 1 addition & 5 deletions skill-template/skill-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,7 @@ lark-cli {{service}} <resource> <method> [flags] # 调用 API
```

> **重要**:使用原生 API 时,必须先运行 `schema` 查看 `--data` / `--params` 参数结构,不要猜测字段格式。
> 所需 scope 以 `lark-cli schema {{service}}.<resource>.<method>` 输出为准;skill 主文不展开完整权限表。

{{resource_sections}}
## 权限表

| 方法 | 所需 scope |
|------|-----------|
{{permission_rows}}
{{/actions}}
409 changes: 73 additions & 336 deletions skills/lark-drive/SKILL.md

Large diffs are not rendered by default.

66 changes: 66 additions & 0 deletions skills/lark-drive/references/lark-drive-comments-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# drive comments guide

> **前置条件:** 先阅读 [`../SKILL.md`](../SKILL.md) 了解 Drive 入口、身份路由和 Wiki token 解包规则;再阅读 [`../../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证与全局参数。

## 创建评论

- 添加评论优先使用 `drive +add-comment`。
- 全文评论:未传 `--block-id` 时默认启用,也可显式传 `--full-comment`;支持 `docx`、旧版 `doc` URL、白名单扩展名普通文件,以及最终解析为这些类型的 Wiki URL。
- 局部评论:传 `--block-id` 时启用;支持 `docx`、`sheet`、`slides`,以及最终解析为这些类型的 Wiki URL。docx block ID 可通过 `docs +fetch --api-version v2 --detail with-ids` 获取;sheet 使用 `<sheetId>!<cell>`;slides 使用 `<slide-block-type>!<xml-id>`。
- 如果 Wiki URL 解包后不是 `doc` / `docx` / `file` / `sheet` / `slides`,不要使用 `+add-comment`。
- Drive 普通文件评论仅支持平台允许的文件类型,常见后缀包括 `.md`、`.txt`、`.json`、`.csv`、`.go`、`.js`、`.py`、`.pptx`、`.png`、`.jpg`、`.jpeg`、`.zip`、`.mp3`、`.mp4`;普通文件只支持全文评论。
- `--content` 需要传 `reply_elements` JSON 数组字符串,例如 `--content '[{"type":"text","text":"正文"}]'`。
- 如果直接调用原生评论 V2 API,先执行 `lark-cli schema drive.file.comments.create_v2` 并优先参考 [`lark-drive-add-comment.md`](lark-drive-add-comment.md)。全文评论省略 `anchor`;doc/docx 局部评论传 `anchor.block_id`;sheet 评论使用 `anchor.block_id` + `sheet_col` + `sheet_row`;slides 评论使用 `anchor.block_id` + `slide_block_type`。

## Review 场景

- 代码、文案、方案 review 场景优先创建局部评论。
- 不同问题尽量拆成多条局部评论,便于逐条解决和追踪。
- Drive 普通文件不支持局部锚点,只能创建全文评论。

## 内容与转义

- 评论内容使用 `reply_elements` 表达,不要把纯 Markdown 当作结构化评论正文。
- `drive +add-comment` 会处理常见文本转义;直接调原生 API 时需要自行转义 `<` 和 `>`,避免被平台当作标签片段。
- 需要在评论中表达代码或 JSON 时,优先作为普通文本元素传入,不要猜测不在 schema 里的富文本字段。

## 查询与统计

- `drive file.comments list` 默认必须传 `is_solved:false`,即仅查询未解决评论。
- 即使用户说“所有评论”“全部评论”“把评论都列出来”,只要没有明确要求包含已解决评论,仍按未解决评论查询。
- 只有用户明确要求包含已解决评论时,才省略 `is_solved`。

```bash
# 默认查询:仅未解决评论
lark-cli drive file.comments list --params '{"file_token":"<DOC_TOKEN>","file_type":"docx","is_solved":false}'

# 用户明确要求包含已解决评论时
lark-cli drive file.comments list --params '{"file_token":"<DOC_TOKEN>","file_type":"docx"}'
```

- `items` 是评论卡片列表,不是平铺的互动消息列表。
- 创建第一条评论时会同时创建该卡片里的第一条 reply;真正承载正文的是 `item.reply_list.replies`。
- 统计“评论数”或“评论卡片数”:统计 `items` 数量,分页场景累加所有页。
- 统计“回复数”:所有 `item.reply_list.replies` 数量之和减去 `items` 数量。
- 统计“总互动数”:所有 `item.reply_list.replies` 数量之和,包含每张评论卡片的首条评论。
- 如果 `item.has_more=true`,继续调用 `drive file.comment.replys list` 拉全该卡片下的回复,再做全量统计。

## 排序

- 只有用户明确提到“最新评论”“最后评论”“最早评论”时,才需要按 `create_time` 排序。
- 排序前必须先处理分页,拉完所有评论;不要只取第一页排序。
- “最新评论” / “最后评论”:按 `create_time` 降序取第一条。
- “最早评论”:按 `create_time` 升序取第一条。
- 用户只说“第一条评论”时,直接使用 `drive file.comments list` 返回的第一条,不额外排序。

## 回复限制

- 全文评论不支持回复:`is_whole=true` 的评论无法添加回复。
- 已解决评论不支持回复:`is_solved=true` 的评论无法添加回复。
- 用户要回复某条评论但该评论不能回复时,只提示限制原因;不要自动替用户寻找其他可回复评论。

## 批量查询与 reaction

- `drive file.comments batch_query` 只用于已知评论 ID 后的批量查询,需要传入具体 comment ID 列表。
- 遍历、统计、获取最新/最早评论等场景使用 `drive file.comments list`。
- reaction(表情、点赞、谁点了什么、添加/删除表情)场景先阅读 [`lark-drive-reactions.md`](lark-drive-reactions.md)。
49 changes: 49 additions & 0 deletions skills/lark-drive/references/lark-drive-permission-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# drive permission guide

> **前置条件:** 先阅读 [`../SKILL.md`](../SKILL.md) 了解 Drive 入口、身份路由和 Wiki token 解包规则;再阅读 [`../../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证与全局参数。

## 权限申请

- 向文档 owner 申请 view / edit 权限时,优先使用 `drive +apply-permission`。
- `drive +apply-permission` 仅支持 user 身份;不要用 bot 反复重试用户个人资源。
- 如果用户只给 token,先尽量用 `drive +inspect` 或上下文恢复 URL / 类型,再申请权限。

## 公开权限错误码

调用 `drive.permission.public.patch` 修改公开权限时,常见业务错误码按下表处理:

| 错误码 | 处理建议 |
|--------|----------|
| `91009` | 当前文件已设置更高安全等级或受组织策略限制,无法开放到目标范围;提示用户在文档 UI 或安全设置中处理 |
| `91010` | 文件 owner 或管理员设置不允许修改公开权限;需要 owner / 管理员调整策略 |
| `91011` | 当前身份没有修改公开权限的权限;切换到有权限的 user,或让 owner 授权 |
| `91012` | 目标公开范围不符合当前租户策略;不要继续扩大权限,提示用户按组织策略处理 |

如果错误信息与上表不一致,以接口返回的 `msg` / `error` 为准,并给出下一步可执行动作。

## 授权当前应用访问文档

当需要把文档权限授予**当前应用(bot)自身**时,先获取当前 bot 的 `open_id`,再授权给该 `open_id`:

```bash
# 1. 获取当前应用的 open_id
lark-cli api GET /open-apis/bot/v3/info --as bot

# 2. 授权当前应用访问文档
lark-cli drive permission.members create \
--params '{"token":"<doc_token>","type":"<resource_type>"}' \
--data '{"member_type":"openid","member_id":"<bot_open_id>","perm":"view","type":"user"}'
```

说明:

- 此方式只适用于授权给当前应用自身。
- 授权给其他用户时,直接使用对方的 `open_id`,不要调用 bot info。
- 不要转移 owner,除非用户明确要求且已说明影响。
- `<resource_type>` 常见值:`doc`、`docx`、`sheet`、`bitable`、`file`、`folder`、`wiki`、`slides`。

## 身份判断

- 用户个人云空间、用户拥有的文档、公开权限申请、密级标签等场景优先 `--as user`。
- bot 创建或已授权给 bot 的资源可使用 `--as bot`。
- bot 因资源不可见失败时,说明资源可见性问题;建议切换 user 身份或先给 bot 授权,不要盲目重试。
2 changes: 1 addition & 1 deletion skills/lark-drive/references/lark-drive-reactions.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# drive reactions

> **前置条件:** 先阅读 [`../SKILL.md`](../SKILL.md) 了解 Drive 评论卡片模型、评论数/回复数统计口径、`file_token` / `file_type` 规则;再阅读 [`../../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
> **前置条件:** 先阅读 [`../SKILL.md`](../SKILL.md) 了解 Drive 入口与身份路由;再阅读 [`lark-drive-comments-guide.md`](lark-drive-comments-guide.md) 了解评论卡片模型、评论数/回复数统计口径、`file_token` / `file_type` 规则;最后阅读 [`../../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。

处理文档评论 / 回复上的 reaction(点赞、表情、各表情数量、谁点了什么、添加/删除表情)。这个场景不常见,但规则比较集中:查询时只有在用户明确需要 reaction 信息时才带 `need_reaction=true`;写入时统一使用 `drive file.comment.reply.reactions update_reaction`,操作对象始终是 `reply_id`。

Expand Down
21 changes: 14 additions & 7 deletions skills/lark-markdown/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: lark-markdown
version: 1.2.0
description: "飞书 Markdown:查看、创建、上传、编辑和比较 Markdown 文件。当用户需要创建或编辑 Markdown 文件、读取、修改、局部 patch 或比较差异时使用。"
description: "飞书 Markdown:查看、创建、上传、编辑和比较 Drive 原生 Markdown 文件。当用户需要创建或编辑 `.md` 文件、读取、修改、局部 patch 或比较差异时使用。不负责:把 Markdown 导入成飞书在线文档 docx(走 lark-drive 的 drive +import --type docx)、文件搜索/权限/评论/移动/删除等云空间管理操作(走 lark-drive)。"
metadata:
requires:
bins: ["lark-cli"]
Expand All @@ -23,6 +23,13 @@ metadata:
- 用户要把本地 Markdown **导入成在线新版文档(docx)**,不要用本 skill,改用 [`lark-drive`](../lark-drive/SKILL.md) 的 `lark-cli drive +import --type docx`
- 用户要对 Markdown 文件做**rename / move / delete / 搜索 / 权限 / 评论**等云空间(云盘/云存储)操作,不要留在本 skill,切到 [`lark-drive`](../lark-drive/SKILL.md)

## 身份策略

- 所有 markdown shortcut 同时支持 `--as user` 和 `--as bot`
- 访问用户个人云空间或用户拥有的文件时,优先使用 `--as user`
- CI / 自动化场景、bot 自己创建或已被授权访问的 Markdown 文件,可使用 `--as bot`
- 如果 bot 因看不到用户资源而失败,不要反复重试;提示用户改用 `--as user` 或先给 bot 授权

## 核心边界

- 本 skill 处理的是 **Drive 中作为普通文件存储的 Markdown**,不是 docx 文档
Expand All @@ -34,7 +41,7 @@ metadata:
- `markdown +patch` 的内部语义是:**先完整下载 Markdown,再本地替换,再整文件覆盖上传**
- `markdown +patch` 不是服务端原子 patch;它是 CLI 侧编排出来的局部更新能力
- `markdown +patch` 当前只支持**单组** `--pattern` / `--content`
- `markdown +patch` 替换后的最终内容**不能为空**;如果替换后整篇 Markdown 变成空字符串,CLI 会直接报错,不会上传空文件
- `markdown +patch` 替换后的最终内容**不能为空**;Drive 不支持 0 字节 Markdown,且空结果通常代表误清空,CLI 会直接报错,不会上传空文件
- `--file` 只接受本地 `.md` 文件路径

## Shortcuts(推荐优先使用)
Expand All @@ -43,11 +50,11 @@ Shortcut 是对常用操作的高级封装(`lark-cli markdown +<verb> [flags]`

| Shortcut | 说明 |
|----------|------|
| [`+create`](references/lark-markdown-create.md) | Create a Markdown file in Drive |
| [`+diff`](references/lark-markdown-diff.md) | Compare two remote Markdown versions, or compare remote Markdown against a local file |
| [`+fetch`](references/lark-markdown-fetch.md) | Fetch a Markdown file from Drive |
| [`+patch`](references/lark-markdown-patch.md) | Patch a Markdown file in Drive via fetch-local-replace-overwrite |
| [`+overwrite`](references/lark-markdown-overwrite.md) | Overwrite an existing Markdown file in Drive |
| [`+create`](references/lark-markdown-create.md) | 在 Drive 中创建原生 Markdown 文件 |
| [`+diff`](references/lark-markdown-diff.md) | 比较两个远端 Markdown 历史版本,或比较远端 Markdown 与本地文件 |
| [`+fetch`](references/lark-markdown-fetch.md) | 读取 Drive 中的原生 Markdown 文件 |
| [`+patch`](references/lark-markdown-patch.md) | 通过下载、替换、覆盖上传的方式局部更新 Markdown 文件 |
| [`+overwrite`](references/lark-markdown-overwrite.md) | 覆盖更新 Drive 中已有的 Markdown 文件 |

## 参考

Expand Down
35 changes: 34 additions & 1 deletion skills/lark-markdown/references/lark-markdown-patch.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,42 @@ lark-cli markdown +patch \
- `--content` 必须显式传入,但允许为空字符串
- 未加 `--regex` 时,行为等价于对整份 Markdown 文本执行 `strings.ReplaceAll`
- 加了 `--regex` 时,行为等价于对整份 Markdown 文本执行 RE2 全量替换;`--content` 里的 `$1`、`${name}` 会按 Go regexp replacement template 解释,字面 `$` 请写成 `$$`
- 替换后的最终 Markdown 不能为空;如果 patch 结果是空字符串,CLI 会直接报错,不会上传空文件
- 替换后的最终 Markdown 不能为空;Drive 不支持 0 字节 Markdown,且空结果通常代表误清空,CLI 会直接报错,不会上传空文件
- `0` 命中时命令仍然成功返回,但不会上传新版本

## GOOD / BAD:正则转义

`--pattern` 默认是字面量,不需要正则转义。只有传 `--regex` 时,`--pattern` 才按 Go RE2 正则解释。

```bash
# GOOD:默认字面量模式,括号和点号按普通文本匹配
lark-cli markdown +patch \
--file-token boxcnxxxx \
--pattern 'TODO(v1.2)' \
--content 'DONE(v1.2)'

# BAD:开启 --regex 后,未转义的 . 会匹配任意字符,括号会变成分组
lark-cli markdown +patch \
--file-token boxcnxxxx \
--regex \
--pattern 'TODO(v1.2)' \
--content 'DONE'

# GOOD:开启 --regex 后,按 RE2 规则转义字面括号和点号
lark-cli markdown +patch \
--file-token boxcnxxxx \
--regex \
--pattern 'TODO\\(v1\\.2\\)' \
--content 'DONE'

# GOOD:replacement 里需要字面 $ 时写成 $$
lark-cli markdown +patch \
--file-token boxcnxxxx \
--regex \
--pattern 'price: (\\d+)' \
--content 'price: $$1'
```

## 实现边界

- 该命令的内部语义是:**download -> local replace -> overwrite upload**
Expand Down
48 changes: 48 additions & 0 deletions skills/lark-shared/references/lark-wiki-token-routing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Wiki token routing

> **前置条件:** 先阅读 [`../SKILL.md`](../SKILL.md) 了解认证、全局参数、身份选择和错误处理。

Wiki 链接里的 `/wiki/<token>` 是知识库节点 token,不是底层文档、表格、Base、幻灯片或文件 token。处理 Wiki URL 时先解包,再按底层对象类型路由到对应 skill 或 API。

## 推荐入口

优先使用 `drive +inspect` 自动识别 URL 类型并解包 Wiki 节点:

```bash
lark-cli drive +inspect --url 'https://example.feishu.cn/wiki/<wiki_token>'
```

返回里的 `type`、`token`、`title`、`url` 是后续操作的 canonical 信息。后续命令使用返回的 canonical token,不要继续把 Wiki 节点 token 当作文件 token 传入。

## 手动解包

当 shortcut 不满足需求时,用 Wiki 节点接口查询底层对象:

```bash
lark-cli wiki spaces get_node --params '{"token":"<wiki_token>"}'
```

从返回结果中读取:

- `node.obj_type`:底层对象类型
- `node.obj_token`:底层对象 token
- `node.space_id`:知识空间 ID
- `node.title`:节点标题

## 路由表

| `obj_type` | 后续处理 |
|------------|----------|
| `docx` / `doc` | 文档正文读取和编辑走 `lark-doc`;评论、权限、导出、文件元数据走 `lark-drive` |
| `sheet` | 单元格、工作表、导出等表格操作走 `lark-sheets`;评论、权限、文件元数据走 `lark-drive` |
| `bitable` | 表、字段、记录、视图、表单、仪表盘、工作流走 `lark-base`;评论、权限、文件元数据走 `lark-drive` |
| `slides` | 幻灯片内容编辑走 `lark-slides`;导出、评论、权限、文件元数据走 `lark-drive` |
| `file` | 普通文件上传、下载、移动、删除、权限、评论走 `lark-drive` |
| `mindnote` | 按当前 CLI 支持能力优先走 `lark-drive`;缺口再评估原生 OpenAPI |

## 规则

- 不要把 Wiki 节点 token 直接当作 `doc_token`、`file_token`、`spreadsheet_token`、`app_token` 或 `presentation_token`。
- Wiki 节点、空间目录、成员管理等知识库结构操作保留 Wiki 节点 token,走 `lark-wiki`。
- 内容、评论、权限、导出等底层对象操作使用解包后的 `obj_token`。
- 如果用户只给 Wiki URL,先解析类型;不要凭标题、路径或上下文猜底层对象类型。
Loading