- CLI
- AI 技能
【免费下载链接】cli
The official Lark/飞书 CLI tool, maintained by the larksuite team — built for humans and AI Agents. Covers core business domains including Messenger, Docs, Base, Sheets, Calendar, Mail, Tasks, Meetings, and more, with 200+ commands and 20+ AI Agent Skills.
本指南围绕官方 Lark/飞书 CLI(lark-cli)的 Slides 历史版本能力展开,讲解如何使用slides +history-list列出 Slides XML 演示文稿的历史版本、通过+history-revert按history_version_id发起回滚,以及用+history-revert-status轮询异步任务状态。读完本文,你将掌握一套可安全落地的版本回滚流程:从候选版本筛选、跨页补拉、候选确认,到异步轮询边界与回滚后的内容验证,并能直接照着命令与参数在真实演示文稿上执行。
背景:为什么回滚需要一套专门流程
Slides 演示文稿在飞书/Lark 侧以 XML 形式存储,每一次编辑都会产生新的历史版本。与普通文档的"直接恢复"不同,CLI 的回滚是异步任务:+history-revert提交后立即返回task_id,真正的回滚在服务端后台执行。因此整个流程天然分为三个阶段:
- 定位版本:通过分页接口
+history-list找到目标版本,拿到回滚所需的history_version_id; - 发起回滚:
+history-revert提交异步任务,拿到task_id与建议轮询间隔poll_after_ms; - 轮询确认:
+history-revert-status持续查询任务状态,直到done/partial_failed/failed,再做回滚后验证。
其中有一个关键概念需要先澄清:回滚接口只接受history_version_id,不要直接把revision_id传给+history-revert。这一约束在 skills/lark-slides/SKILL.md 中被标记为 CRITICAL 级别:history_version_id对应服务端minor_history.version,是回滚接口需要的 ID;而revision_id是文档修订号,同一revision_id可能对应多条历史记录,不能作为回滚依据。
三个命令与底层实现总览
三个命令均在 shortcuts/slides/slides_history.go 中注册,统一走/open-apis/slides_ai/v1/xml_presentations/{xml_presentation_id}/...这一组 Slides AI OpenAPI 端点:
| 命令 | 底层端点 | HTTP 方法 | 风险等级 | 必填参数 | |-|-|-|-|-| |+history-list|.../histories| GET | read |--presentation| |+history-revert|.../history/revert| POST | write |--presentation、--history-version-id| |+history-revert-status|.../history/revert_status| GET | read |--presentation、--task-id|
权限声明(源码中Scopes/ConditionalScopes字段)也值得注意:
+history-list与+history-revert-status需要slides:presentation:read;+history-revert属于写操作,需要slides:presentation:update与slides:presentation:write_only;- 三个命令都声明了条件权限
wiki:node:read——只有当--presentation传入的是 wiki URL 时才需要额外解析; - 三者均支持
user与bot两种身份(AuthTypes)。
--presentation的取值支持三种形态(requiredPresentationRefFlag定义):xml_presentation_id、Slides URL,或可解析为 Slides 的 wiki URL。当传入 wiki URL 时,执行期会先调用 wiki 节点解析接口(/open-apis/wiki/v2/spaces/node_by_token)把 wiki 节点解析为真实的 slides token,再拼接上述端点——这一点在单元测试 TestSlidesHistoryExecuteResolvesWikiPresentation 中通过 mock 验证:先返回obj_type: slides与obj_token,随后才发起histories请求。
安全流程:七步完成一次可信回滚
为了不让"回滚"这个高风险操作出现误判、误回滚或重复提交,CLI 定义了一条标准安全流程:
- 先用分页接口
+history-list找到目标版本的history_version_id。+history-list是分页接口,返回has_more与page_token,需要继续翻页时再传--page-token。 - 如果用户指定的是
revision_id:不要假设它唯一,也不要把revision_id直接传给+history-revert。先拉一页并在entries[]中筛选revision_id相同的候选;如果未匹配到且has_more=true,继续用page_token翻页;如果已匹配到候选,最多额外再拉一页补齐可能跨页的相邻候选。最终优先根据用户目标时间与edit_time的接近程度选择最合适的一条,取同一条的history_version_id;如果没有目标时间、或多个候选无法可靠区分,则向用户展示候选版本并确认后回滚。 - 如果用户指定的是某一时刻但没有指定
revision_id:按entries[].edit_time匹配,优先选择不晚于目标时刻的最近一条历史记录;无法明确匹配时先向用户确认候选版本。 - 使用
+history-revert发起回滚:接口立即返回task_id,回滚任务在服务端异步执行。 - 如果返回
status: running:保存task_id,按照返回的poll_after_ms等待后调用+history-revert-status。任务创建成功后,不得因为状态查询失败而重新发起回滚。 - 停止条件:状态变为
done、partial_failed或failed后停止轮询;达到整体轮询上限时也停止轮询,并向用户返回task_id和当前状态。 - 回滚完成后验证:用
slides +xml-get读取演示文稿内容确认。
这条流程把"定位→确认→提交→轮询→验证"串成闭环,每一步都避免了对服务端状态的猜测,是 Agent 与人类用户共用同一套命令时的可靠基线。
按 revision_id 或时间点回滚的智能匹配策略
当用户表达"回滚到 revision_id=42""恢复到昨天下午 3 点的版本"这类需求时,Agent 应当执行如下细化流程:
- 执行
slides +history-list --presentation <presentation>获取第一页历史记录;只有has_more=true且还需要更多候选时才继续传--page-token翻页。 - 用户给出
revision_id时:- 先筛选当前页中
entries[].revision_id == 用户给出的 revision_id; - 未命中且
has_more=true,继续拉下一页; - 已命中候选,最多额外再拉一页,补齐同一个
revision_id可能跨页出现的相邻history_version_id; - 若用户同时给出目标时间,在候选里选择
edit_time与目标时间最接近的一条; - 若未给目标时间但候选只有一条,可直接使用;
- 若多个候选无法可靠区分,不要自行取第一条,向用户展示候选并确认。
- 先筛选当前页中
- 用户只给出时间时:用
entries[].edit_time匹配,选择目标时刻之前最近的一条;如果用户表达的是"最接近某时刻",则选择绝对时间差最小的一条。 - 从最终匹配条目读取
history_version_id(对应服务端minor_history.version)。 - 执行
slides +history-revert --presentation <presentation> --history-version-id <history_version_id>。
候选确认时使用类似格式,让用户能一眼区分:
同一个 revision_id 命中多个历史版本,请确认要回滚哪一条: - history_version_id=11 revision_id=42 edit_time=2026-06-22T12:24:45Z name=... - history_version_id=12 revision_id=42 edit_time=2026-06-22T12:25:14Z name=...这里有一个时间格式约定必须遵守:entries[].edit_time是UTC RFC3339 时间字符串(例如2026-06-22T12:24:45Z)。按时间匹配时先将其解析为时间值,再比较先后关系或时间差,不要做字符串比较。
命令与参数速查
# 列出历史版本 lark-cli slides +history-list --presentation "<slides_url_or_token>" --page-size 20 # 翻页 lark-cli slides +history-list --presentation "<slides_url_or_token>" --page-size 20 --page-token "<page_token>" # 发起回滚任务,立即返回 task_id lark-cli slides +history-revert --presentation "<slides_url_or_token>" --history-version-id 42 # 查询回滚任务状态 lark-cli slides +history-revert-status --presentation "<slides_url_or_token>" --task-id "<task_id>"完整参数说明如下(与源码 Flag 定义一致):
| 命令 | 参数 | 必填 | 说明 | |-|-|-|-| |+history-list|--presentation| 是 |xml_presentation_id、Slides URL,或可解析为 Slides 的 wiki URL | |+history-list|--page-size| 否 | 返回条数,范围1-20,默认20| |+history-list|--page-token| 否 | 上一页返回的page_token| |+history-revert|--presentation| 是 | 同一个演示文稿 | |+history-revert|--history-version-id| 是 |+history-list返回的history_version_id,必须大于 0 | |+history-revert-status|--presentation| 是 | 同一个演示文稿 | |+history-revert-status|--task-id| 是 |+history-revert返回的task_id|
参数校验在源码层面对齐了文档约束(见 shortcuts/slides/slides_history.go 中的validateSlidesHistoryPageSize与validateSlidesHistoryVersionID):
--page-size必须落在1-20,越界报ValidationError;--history-version-id必须是正整数字符串(strconv.ParseInt失败或<= 0均拒绝),错误信息明确提示"必须是slides +history-list返回的正整数";--task-id不允许为空。
对应地,TestSlidesHistoryValidation 覆盖了"page-size 传 0""history-version-id 传 abc / 0""task-id 传空串"等边界用例,断言错误均带正确的参数名(--page-size、--history-version-id、--task-id)。
异步轮询策略:边界条件与失败语义
由于回滚是异步任务,轮询策略决定了流程的健壮性。标准策略如下:
+history-revert返回task_id后,认为回滚任务已经成功创建。- 如果
status不是running,不再调用状态接口(任务可能已同步完成)。 - 如果
status是running,等待响应中的poll_after_ms后调用+history-revert-status;poll_after_ms缺失、为0或非法时,默认等待 10 秒。 - 状态查询返回
running时继续轮询;返回done、partial_failed或failed时停止。 - 除非用户另有要求,默认最多轮询5 分钟。达到上限后停止轮询,向用户说明任务仍在运行并返回
task_id,不得将其描述为回滚失败。 - 状态查询出现临时错误时,按相同间隔最多连续重试 3 次;只重试
+history-revert-status,不得重新调用+history-revert(避免重复回滚)。 done后读取当前演示文稿内容进行验证。partial_failed或failed时展示failed_block_tokens;除非用户明确确认,不得自动再次发起回滚。
这条策略的关键点可以浓缩为三条底线:任务创建后不重复提交、轮询超时不等于失败、失败后的再次回滚必须经用户确认。
返回值要点
+history-list返回(分页结构):
{ "entries": [ { "revision_id": 42, "history_version_id": "11", "edit_time": "2026-06-22T12:24:45Z", "type": 1, "name": "版本名", "description": "版本说明", "editor_ids": ["ou_xxx"] } ], "has_more": true, "page_token": "page_token" }+history-revert返回(异步任务创建确认):
{ "task_id": "task_xxx", "status": "running", "history_version_id": "11", "poll_after_ms": 10000 }+history-revert-status返回:
{ "status": "partial_failed", "history_version_id": "11", "failed_block_tokens": ["blk_xxx"] }status可能的取值为running、done、partial_failed、failed。当状态是partial_failed或failed时,优先检查failed_block_tokens——它列出了回滚失败的块(block)标识,是向用户说明失败范围的关键依据。
回滚后验证
回滚成功后必须读取一次当前内容确认,这也是安全流程的最后一步:
lark-cli slides +xml-get --presentation "<slides_url_or_token>" --output ./presentation.xml+xml-get的实现见 shortcuts/slides/slides_xml_get.go:--output指定本地 XML 输出路径(现有文件会被覆盖),也可省略--output让 XML 以 JSON envelope 形式返回,或用--raw直接打印原始 XML 到 stdout;--revision-id默认-1表示最新版本。回滚验证时读取最新内容,确认目标版本内容已生效。
从源码与测试看实现保障
参数与请求构造
三个命令的请求构造非常规整:
+history-list:GET,Query 参数page_size、page_token(slidesHistoryListParams中仅在非空时才带上page_token);+history-revert:POST,请求体为{"history_version_id": "..."}(slidesHistoryRevertBody),且不包含wait_timeout_ms这类等待参数——TestSlidesHistoryDryRun 与 TestSlidesHistoryDryRunE2E 都专门断言了 revert 请求体不得出现wait_timeout_ms,说明回滚被刻意设计为纯异步提交,不依赖同步等待;+history-revert-status:GET,Query 参数task_id。
Dry-run 与两步编排
+history-list等命令支持--dry-run预演。对普通 token 只需一步:GET /open-apis/slides_ai/v1/xml_presentations/{id}/histories;对 wiki URL 则是两步编排:先GET /open-apis/wiki/v2/spaces/node_by_token解析 wiki 节点,再发起历史版本请求(dry-run 中占位为<resolved_slides_token>)。TestSlidesHistoryDryRunWithWikiPresentation 断言两步调用依次出现,TestSlidesHistoryDryRunE2E 在真实 CLI 进程上验证了三个命令 dry-run 的端点、方法与参数。
E2E 工作流测试
最完整的证据来自端到端工作流测试 TestSlidesHistoryWorkflow(通过设置环境变量LARK_SLIDES_HISTORY_E2E=1并携带 user token 开启)。它完整走了一遍真实回滚链路:
slides +create创建演示文稿,记录原始内容 marker 与revision_id;slides +update-slide写入更新 marker,确认revision_id增大;- 轮询
+history-list,在entries[]中按revision_id匹配出原始版本的history_version_id; +history-revert发起回滚,若status == "running"则用task_id轮询+history-revert-status直到非running;- 断言最终状态为
done,再读取整篇 XML 确认内容恢复为原始 marker。
这个测试同时验证了文档中反复强调的两点:按revision_id在历史记录中定位history_version_id的可行性,以及回滚后必须读回内容做验证的必要性。
常见场景速记
| 用户诉求 | 推荐动作 | |-|-| | "回滚到 revision_id=42" | 翻页筛选revision_id == 42的候选,必要时补拉一页,确认后取history_version_id回滚 | | "恢复到昨天下午 3 点" | 按edit_time匹配目标时刻之前最近的记录 | | "最接近某时刻的版本" | 按edit_time与目标时刻的绝对时间差取最小 | | 回滚后想看结果 |+xml-get读取当前 XML 确认内容 | | 任务一直 running | 按poll_after_ms(默认 10s)轮询,整体上限默认 5 分钟,超时返回task_id而非报失败 |
结合 skills/lark-slides/references/cli/lark-slides-history.md 原文档、skills/lark-slides/SKILL.md 的技能约束以及 shortcuts/slides/slides_history.go 的实现,这套"定位版本 → 确认候选 → 异步回滚 → 轮询状态 → 读回验证"的闭环已经足够支撑人类用户与 AI Agent 在飞书/Lark 幻灯片上安全、可审计地完成任意历史版本回滚。
- CLI
- AI 技能
【免费下载链接】cli
The official Lark/飞书 CLI tool, maintained by the larksuite team — built for humans and AI Agents. Covers core business domains including Messenger, Docs, Base, Sheets, Calendar, Mail, Tasks, Meetings, and more, with 200+ commands and 20+ AI Agent Skills.
相关推荐
飞书 CLI(lark-cli)Docx 历史版本管理:+history-list / +history-revert / +history-revert-status 回滚实战指南
飞书 CLI(lark cli)Docx 历史版本管理:+history list / +history revert / +history revert st
CLIAI 技能lark-cli Base 记录变更历史查询:`+record-history-list` 命令实战与实现原理
lark cli Base 记录变更历史查询: +record history list 命令实战与实现原理 导读 +record history list 是
CLIAI 技能飞书 CLI slides 领域命令全景指南:从 lark-slides 技能体系到幻灯片创建、编辑与回滚实战
飞书 CLI slides 领域命令全景指南:从 lark slides 技能体系到幻灯片创建、编辑与回滚实战 本文基于当前仓库中 affordance/sli
CLIAI 技能
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考