skillZs
★ LIVE SKILL TAGS ★
>>> LIVE SKILLS INDEX <<<
* OPEN SOURCE *
NO LOGIN, NO TRACKING
※ REAL INSTALL DATA ※
← back to all skills
riba2534/feishu-cli166 installs

feishu-cli-markdown

飞书云盘原生 Markdown 文件操作(与 doc import/export 互补)。 markdown create 上传新 .md 到云盘;markdown fetch 下载为本地 .md; markdown overwrite 用本地 .md 覆盖云盘已有文件(保 file_token 不变,分享链接持久); markdown diff 在本地比对远端最新/历史版本,不改远端。 当 doc 文档不适合(图床、密集代码块、版本管理)走 .md 原生文件路径。 Drive upload_all + 自拼 Formdata multipart(SDK 不暴露 file_token field)。 当用户请求"上传 markdown"、"下载 md"、"覆盖云盘 md"、"md diff"、"比对 markdown 版本"时使用。

How do I install this agent skill?

npx skills add https://github.com/riba2534/feishu-cli --skill feishu-cli-markdown
view source ↗

Is this agent skill safe to install?

  • Gen Agent Trust Hubpass

    The skill provides instructions for managing Markdown files on Feishu Drive using the feishu-cli tool. It enables operations like creating, downloading, overwriting, and diffing files while maintaining persistent file tokens. All referenced resources are consistent with the author's identity, and no malicious patterns were identified.

  • Socketwarn

    1 alert: gptSecurity

  • Snykwarn

    Risk: MEDIUM · 1 issue

What does this agent skill do?

飞书云盘原生 Markdown(markdown create/fetch/overwrite/diff)

markdown 命令组把 Drive 上的 .md 当作普通文件整体读写,保留原始 Markdown 源码,不做 Markdown ↔ 飞书 docx 块的转换。

feishu-cli:如尚未安装,请前往 riba2534/feishu-cli 获取安装方式。

核心概念:与 doc import / doc export 的区别

命令行为创建出的类型适用场景
doc importMarkdown → 飞书 docx 块(标题/列表/表格/Callout/Mermaid 画板…)docx(在线协同文档)给人读、要排版、要团队评论
doc exportdocx → Markdown(块解析回 markdown 源码)本地 .md从飞书 docx 落盘到 Git
markdown create/fetch/overwrite把 .md 整体上传/下载,不转换file(Drive 普通文件)AI agent 直接落盘原汁原味 .md、保留 fenced code block 缩进、当图床/密集代码块/版本管理用

判断走哪条:

  • 想要飞书 docx 渲染(人读、排版、表格分块、画板渲染)→ doc import
  • 想要原始 .md 文本 unchanged 保留在云盘(AI agent 读回完全一致;docx 块解析有损)→ markdown create
  • 想反复覆盖同一份 .md、保持 file_token 不变(分享链接持久)→ markdown overwrite

前置条件

  • 认证:所有 markdown 命令默认走 User Access Token(执行 feishu-cli auth login 登录)
  • 预检:feishu-cli auth check --scope "drive:file:upload drive:file:download"

命令速查

1. markdown create — 上传新 .md 到云盘

# 从字符串内容创建
feishu-cli markdown create --name plan.md --content "# Plan\n\n- todo 1"

# 从本地文件创建(--name 缺省时取本地 basename)
feishu-cli markdown create --content-file ./local.md
feishu-cli markdown create --file ./local.md

# 指定目标文件夹
feishu-cli markdown create --name draft.md --content-file ./tmp.md --folder-token fldxxx

# JSON 输出(拿 file_token 给后续步骤)
feishu-cli markdown create --name plan.md --content-file ./plan.md -o json

关键 flag:

flag说明
--name远端文件名,必须 .md 结尾。create:--content 时必填、--content-file 时可省取本地 basename。overwrite:--content 时必填、--content-file 时可省取本地 basename;显式传入 = 同时改名
--content字符串内容(与 --content-file 二选一)
--content-file本地 .md 文件路径
--file官方 lark-cli 兼容别名,等价于 --content-file
--folder-token目标文件夹(缺省 Drive 根目录)
-o jsonJSON 输出(含 file_token / file_name / size_bytes)
--user-access-token覆盖登录态

校验:空内容直接报错(不允许创建空 .md)。

2. markdown fetch — 下载云盘 .md

# 打印到 stdout(缺省 --output-path 时,行为与 lark-cli markdown +fetch 一致)
feishu-cli markdown fetch --file-token boxcnxxx

# 落盘到本地路径
feishu-cli markdown fetch --file-token boxcnxxx --output-path ./local.md

# 路径已存在时强制覆盖
feishu-cli markdown fetch --file-token boxcnxxx --output-path ./local.md --overwrite

# JSON 输出(含 content 字符串)
feishu-cli markdown fetch --file-token boxcnxxx -o json

关键 flag:

flag说明
--file-tokenMarkdown 文件 token(必填)
--output-path本地保存路径;目录时拼 <fileToken>.md;缺省打印 stdout
--overwrite本地文件已存在时覆盖(缺省直接报错)
-o, --output jsonJSON 输出;不传 --output-path 时包含 content 字符串

3. markdown overwrite — 覆盖已有 .md(保 file_token)

# 字符串覆盖
feishu-cli markdown overwrite --file-token boxcnxxx --name existing.md --content "新内容"

# 本地文件覆盖
feishu-cli markdown overwrite --file-token boxcnxxx --content-file ./new.md
feishu-cli markdown overwrite --file-token boxcnxxx --file ./new.md

# 覆盖 + 改名(必须 .md 结尾)
feishu-cli markdown overwrite --file-token boxcnxxx --content-file ./new.md --name renamed.md

关键 flag:

flag说明
--file-token目标文件 token(必填)
--content / --content-file新内容(二选一)
--name覆盖后文件名(.md 结尾;--content 时必填;--content-file 缺省使用本地 basename)
-o jsonJSON 输出

核心价值:file_token 保持不变 → 分享链接持久、其他人收藏的链接不失效;多次迭代场景(AI agent 每天更新同一份 .md)优于"删了重建"。

4. markdown diff — 本地比对远端最新/历史版本(只读,不改远端)

下载远端 Markdown 内容并在本地计算 unified diff,不修改远端文件。三种比对模式(由参数组合决定,互斥):

# 模式 1:远端最新 vs 本地文件
feishu-cli markdown diff --file-token boxcnxxx --file ./local.md

# 模式 2:远端某版本 vs 远端最新
feishu-cli markdown diff --file-token boxcnxxx --from-version 3

# 模式 3:远端版本 A vs 版本 B(--to-version 需配合 --from-version)
feishu-cli markdown diff --file-token boxcnxxx --from-version 2 --to-version 5 --context-lines 1

# 结构化输出 + 内置 jq 过滤(--format/--jq 与其它新命令一致;-o json 作兼容别名)
feishu-cli markdown diff --file-token boxcnxxx --file ./local.md --format json
feishu-cli markdown diff --file-token boxcnxxx --file ./local.md --jq '.added_lines'
feishu-cli markdown diff --file-token boxcnxxx --file ./local.md --format table --jq '{identical,added_lines,removed_lines}'
feishu-cli markdown diff --file-token boxcnxxx --file ./local.md -o json   # 兼容写法,等价 --format json

关键 flag:

flag说明
--file-token目标 Markdown 文件 token(必填)
--file本地 .md 路径(模式 1:与远端最新比对)
--from-version起始远端版本号(模式 2/3)
--to-version目标远端版本号(模式 3,需配合 --from-version)
--context-lines每个 hunk 上下保留的未变更上下文行数(默认 3)
--dry-run只打印比对计划,不下载/不比对
--formatjson|pretty|table|ndjson|csv 结构化输出;缺省打印 unified diff 文本
--jq内置 gojq 过滤结构化输出(如 --jq '.added_lines',无需外部 jq)
-o json兼容别名,等价 --format json

结构化输出结构(--format json / -o json,顶层 9 字段,可直接 --jq 取改动量 / 判一致):

{
  "detection": "local_vs_remote",   // 比对模式:local_vs_remote(模式 1)/ remote_vs_remote(模式 2/3)
  "from": "remote (latest)",        // 左侧来源名(模式 1="remote (latest)";模式 2/3="remote@version=N")
  "to": "local: ./local.md",        // 右侧来源名(模式 1="local: <path>";模式 2="remote (latest)";模式 3="remote@version=N")
  "size_bytes_before": 1024,        // 左侧内容字节数
  "size_bytes_after": 1088,         // 右侧内容字节数
  "identical": false,               // 是否无差异(等价于 hunks 为空)
  "added_lines": 5,                 // 新增行数(统计所有 hunk 中 op="+")
  "removed_lines": 2,               // 删除行数(统计所有 hunk 中 op="-")
  "hunks": [                        // unified diff 的 hunk 数组(无差异时为空数组)
    {
      "old_start": 10, "old_lines": 4,   // 左侧起始行 / 行数
      "new_start": 10, "new_lines": 7,   // 右侧起始行 / 行数
      "lines": [
        { "op": " ", "text": "上下文行" },   // op: " "=未变 / "-"=删除 / "+"=新增
        { "op": "-", "text": "旧内容" },
        { "op": "+", "text": "新内容" }
      ]
    }
  ]
}

常用内置 --jq(无需外部 jq):--jq '.identical' 判是否一致、--jq '.added_lines, .removed_lines' 取改动量、--jq '.hunks[].lines[] | select(.op=="+") | .text' 拉所有新增行。

与 overwrite 配合:覆盖前先 diff --file ./local.md 预览本地相对远端最新的改动,确认后再 overwrite,避免误覆盖。

底层实现 & 踩坑

1. SDK 不暴露 file_token field —— 自拼 multipart

飞书 Go SDK v3.5.3 的 UploadAllFileReqBody 只暴露 file_name / parent_type / parent_node / size / checksum / file,没有 file_token 字段。

但官方 API POST /open-apis/drive/v1/files/upload_all 是支持 file_token 的:带 file_token 时覆盖原文件保留 token、刷新 version/size;不带时按 parent_type+parent_node 在指定目录新建。

为绕开 SDK 限制,internal/client/markdown.go:OverwriteFileWithToken 用 client.Post + *larkcore.Formdata 自己拼 multipart(translator 检测到 *Formdata 会自动切到 FileUpload 多部分序列化路径,见 SDK core/reqtranslator.go:payload)。endpoint 仍是官方 upload_all,参考 lark-cli shortcuts/markdown/helpers.go:uploadMarkdownFileAll 的写法。

2. 文件大小上限 ≤ 20MB

upload_all 单次上传 API 上限 20MB,本命令组只走单次上传路径:

  • markdown create 调 client.UploadFileWithToken(> 20MB 时该函数会自动切到分片管线,但 markdown create 主场景是文本 .md 远小于 20MB)
  • markdown overwrite 只支持 ≤ 20MB 小文件,大文件覆盖需要分片接口,本命令组未实现。如果是几十 MB 的 .md(罕见,比如海量日志贴)走 drive upload 分片管线创建新文件,无法保留原 file_token。

markdown diff 另有独立的行数/矩阵上限(与 20MB 上传上限无关,防 LCS 矩阵 OOM):

  • 单侧 ≤ 20000 行:任一侧超过即报错 内容过大(N 行 / M 行),单侧超过行数上限 20000,建议用外部 diff 工具
  • 两侧行数乘积 ≤ 2000 万单元:LCS 用完整 (n+1)×(m+1) int 矩阵,内存随两侧行数乘积增长;乘积超限报错 内容过大(N × M 行),LCS 矩阵超过 20000000 单元上限(防 OOM),建议用外部 diff 工具
  • 两条都在下载完成、计算 LCS 之前拦截(cmd/markdown_diff.go:checkDiffSize)。长 .md(海量日志贴、全量代码 dump)跑 diff 命中该报错时,改用本地 diff / git diff 等外部工具,或先用 markdown fetch 落盘两侧再外部比对。

3. .md 后缀强制校验

--name(create)和 --name(overwrite)都强制 .md 结尾(lowercase 检查后缀),非 .md 直接报错。如果想存 .markdown / .mdx 走 drive upload 老路径。

4. 空内容直接报错

--content "" / 空 --content-file 都被拒绝("Markdown 内容为空,不支持创建/覆盖为空文件")。需要"清空"语义的话走 markdown overwrite --content " " 写一个占位空格。

5. fetch 的路径输出与 JSON 输出分离

markdown fetch 使用 --output-path 保存到本地,使用 -o json 输出 JSON:

  • --output-path ./x.md → 落盘到 ./x.md
  • -o json → 把 {file_token, content, size_bytes} 打到 stdout
  • 两者可叠加:落盘 + 同时 stdout JSON 摘要

6. --output-path 是目录时的兜底文件名

markdown fetch --output-path ./downloads/ 会拼成 ./downloads/<fileToken>.md(不从响应头解析原文件名,与 drive download 行为一致)。要保留原文件名请自己加查询步骤再拼路径。

何时转走 doc import/export

  • 要飞书 docx 渲染体验(人读、表格分行、Mermaid 转画板、Callout 高亮)→ doc import(参 feishu-cli-import skill)
  • 要从飞书 docx 落盘到 Git 仓库(块解析回 markdown)→ doc export(参 feishu-cli-export skill)
  • 要把 Markdown 转换前 sanity check(Mermaid 花括号、表格 9×9 限制、Callout 6 种类型)→ ../feishu-cli-import/references/doc-guide.md

何时转走 drive upload

  • 大文件 > 20MB(罕见,但比如全量代码 dump、长 log)→ feishu-cli drive upload --file xxx.md 走分片,会创建新 file_token
  • 非 .md 扩展名(.mdx / .markdown / .txt)→ drive upload

权限要求

命令所需 scope
markdown createdrive:file:upload(或 drive:drive)
markdown fetchdrive:file:download(或 drive:drive)
markdown overwritedrive:file:upload + drive:drive.metadata:readonly;且 User Token 对目标文件有编辑权限
markdown diffdrive:file:download(或 drive:drive)

推荐做法:执行 feishu-cli auth login 登录后,由 auth check --scope "drive:file:upload drive:file:download" 预检;缺 scope 时按提示 auth login 补申请。

典型工作流

工作流 A:AI agent 每天迭代同一份 .md

# Day 1:创建一次拿到 file_token
FT=$(feishu-cli markdown create --name daily-summary.md --content-file ./summary.md -o json | jq -r '.file_token')
echo "$FT" > ~/.cache/daily-summary.token

# Day 2+:覆盖(file_token 不变,分享链接持久)
feishu-cli markdown overwrite --file-token "$(cat ~/.cache/daily-summary.token)" --content-file ./summary.md

工作流 B:从云盘 .md 落盘到本地

# 读回原汁原味 Markdown 源码
feishu-cli markdown fetch --file-token boxcnxxx --output-path ./local.md --overwrite

# 编辑后写回
feishu-cli markdown overwrite --file-token boxcnxxx --content-file ./local.md

工作流 C:与 doc import 协作(先落盘 .md 再批量 import)

# 上游产出 .md 到云盘(保留源码备份)
feishu-cli markdown create --name design.md --content-file ./design.md --folder-token fldxxx

# 下游再走 doc import 生成飞书 docx 给团队阅读
feishu-cli doc import ./design.md --title "设计稿" --upload-images

注意事项

  • 默认 User Access Token:所有 markdown 命令未登录时统一提示 feishu-cli auth login
  • 不做 Markdown 转换:本命令组保留 .md 字节流不变,不做飞书 docx 块转换,不触发图床、画板渲染、Callout 等增强逻辑——需要这些走 doc import
  • upload_all 单次 ≤ 20MB:create / overwrite 共用 endpoint,大文件覆盖未实现,绕路走 drive upload(创建新 file_token)
  • fetch 输出参数:路径走 --output-path,格式走 -o/--output

.md 后缀强制、空内容拒绝两条已经在「核心 flag」与「踩坑」章节出现,这里不再重复,详见 overwrite flag 表 和 踩坑 §3/§4。

常见错误

实际报错示例(参 cmd/markdown_overwrite.go + internal/client/markdown.go:OverwriteFileWithToken):

触发条件错误信息排查方向
User Token 对目标文件无编辑权限覆盖文件失败: code=<非 0>, msg=<飞书返回>(常见 1061004 forbidden、1061045 no permission)在飞书云盘右键文件 → 共享 → 给当前用户加「可编辑」;或换文件所有者的 token;或检查 scope drive:file:upload 是否已授予
文件大小超 20MB(--content)--content 大小 <N> 字节超过 20MB API 上限切分文件或换 drive upload(会创建新 file_token,分享链接失效)
文件大小超 20MB(--content-file)--content-file 大小 <N> 字节超过 20MB API 上限,请切分或用多次 fetch+overwrite同上;CLI 在读盘前 os.Stat 已拦截,不浪费上传带宽
--name 不以 .md 结尾--name 必须以 .md 结尾,得到 "xxx.txt"改 .md 后缀;.mdx / .markdown 必须走 drive upload
--content-file 路径不存在读取本地文件失败: open <path>: no such file or directory检查路径是否相对当前目录;建议传绝对路径
--content-file 是目录--content-file 必须指向文件,不是目录指向具体 .md 文件
既给 --content 又给 --content-file--content 与 --content-file 不能同时使用二选一
都没给请提供 --content 或 --content-file至少传一个
--content 模式漏 --name使用 --content 时必须提供 --name 指定远端文件名(保留原名请加 --name <现有文件名>.md)显式 --name existing.md(不会自动 fallback fileToken.md)
内容为空字节Markdown 内容为空,不支持把 .md 覆盖为空文件要清空语义传 --content " "(占位空格)
HTTP 层异常覆盖文件失败: HTTP <status>, body: <raw>网络/代理问题,附带原始 body 便于排查
响应解析失败解析覆盖响应失败: <json error>飞书侧返回非 JSON(极罕见,通常网关错误页)

权限不足时飞书 API 直接返回 code != 0 的业务错(如 1061004、1061045),CLI 层透传 msg 字段;若同时缺 scope 会在 auth check 阶段就拦截,建议执行前先跑 feishu-cli auth check --scope "drive:file:upload"。

与老命令的对照

老命令新 markdown 命令差异
drive upload --file x.mdmarkdown create --content-file x.mdmarkdown 强制 .md 后缀 + 空内容校验 + AI agent 友好
drive download --file-token xxxmarkdown fetch --file-token xxxmarkdown 默认打印 stdout(文本场景)+ 目录路径自动拼 .md
无markdown overwrite老命令没有覆盖语义(只能"删了重建",file_token 变化)

老 drive upload/download 仍然可用(二进制、非 .md 走老路径),新能力集中在 markdown overwrite(保 file_token 覆盖)。

v1 PR quality-pass 加固

  • drive/v1/files/upload_all 单次上传 ≤ 20MB(create / overwrite 共用 endpoint)。CLI 层在 --content / --content-file 都做 pre-check,超过直接报错不浪费带宽
  • overwrite 必须显式 --name(用 --content 时):不再 fallback <fileToken>.md 默默改名远端文件;保留原名请显式 --name <existing>.md

Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.

<a href="https://skillzs.dev/skills/riba2534/feishu-cli/feishu-cli-markdown">View feishu-cli-markdown on skillZs</a>