forked from AxTps/Starlight_Lancher
feat:移除了弹窗,服务器添加sls
This commit is contained in:
115
.agents/skills/lark-wiki/SKILL.md
Normal file
115
.agents/skills/lark-wiki/SKILL.md
Normal file
@ -0,0 +1,115 @@
|
||||
---
|
||||
name: lark-wiki
|
||||
version: 1.0.3
|
||||
description: "飞书知识库:管理知识空间、空间成员和文档节点。创建和查询知识空间、查看和管理空间成员、管理节点层级结构、在知识库中组织文档和快捷方式。当用户需要在知识库中查找或创建文档、浏览知识空间结构、查看或管理空间成员、移动或复制节点时使用。当用户给出 doubao.com 的 /wiki/ URL/token 时,也应直接使用本 skill,不要因为域名不是飞书而回退到 WebFetch;路由依据是 URL 路径模式和 token,而不是域名。不负责:上传文件到知识库节点下(走 lark-drive)、编辑文档/表格/Base 内容(走 lark-doc / lark-sheets / lark-base)。"
|
||||
metadata:
|
||||
requires:
|
||||
bins: ["lark-cli"]
|
||||
cliHelp: "lark-cli wiki --help"
|
||||
---
|
||||
|
||||
# wiki (v2)
|
||||
|
||||
**CRITICAL — 开始前 MUST 先用 Read 工具读取 [`../lark-shared/SKILL.md`](../lark-shared/SKILL.md),其中包含认证、权限处理**
|
||||
|
||||
> **成员管理硬限制:**
|
||||
> - 如果目标是“部门”,先判断身份,再决定是否继续。
|
||||
> - `--as bot` 对应 `tenant_access_token`。官方限制:这种身份下不能使用部门 ID (`opendepartmentid`) 添加知识空间成员。
|
||||
> - 遇到“部门 + --as bot”时,禁止先调用 `lark-cli wiki +member-add` 试错;直接说明该路径不可行。
|
||||
> - 如果用户明确要求“以 bot 身份运行”,且目标是部门,必须停下说明 bot 路径无法完成,不要静默切到 `--as user`。
|
||||
|
||||
## 身份选择:优先使用 user 身份
|
||||
|
||||
知识空间和节点都是用户的个人资源,**策略上应优先显式使用 `--as user`**(CLI 的 `--as` 默认值为 `auto`,不带 `--as` 时常被解析成 `bot`,列出的是应用所属空间而非用户的)。仅当用户明确要求“应用 / bot 视角”时才用 `--as bot`(仍受上面的成员管理硬限制约束)。
|
||||
|
||||
## 快速决策
|
||||
|
||||
- 用户要**按特定主题 / 关键词 / 内容线索查找资料并收集到知识库节点或新建知识库节点下**,必须先阅读 [`../lark-drive/references/lark-drive-workflow.md`](../lark-drive/references/lark-drive-workflow.md),再按其中 `Workflow Registry` 进入 [`topic_move_collector`](../lark-drive/references/lark-drive-workflow-topic-move-collector.md) workflow。该 workflow 使用 Drive 全量搜索召回,再按 Wiki 目标解析、确认和移动;不要只用 Wiki 节点列表做局部遍历。
|
||||
- 用户要**整理 / 盘点 / 归类 / 重构知识库、个人文档库、文档库目录或 Wiki 节点结构**,或要生成整理方案、目标目录树、移动计划时,不要只使用 Wiki 节点 API。必须先阅读 [`../lark-drive/references/lark-drive-workflow.md`](../lark-drive/references/lark-drive-workflow.md),再按其中 `Workflow Registry` 进入 [`knowledge_organize`](../lark-drive/references/lark-drive-workflow-knowledge-organize.md) workflow;该 workflow 负责 Drive / Wiki / 个人文档库的统一入口解析、资源盘点、分类计划、写前确认和结果验证。
|
||||
- 用户要把**已有 Wiki 节点移出知识库,放到 Drive 文件夹或“我的空间”根目录**:使用 `wiki +move-to-drive`,不要使用 `wiki +move` 或 `drive +move`。这是会改变节点归属和权限继承的写操作,执行前确认源节点与目标位置。
|
||||
- 用户给的是知识库 URL(`.../wiki/<token>`),且后续要查成员/加成员/删成员:先调用 `lark-cli wiki spaces get_node --params '{"token":"<wiki_token>"}'` 获取 `space_id`,后续成员接口统一使用 `space_id`。
|
||||
- 用户要**删除**知识空间(`wiki +delete-space`)但只给了名称或 URL:**不能**把名称 / URL 原样传给 `--space-id`,必须先解析出真实 `space_id`。解析方式:
|
||||
- URL(`.../wiki/<token>`):`lark-cli wiki spaces get_node --params '{"token":"<wiki_token>"}' --format json`,读 `data.node.space_id`。
|
||||
- 只知名称:`lark-cli wiki spaces list --format json`,边翻页边收集 items 并按 `name` 精确匹配;**一旦任一页累计到至少 1 条精确匹配就停止翻页**。只有当翻完所有页(`has_more=false`)仍无精确匹配时,才对已收集的全量 items 做宽松匹配(`name` trim 空格、大小写不敏感、子串包含)。
|
||||
- **关键安全约束**:无论精确还是模糊,**无论命中 1 条还是多条,发起删除前都必须把候选(`name` + `space_id` + `description` + `space_type`)列给用户,由用户明确选定一个 `space_id` 再执行**。不要因为"只命中一条"就自动执行删除。
|
||||
- 命中 0 条:停下来问用户是名称拼错了还是调用方无权限;**不要**自行改名字重试。
|
||||
- 用户明确选定后再执行 `lark-cli wiki +delete-space --space-id <ID> --yes`(高风险写操作,必须显式 `--yes`)。
|
||||
- 反例:不要把 wiki URL / 名称直接当 `--space-id`(如 `--space-id "https://.../wiki/<wiki_token>"`);务必先用 `wiki spaces get_node` 解析出 `data.node.space_id` 再传。
|
||||
- 用户要在知识库中创建新节点,优先使用 `lark-cli wiki +node-create`。
|
||||
- 用户要列出 Wiki 节点:先用 `wiki +space-list --as user` 拿数字 `space_id`,再用 `wiki +node-list --space-id <space_id>`。不要把 wiki URL、node token、doc token、名称直接当 `--space-id`。钻子节点时 `--parent-node-token` 必须是 wiki node token;如果用户给的是 docx/sheet/base URL,先用 `wiki +node-get --node-token <url>` 解析出 `node_token`。
|
||||
- `wiki +node-list` 命中 `invalid_parameters`、`not_found`、`permission_denied` 时,不要重复调用同一参数;按 hint 修 `space_id` / `parent_node_token` / 权限。只有 `rate_limit` 才做退避重试。
|
||||
- 用户说“给知识库添加成员/管理员”:先把目标解析成“用户 / 群 / 部门 / 应用”四类之一,再决定 `--member-type`,不要先调 `wiki +member-add` 再根据报错反推类型。
|
||||
- 用户说“部门 + bot”:这是已知不支持路径。不要继续尝试 `wiki +member-add --as bot`;直接提示必须改成 `--as user`,或明确告知当前要求无法完成。
|
||||
- 用户说“用户 / 群 / 应用 + 添加成员”:先解析对应 ID,再执行 `wiki +member-add`。
|
||||
- 用户说“查看 / 列出空间成员”:用 `wiki +member-list`;该 shortcut 默认只取一页,多成员场景显式加 `--page-all`。
|
||||
- 用户说“移除 / 删除空间成员”:用 `wiki +member-remove`,必须传齐原始授予时的 `--member-type` 和 `--member-role`(不知道就先 `wiki +member-list` 查一下)。
|
||||
|
||||
## Shortcuts(推荐优先使用)
|
||||
|
||||
Shortcut 是对常用操作的高级封装(`lark-cli wiki +<verb> [flags]`)。有 Shortcut 的操作优先使用。
|
||||
|
||||
| Shortcut | 说明 |
|
||||
|----------|------|
|
||||
| [`+move`](references/lark-wiki-move.md) | Move a wiki node, or move a Drive document into Wiki |
|
||||
| [`+move-to-drive`](references/lark-wiki-move-to-drive.md) | Move a wiki node to a Drive folder and poll the async task |
|
||||
| [`+node-create`](references/lark-wiki-node-create.md) | Create a wiki node with automatic space resolution |
|
||||
| [`+delete-space`](references/lark-wiki-delete-space.md) | Delete a wiki space, polling the async delete task when needed |
|
||||
| [`+space-list`](references/lark-wiki-space-list.md) | List all wiki spaces accessible to the caller |
|
||||
| [`+space-create`](references/lark-wiki-space-create.md) | Create a wiki space (user identity only) |
|
||||
| [`+node-list`](references/lark-wiki-node-list.md) | List wiki nodes in a space or under a parent node (supports pagination) |
|
||||
| [`+node-copy`](references/lark-wiki-node-copy.md) | Copy a wiki node to a target space or parent node |
|
||||
| [`+node-get`](references/lark-wiki-node-get.md) | Get a wiki node's details by node_token / obj_token / Lark URL |
|
||||
| [`+node-delete`](references/lark-wiki-node-delete.md) | Delete a wiki node, polling the async delete task when needed |
|
||||
| [`+member-add`](references/lark-wiki-member-add.md) | Add a member to a wiki space |
|
||||
| [`+member-remove`](references/lark-wiki-member-remove.md) | Remove a member from a wiki space |
|
||||
| [`+member-list`](references/lark-wiki-member-list.md) | List members of a wiki space (supports pagination) |
|
||||
|
||||
## 成员添加流程
|
||||
|
||||
- 调用 `lark-cli wiki +member-add` 前,先把自然语言里的“人 / 群 / 部门 / 应用”解析成正确的 `--member-id`,不要猜格式。
|
||||
- 用户场景默认优先 `--member-type=openid`:用 `lark-cli contact +search-user --query "<姓名/邮箱/手机号>" --format json` 获取 `open_id`。
|
||||
- 群组场景使用 `--member-type=openchat`:用 `lark-cli im +chat-search --query "<群名关键词>" --format json` 获取 `chat_id`。
|
||||
- 应用场景使用 `--member-type=appid`:`--member-id` 传应用 ID,格式通常为 `cli_xxx`。
|
||||
- `userid` / `unionid` 只在下游明确要求时才使用;先拿到 `open_id`,再调用 `lark-cli api GET /open-apis/contact/v3/users/<open_id> --params '{"user_id_type":"open_id"}' --format json` 读取 `user_id` / `union_id`。
|
||||
- 部门场景使用 `--member-type=opendepartmentid`:当前 CLI 没有 shortcut,需调用 `lark-cli api POST /open-apis/contact/v3/departments/search --as user --params '{"department_id_type":"open_department_id"}' --data '{"query":"<部门名>"}'` 获取 `open_department_id`。
|
||||
- 只有在目标类型和身份都已确认可行后,才调用 `lark-cli wiki +member-add`。对于部门场景,这意味着必须是 `--as user`。
|
||||
|
||||
## 目标语义约束
|
||||
|
||||
- `我的文档库` / `My Document Library` / `我的知识库` / `个人知识库` / `my_library` 都应视为 **Wiki personal library**,不是 Drive 根目录
|
||||
- 处理这类目标时,先解析 `my_library` 对应的真实 `space_id`,再执行 `wiki +move`、`wiki +node-create` 或其他 Wiki 写操作
|
||||
- 不要因为缺少显式 `space_id` 就退化成 `drive +move`
|
||||
- 如果用户明确说的是 Drive 文件夹、云空间(云盘/云存储)根目录、`我的空间`,再按源对象分流:源对象是 Wiki 节点时用 `wiki +move-to-drive`,源对象已在 Drive 时用 `drive +move`
|
||||
|
||||
## API Resources
|
||||
|
||||
```bash
|
||||
lark-cli schema wiki.<resource>.<method> # 调用原生 API 前必须先查看 --data / --params 参数结构,不要猜测字段格式
|
||||
lark-cli wiki <resource> <method> [flags] # 调用 API
|
||||
```
|
||||
|
||||
### spaces
|
||||
|
||||
- `create` — 创建知识空间
|
||||
- `get` — 获取知识空间信息
|
||||
- `get_node` — 获取知识空间节点信息
|
||||
- `list` — 获取知识空间列表
|
||||
|
||||
### members
|
||||
|
||||
- `create` — 添加知识空间成员
|
||||
- `delete` — 删除知识空间成员
|
||||
- `list` — 获取知识空间成员列表
|
||||
|
||||
### nodes
|
||||
|
||||
- `copy` — 创建知识空间节点副本
|
||||
- `create` — 创建知识空间节点
|
||||
- `list` — 获取知识空间子节点列表
|
||||
|
||||
## 不在本 skill 范围
|
||||
|
||||
- 上传 / 下载文件到知识库节点下 → [`lark-drive`](../lark-drive/SKILL.md)(`drive +upload --wiki-token`)
|
||||
- 编辑文档正文内容 → [`lark-doc`](../lark-doc/SKILL.md)
|
||||
- 表格 / 多维表格数据操作 → [`lark-sheets`](../lark-sheets/SKILL.md) / [`lark-base`](../lark-base/SKILL.md)
|
||||
- 按名称搜索文档 / Wiki / 表格文件、评论与权限管理 → [`lark-drive`](../lark-drive/SKILL.md)
|
||||
205
.agents/skills/lark-wiki/references/lark-wiki-delete-space.md
Normal file
205
.agents/skills/lark-wiki/references/lark-wiki-delete-space.md
Normal file
@ -0,0 +1,205 @@
|
||||
# wiki +delete-space
|
||||
|
||||
> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
|
||||
|
||||
删除一个飞书知识空间(知识库)。OpenAPI 对应 `DELETE /open-apis/wiki/v2/spaces/:space_id`。
|
||||
|
||||
- **不可逆**:该操作会将知识空间连同其下所有节点彻底删除,执行前必须反复确认
|
||||
- **同步 / 异步两种返回**:
|
||||
- 如果接口直接返回空 `task_id`,说明删除同步完成,shortcut 立即返回 `ready=true`
|
||||
- 如果接口返回非空 `task_id`,shortcut 会先对任务做有限轮询;轮询窗口内仍未完成会输出 `next_command`,引导调用方使用 `lark-cli drive +task_result --scenario wiki_delete_space --task-id <TASK_ID>` 继续查
|
||||
|
||||
## 命令
|
||||
|
||||
```bash
|
||||
# 同步或异步删除一个知识空间(必须显式加 --yes 确认)
|
||||
lark-cli wiki +delete-space \
|
||||
--space-id <SPACE_ID> \
|
||||
--yes
|
||||
|
||||
# 预览底层调用链(不会真的删除)
|
||||
lark-cli wiki +delete-space \
|
||||
--space-id <SPACE_ID> \
|
||||
--dry-run
|
||||
```
|
||||
|
||||
## 参数
|
||||
|
||||
| 参数 | 必填 | 说明 |
|
||||
|------|------|------|
|
||||
| `--space-id` | 是 | 要删除的知识空间 ID |
|
||||
| `--yes` | 是(真删时) | 高风险写操作确认。不传则 CLI 直接返回 `unsafe_operation_blocked` 错误 |
|
||||
|
||||
## 行为说明
|
||||
|
||||
- **请求**:对 `/open-apis/wiki/v2/spaces/{space_id}` 发送 `DELETE`
|
||||
- **同步返回**:响应 `data.task_id` 为空字符串时直接返回 `ready=true`、`failed=false`、`status_msg="success"`
|
||||
- **异步返回**:响应 `data.task_id` 非空时进入有限轮询
|
||||
- **任务轮询**:调用 `GET /open-apis/wiki/v2/tasks/{task_id}?task_type=delete_space`,读取 `data.task.delete_space_result.status`
|
||||
- `status=success` → `ready=true`
|
||||
- `status=failure` / `status=failed` → 返回错误(`wiki delete-space task failed: <status_msg 或 status>`)
|
||||
- 其他值(如 `processing`、`running`)→ 视为进行中,继续轮询
|
||||
- **有限轮询窗口**:固定最多轮询 `30` 次,每次间隔 `2` 秒
|
||||
- **轮询超时不是失败**:如果窗口结束任务仍在处理中,会返回 `task_id`、`status`、`status_msg`、`ready=false`、`timed_out=true`、`next_command`
|
||||
- **继续查询**:看到 `next_command` 后,改用 `lark-cli drive +task_result --scenario wiki_delete_space --task-id <TASK_ID>` 继续查
|
||||
- **轮询请求全部失败时直接报错**:如果任务已创建,但后续每一次状态查询都失败,shortcut 会返回带 hint 的错误,并给出继续查询命令
|
||||
|
||||
## 返回结果
|
||||
|
||||
### 同步删除
|
||||
|
||||
```json
|
||||
{
|
||||
"space_id": "7629741305993170448",
|
||||
"ready": true,
|
||||
"failed": false,
|
||||
"status": "success",
|
||||
"status_msg": "success"
|
||||
}
|
||||
```
|
||||
|
||||
### 异步删除完成
|
||||
|
||||
```json
|
||||
{
|
||||
"space_id": "7629741305993170448",
|
||||
"task_id": "7631425120875056669-965458aec67417f5982250806c97950697ccb82f",
|
||||
"ready": true,
|
||||
"failed": false,
|
||||
"status": "success",
|
||||
"status_msg": "success"
|
||||
}
|
||||
```
|
||||
|
||||
### 异步轮询超时
|
||||
|
||||
```json
|
||||
{
|
||||
"space_id": "7629741305993170448",
|
||||
"task_id": "7631425120875056669-965458aec67417f5982250806c97950697ccb82f",
|
||||
"ready": false,
|
||||
"failed": false,
|
||||
"status": "processing",
|
||||
"status_msg": "processing",
|
||||
"timed_out": true,
|
||||
"next_command": "lark-cli drive +task_result --scenario wiki_delete_space --task-id 7631425120875056669-965458aec67417f5982250806c97950697ccb82f --as user"
|
||||
}
|
||||
```
|
||||
|
||||
**输出字段说明:**
|
||||
|
||||
- `space_id`:入参的知识空间 ID
|
||||
- `ready`:任务是否已经完成
|
||||
- `failed`:任务是否已失败(显式返回 `failure` / `failed` 时为 `true`)
|
||||
- `task_id`:异步任务 ID,仅异步场景返回
|
||||
- `status` / `status_msg`:异步任务的原始状态和可读标签
|
||||
- `timed_out`、`next_command`:轮询窗口内未完成时返回
|
||||
|
||||
## dry-run 编排
|
||||
|
||||
dry-run 会展示两步调用链:
|
||||
|
||||
1. `DELETE /open-apis/wiki/v2/spaces/{space_id}`
|
||||
2. `GET /open-apis/wiki/v2/tasks/{task_id}?task_type=delete_space`(仅异步时真实发生)
|
||||
|
||||
## 权限说明
|
||||
|
||||
当前 shortcut 声明的权限为 `wiki:space:write_only` 和 `wiki:space:read`。前者用于发起删除请求,后者用于轮询同一命令内的异步任务状态;如果本地 token 缺失任一权限,CLI 会直接提示重新执行 `lark-cli auth login --scope "wiki:space:write_only wiki:space:read"`。
|
||||
|
||||
异步超时后的 `lark-cli drive +task_result --scenario wiki_delete_space --task-id <TASK_ID>` 只需 `wiki:space:read`(纯读任务状态)。
|
||||
|
||||
## 空间解析:如何拿到 `space_id`
|
||||
|
||||
`wiki +delete-space` 只接受 `--space-id` 作为目标。用户在对话里常常只说知识库的**名称**或贴一条**知识库 URL**,这时**不能**把名称 / URL 原样当成 `space_id` 传进去,必须先解析。三种输入路径:
|
||||
|
||||
### 1. 已经有 `space_id`
|
||||
直接用,无需解析。
|
||||
|
||||
### 2. 只有知识库 URL(`.../wiki/<token>`)
|
||||
|
||||
```bash
|
||||
lark-cli wiki spaces get_node \
|
||||
--params '{"token":"<wiki_token>"}' \
|
||||
--format json
|
||||
```
|
||||
|
||||
读取 `data.node.space_id`。
|
||||
|
||||
### 3. 只有知识库名称
|
||||
|
||||
调用 `wiki spaces list`:
|
||||
|
||||
```bash
|
||||
# 第一页
|
||||
lark-cli wiki spaces list --format json
|
||||
|
||||
# 如果需要继续翻页(看下方停止条件),带上 page_token
|
||||
lark-cli wiki spaces list --params '{"page_token":"<上一页返回的 page_token>"}' --format json
|
||||
```
|
||||
|
||||
#### 翻页与匹配策略
|
||||
|
||||
**边翻边匹配**:每拿一页就在已累计的 items 上对 `name` 做精确匹配(区分大小写、保留空格),满足任一条件即停止翻页:
|
||||
|
||||
- (A) **累计精确匹配 ≥ 1 条** → 停止翻页,已找到目标
|
||||
- (B) **`has_more=false`**(已翻完所有页)→ 停止翻页
|
||||
|
||||
结束后:
|
||||
|
||||
1. 如果累计精确匹配 ≥ 1:把**所有**精确匹配作为候选列给用户
|
||||
2. 如果精确匹配 = 0(此时必然已走到 `has_more=false`,已收集全量 items):在全量 items 上做**宽松匹配**(`name` trim 空格 + 大小写不敏感 + 子串包含),作为候选
|
||||
3. 宽松匹配也 0 条:停下来问用户是不是名字拼错、或者调用方没权限看到这个空间;**不要**自己改名字重试
|
||||
|
||||
> 不做更激进的归一化(比如去括号、去版本号尾缀),那些容易把 "客户台账(归档)" 误命中到 "客户台账"。
|
||||
|
||||
#### 早停的小边界
|
||||
|
||||
早停(条件 A)意味着**可能漏掉**位于更后面页的同名空间。这种重名 corner case 由下面的"用户确认"兜底:LLM 展示候选时应照抄 `name + space_id`,用户如果觉得不是自己想删的那一个,可以要求继续翻页。
|
||||
|
||||
#### 确认流程(硬约束)
|
||||
|
||||
**无论精确还是模糊,无论命中 1 条还是多条,发起删除前都必须先把候选列给用户**,由用户明确回选一个 `space_id`。不要因为"只命中一条"就跳过确认直接删。
|
||||
|
||||
列候选时至少包含以下字段,方便用户分辨:
|
||||
|
||||
- `name`(原始值,不做归一化)
|
||||
- `space_id`
|
||||
- `space_type`(`team` / `person` 等)
|
||||
- `description`(若有)
|
||||
- `visibility`(若有)
|
||||
|
||||
示例话术:
|
||||
|
||||
```text
|
||||
根据 "客户台账" 找到以下候选:
|
||||
1) name="客户台账", space_id=7629...0448, space_type=team, description="销售部"
|
||||
2) name="客户台账(归档)", space_id=7629...0449, space_type=team, description="2023 以前"
|
||||
请回复序号或 space_id 确认要删除的那一个;如果都不是请说明。
|
||||
```
|
||||
|
||||
命中 0 条:停下来问用户是名称拼错了、还是调用方无权限看到这个空间;**不要**自动尝试改名字再查一次。
|
||||
|
||||
#### 执行删除
|
||||
|
||||
用户明确选定 `space_id` 后:
|
||||
|
||||
```bash
|
||||
lark-cli wiki +delete-space --space-id <RESOLVED_SPACE_ID> --yes
|
||||
```
|
||||
|
||||
> [!IMPORTANT]
|
||||
> 删库不可逆。关键不变量:**发给服务端的 `--space-id` 必须是用户在上一轮对话里明确指认过的那一个**,不是 LLM 单方面"从匹配结果自动选"。
|
||||
|
||||
## 风险等级
|
||||
|
||||
- Risk:**`high-risk-write`**
|
||||
- 框架会强制要求 `--yes` 确认;不传 `--yes` 时命令会直接返回 `unsafe_operation_blocked` 错误,不会真的发请求
|
||||
|
||||
> [!CAUTION]
|
||||
> `wiki +delete-space` 是**不可逆的写入操作**。执行前务必与用户再次确认 `--space-id`,并清楚该空间下的所有节点都会一并被删除。
|
||||
|
||||
## 参考
|
||||
|
||||
- [lark-wiki](../SKILL.md) -- 知识库全部命令
|
||||
- [lark-shared](../../lark-shared/SKILL.md) -- 认证和全局参数
|
||||
- [drive +task_result](../../lark-drive/references/lark-drive-task-result.md) -- 异步任务的续跑查询命令
|
||||
67
.agents/skills/lark-wiki/references/lark-wiki-member-add.md
Normal file
67
.agents/skills/lark-wiki/references/lark-wiki-member-add.md
Normal file
@ -0,0 +1,67 @@
|
||||
# lark-wiki +member-add
|
||||
|
||||
Add a member to a wiki space. OpenAPI: `POST /open-apis/wiki/v2/spaces/:space_id/members`. Shortcut over the raw `wiki members create` — adds enum hints, optional `--need-notification`, `my_library` resolution, and a flattened single-member output envelope.
|
||||
|
||||
> The underlying `members.create` API is flagged `danger: true` in the schema browser, but adding a member is **not** confirmation-gated (no `--yes`). To revert, call [`+member-remove`](lark-wiki-member-remove.md) with the same `(member_id, member_type, member_role)` tuple.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# Add a user as a regular member
|
||||
lark-cli wiki +member-add \
|
||||
--space-id <space_id> \
|
||||
--member-id <open_id|email|user_id|app_id|...> \
|
||||
--member-type <openid|email|userid|unionid|openchat|opendepartmentid|appid> \
|
||||
--member-role <admin|member> \
|
||||
[--need-notification] \
|
||||
[--as user|bot]
|
||||
|
||||
# Personal library (resolves my_library to the per-user real space first)
|
||||
lark-cli wiki +member-add \
|
||||
--space-id my_library \
|
||||
--member-id ou_xxx --member-type openid --member-role member \
|
||||
--as user
|
||||
|
||||
# Preview the call chain without writing
|
||||
lark-cli wiki +member-add \
|
||||
--space-id <space_id> --member-id <id> --member-type openid --member-role admin \
|
||||
--dry-run
|
||||
```
|
||||
|
||||
## Flags
|
||||
|
||||
| Flag | Type | Required | Default | Description |
|
||||
|------|------|----------|---------|-------------|
|
||||
| `--space-id` | string | **Yes** | — | Wiki space ID; use `my_library` for the personal document library (user only) |
|
||||
| `--member-id` | string | **Yes** | — | Member ID; interpretation is decided by `--member-type` |
|
||||
| `--member-type` | enum | **Yes** | — | `openchat` / `userid` / `email` / `opendepartmentid` / `openid` / `unionid` / `appid` |
|
||||
| `--member-role` | enum | **Yes** | — | `admin` (full space administration) / `member` (collaborator) |
|
||||
| `--need-notification` | bool | No | unset | Send an in-app notification after the grant. **Omitting the flag sends no `need_notification` query at all** — passing `--need-notification=false` is the explicit opt-out |
|
||||
| `--as` | enum | No | `auto` | Identity `user`/`bot`; wiki is user-centric → pass `--as user` |
|
||||
|
||||
## Output
|
||||
|
||||
```json
|
||||
{
|
||||
"space_id": "7160145948494381236",
|
||||
"member_id": "ou_449b53ad6aee526f7ed311b216aabcef",
|
||||
"member_type": "openid",
|
||||
"member_role": "admin",
|
||||
"type": "user"
|
||||
}
|
||||
```
|
||||
|
||||
`type` is a read-only enum (`user` / `chat` / `department`) the server attaches; absent when the API omits it.
|
||||
|
||||
## Notes
|
||||
|
||||
- **Bot + `my_library` is rejected upfront** — `my_library` is a per-user alias with no meaning for a tenant token. Pass an explicit `--space-id` when `--as bot`.
|
||||
- **Bot + `opendepartmentid` is a known unsupported path on the backend.** The CLI does not pre-block it (the API may evolve), but the call will fail. Use `--as user` for department adds.
|
||||
- **App member uses `--member-type=appid`.** The corresponding `--member-id` is the app ID, commonly formatted as `cli_xxx`.
|
||||
- Resolve `--member-id` **before** calling: `lark-cli contact +search-user` for users, `lark-cli im +chat-search` for groups, `lark-cli api POST /open-apis/contact/v3/departments/search` for departments. Do not call `+member-add` first and reverse-engineer the type from the error.
|
||||
- The role switch (`admin` ⇄ `member`) is not a single update — call [`+member-remove`](lark-wiki-member-remove.md) for the old role first, then `+member-add` with the new one.
|
||||
- `--dry-run` previews 2 steps when `--space-id my_library` (resolve → add), 1 step otherwise.
|
||||
|
||||
## Required Scope
|
||||
|
||||
`wiki:member:create`
|
||||
76
.agents/skills/lark-wiki/references/lark-wiki-member-list.md
Normal file
76
.agents/skills/lark-wiki/references/lark-wiki-member-list.md
Normal file
@ -0,0 +1,76 @@
|
||||
# lark-wiki +member-list
|
||||
|
||||
List the members of a wiki space. OpenAPI: `GET /open-apis/wiki/v2/spaces/:space_id/members`. **Default fetches a single page** (matches `+space-list` / `+node-list`); pass `--page-all` to walk every page.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# Default: single page
|
||||
lark-cli wiki +member-list --space-id <space_id>
|
||||
|
||||
# Walk every page (capped by --page-limit, default 10)
|
||||
lark-cli wiki +member-list --space-id <space_id> --page-all
|
||||
|
||||
# Walk every page, no cap
|
||||
lark-cli wiki +member-list --space-id <space_id> --page-all --page-limit 0
|
||||
|
||||
# Resume from a specific cursor (single-page fetch regardless of --page-all)
|
||||
lark-cli wiki +member-list --space-id <space_id> --page-token <TOKEN>
|
||||
|
||||
# Personal library
|
||||
lark-cli wiki +member-list --space-id my_library --as user
|
||||
|
||||
# Pretty / table / csv / ndjson output
|
||||
lark-cli wiki +member-list --space-id <space_id> --format pretty
|
||||
lark-cli wiki +member-list --space-id <space_id> --format table
|
||||
```
|
||||
|
||||
## Flags
|
||||
|
||||
| Flag | Type | Required | Default | Description |
|
||||
|------|------|----------|---------|-------------|
|
||||
| `--space-id` | string | **Yes** | — | Wiki space ID; use `my_library` for the personal document library (user only) |
|
||||
| `--page-size` | int | No | 50 | Page size, 1-50 |
|
||||
| `--page-token` | string | No | — | Page cursor; implies single-page fetch (no auto-pagination) |
|
||||
| `--page-all` | bool | No | `false` | Automatically paginate through all pages (capped by `--page-limit`) |
|
||||
| `--page-limit` | int | No | 10 | Max pages with `--page-all` (0 = unlimited) |
|
||||
| `--format` | enum | No | `json` | `json` / `pretty` / `table` / `csv` / `ndjson` |
|
||||
| `--as` | enum | No | `auto` | Identity `user`/`bot`; wiki is user-centric → pass `--as user` |
|
||||
|
||||
## Output
|
||||
|
||||
```json
|
||||
{
|
||||
"ok": true,
|
||||
"data": {
|
||||
"space_id": "7160145948494381236",
|
||||
"members": [
|
||||
{
|
||||
"member_id": "ou_449b53ad6aee526f7ed311b216aabcef",
|
||||
"member_type": "openid",
|
||||
"member_role": "admin"
|
||||
},
|
||||
{
|
||||
"member_id": "ou_67e5ecb64ce1c0bd94612c17999db411",
|
||||
"member_type": "openid",
|
||||
"member_role": "member"
|
||||
}
|
||||
],
|
||||
"has_more": false,
|
||||
"page_token": ""
|
||||
},
|
||||
"meta": { "count": 2 }
|
||||
}
|
||||
```
|
||||
|
||||
`type` (`user` / `chat` / `department`) is included when the server returns it. When the default single-page fetch (or `--page-all` capped by `--page-limit`) does not exhaust the upstream cursor, `has_more=true` and `page_token=<cursor>` so the caller can resume.
|
||||
|
||||
## Notes
|
||||
|
||||
- **Bot + `my_library` is rejected upfront** — pass an explicit `--space-id` when `--as bot`.
|
||||
- Use `member_id` from the output as `--member-id` for [`+member-remove`](lark-wiki-member-remove.md); `member_type` and `member_role` must be passed exactly as listed to remove a grant.
|
||||
- `--dry-run` previews 2 steps when `--space-id my_library` (resolve → list), 1 step otherwise.
|
||||
|
||||
## Required Scope
|
||||
|
||||
`wiki:member:retrieve`
|
||||
@ -0,0 +1,61 @@
|
||||
# lark-wiki +member-remove
|
||||
|
||||
Remove a member from a wiki space. OpenAPI: `DELETE /open-apis/wiki/v2/spaces/:space_id/members/:member_id`. Unlike most DELETEs, this endpoint **requires a body** carrying `member_type` and `member_role` — the `:member_id` path segment alone is ambiguous without both.
|
||||
|
||||
> The underlying `members.delete` API is flagged `danger: true` in the schema browser, but the operation is recoverable — call [`+member-add`](lark-wiki-member-add.md) with the same `(member_id, member_type, member_role)` to restore. No `--yes` gate.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
lark-cli wiki +member-remove \
|
||||
--space-id <space_id> \
|
||||
--member-id <open_id|email|user_id|app_id|...> \
|
||||
--member-type <openid|email|userid|unionid|openchat|opendepartmentid|appid> \
|
||||
--member-role <admin|member> \
|
||||
[--as user|bot]
|
||||
|
||||
# Personal library (resolves my_library first)
|
||||
lark-cli wiki +member-remove \
|
||||
--space-id my_library \
|
||||
--member-id ou_xxx --member-type openid --member-role member \
|
||||
--as user
|
||||
|
||||
# Preview the call chain without deleting
|
||||
lark-cli wiki +member-remove \
|
||||
--space-id <id> --member-id <id> --member-type openid --member-role admin \
|
||||
--dry-run
|
||||
```
|
||||
|
||||
## Flags
|
||||
|
||||
| Flag | Type | Required | Default | Description |
|
||||
|------|------|----------|---------|-------------|
|
||||
| `--space-id` | string | **Yes** | — | Wiki space ID; use `my_library` for the personal document library (user only) |
|
||||
| `--member-id` | string | **Yes** | — | Member ID; interpretation is decided by `--member-type` |
|
||||
| `--member-type` | enum | **Yes** | — | Must **match the original grant**: `openchat` / `userid` / `email` / `opendepartmentid` / `openid` / `unionid` / `appid` |
|
||||
| `--member-role` | enum | **Yes** | — | Must **match the original grant**: `admin` / `member` |
|
||||
| `--as` | enum | No | `auto` | Identity `user`/`bot`; wiki is user-centric → pass `--as user` |
|
||||
|
||||
## Output
|
||||
|
||||
```json
|
||||
{
|
||||
"space_id": "7160145948494381236",
|
||||
"member_id": "ou_449b53ad6aee526f7ed311b216aabcef",
|
||||
"member_type": "openid",
|
||||
"member_role": "admin"
|
||||
}
|
||||
```
|
||||
|
||||
If the API ever omits the member echo, the CLI falls back to surfacing the caller-supplied `(member_id, member_type, member_role)` so scripts still see what was removed.
|
||||
|
||||
## Notes
|
||||
|
||||
- **`--member-type` and `--member-role` must match the original grant.** Revoking a non-existent `(member_id, type, role)` tuple is a no-op error from the API. If you do not know the current role, run [`+member-list`](lark-wiki-member-list.md) first.
|
||||
- **Role switch is not a single update.** To move someone between `admin` and `member`, call `+member-remove` with the old role first, then [`+member-add`](lark-wiki-member-add.md) with the new one.
|
||||
- **Bot + `my_library` is rejected upfront.** Pass an explicit `--space-id` when `--as bot`.
|
||||
- `--dry-run` previews 2 steps when `--space-id my_library` (resolve → delete), 1 step otherwise.
|
||||
|
||||
## Required Scope
|
||||
|
||||
`wiki:member:update`
|
||||
122
.agents/skills/lark-wiki/references/lark-wiki-move-to-drive.md
Normal file
122
.agents/skills/lark-wiki/references/lark-wiki-move-to-drive.md
Normal file
@ -0,0 +1,122 @@
|
||||
# wiki +move-to-drive
|
||||
|
||||
> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
|
||||
|
||||
将已有 Wiki 节点移出知识库,并放到指定 Drive 文件夹;省略目标文件夹时放到当前调用身份的“我的空间”根目录。该操作始终创建异步任务,shortcut 会自动有限轮询。
|
||||
|
||||
## 何时使用
|
||||
|
||||
| 源对象 | 目标位置 | 命令 |
|
||||
|--------|----------|------|
|
||||
| Wiki 节点 | Wiki 空间或 Wiki 父节点 | `wiki +move` |
|
||||
| Drive 文档 | Wiki 空间或 Wiki 父节点 | `wiki +move` |
|
||||
| Wiki 节点 | Drive 文件夹或“我的空间”根目录 | `wiki +move-to-drive` |
|
||||
| Drive 文件 / 文件夹 | Drive 文件夹或根目录 | `drive +move` |
|
||||
|
||||
`--node-token` 必须是 Wiki 节点 token,不是底层文档的 `obj_token`。无法判断时,先执行 `wiki +node-get --node-token <URL_OR_TOKEN>`。
|
||||
|
||||
## 命令
|
||||
|
||||
```bash
|
||||
# 移到指定 Drive 文件夹
|
||||
lark-cli wiki +move-to-drive \
|
||||
--node-token <WIKI_NODE_TOKEN> \
|
||||
--folder-token <TARGET_FOLDER_TOKEN> \
|
||||
--as user
|
||||
|
||||
# 移到当前调用身份的“我的空间”根目录
|
||||
lark-cli wiki +move-to-drive \
|
||||
--node-token <WIKI_NODE_TOKEN> \
|
||||
--as user
|
||||
|
||||
# 预览提交任务和轮询任务两步请求
|
||||
lark-cli wiki +move-to-drive \
|
||||
--node-token <WIKI_NODE_TOKEN> \
|
||||
--folder-token <TARGET_FOLDER_TOKEN> \
|
||||
--dry-run
|
||||
```
|
||||
|
||||
## 参数
|
||||
|
||||
| 参数 | 必填 | 说明 |
|
||||
|------|------|------|
|
||||
| `--node-token` | 是 | 要移出知识库的 Wiki 节点 token |
|
||||
| `--folder-token` | 否 | 目标 Drive 文件夹 token;省略时移动到当前调用身份的“我的空间”根目录 |
|
||||
|
||||
## 异步协议与续跑
|
||||
|
||||
shortcut 会按以下协议执行:
|
||||
|
||||
1. `POST /open-apis/wiki/v2/nodes/{node_token}/move_wiki_to_docs`,取得完整、不可拆分的 `task_id`。
|
||||
2. `GET /open-apis/wiki/v2/tasks/{task_id}?task_type=move_wiki_to_docs`。
|
||||
3. 读取 `data.task.move_wiki_to_docs_result`:`status=1` 表示处理中,`status=0` 表示成功,`status=-1` 表示失败。
|
||||
|
||||
任务查询必须使用 `task_type=move_wiki_to_docs`、`move_wiki_to_docs_result` 和数值状态;不要回退到其他 task type、result 字段或字符串状态。
|
||||
|
||||
- 最多轮询 30 次,每次间隔 2 秒。
|
||||
- 轮询窗口内成功时返回 `ready=true`,并尽可能返回 `obj_token`、`obj_type` 和 `url`。
|
||||
- 仍在处理中时返回 `ready=false`、`timed_out=true`、完整 `task_id` 和 `next_command`;超时不代表任务失败。
|
||||
- 任务进入失败态时返回结构化错误。
|
||||
- `task_id` 是服务端签名的 opaque ID,可能包含多个连字符;必须原样保存,不能自行切分。
|
||||
- 续跑必须保持和初始移动相同的 `--profile` 与 `--as user|bot` 身份,否则可能收到权限错误;shortcut 返回的 `next_command` 会保留两者。
|
||||
|
||||
手动续跑命令:
|
||||
|
||||
```bash
|
||||
lark-cli drive +task_result \
|
||||
--scenario wiki_move_to_drive \
|
||||
--task-id <COMPLETE_TASK_ID> \
|
||||
--as user
|
||||
```
|
||||
|
||||
## 典型返回
|
||||
|
||||
成功:
|
||||
|
||||
```json
|
||||
{
|
||||
"node_token": "wikcnXXX",
|
||||
"folder_token": "fldcnXXX",
|
||||
"task_id": "<OPAQUE_TASK_ID>",
|
||||
"ready": true,
|
||||
"failed": false,
|
||||
"status": 0,
|
||||
"status_msg": "success",
|
||||
"obj_token": "doxcnXXX",
|
||||
"obj_type": "docx",
|
||||
"url": "https://example.feishu.cn/docx/doxcnXXX"
|
||||
}
|
||||
```
|
||||
|
||||
轮询窗口超时:
|
||||
|
||||
```json
|
||||
{
|
||||
"node_token": "wikcnXXX",
|
||||
"folder_token": "",
|
||||
"task_id": "<OPAQUE_TASK_ID>",
|
||||
"ready": false,
|
||||
"failed": false,
|
||||
"status": 1,
|
||||
"status_msg": "processing",
|
||||
"timed_out": true,
|
||||
"next_command": "lark-cli drive +task_result --scenario wiki_move_to_drive --task-id <OPAQUE_TASK_ID> --as user"
|
||||
}
|
||||
```
|
||||
|
||||
## 权限与影响
|
||||
|
||||
- CLI 写操作预检查使用 `space:document:move`,任务轮询使用 `wiki:space:read`。
|
||||
- 调用方必须能移动源 Wiki 节点并写入目标 Drive 文件夹。
|
||||
- 成功后源节点会从 Wiki 树中消失,目标文档改用 Drive 目标位置的权限模型;原 Wiki 层级继承权限不再保留。
|
||||
- 省略 `--folder-token` 时,“根目录”属于当前 `--as` 身份,user 与 bot 的可见资源范围可能不同。
|
||||
|
||||
> [!CAUTION]
|
||||
> 这是会改变文档归属和权限继承的**写入操作**。执行前必须确认源 Wiki 节点、目标 Drive 位置和调用身份。
|
||||
|
||||
## 参考
|
||||
|
||||
- [lark-wiki](../SKILL.md) -- 知识库全部命令
|
||||
- [wiki +move](lark-wiki-move.md) -- Wiki 内移动与 Drive 文档迁入 Wiki
|
||||
- [drive +task_result](../../lark-drive/references/lark-drive-task-result.md) -- 超时后的任务续跑
|
||||
- [lark-shared](../../lark-shared/SKILL.md) -- 认证和全局参数
|
||||
185
.agents/skills/lark-wiki/references/lark-wiki-move.md
Normal file
185
.agents/skills/lark-wiki/references/lark-wiki-move.md
Normal file
@ -0,0 +1,185 @@
|
||||
# wiki +move
|
||||
|
||||
> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
|
||||
|
||||
在飞书知识库中移动已有 Wiki 节点,或将 Drive 文档迁入 Wiki。这个 shortcut 统一封装了两类流程:
|
||||
|
||||
- `node` 模式:移动已有 Wiki 节点,可同空间移动,也可跨空间移动
|
||||
- `docs_to_wiki` 模式:把 Drive 文档迁入目标知识空间;必要时可提交移动申请,并在异步任务场景下自动有限轮询
|
||||
|
||||
当 `docs_to_wiki` 返回 `task_id` 时,shortcut 会先轮询一小段时间;如果轮询窗口内仍未完成,会返回 `next_command`,让调用方继续执行 `lark-cli drive +task_result --scenario wiki_move --task-id <TASK_ID>`。
|
||||
|
||||
## 与 `wiki +move-to-drive` / `drive +move` 的区别
|
||||
|
||||
- `wiki +move` 的目标是 **知识空间或 Wiki 父节点**,使用 `--target-space-id` / `--target-parent-token`
|
||||
- `wiki +move-to-drive` 把 **已有 Wiki 节点移出知识库,放入 Drive 文件夹或“我的空间”根目录**,使用 `--folder-token`
|
||||
- `drive +move` 的目标是 **Drive 文件夹**,使用 `--folder-token`
|
||||
- 如果源对象已经是 Wiki 节点:目标仍是 Wiki 时使用 `wiki +move`;目标是 Drive 文件夹或根目录时使用 `wiki +move-to-drive`
|
||||
- 如果源对象还是 Drive 文档,但用户要“迁入知识库”“挂到某个 Wiki 页面下”,也应使用 `wiki +move`
|
||||
- 如果用户只是想整理云空间(云盘/云存储)文件夹,把文件/文件夹挪到另一个 Drive 文件夹,应使用 `drive +move`
|
||||
|
||||
## 口语目标识别
|
||||
|
||||
- 当用户说“移动到某个知识库”“挂到某个页面下”“迁入 Wiki”时,按 **Wiki 目标** 处理,优先使用 `wiki +move`
|
||||
- 当用户说“移动到某个文件夹”“移动到云空间(云盘/云存储)根目录”时,按 **Drive 文件夹目标** 处理;源对象是 Wiki 节点时使用 `wiki +move-to-drive`,源对象已在 Drive 时使用 `drive +move`
|
||||
- 当用户说“移动到我的文档库”“移动到我的知识库”“放到个人知识库”时,应先按 **Wiki 个人知识库目标** 理解,而不是直接退化成 `drive +move`
|
||||
- 遇到“我的文档库”这类表述时,可以把它理解成:先用 `my_library` 去查询用户个人知识库,再拿到真实 `space_id`
|
||||
- 推荐做法是先执行 `lark-cli wiki spaces get --params '{"space_id":"my_library"}'`,取回真实知识库 `space_id`,再把这个 `space_id` 用到 `wiki +move`
|
||||
- 当前 `wiki +move` 文档的主示例仍以显式 `--target-space-id` / `--target-parent-token` 为主;如果调用方只有自然语言目标,不要因为目标暂时不明确就改走 `drive +move`
|
||||
|
||||
## 命令
|
||||
|
||||
```bash
|
||||
# 将已有 wiki 节点移动到另一个父节点下
|
||||
lark-cli wiki +move \
|
||||
--node-token <NODE_TOKEN> \
|
||||
--target-parent-token <TARGET_PARENT_TOKEN>
|
||||
|
||||
# 将已有 wiki 节点移动到另一个知识空间根目录
|
||||
lark-cli wiki +move \
|
||||
--node-token <NODE_TOKEN> \
|
||||
--target-space-id <TARGET_SPACE_ID>
|
||||
|
||||
# 将 Drive 文档迁入某个知识空间根目录
|
||||
lark-cli wiki +move \
|
||||
--obj-type docx \
|
||||
--obj-token <DOC_TOKEN> \
|
||||
--target-space-id <TARGET_SPACE_ID>
|
||||
|
||||
# 将 Drive 文档迁入某个父节点下;如果当前没有直接移动权限,则提交申请
|
||||
lark-cli wiki +move \
|
||||
--obj-type sheet \
|
||||
--obj-token <SHEET_TOKEN> \
|
||||
--target-space-id <TARGET_SPACE_ID> \
|
||||
--target-parent-token <TARGET_PARENT_TOKEN> \
|
||||
--apply
|
||||
|
||||
# 预览底层调用链
|
||||
lark-cli wiki +move \
|
||||
--obj-type docx \
|
||||
--obj-token <DOC_TOKEN> \
|
||||
--target-space-id <TARGET_SPACE_ID> \
|
||||
--dry-run
|
||||
```
|
||||
|
||||
## 参数
|
||||
|
||||
| 参数 | 必填 | 说明 |
|
||||
|------|------|------|
|
||||
| `--node-token` | 条件必填 | 要移动的 Wiki 节点 token。传入后命令进入 `node` 模式 |
|
||||
| `--source-space-id` | 否 | 源知识空间 ID,仅 `node` 模式可用;不传时会根据 `--node-token` 自动解析 |
|
||||
| `--target-space-id` | 条件必填 | 目标知识空间 ID。`docs_to_wiki` 模式必填;`node` 模式下如果不传,则必须传 `--target-parent-token` |
|
||||
| `--target-parent-token` | 否 | 目标父节点 token。`docs_to_wiki` 不传时表示迁入目标知识空间根目录 |
|
||||
| `--obj-type` | 条件必填 | Drive 文档类型,仅 `docs_to_wiki` 模式可用。可选值:`doc`、`sheet`、`bitable`、`mindnote`、`docx`、`file`、`slides` |
|
||||
| `--obj-token` | 条件必填 | Drive 文档 token,仅 `docs_to_wiki` 模式可用 |
|
||||
| `--apply` | 否 | 仅 `docs_to_wiki` 模式可用;当当前调用方不能直接移动文档时,提交一个 move request |
|
||||
|
||||
## 模式选择与校验规则
|
||||
|
||||
- **`node` 模式**:只要传了 `--node-token`,就会按“移动已有 Wiki 节点”执行
|
||||
- **`docs_to_wiki` 模式**:未传 `--node-token` 时,按“把 Drive 文档迁入 Wiki”执行
|
||||
- `node` 模式下,`--node-token` 不能与 `--obj-type`、`--obj-token`、`--apply` 同时使用
|
||||
- `node` 模式下,`--target-parent-token` 和 `--target-space-id` 不能同时为空
|
||||
- `docs_to_wiki` 模式下,必须同时提供 `--obj-type`、`--obj-token`、`--target-space-id`
|
||||
- `docs_to_wiki` 模式下,`--source-space-id` 非法,只能用于 `node` 模式
|
||||
|
||||
## 空间解析与一致性校验
|
||||
|
||||
### `node` 模式
|
||||
|
||||
- **源空间解析**:如果未传 `--source-space-id`,shortcut 会先调用 `GET /open-apis/wiki/v2/spaces/get_node` 查询 `--node-token`,再读取其 `space_id`
|
||||
- **目标父节点解析**:如果传了 `--target-parent-token`,shortcut 会先解析该父节点所属的 `space_id`
|
||||
- **一致性校验**:如果同时传了 `--target-space-id` 和 `--target-parent-token`,shortcut 会校验两者是否属于同一个知识空间;不一致时直接返回验证错误
|
||||
- **移动到空间根目录**:如果只传 `--target-space-id`,则表示移动到该知识空间根目录
|
||||
|
||||
### `docs_to_wiki` 模式
|
||||
|
||||
- `--target-space-id` 始终必填
|
||||
- `--target-parent-token` 可选;不传时表示移动到目标知识空间根目录
|
||||
- 请求体会自动映射成 `obj_type`、`obj_token`、`parent_wiki_token`、`apply`
|
||||
|
||||
## 行为说明
|
||||
|
||||
- **`node` 模式是同步操作**:请求成功后直接返回移动后的节点信息
|
||||
- **`docs_to_wiki` 可能是同步,也可能是异步**:
|
||||
- 如果接口直接返回 `wiki_token`,shortcut 会立刻返回 `ready=true`
|
||||
- 如果接口返回 `applied=true`,shortcut 会返回 `ready=false`、`failed=false`、`applied=true` 和 `status_msg="move request submitted for approval"`
|
||||
- 如果接口返回 `task_id`,shortcut 会先进入有限轮询
|
||||
- **有限轮询窗口**:固定最多轮询 `30` 次,每次间隔 `2` 秒
|
||||
- **轮询超时不是失败**:如果轮询窗口结束任务仍在处理中,会返回 `task_id`、`status`、`status_msg`、`ready=false`、`timed_out=true` 和 `next_command`
|
||||
- **继续查询**:看到 `next_command` 后,改用 `lark-cli drive +task_result --scenario wiki_move --task-id <TASK_ID>` 继续查
|
||||
- **任务失败直接报错**:如果轮询期间任务进入失败态,shortcut 会直接返回错误,不会再输出 `ready=false` 结果
|
||||
- **轮询请求全部失败时也直接报错**:如果任务已创建,但后续每一次状态查询都失败,shortcut 会返回带 hint 的错误,并给出继续查询命令
|
||||
|
||||
## 返回结果
|
||||
|
||||
### `node` 模式典型返回
|
||||
|
||||
```json
|
||||
{
|
||||
"mode": "node",
|
||||
"source_space_id": "space_src",
|
||||
"target_space_id": "space_dst",
|
||||
"space_id": "space_dst",
|
||||
"node_token": "wikcnode_xxx",
|
||||
"obj_token": "doccn_xxx",
|
||||
"obj_type": "docx",
|
||||
"parent_node_token": "wikcparent_xxx",
|
||||
"node_type": "origin",
|
||||
"origin_node_token": "",
|
||||
"title": "项目计划",
|
||||
"has_child": false
|
||||
}
|
||||
```
|
||||
|
||||
### `docs_to_wiki` 异步超时返回
|
||||
|
||||
```json
|
||||
{
|
||||
"mode": "docs_to_wiki",
|
||||
"obj_type": "docx",
|
||||
"obj_token": "doccn_xxx",
|
||||
"target_space_id": "space_xxx",
|
||||
"target_parent_token": "wikcparent_xxx",
|
||||
"task_id": "7500000000000000001",
|
||||
"ready": false,
|
||||
"failed": false,
|
||||
"status": 1,
|
||||
"status_msg": "processing",
|
||||
"timed_out": true,
|
||||
"next_command": "lark-cli drive +task_result --scenario wiki_move --task-id 7500000000000000001"
|
||||
}
|
||||
```
|
||||
|
||||
**输出字段说明:**
|
||||
|
||||
- `mode`:当前执行模式,值为 `node` 或 `docs_to_wiki`
|
||||
- `ready`:任务是否已经完成并可直接继续使用结果
|
||||
- `failed`:任务是否已失败
|
||||
- `task_id`:异步任务 ID,仅异步场景返回
|
||||
- `status` / `status_msg`:异步任务的主状态码和可读状态
|
||||
- `wiki_token`:docs-to-wiki 成功后返回的 Wiki 节点 token;同时也会镜像到 `node_token`
|
||||
- `space_id`、`node_token`、`obj_token`、`obj_type`、`parent_node_token`、`title` 等:成功拿到节点信息时返回,方便下游继续调用
|
||||
|
||||
## dry-run 编排
|
||||
|
||||
- `node` 模式下,dry-run 会根据是否需要解析源节点 / 目标父节点,展示 1 到 3 步的调用链
|
||||
- `docs_to_wiki` 模式下,dry-run 会展示两步:
|
||||
1. `POST /open-apis/wiki/v2/spaces/{target_space_id}/nodes/move_docs_to_wiki`
|
||||
2. `GET /open-apis/wiki/v2/tasks/{task_id}?task_type=move`
|
||||
|
||||
## 权限说明
|
||||
|
||||
CLI 会在执行前做本地 scope 预检查;当前 shortcut 声明的权限为 `wiki:node:move`、`wiki:node:read`、`wiki:space:read`(分别覆盖 move 写操作、节点解析读操作、以及异步任务轮询读操作)。如果本地 token 已记录 scopes 且缺失任一权限,命令会直接提示重新执行 `lark-cli auth login --scope ...`。
|
||||
|
||||
当异步任务超时后,后续 `lark-cli drive +task_result --scenario wiki_move --task-id <TASK_ID>` 只需要 `wiki:space:read` 权限。
|
||||
|
||||
> [!CAUTION]
|
||||
> `wiki +move` 是**写入操作**。执行前必须确认用户意图,以及目标节点 / 目标知识空间是否明确。
|
||||
|
||||
## 参考
|
||||
|
||||
- [lark-wiki](../SKILL.md) -- 知识库全部命令
|
||||
- [lark-shared](../../lark-shared/SKILL.md) -- 认证和全局参数
|
||||
- [wiki +move-to-drive](lark-wiki-move-to-drive.md) -- 将 Wiki 节点移出知识库并放入 Drive
|
||||
- [drive +task_result](../../lark-drive/references/lark-drive-task-result.md) -- docs-to-wiki 异步任务的续跑查询命令
|
||||
72
.agents/skills/lark-wiki/references/lark-wiki-node-copy.md
Normal file
72
.agents/skills/lark-wiki/references/lark-wiki-node-copy.md
Normal file
@ -0,0 +1,72 @@
|
||||
# lark-wiki +node-copy
|
||||
|
||||
Copy a wiki node (including its content) to a target space or under a target parent node. Used for cross-space migration.
|
||||
|
||||
> ⚠️ **High-risk write** — the upstream API is flagged `danger: true`, so this shortcut requires explicit `--yes` confirmation before issuing the request. Forgetting `--yes` returns a `confirmation_required` error and the copy is **not** performed.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
lark-cli wiki +node-copy \
|
||||
--space-id <source_space_id> \
|
||||
--node-token <source_node_token> \
|
||||
(--target-space-id <target_space_id> | --target-parent-node-token <token>) \
|
||||
[--title <new_title>] \
|
||||
--yes \
|
||||
[--as user|bot]
|
||||
```
|
||||
|
||||
## Flags
|
||||
|
||||
| Flag | Required | Description |
|
||||
|------|----------|-------------|
|
||||
| `--space-id` | **Yes** | Source wiki space ID |
|
||||
| `--node-token` | **Yes** | Source node token to copy |
|
||||
| `--target-space-id` | Conditional | Target space ID. Required if `--target-parent-node-token` is not set |
|
||||
| `--target-parent-node-token` | Conditional | Target parent node token. Required if `--target-space-id` is not set |
|
||||
| `--title` | No | New title for the copied node. Omit to keep the original title |
|
||||
| `--yes` | **Yes** | Confirm the high-risk operation. Without this flag the shortcut refuses to send the API request |
|
||||
| `--format` | No | Output format: `json` (default) / `pretty` / `table` / `csv` / `ndjson` |
|
||||
| `--as` | No | Identity `user`/`bot` (default `auto`); wiki is user-centric → pass `--as user` |
|
||||
|
||||
> At least one of `--target-space-id` or `--target-parent-node-token` must be provided.
|
||||
|
||||
## Output
|
||||
|
||||
```json
|
||||
{
|
||||
"space_id": "target_space_id",
|
||||
"node_token": "wikcn_EXAMPLE_TOKEN",
|
||||
"obj_token": "doccn_EXAMPLE_TOKEN",
|
||||
"obj_type": "docx",
|
||||
"node_type": "origin",
|
||||
"title": "Getting Started (Copy)",
|
||||
"parent_node_token": "",
|
||||
"has_child": false
|
||||
}
|
||||
```
|
||||
|
||||
## Migration workflow
|
||||
|
||||
To migrate a subtree from one space to another:
|
||||
|
||||
```bash
|
||||
# 1. List nodes in the source space
|
||||
lark-cli wiki +node-list --space-id source_space_id
|
||||
|
||||
# 2. Copy each node to the target space
|
||||
lark-cli wiki +node-copy \
|
||||
--space-id <source_space_id> \
|
||||
--node-token wikcn_EXAMPLE_TOKEN \
|
||||
--target-space-id <target_space_id> \
|
||||
--yes
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Copying is recursive — the subtree under the node is also copied.
|
||||
- There is no native move API; migration = copy to target + (manually delete source if needed).
|
||||
|
||||
## Required Scope
|
||||
|
||||
`wiki:node:copy`
|
||||
127
.agents/skills/lark-wiki/references/lark-wiki-node-create.md
Normal file
127
.agents/skills/lark-wiki/references/lark-wiki-node-create.md
Normal file
@ -0,0 +1,127 @@
|
||||
# wiki +node-create
|
||||
|
||||
> **前置条件:** 先阅读 [`../lark-shared/SKILL.md`](../../lark-shared/SKILL.md) 了解认证、全局参数和安全规则。
|
||||
|
||||
在飞书知识库中创建一个新节点,并自动解析目标知识空间。该 shortcut 对原生 `wiki.nodes.create` 做了一层更适合日常使用的封装:可以直接指定 `space_id`,也可以从父节点自动反查所属空间;在 `user` 身份下,如果同时省略 `--space-id` 和 `--parent-node-token`,还会自动回退到个人知识库 `my_library`。
|
||||
|
||||
## 命令
|
||||
|
||||
```bash
|
||||
# 在个人知识库根目录下创建一个 docx 节点(user 身份默认回退到 my_library)
|
||||
lark-cli wiki +node-create \
|
||||
--title "项目计划"
|
||||
|
||||
# 在指定知识空间中创建一个 docx 节点
|
||||
lark-cli wiki +node-create \
|
||||
--space-id <SPACE_ID> \
|
||||
--title "项目计划"
|
||||
|
||||
# 在指定父节点下创建一个子节点
|
||||
lark-cli wiki +node-create \
|
||||
--parent-node-token <PARENT_NODE_TOKEN> \
|
||||
--title "迭代记录"
|
||||
|
||||
# 显式指定创建到个人知识库(仅 user 身份;bot 不支持 `--space-id my_library`)
|
||||
lark-cli wiki +node-create \
|
||||
--space-id my_library \
|
||||
--title "学习笔记"
|
||||
|
||||
# 创建一个快捷方式节点(shortcut)
|
||||
lark-cli wiki +node-create \
|
||||
--parent-node-token <PARENT_NODE_TOKEN> \
|
||||
--node-type shortcut \
|
||||
--origin-node-token <ORIGIN_NODE_TOKEN> \
|
||||
--title "原文档快捷方式"
|
||||
|
||||
# 创建非 docx 类型节点
|
||||
lark-cli wiki +node-create \
|
||||
--space-id <SPACE_ID> \
|
||||
--obj-type sheet \
|
||||
--title "周报数据"
|
||||
|
||||
# 预览底层调用链
|
||||
lark-cli wiki +node-create \
|
||||
--title "Roadmap" \
|
||||
--dry-run
|
||||
```
|
||||
|
||||
## 返回值
|
||||
|
||||
成功后会返回一个 JSON 对象,常见字段包括:
|
||||
|
||||
- `resolved_space_id`:最终用于创建的真实知识空间 ID
|
||||
- `resolved_by`:空间解析来源,可能是 `explicit_space_id`、`parent_node_token`、`my_library`
|
||||
- `node_token`:新建知识库节点 token
|
||||
- `obj_token`:节点关联对象 token
|
||||
- `obj_type`:节点关联对象类型
|
||||
- `node_type`:节点类型
|
||||
- `title`:节点标题
|
||||
- `permission_grant`(可选):仅 `--as bot` 时返回,说明是否已自动为当前 CLI 用户授予可管理权限
|
||||
|
||||
> [!IMPORTANT]
|
||||
> 如果节点是**以应用身份(bot)创建**的,如 `lark-cli wiki +node-create --as bot`,在创建成功后 CLI 会**尝试为当前 CLI 用户自动授予该知识库节点的 `full_access`(可管理权限)**。
|
||||
>
|
||||
> 以应用身份创建时,结果里会额外返回 `permission_grant` 字段,明确说明授权结果:
|
||||
> - `status = granted`:当前 CLI 用户已获得该知识库节点的可管理权限
|
||||
> - `status = skipped`:本地没有可用的当前用户 `open_id`,因此不会自动授权;可提示用户先完成 `lark-cli auth login`,再让 AI / agent 继续使用应用身份(bot)授予当前用户权限
|
||||
> - `status = failed`:节点已创建成功,但自动授权用户失败;会带上失败原因,并提示稍后重试或继续使用 bot 身份处理该节点
|
||||
>
|
||||
> `permission_grant.perm = full_access` 表示该资源已授予“可管理权限”
|
||||
>
|
||||
> **不要擅自执行 owner 转移。** 如果用户需要把 owner 转给自己,必须单独确认。
|
||||
|
||||
## 参数
|
||||
|
||||
| 参数 | 必填 | 说明 |
|
||||
|------|------|------|
|
||||
| `--space-id` | 否 | 目标知识空间 ID;`user` 身份可传特殊值 `my_library` 表示个人知识库,`bot` 身份不支持该值 |
|
||||
| `--parent-node-token` | 否 | 父知识库节点 token;传入后会在该节点下创建新节点 |
|
||||
| `--title` | 否 | 节点标题 |
|
||||
| `--node-type` | 否 | 节点类型,默认 `origin`;可选值:`origin`、`shortcut` |
|
||||
| `--obj-type` | 否 | 节点对应对象类型,默认 `docx`;可选值:`sheet`、`mindnote`、`bitable`、`docx`、`slides` |
|
||||
| `--origin-node-token` | 否 | 当 `--node-type=shortcut` 时必填,表示快捷方式指向的源节点 token |
|
||||
|
||||
## 空间解析规则
|
||||
|
||||
- **优先级**:`--space-id` > `--parent-node-token` > `my_library`
|
||||
- **显式 space**:传了 `--space-id` 时,shortcut 会直接使用该空间;如果该值是 `my_library`,则仅 `user` 身份可用,并会先调用 `GET /open-apis/wiki/v2/spaces/my_library` 解析成真实 `space_id`
|
||||
- **父节点推断**:未传 `--space-id` 但传了 `--parent-node-token` 时,会先调用 `GET /open-apis/wiki/v2/spaces/get_node` 获取父节点,再读取其 `space_id`
|
||||
- **个人知识库回退**:`user` 身份下,如果 `--space-id` 和 `--parent-node-token` 都没传,会自动解析 `my_library`
|
||||
- **bot 身份限制**:`bot` 身份既没有“个人知识库”回退语义,也不支持显式传 `--space-id my_library`;请改用真实 `space_id` 或 `--parent-node-token`
|
||||
|
||||
## shortcut 节点规则
|
||||
|
||||
- `--node-type=shortcut` 时,必须同时提供 `--origin-node-token`
|
||||
- `--node-type=origin` 时,不能传 `--origin-node-token`
|
||||
- `shortcut` 节点只是知识库中的快捷方式入口;真正被引用的节点由 `--origin-node-token` 指定
|
||||
|
||||
## 一致性校验
|
||||
|
||||
- 如果同时传了 `--space-id` 和 `--parent-node-token`,shortcut 会校验父节点所属空间是否与 `--space-id` 一致
|
||||
- 如果两者解析出的空间不一致,命令会直接返回验证错误,而不会继续创建
|
||||
- 对于 `my_library`,`user` 身份下也会先解析出真实 `space_id` 后再做这层校验
|
||||
|
||||
## 行为说明
|
||||
|
||||
- **默认对象类型**:不传 `--obj-type` 时默认创建 `docx` 节点
|
||||
- **默认节点类型**:不传 `--node-type` 时默认创建普通节点 `origin`
|
||||
- **dry-run 编排**:
|
||||
- 仅传 `--title`:会展示 `my_library` 解析 + 创建节点 两步调用
|
||||
- 仅传 `--parent-node-token`:会展示“查询父节点 -> 创建节点”两步调用
|
||||
- 同时需要 `my_library` 和父节点时:会展示三步调用链
|
||||
- **bot 自动授权**:若使用 `--as bot`,结果还会额外带上 `permission_grant`,用于说明是否已自动为当前 CLI 用户授予新建节点的可管理权限
|
||||
- **输出结果**:成功后会返回 `resolved_space_id`、`resolved_by`、`node_token`、`obj_token`、`obj_type`、`node_type`、`title` 等字段,便于后续继续操作
|
||||
|
||||
## 推荐场景
|
||||
|
||||
- 用户说“在我的知识库里新建一篇页面”时,优先用 `lark-cli wiki +node-create --title "..."`
|
||||
- 用户已经给出父页面链接或 `parent_node_token` 时,优先传 `--parent-node-token`,让 shortcut 自动推导空间
|
||||
- 需要创建知识库快捷方式时,使用 `--node-type shortcut --origin-node-token <token>`
|
||||
|
||||
> [!CAUTION]
|
||||
> `wiki +node-create` 是**写入操作**,执行前必须确认用户意图。
|
||||
|
||||
## 参考
|
||||
|
||||
- [lark-wiki](../SKILL.md) -- 知识库全部命令
|
||||
- [lark-shared](../../lark-shared/SKILL.md) -- 认证和全局参数
|
||||
62
.agents/skills/lark-wiki/references/lark-wiki-node-delete.md
Normal file
62
.agents/skills/lark-wiki/references/lark-wiki-node-delete.md
Normal file
@ -0,0 +1,62 @@
|
||||
# lark-wiki +node-delete
|
||||
|
||||
Delete a wiki node (or pull a cloud doc out of Wiki). OpenAPI: `DELETE /open-apis/wiki/v2/spaces/:space_id/nodes/:node_token`.
|
||||
|
||||
> ⚠️ **High-risk write & irreversible** — deletes the node and (by default) its whole subtree. Requires explicit `--yes`; without it the CLI returns a `confirmation_required` error and nothing is deleted.
|
||||
|
||||
- **Sync / async**: an empty `task_id` means the delete completed synchronously (`ready=true`). A non-empty `task_id` triggers bounded polling; if the window elapses the output carries `timed_out=true` and a `next_command`:
|
||||
`lark-cli drive +task_result --scenario wiki_delete_node --task-id <TASK_ID> --as <user|bot>`
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
lark-cli wiki +node-delete \
|
||||
--node-token <node_token | obj_token | Lark URL> \
|
||||
[--obj-type <wiki|doc|docx|sheet|bitable|mindnote|slides|file>] \
|
||||
[--space-id <space_id>] \
|
||||
[--include-children=true|false] \
|
||||
--yes \
|
||||
[--as user|bot]
|
||||
|
||||
# Preview the call chain without deleting
|
||||
lark-cli wiki +node-delete --node-token <token> --obj-type wiki --dry-run
|
||||
```
|
||||
|
||||
## Flags
|
||||
|
||||
| Flag | Type | Required | Default | Description |
|
||||
|------|------|----------|---------|-------------|
|
||||
| `--node-token` | string | **Yes** | — | `node_token`, cloud-doc `obj_token`, or a Lark URL embedding one; URL paths also imply `--obj-type` |
|
||||
| `--obj-type` | enum | Conditional | — | Required for a raw token (URL inputs auto-infer). `wiki` = the token is a `node_token`; otherwise the cloud-doc type |
|
||||
| `--space-id` | string | No | — | Auto-resolved via `get_node` when omitted (extra lookup; pass it to skip) |
|
||||
| `--include-children` | bool | No | `true` | Cascade-delete the subtree (default). `--include-children=false` lifts direct children up to the parent |
|
||||
| `--yes` | bool | Yes (real delete) | — | Confirm the high-risk operation. Without it the CLI returns `confirmation_required` |
|
||||
| `--as` | enum | No | `auto` | Identity `user`/`bot`; wiki is user-centric → pass `--as user` |
|
||||
|
||||
## Output
|
||||
|
||||
```json
|
||||
{
|
||||
"space_id": "7160145948494381236",
|
||||
"node_token": "wikcnEXAMPLE",
|
||||
"obj_type": "wiki",
|
||||
"include_children": true,
|
||||
"ready": true,
|
||||
"failed": false,
|
||||
"status": "success",
|
||||
"status_msg": "success"
|
||||
}
|
||||
```
|
||||
|
||||
Async/timeout adds `task_id`, `timed_out`, and `next_command`.
|
||||
|
||||
## Behavior
|
||||
|
||||
- **Task poll**: `GET /open-apis/wiki/v2/tasks/{task_id}?task_type=delete_node`. The status lives under `data.task.simple_task_result.status` (the gateway's generic key — **not** `delete_node_result`); that object has no `status_msg`, so the label falls back to the status code.
|
||||
- **Error hints**:
|
||||
- `131011` → the node has delete-approval enabled; apply via the Wiki UI (CLI cannot bypass approval).
|
||||
- `131003` → subtree too large to cascade-delete; use `--include-children=false` or delete sub-trees first.
|
||||
|
||||
## Required Scope
|
||||
|
||||
`wiki:node:create` (the delete endpoint declares this scope). Auto-resolving `space_id` additionally needs `wiki:node:retrieve`; pass `--space-id` to avoid that lookup.
|
||||
57
.agents/skills/lark-wiki/references/lark-wiki-node-get.md
Normal file
57
.agents/skills/lark-wiki/references/lark-wiki-node-get.md
Normal file
@ -0,0 +1,57 @@
|
||||
# lark-wiki +node-get
|
||||
|
||||
Get a wiki node's details by `node_token`, `obj_token`, or a Lark URL. Use this as the "what am I about to touch?" step before `+move` / `+node-copy` / `+node-delete`.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
lark-cli wiki +node-get \
|
||||
--node-token <node_token | obj_token | Lark URL> \
|
||||
[--obj-type <doc|docx|sheet|bitable|mindnote|slides|file>] \
|
||||
[--space-id <space_id>] \
|
||||
[--format json|pretty|table|csv|ndjson] \
|
||||
[--as user|bot]
|
||||
```
|
||||
|
||||
## Flags
|
||||
|
||||
| Flag | Type | Required | Default | Description |
|
||||
|------|------|----------|---------|-------------|
|
||||
| `--node-token` | string | **Yes** | — | `node_token`, cloud-doc `obj_token`, or a Lark URL embedding one (e.g. `https://feishu.cn/wiki/<token>` or `https://feishu.cn/docx/<token>`). Matches the `--node-token` naming used by sibling `+node-delete` / `+node-copy` / `+move`. |
|
||||
| `--token` | string | — (deprecated) | — | Deprecated original name; still accepted for backward compatibility but emits a `Flag --token has been deprecated, use --node-token instead` warning on stderr. New scripts should use `--node-token`. |
|
||||
| `--obj-type` | enum | No | — | Needed when `--node-token` is a raw `obj_token`; auto-inferred from typed Lark URLs. If omitted for a raw token, the shortcut treats it as a wiki `node_token`. |
|
||||
| `--space-id` | string | No | — | Optional cross-check: fail if the resolved node does not live in this space |
|
||||
| `--format` | enum | No | `json` | `json` / `pretty` / `table` / `csv` / `ndjson` |
|
||||
| `--as` | enum | No | `auto` | Identity `user`/`bot`; wiki is user-centric → pass `--as user` |
|
||||
|
||||
## Output
|
||||
|
||||
```json
|
||||
{
|
||||
"space_id": "7160145948494381236",
|
||||
"node_token": "wikcnEXAMPLE",
|
||||
"obj_token": "docxEXAMPLE",
|
||||
"obj_type": "docx",
|
||||
"node_type": "origin",
|
||||
"parent_node_token": "wikcnPARENT",
|
||||
"origin_node_token": "",
|
||||
"title": "Design Spec",
|
||||
"has_child": true,
|
||||
"creator": "ou_xxx",
|
||||
"owner": "ou_yyy",
|
||||
"obj_edit_time": "1700000000",
|
||||
"obj_create_time": "1690000000",
|
||||
"node_create_time": "1690000001",
|
||||
"updated_at": "2023-11-14T22:13:20Z"
|
||||
}
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- The underlying API is `GET /open-apis/wiki/v2/spaces/get_node`. For a `node_token` no `obj_type` is sent; for an `obj_token` the `obj_type` (explicit or URL-inferred) is required.
|
||||
- `creator` falls back to `creator` when `node_creator` is absent. `updated_at` is `obj_edit_time` formatted as RFC3339.
|
||||
- No `url` is returned: `get_node` does not provide one and a synthesized `www.feishu.cn/wiki/<node_token>` link is non-canonical/misleading for a read command. Use `node_token` / `obj_token` as the identifiers.
|
||||
|
||||
## Required Scope
|
||||
|
||||
`wiki:node:retrieve`
|
||||
95
.agents/skills/lark-wiki/references/lark-wiki-node-list.md
Normal file
95
.agents/skills/lark-wiki/references/lark-wiki-node-list.md
Normal file
@ -0,0 +1,95 @@
|
||||
# lark-wiki +node-list
|
||||
|
||||
List wiki nodes in a space or under a specific parent node. **Default fetches a single page** (large knowledge bases can have thousands of nodes — opt into `--page-all` explicitly with an eye on `--page-limit`).
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# Default: single page of root nodes
|
||||
lark-cli wiki +node-list --space-id <SPACE_ID>
|
||||
|
||||
# Drill into a sub-directory (still single page by default)
|
||||
lark-cli wiki +node-list --space-id <SPACE_ID> --parent-node-token <NODE_TOKEN>
|
||||
|
||||
# Drill with a wiki URL (CLI normalizes /wiki/<token> to node_token)
|
||||
lark-cli wiki +node-list --space-id <SPACE_ID> --parent-node-token "https://feishu.cn/wiki/wikcn_xxx"
|
||||
|
||||
# Personal document library (user identity only)
|
||||
lark-cli wiki +node-list --space-id my_library --as user
|
||||
|
||||
# Walk every page (capped by --page-limit, default 10)
|
||||
lark-cli wiki +node-list --space-id <SPACE_ID> --page-all
|
||||
|
||||
# Walk every page with a higher cap
|
||||
lark-cli wiki +node-list --space-id <SPACE_ID> --page-all --page-limit 30
|
||||
|
||||
# Resume from a cursor
|
||||
lark-cli wiki +node-list --space-id <SPACE_ID> --page-token <TOKEN>
|
||||
|
||||
# Pretty / table output
|
||||
lark-cli wiki +node-list --space-id <SPACE_ID> --format pretty
|
||||
```
|
||||
|
||||
## Flags
|
||||
|
||||
| Flag | Type | Required | Default | Description |
|
||||
|------|------|----------|---------|-------------|
|
||||
| `--space-id` | string | **Yes** | — | Numeric wiki space ID. Use `my_library` for personal document library (user only) |
|
||||
| `--parent-node-token` | string | No | — | Parent wiki node token, or a `/wiki/<token>` URL; omit to list the space root |
|
||||
| `--page-size` | int | No | 50 | Page size, 1-50 |
|
||||
| `--page-token` | string | No | — | Page cursor; implies single-page fetch (no auto-pagination) |
|
||||
| `--page-all` | bool | No | `false` | Automatically paginate through all pages (capped by `--page-limit`) |
|
||||
| `--page-limit` | int | No | 10 | Max pages with `--page-all` (0 = unlimited) |
|
||||
| `--format` | enum | No | `json` | `json` / `pretty` / `table` / `csv` / `ndjson` |
|
||||
| `--as` | enum | No | `auto` | Identity `user`/`bot`; wiki is user-centric → pass `--as user` (`my_library` requires `--as user`) |
|
||||
|
||||
## Output
|
||||
|
||||
```json
|
||||
{
|
||||
"ok": true,
|
||||
"data": {
|
||||
"nodes": [
|
||||
{
|
||||
"space_id": "6946843325487912356",
|
||||
"node_token": "wikcn_EXAMPLE_TOKEN",
|
||||
"obj_token": "doccn_EXAMPLE_TOKEN",
|
||||
"obj_type": "docx",
|
||||
"parent_node_token": "",
|
||||
"node_type": "origin",
|
||||
"title": "Getting Started",
|
||||
"has_child": true
|
||||
}
|
||||
],
|
||||
"has_more": false,
|
||||
"page_token": ""
|
||||
},
|
||||
"meta": { "count": 1 }
|
||||
}
|
||||
```
|
||||
|
||||
When the default single-page fetch (or `--page-all` capped by `--page-limit`) does not exhaust the upstream cursor, `has_more=true` and `page_token=<cursor>` so the caller can resume via `--page-token` or by increasing `--page-limit`.
|
||||
|
||||
## Traverse the wiki tree
|
||||
|
||||
To list all content recursively, call `+node-list` again with each node's `node_token` as `--parent-node-token` when `has_child` is `true`.
|
||||
|
||||
```bash
|
||||
# Step 1: list root nodes
|
||||
lark-cli wiki +node-list --space-id 6946843325487912356
|
||||
|
||||
# Step 2: drill into a node that has children
|
||||
lark-cli wiki +node-list --space-id 6946843325487912356 --parent-node-token wikcn_EXAMPLE_TOKEN
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- `--space-id my_library` is a per-user alias and only valid with `--as user`. The shortcut will refuse `--as bot` with `my_library` upfront.
|
||||
- `--space-id` is a numeric wiki `space_id`. Do not pass a wiki URL, wiki node token, document token, or title. Use `lark-cli wiki +space-list --as user` to discover it.
|
||||
- `--parent-node-token` must resolve to a wiki node token. If you have a docx/sheet/base/file URL, first run `lark-cli wiki +node-get --node-token <url>` and use the returned `node_token`.
|
||||
- Treat `invalid_parameters` (`space_id is not int`, `invalid page_token`), `not_found` (`node not found by parent node token`), and `permission_denied` as terminal for the current arguments. Fix the argument or permission before retrying.
|
||||
- For `rate_limit`, stop immediate retries and retry later with exponential backoff or a smaller `--page-limit`.
|
||||
|
||||
## Required Scope
|
||||
|
||||
`wiki:node:retrieve`
|
||||
@ -0,0 +1,46 @@
|
||||
# lark-wiki +space-create
|
||||
|
||||
Create a wiki space. OpenAPI: `POST /open-apis/wiki/v2/spaces`. This is the project-initialization entry point — the alternative is hand-writing `wiki spaces create --params '{...}'`.
|
||||
|
||||
> The underlying `spaces.create` API is flagged `danger: true` in the schema browser, but it is **not** confirmation-gated (no `--yes`). A space created by mistake is recoverable via `wiki +delete-space`.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
lark-cli wiki +space-create \
|
||||
--name <space_name> \
|
||||
[--description <text>] \
|
||||
[--as user]
|
||||
```
|
||||
|
||||
## Flags
|
||||
|
||||
| Flag | Type | Required | Default | Description |
|
||||
|------|------|----------|---------|-------------|
|
||||
| `--name` | string | **Yes** | — | Wiki space name. Blank/whitespace is rejected (an unnamed space is almost always an accident) |
|
||||
| `--description` | string | No | — | Wiki space description |
|
||||
| `--as` | enum | No | `user` | **User identity only** — the create API does not accept a tenant/bot token; `--as bot` is rejected upfront |
|
||||
|
||||
## Output
|
||||
|
||||
```json
|
||||
{
|
||||
"space_id": "7160145948494381236",
|
||||
"name": "Engineering Wiki",
|
||||
"description": "team docs",
|
||||
"space_type": "team",
|
||||
"visibility": "private",
|
||||
"open_sharing": "closed"
|
||||
}
|
||||
```
|
||||
|
||||
There is no `url` field — the create API does not return one.
|
||||
|
||||
## Notes
|
||||
|
||||
- Only `--as user` is supported; this command declares `AuthTypes: ["user"]` and the framework rejects `--as bot` with a clear message.
|
||||
- `--dry-run` previews the `POST /open-apis/wiki/v2/spaces` request (and surfaces the blank-name validation error early).
|
||||
|
||||
## Required Scope
|
||||
|
||||
`wiki:space:write_only`
|
||||
68
.agents/skills/lark-wiki/references/lark-wiki-space-list.md
Normal file
68
.agents/skills/lark-wiki/references/lark-wiki-space-list.md
Normal file
@ -0,0 +1,68 @@
|
||||
# lark-wiki +space-list
|
||||
|
||||
List wiki spaces accessible to the caller. **Default fetches a single page** (matches the rest of the CLI's list shortcuts); pass `--page-all` to walk every page.
|
||||
|
||||
## Usage
|
||||
|
||||
```bash
|
||||
# Default: single page (first up to --page-size items)
|
||||
lark-cli wiki +space-list
|
||||
|
||||
# Walk every page (capped by --page-limit, default 10)
|
||||
lark-cli wiki +space-list --page-all
|
||||
|
||||
# Walk every page, no cap (use with care if you have many spaces)
|
||||
lark-cli wiki +space-list --page-all --page-limit 0
|
||||
|
||||
# Resume from a specific cursor (single-page fetch regardless of --page-all)
|
||||
lark-cli wiki +space-list --page-token <TOKEN>
|
||||
|
||||
# Pretty / table / csv / ndjson output
|
||||
lark-cli wiki +space-list --format pretty
|
||||
lark-cli wiki +space-list --format table
|
||||
```
|
||||
|
||||
## Flags
|
||||
|
||||
| Flag | Type | Default | Description |
|
||||
|------|------|---------|-------------|
|
||||
| `--page-size` | int | 50 | Page size, 1-50 |
|
||||
| `--page-token` | string | — | Page cursor; implies single-page fetch (no auto-pagination) |
|
||||
| `--page-all` | bool | `false` | Automatically paginate through all pages (capped by `--page-limit`) |
|
||||
| `--page-limit` | int | 10 | Max pages with `--page-all` (0 = unlimited) |
|
||||
| `--format` | enum | `json` | `json` / `pretty` / `table` / `csv` / `ndjson` |
|
||||
| `--as` | enum | `auto` | Identity `user`/`bot`; wiki is user-centric → pass `--as user` |
|
||||
|
||||
## Output
|
||||
|
||||
```json
|
||||
{
|
||||
"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 }
|
||||
}
|
||||
```
|
||||
|
||||
When the default single-page fetch (or `--page-all` capped by `--page-limit`) does not exhaust the upstream cursor, `has_more=true` and `page_token=<cursor>` so the caller can resume via `--page-token` or by increasing `--page-limit`.
|
||||
|
||||
## Notes
|
||||
|
||||
- **The underlying API never returns the my_library personal library**; resolve it via `lark-cli wiki spaces get --params '{"space_id":"my_library"}'`.
|
||||
- Use `space_id` from the output as `--space-id` for `+node-list` or `+node-copy`.
|
||||
|
||||
## Required Scope
|
||||
|
||||
`wiki:space:retrieve`
|
||||
Reference in New Issue
Block a user