飞书知识库空间盘点:lark-cli 的 wiki +space-list 命令使用与分页机制全解
【免费下载链接】cliThe 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.项目地址: https://gitcode.com/gh_mirrors/cli414/cli
导读
wiki +space-list是 Lark/飞书 CLI(lark-cli)提供的知识库(Wiki)核心只读命令,用于列出调用方当前可访问的所有知识空间(Wiki Space),并内置了与 CLI 其余 list 类快捷命令一致的单页默认策略与完整的分页游标机制。本文以 lark-wiki-space-list.md 为骨架,结合仓库源码(wiki_space_list.go)与端到端测试(wiki_shortcut_workflow_test.go)逐项展开:读完本文,你将掌握该命令的全部参数语义、JSON/pretty 等输出格式、游标续页与--page-all的取舍策略、my_library个人知识库的边界,以及如何用返回的space_id衔接+node-list/+node-copy等下游命令。
命令概览:一条命令盘点全部知识空间
在 lark-wiki 技能包的 Shortcuts 体系中,+space-list被定义为“List wiki spaces accessible to the caller”(列出调用方可访问的知识空间),风险等级为read,支持user与bot两种身份,并声明了最窄权限范围wiki:space:retrieve(源码见 wiki_space_list.go)。
默认行为:与 CLI 其他 list 类快捷命令保持一致,默认只抓取一页(每页最多--page-size条)。要遍历全部空间,必须显式传入--page-all,并受--page-limit(默认 10 页)上限约束。这一默认策略在源码注释中有明确说明:Default fetches a single page (matches other list shortcuts in this CLI)。
使用方式与典型场景
最简用法:单页查看
# 默认:单页(最多 --page-size 条) lark-cli wiki +space-list # 显式指定身份为 user(知识空间是用户中心资源,见下文“身份选择”) lark-cli wiki +space-list --as user遍历全部空间
# 遍历每一页(受 --page-limit 上限约束,默认 10 页) lark-cli wiki +space-list --page-all # 遍历每一页且不设上限(空间很多时慎用) lark-cli wiki +space-list --page-all --page-limit 0从游标续页
# 从指定游标续页(无论是否带 --page-all,都按单页获取) lark-cli wiki +space-list --page-token <TOKEN>不同输出格式
lark-cli wiki +space-list --format pretty lark-cli wiki +space-list --format table lark-cli wiki +space-list --format csv lark-cli wiki +space-list --format ndjson参数详解(Flags)
| Flag | 类型 | 默认值 | 说明 |
|---|---|---|---|
--page-size | int | 50 | 每页条数,取值范围 1–50 |
--page-token | string | — | 分页游标;一旦指定即视为单页获取(不自动翻页) |
--page-all | bool | false | 自动翻页拉取所有页(受--page-limit上限约束) |
--page-limit | int | 10 | --page-all模式下最多拉取页数(0 表示不设上限) |
--format | enum | json | json/pretty/table/csv/ndjson |
--as | enum | auto | 身份user/bot;知识空间是用户中心资源,建议显式传--as user |
源码级佐证:这些 flag 的定义与默认值直接声明在 wiki_space_list.go 的common.Shortcut.Flags中,其中page-size的默认值来自常量wikiSpaceListDefaultPageSize = 50,取值范围上限来自wikiSpaceListMaxPageSize = 50。
校验逻辑:非法参数直接拦截
命令内置了参数预校验validateWikiListPagination(wiki_space_list.go),在任何网络请求发出之前就会拒绝非法输入:
--page-size必须落在1 ~ 50之间,否则报--page-size must be between 1 and 50(错误子类型SubtypeInvalidArgument);--page-limit必须是非负整数,否则报--page-limit must be a non-negative integer。
该校验函数同时被+space-list与+node-list共享(注释中明确说明shared by +space-list and +node-list),确保两个 list 命令的分页语义完全一致。
输出结构解析
默认 JSON 输出采用 CLI 统一的外层信封结构(ok+data+meta):
{ "ok": true, "data": { "spaces": [ { "space_id": "6946843325487912356", "name": "Engineering Wiki", "description": "...", "space_type": "team", "visibility": "private", "open_sharing": "closed" } ], "has_more": false, "page_token": "" }, "meta": { "count": 1 } }字段语义:
| 字段 | 说明 |
|---|---|
data.spaces[] | 空间列表,每项含space_id、name、description、space_type、visibility、open_sharing六个字段 |
data.has_more | 上游是否还有更多页 |
data.page_token | 下一页游标(无更多页时为空字符串) |
meta.count | 本次返回的空间数量 |
稳定信封契约(有端到端测试保证):在 wiki_shortcut_workflow_test.go 中,QA-P1 用例对+space-list的输出做了严格断言:
data.spaces必须始终存在且是数组——即使为空也是[]而不是null(源码中fetchWikiSpaces返回的切片始终非 nil,注释明确写道The returned slice is always non-nil so json output stays as [] instead of null,见 wiki_space_list.go);data.has_more与data.page_token必须始终存在,绝不省略,以便下游 Agent 无论是否触发翻页上限都能据此续页;meta.count必须等于len(data.spaces)(count 为 0 时该字段被omitempty省略,这是信封框架的既有行为,测试注释对此有说明)。
续页信号:当默认单页获取(或--page-all被--page-limit截断)未能耗尽上游游标时,返回has_more=true且page_token=<cursor>,调用方可以:
- 用
--page-token <cursor>继续拉取;或 - 调大
--page-limit重新--page-all。
pretty 格式的行为细节
--format pretty走独立渲染器renderWikiSpacesPretty(wiki_space_list.go),有几处值得注意的细节:
- 空结果时输出
No wiki spaces found.; - 若“当前页为空但服务端报告还有更多页”(即
has_more=true且page_token非空),会输出Current page is empty but the server reports more pages.并提示使用--page-all或--page-token续页——这是对“这页真没有 vs 还没翻完”两种情况的刻意区分,避免调用方在翻页未完时误判为无数据; - 每项按
[序号] 名称展示,随后缩进列出space_id、space_type、visibility、open_sharing与可选的description;缺失字段统一以-占位(valueOrDash); - 列表末尾若还有下一页,会打印
Next page token: <cursor>。
底层实现:分页循环如何工作
fetchWikiSpaces(wiki_space_list.go)是命令的核心执行逻辑,它把四个分页 flag 组合成三种行为模式:
- 默认(无
--page-all、无--page-token):从起点抓取一页即返回; --page-token X:从游标 X 开始抓取一页(自动翻页被禁用);--page-all:持续抓取后续页面,直到has_more=false、游标耗尽、或达到--page-limit(默认 10 页;0 表示不设上限)。
每次请求都打到飞书开放平台GET /open-apis/wiki/v2/spaces(常量wikiSpacesAPIPath),携带page_size(以及需要时的page_token)参数,通过runtime.CallAPITyped发起。循环结束后返回最后一个页面的has_more/page_token作为信封字段,保证调用方总能拿到真实的续页信号。
两个防御性设计:
--page-token优先:wikiListShouldAutoPaginate(wiki_space_list.go)明确规定——只要显式传了--page-token,就绝不自动翻页(--page-all被忽略)。因为调用方已经给出了明确的游标,自动翻页反而可能打乱续页语义;- 冲突提示:
warnIfConflictingPagingFlags(wiki_space_list.go)在同时传--page-token与--page-all时向 stderr 打印警告--page-token is set, so --page-all is ignored,避免调用方误以为两个 flag 会叠加生效。
Dry-run 支持:DryRun实现(wiki_space_list.go)会构造出将要发出的 GET 请求(含page_size/page_token参数),并显式标注“Auto-paginates through all pages (capped by --page-limit when > 0)”来提示调用方翻页循环是否会触发——方便在不实际请求的情况下验证分页行为。
身份选择:为什么建议显式传 --as user
知识空间与节点本质上是用户的个人资源。CLI 的--as默认值是auto,不带--as时常被解析为bot,此时列出的是应用(tenant_access_token)所属的空间,而不是用户的空间。因此 lark-wiki/SKILL.md 的策略明确要求:知识库相关操作优先显式使用--as user,仅在用户明确要求“应用 / bot 视角”时才用--as bot。
这一点同样贯穿到下游:+node-list的--space-id my_library别名只对--as user有效,bot 身份下会被提前拒绝并给出明确提示(源码见 wiki_node_list.go)。
与 my_library 的边界:列表 API 永远不返回个人知识库
一个容易踩坑的事实:底层列表 API 永远不会返回my_library个人知识库。调用方可访问的空间列表里不会有它。需要个人知识库时,必须通过 get 类操作显式解析:
lark-cli wiki spaces get --params '{"space_id":"my_library"}'该别名在源码中以常量wikiMyLibrarySpaceID = "my_library"定义(wiki_node_create.go),并通过resolveMyLibrarySpaceID(wiki_node_create.go)调用GET /open-apis/wiki/v2/spaces/my_library解析出用户真实的数字space_id,供+node-create、+node-list等接受该别名的快捷命令共享使用——这也是为什么+space-list的结果中看不到它:它属于用户个人库,不属于可枚举的空间集合。
下游衔接:把 space_id 用起来
+space-list的输出价值在于产出真实的数字space_id,它是后续 Wiki 操作的核心入参:
# 1. 盘点空间,拿到 space_id lark-cli wiki +space-list --as user # 2. 列出某空间根节点(默认单页) lark-cli wiki +node-list --space-id 6946843325487912356 # 3. 把节点复制到目标空间(--space-id 指目标空间) lark-cli wiki +node-copy --space-id 6946843325487912356 --node-token <NODE_TOKEN> ...对应关系在文档与源码中都有明确约定:+space-list的 Notes 部分指出“Usespace_idfrom the output as--space-idfor+node-listor+node-copy”;wiki_node_list.go 的校验逻辑更是硬性要求--space-id必须是数字形式的 wikispace_id——传入 URL、节点 token、文档 token 或标题都会被拒绝,并提示先运行lark-cli wiki +space-list --as user获取正确的 ID。
权限要求
调用该命令需要以下权限范围:
| 项 | 值 |
|---|---|
| Required Scope | wiki:space:retrieve |
源码中对该范围的选择有一处值得注意的设计考量(wiki_space_list.go 的注释):上游 API 实际接受wiki:wiki/wiki:wiki:readonly/wiki:space:retrieve三种范围中的任意一种,但由于框架的 preflight 做的是精确字符串匹配(见 internal/auth/scope.go),如果声明更宽的只读形式,反而会错误拒绝那些只携带窄范围wiki:space:retrieve的 token,并给出误导性的“缺权限”提示。因此命令故意声明最窄范围,以与真实携带的 token 精确对齐。
结语
wiki +space-list虽然是一条只读的“盘点”命令,但它的分页策略、信封契约与身份语义是整个 Wiki 快捷命令体系的样板:理解它,就等于理解了+node-list、+member-list等兄弟命令的通用行为模式。实际使用时记住三条核心心法即可:
- 默认单页,要全量就
--page-all,并随时用--page-limit(或--page-token)控制节奏; - 显式
--as user,因为知识空间是用户中心资源,auto常被解析成 bot 而看不到用户的空间; space_id是硬通货——从本命令的输出中取数字space_id,再喂给+node-list/+node-copy/+node-create,不要传 URL 或名称。
【免费下载链接】cliThe 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.项目地址: https://gitcode.com/gh_mirrors/cli414/cli
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考