---
name: wecomcli-disk
version: 1.0.0
description: 何时用:仅当用户明确指向企业微信微盘/网盘/共享空间或给出 drive.weixin.qq.com 链接时使用;泛指文件管理默认走本地文件工具。微盘文件级操作:列出、搜索、读取元信息、上传、下载、重命名、新建文件夹;在线文档内容读写走 doc/sheet/smartsheet/smartpage 对应技能,不由本技能接管。
metadata:
  requires:
    bins: ["wecom-cli"]
  cliHelp: "wecom-cli disk --help"
---

# 企业微信微盘

> 执行任何 `wecom-cli` 命令前，必须先读取并完成 `wecomcli-shared` 技能的公共前置检查。

资源型 skill，负责微盘文件的列出、搜索、读取信息、上传、下载、重命名与新建文件夹。

## 适用范围

### 适用

- 列出微盘最近查看的文件
- 按关键词/类型/创建者/共享空间搜索微盘文件或文件夹
- 读取微盘文件基础信息
- 上传本地文件到微盘指定文件夹
- 下载微盘文件到本地
- 重命名微盘文件
- 在微盘中新建文件夹

### 不适用

- 移动微盘文件或文件夹 → 告知用户暂未支持，建议前往企业微信客户端手动操作
- 删除微盘文件 / 复制微盘文件 → 告知用户暂未支持，建议前往企业微信客户端手动操作
- 删除 / 重命名微盘文件夹（`folder`）、调整目录树结构 → 告知用户暂未支持，建议前往企业微信客户端手动操作
- 创建 / 删除共享空间（`space`）、修改空间成员与空间设置 → 告知用户暂未支持，建议前往企业微信客户端手动操作
- 给机器人授予某空间的权限 / 把机器人加入共享空间成员 → 微盘**没有**该功能，任何渠道都做不到（客户端也不行）。**禁止**向用户提出这类建议，也不要引导用户"联系空间管理员给机器人授权"
- 修改文件分享权限、生成分享链接、撤销分享、设置访问密码 / 有效期 → 告知用户暂未支持，建议前往企业微信客户端手动操作
- 微盘文件版本管理（查看历史版本、恢复旧版本、比对版本） → 告知用户暂未支持
- 撤销 / 修改已上传的文件（覆盖上传 / 秒传 / 断点续传） → 告知用户暂未支持；如需替换，请重新走「上传文件」上传一份新文件
- 解析微盘文件的**内容**（正文提取、OCR、看图问答、PDF/Word/Excel 解析等） → 本 skill 负责把文件下载到本地拿 `file_path`
- 视频 / 音频文件的转写或字幕生成 → 告知用户暂未支持
- 持续监视微盘变更 / 实时通知新文件到达 → 无法主动监视，不要承诺「有新文件时告知你」，请让用户稍后主动再次发起查询

### 路由决策（判断本 skill / 其他 skill）

| 用户输入信号 | 路由到 |
|---|---|
| 明确提"微盘 / 网盘 / disk / Wecom 网盘" | 本 skill |
| 提供 `https://drive.weixin.qq.com/s?k=...` 链接（微盘分享 URL） | 本 skill（作为 `get` / `download` 的 `url` 入参） |
| 提供 `https://doc.weixin.qq.com/<doc\|sheet\|smartsheet\|smartpage>/...` 链接 | 对应 `wecomcli-doc` / `wecomcli-sheet` / `wecomcli-smartsheet` / `wecomcli-smartpage` |
| 在线文档 `doc` / `sheet` / `smartsheet` / `smartpage` 的读写内容 | 同上对应文档 skill |
| 改文档权限 / 加成员 / 改文档名（针对 doc/sheet/smartsheet/smartpage） | `wecomcli-doc-manage` |

> 注意：`doc.weixin.qq.com` / `page.weixin.qq.com` 是在线文档域名，`drive.weixin.qq.com` 才是微盘域名，切勿混用。

### 文件类型枚举

`doc`（在线文档）、`sheet`（在线表格）、`ppt`（在线幻灯片）、`collect`（收集表）、`mind`（思维导图）、`flow`（流程图）、`smartsheet`（智能表格）、`smartpage`（智能主页）、`journal`（汇报）、`pdf`（PDF）、`offline_word`（离线 Word）、`offline_excel`（离线 Excel）、`offline_ppt`（离线 PPT）、`offline_pdf`（离线 PDF）、`image`（图片）、`videoaudio`（视频音频）、`design`（设计稿）。在线文档保持原名，离线文件用 `offline_` 前缀区分。腾讯文档不在本 skill 范围，按【路由决策】表改走对应文档 skill。

> **在线/离线模糊时同时搜**：用户说「Excel」「Word」「PPT」「PDF」等未明确在线还是离线时，`file_types` 同时传入在线版和离线版（如 `["sheet", "offline_excel"]`），避免遗漏。其余类型按上方枚举名按字面对应传入即可。

## 接口详述

### 列出文件

获取用户微盘最近查看的文件列表，支持分页。

**命令**

```bash
wecom-cli disk files list --json '{"limit": 10}'
```

**入参**

| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|:----:|---|---|
| `cursor` | string | 否 | `""` | 分页游标；不传或传空串则获取首页数据 |
| `limit` | number | 否 | 10 | 每页返回的最大条数；不传则使用服务默认值，最大 100 |

**返回**

| 字段 | 类型 | 说明 |
|---|---|---|
| `has_more` | boolean | 是否还有更多数据；`true` 时用 `next_cursor` 续取 |
| `next_cursor` | string | 下一页游标 |
| `files[].id` | string | 文件 ID 或文件夹 ID |
| `files[].file_name` | string | 文件名称 |
| `files[].docid` | string | 文档 ID，仅 `type=smartsheet` / `smartpage` / `sheet` / `word` / `ppt` / `collect` / `journal` 时有意义 |
| `files[].type` | string | 文件类型：`file` / `folder` / `space` / `smartsheet` / `smartpage` / `sheet` / `word` / `ppt` / `collect` / `journal` / `flow` / `mind` |
| `files[].file_size` | number | 文件大小（字节）；仅 `type=file` 时有意义 |
| `files[].creator_userid` | string | 创建者 userid |
| `files[].space_id` | string | 所属共享空间 ID |
| `files[].space_name` | string | 所在共享空间名称 |
| `files[].folder_id` | string | 所在文件夹 ID |
| `files[].folder_name` | string | 所在文件夹名称 |
| `files[].create_time` | string | 创建时间，`YYYY-MM-DD HH:mm:ss` |
| `files[].update_time` | string | 最后更新时间，`YYYY-MM-DD HH:mm:ss` |
| `files[].path` | string | 文件完整路径 |
| `files[].doc_url` | string | 文档打开链接，仅在线文档类型（`smartsheet` / `smartpage` / `sheet` / `word` / `ppt` / `collect` / `journal`）时填充 |

### 搜索文件

按关键词、文件类型、创建者、共享空间、排序等条件搜索微盘文件、文件夹或共享空间。

**命令**

```bash
wecom-cli disk files search --json '{"keywords": ["季度汇报"], "search_type": "file", "sort_by": "modify_time", "sort_order": "desc", "limit": 10}'
```

**入参**

| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|:----:|---|---|
| `keywords` | string[] | 选填 | — | 字面关键词数组，长度 0~20（or 关系）；与 `creator_userids` / `search_type` / `file_types` **四选一，至少传一个**   |
| `creator_userids` | string[] | 选填 | — | 限定创建者 `userid` 列表，长度 0~50，不传则不过滤；与 `keywords` / `search_type` / `file_types` **四选一，至少传一个**；用户给的是姓名时通过 `wecomcli-contact` 解析为 `userid` |
| `search_type` | string | 选填 | `all` | 查询范围枚举：`all` / `file`（文件）/ `folder`（文件夹）/ `space`（共享空间）；与 `keywords` / `creator_userids` / `file_types` **四选一，至少传一个**； |
| `file_types` | string[] | 选填 | — | 限定文件类型，长度 0~10；可选 `doc` / `sheet` / `ppt` / `collect` / `mind` / `flow` / `smartsheet` / `smartpage` / `journal` / `pdf` / `offline_word` / `offline_excel` / `offline_ppt` / `offline_pdf` / `image` / `videoaudio` / `design`（在线文档保持原名，离线文档用 `offline_` 前缀区分）；不得传枚举外的值；与 `keywords` / `creator_userids`/ `search_type` **四选一，至少传一个**|
| `space_keywords` | string[] | 否 | — | 限定所在空间名称的关键词，长度 0~10，or 关系；命中的 space 会被作为搜索范围；不传则不限空间；**附加过滤条件，不能单独触发搜索** |
| `sort_by` | string | 否 | `best_match` | 排序方式：`best_match` / `modify_time` / `file_size`；不得传枚举外的值 |
| `sort_order` | string | 否 | `desc` | 排序方向：`asc` / `desc`；仅在 `sort_by=modify_time` 或 `file_size` 时需传 |
| `cursor` | string | 否 | — | 分批拉取增量 key，上一次请求返回的 `next_cursor`；不传则从头开始 |
| `limit` | number | 否 | 10 | 每页最大返回条数，最大 100 |

**返回**

| 字段 | 类型 | 说明 |
|---|---|---|
| `has_more` | boolean | 是否还有更多数据；`true` 时用 `next_cursor` 续取 |
| `next_cursor` | string | 下一页游标 |
| `files[].id` | string | 微盘文件 ID / 文件夹 ID / 空间 ID |
| `files[].type` | string | 命中项类型：`file` / `folder` / `space` / `smartsheet` / `smartpage` / `sheet` / `word` / `ppt` / `flow` / `mind` / `journal` / `collect`|
| `files[].file_name` | string | 名称（文件名 / 文件夹名 / 空间名） |
| `files[].file_size` | number | 文件大小（字节），仅 `type=file` 时有意义 |
| `files[].creator_userid` | string | 创建者 userid |
| `files[].space_id` | string | 所在共享空间 ID |
| `files[].space_name` | string | 所在共享空间名称 |
| `files[].folder_id` | string | 所在父文件夹 ID；位于空间根目录时等于 `space_id` |
| `files[].folder_name` | string | 所在文件夹名称 |
| `files[].path` | string | 文件完整路径；`space_name` 与 `folder_name` 同名时不一定是父子关系，可能平级，以 `path` 为准判断层级 |
| `files[].create_time` | string | 创建时间，`YYYY-MM-DD HH:mm:ss` |
| `files[].update_time` | string | 最近更新时间，`YYYY-MM-DD HH:mm:ss` |
| `files[].docid` | string | 文档 ID，仅 `type=smartsheet` / `smartpage` / `sheet` / `word` / `ppt` / `collect` / `journal` 时有意义 |
| `files[].doc_url` | string | 文档打开链接，仅在线文档类型时填充；**可直接作为在线文档分享链接发送给用户/群，无需额外处理** |
| `files[].title_highlight` | string[] | 标题命中关键词的高亮摘要片段；`type=space` 时为空 |
| `files[].text_highlight` | string[] | 正文命中关键词的高亮摘要片段；`type=space` 时为空 |

> **在线文档命中项处理约束——极重要**：搜索返回的 `type` 若为 `smartsheet` / `smartpage` / `sheet` / `word` / `ppt` / `journal` / `collect` / `mind` / `flow`，这些是**在线协作文档**（正文存云端，非二进制文件），**禁止**走 `disk files download`（会失败或拿到空壳），也不适合走 `disk files get`。其中 `smartsheet` / `smartpage` / `sheet` / `word` 有对应的下游 skill 可读正文，路由见文末【跨技能依赖】表；**`ppt` / `journal` / `collect` / `mind` / `flow` 目前没有任何下游 skill 或 CLI 能读取正文**，命中这些类型且用户要看内容时，直接告知暂不支持读取，引导用户用 `doc_url` 在企业微信客户端内打开查看。仅当 `type=file` 时才可用 `id` 作为 `file_id` 调 `disk files download` 拿本地文件。

**使用规则**

- **触发条件（唯一权威描述）**：`keywords` / `creator_userids` / `search_type` / `file_types` **四选一，至少传一个**；`space_keywords` 只是附加过滤条件，**不能单独触发搜索**。若四者全空则用自然语言追问后再发起搜索。若用户仅给出空间关键词（如「在 XX 空间里搜一下」），可用自然语言追问具体搜索内容。
- **多次搜不到就如实告知**：多次调整关键词/类型后仍无结果时，停止搜索，如实告知用户是「搜不到文件」还是「搜不到该空间」，不要反复换词硬搜。
- **可选参数传值策略——默认不传，仅在用户明确点名时才传**：

  | 参数 | 何时不传（后端默认） | 何时传（用户明确表达时） |
  |---|---|---|
  | `search_type` | 用户笼统说"搜一下 xxx / 找 xxx / 文件 / 资料"等未明确对象类型 → 后端按 `all` | 明确说"只搜文件夹 / 目录"→`folder`；"只搜共享空间 / 团队空间"→`space`；"只要文件，不要文件夹"→`file` |
  | `sort_by` | 用户无排序偏好 → 后端按 `best_match` | "最新 / 最近改 / 最早"→`modify_time`；"最大 / 最小"→`file_size` |
  | `sort_order` | `sort_by=best_match` 时无需传 | 传 `modify_time` / `file_size` 时按新→旧用 `desc`、旧→新用 `asc`；不传则默认 `desc` |
  | `file_types` | 用户笼统说"文档 / 文件 / 资料 / 材料"或业务概念（合同 / 报告 / 会议纪要）→ 不过滤，靠 `keywords` 兑现 | 用户明确点到具体形态（PPT / Excel / PDF / 图片 / 智能表格 等），把对应枚举一并塞入数组 |
  | `space_keywords` | 不限空间时 | 用户说"在 XX 空间 / XX 团队盘里搜" → 填空间名关键词（本接口不接受 `space_id`） |

- **`keywords` 不要混入文件类型后缀**：用户说「搜一下 Excel 报告」「找 PPT 方案」时，文件类型后缀（Excel/PPT/Word/PDF）交给 `file_types` 过滤，`keywords` 只保留业务关键词（如「报告」「方案」）。例：「Excel 报告」→ `keywords:["报告"]` + `file_types:["sheet","offline_excel"]`。
- **`file_types` 口语→枚举映射**：见上方「文件类型枚举」表中的「用户口语表达」列。
- **分页续传**：`has_more=true` 时用 `next_cursor` 作为下一次调用的 `cursor`；首次调用 `cursor` 传空串。
- **不支持时间范围过滤**：本接口没有 `begin_time` / `end_time` 字段，禁止伪造；若用户给出"最近 3 天 / 上周 / 本月"等时间范围，先按 `sort_by=modify_time`, `sort_order=desc` 拉取，再由客户端根据 `update_time` 二次筛选。
- **结果总结顺序跟随排序方向**：`sort_order=desc`（默认，新→旧）时，向用户总结结果也应从最新到最旧展示，不要颠倒顺序。

### 读取文件信息

根据 `file_id` 或微盘文件 URL 读取文件基础信息。

**命令**

```bash
wecom-cli disk files get --json '{"file_id": "FILE_ID"}'
```

**入参**

| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|:----:|---|---|
| `file_id` | string | 二选一 | — | 文件 ID；与 `url` 二选一；同时提供时优先使用 `file_id` |
| `url` | string | 二选一 | — | 微盘文件分享 URL（形如 `https://drive.weixin.qq.com/s?k=AJEAIQdfAAoN4N17GM`）；与 `file_id` 二选一 |

**返回**

| 字段 | 类型 | 说明 |
|---|---|---|
| `file.id` | string | 文件 ID 或文件夹 ID |
| `file.file_name` | string | 文件名称 |
| `file.docid` | string | 文档 ID，仅 `type=smartsheet` / `smartpage` / `sheet` / `word` / `ppt` / `collect` / `journal` 时有意义 |
| `file.type` | string | 文件类型：`file` / `folder` / `space` / `smartsheet` / `smartpage` / `sheet` / `word` / `ppt` / `collect` / `journal` / `flow` / `mind` |
| `file.file_size` | number | 文件大小（字节）；仅 `type=file` 时有意义 |
| `file.creator_userid` | string | 创建者 userid |
| `file.space_id` | string | 所属共享空间 ID |
| `file.space_name` | string | 所在共享空间名称 |
| `file.folder_id` | string | 所在文件夹 ID，可能为文件夹 `file_id` 或空间 `space_id` |
| `file.folder_name` | string | 所在文件夹名称 |
| `file.create_time` | string | 创建时间，`YYYY-MM-DD HH:mm:ss` |
| `file.update_time` | string | 最后更新时间，`YYYY-MM-DD HH:mm:ss` |
| `file.path` | string | 文件完整路径 |
| `file.doc_url` | string | 文档打开链接，仅在线文档类型（`smartsheet` / `smartpage` / `sheet` / `word` / `ppt` / `collect` / `journal`）时填充 |

### 上传文件

将本地文件上传到微盘指定目录。支持两种上传方式：**A. 素材方式** 上下文中已有 `media_id` 时直接传 `file_content_media`；**B. 本地路径方式** 直接传 `file_path`。两者二选一。

**命令**

```bash
wecom-cli disk files upload --json '{"folder_id": "FOLDER_ID", "file_name": "季度汇报.pptx", "file_content_media": "mcxxx"}'
```

或直接使用本地文件路径：

```bash
wecom-cli disk files upload --json '{"folder_id": "FOLDER_ID", "file_name": "季度汇报.pptx", "file_path": "/tmp/季度汇报.pptx"}'
```

**入参**

| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|:----:|---|---|
| `folder_id` | string | 否 | — | 目标文件夹 ID；可传文件夹 `file_id` 或空间 `space_id`；不传则默认上传到默认空间 |
| `file_name` | string | 条件必填 | — | 文件名称（含扩展名）；长度 1~255；禁止包含字符 `/ \ : * ? " < > \|`；传 `file_path` 时不传则从路径自动提取，传 `file_content_media` 时必填 |
| `file_content_media` | string | 二选一 | — | 文件素材的 `media_id`（前缀 `mc`），禁止自行构造或猜测；与 `file_path` 二选一 |
| `file_path` | string | 二选一 | — | 本地文件绝对路径；与 `file_content_media` 二选一，两者必须提供其一 |

**返回**

| 字段 | 类型 | 说明 |
|---|---|---|
| `file.id` | string | 上传后的文件 ID |
| `file.file_name` | string | 文件名称 |
| `file.docid` | string | 文档 ID，仅 `type=smartsheet` / `smartpage` / `sheet` / `word` / `ppt` / `collect` / `journal` 时有意义 |
| `file.type` | string | 文件类型 |
| `file.file_size` | number | 文件大小（字节）；仅 `type=file` 时有意义 |
| `file.creator_userid` | string | 创建者 userid |
| `file.space_id` | string | 所属共享空间 ID |
| `file.space_name` | string | 所在共享空间名称 |
| `file.folder_id` | string | 所在文件夹 ID |
| `file.folder_name` | string | 所在文件夹名称 |
| `file.create_time` | string | 创建时间 |
| `file.update_time` | string | 最后更新时间 |
| `file.path` | string | 文件完整路径 |
| `file.doc_url` | string | 文档打开链接，仅在线文档类型时填充 |

**使用规则**

上传分两条路径，按用户手上的素材形态选一条即可：

**路径 A：素材方式（`file_content_media`）**

适用场景：上下文中**已有可用的 `media_id`**（前置技能返回的、或用户直接给出的），无需再走 `media +upload`。

1. 确认 `folder_id`：用户没提供时不传则默认上传到默认空间
2. 直接把已有的 `media_id` 填入 `file_content_media`，调 `disk files upload`

**路径 B：本地路径方式（`file_path`）**

1. 用户已经明确给出本地文件路径（或前置技能返回了本地 `file_path`，例如 `disk files download` 下载后的路径）时可直接使用
2. 确认 `folder_id`：用户没提供时不传则默认上传到默认空间
3. 直接把本地路径填入 `file_path`，调 `disk files upload`（不需要再走 `wecomcli-media`）

> **二选一互斥**：`file_content_media` 与 `file_path` 只能选其中之一，不能同时传，也不能都不传。用户既没给 `media_id` 也没给本地文件路径时用自然语言追问，禁止靠搜索/幻觉凑一个文件。

### 下载文件

将微盘文件下载到本地，返回本地文件路径。

**命令**

```bash
wecom-cli disk files download --json '{"file_id": "FILE_ID"}'
```

**入参**

| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|:----:|---|---|
| `file_id` | string | 二选一 | — | 要下载的文件 ID，与 `url` 二选一；不传则必须传 `url` |
| `url` | string | 二选一 | — | 文件 URL，与 `file_id` 二选一；不传则必须传 `file_id` |

**返回**

| 字段 | 类型 | 说明 |
|---|---|---|
| `file_path` | string | 框架保存为本地文件后返回的文件路径 |
| `file_content` | string | 文件内容（内容不长时直接返回字符串） |
| `size` | number | 文件大小，单位字节 |

**使用规则**

- **仅适用于离线二进制文件**：只有 `type=file`（对应 `file_types` 中的 `offline_word` / `offline_excel` / `offline_ppt` / `offline_pdf` / `image` / `videoaudio` / `design`）才能通过本接口下载到本地。
- **在线文档形态一律不走下载**：若搜索返回的 `type` 是 `smartsheet` / `smartpage` / `sheet` / `word` / `ppt` / `journal` / `collect` / `mind` / `flow`，**禁止**把它们的 `id` 或 `doc_url` 当 `file_id` / `url` 传入本接口，会失败或拿到无效文件。其中 `smartsheet` / `smartpage` / `sheet` / `word` 要读取内容请按文末【跨技能依赖】表用 `docid` 路由到对应的下游文档技能；`ppt` / `journal` / `collect` / `mind` / `flow` 目前**没有下游技能可读正文**，直接告知用户暂不支持，引导其用 `doc_url` 在企业微信客户端内打开查看。
- **URL 形态识别**：只有 `https://drive.weixin.qq.com/s?k=...` 是微盘文件分享 URL，可作为 `url` 参数；`https://doc.weixin.qq.com/...` / `https://page.weixin.qq.com/...` 都是在线文档链接，禁止传入本接口。

### 重命名文件

修改微盘文件名称。

**命令**

```bash
wecom-cli disk files rename --json '{"file_id": "FILE_ID", "new_name": "新文件名称.xlsx"}'
```

**入参**

| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|:----:|---|---|
| `file_id` | string | 是 | — | 文件 ID（必填） |
| `new_name` | string | 是 | — | 新的文件名称（必填，含扩展名）；长度 1~255；禁止包含字符 `/ \ : * ? " < > \|` |

**返回**

| 字段 | 类型 | 说明 |
|---|---|---|
| `status` | string | 操作结果，成功时为 `"success"` |

> 本接口不返回 `file` 对象；如需最新元数据，可再走「读取文件信息」。

### 创建文件夹

在微盘指定目录下创建新文件夹。

**命令**

```bash
wecom-cli disk folders create --json '{"folder_id": "FOLDER_ID", "folder_name": "新建文件夹"}'
```

**入参**

| 字段 | 类型 | 必填 | 默认值 | 说明 |
|---|---|:----:|---|---|
| `folder_id` | string | 选填 | — | 目标父文件夹 ID；可传文件夹 `file_id` 或空间 `space_id`，不传则默认创建到个人空间根目录 |
| `folder_name` | string | 是 | — | 文件夹名称 |

**返回**

| 字段 | 类型 | 说明 |
|---|---|---|
| `folder.id` | string | 文件夹 ID |
| `folder.file_name` | string | 文件夹名称 |
| `folder.docid` | string | 文档 ID，仅在线文档类型时有意义 |
| `folder.type` | string | 文件类型：`folder` |
| `folder.file_size` | number | 文件大小（字节）；仅 `type=file` 时有意义 |
| `folder.creator_userid` | string | 创建者 userid |
| `folder.space_id` | string | 所属共享空间 ID |
| `folder.space_name` | string | 所在空间名；对空间有权限时才返回，与 `space_id` 同时出现 |
| `folder.folder_id` | string | 所在父文件夹 ID，可能为文件夹 `file_id` 或空间 `space_id` |
| `folder.folder_name` | string | 所在父文件夹名；对父文件夹有权限时才返回，与 `folder_id` 同时出现 |
| `folder.create_time` | string | 创建时间，`YYYY-MM-DD HH:mm:ss` |
| `folder.update_time` | string | 最后更新时间，`YYYY-MM-DD HH:mm:ss` |
| `folder.path` | string | 文件夹完整路径 |
| `folder.doc_url` | string | 文档打开链接，仅在线文档类型时填充 |

## 关键约束

- **文件名不是 `file_id`**：用户给的是文件名/关键词时，先走 `disk files search` 拿 `file_id`，禁止把文件名直接当 `file_id` 拼接。
- **上传素材来源约束**：`upload` 的 `file_content_media` 与 `file_path` 二选一，两者必须提供其一，不能同时传。`file_content_media` 必须是合法的 `media_id`（前缀 `mc`），禁止自行构造或猜测；`file_path` 只能是用户明确给出或前置技能返回的**真实本地文件路径**，禁止编造。两者都没有时用自然语言追问，禁止靠搜索/幻觉凑一个文件。
- **搜索必须有界**：一组条件搜完必要时再调整一次；2~3 轮仍无结果就停下来如实告知用户"未搜到"，并请用户提供更准确的关键词/文件类型/创建者，禁止无限换关键词硬搜。
- **CLI 报错原样转达**：命令返回明确错误码时如实告知用户并给替代建议，禁止用 curl / python 等通用手段绕过 CLI 强行完成。
- **内部 ID 不外露**：`creator_userid` / `space_id` / `folder_id` / `file_id` / `docid` 等任何 ID 仅用于后续接口调用，**禁止**直接展示给用户；`creator_userid` 若需展示创建者信息，先用 `wecomcli-contact` 解析为姓名。
- **重名空间/文件夹时追问**：搜索返回多个同名空间或文件夹时，用自然语言追问让用户选择具体目标，禁止随意选第一个或猜一个。
- **参数缺失 / 多候选 / 意图确认**：用自然语言追问让用户明确，不要瞎猜。

## 结果展示规范

向用户展示 `list` / `search` 结果时严格遵守：

- **用 markdown 无序列表逐条展示，禁止使用表格**——最多展示 10 条。
- 每条首行：该项返回的 `doc_url` 非空时（在线文档），写成 `- [文件名](doc_url)` 形式的 markdown 链接；`doc_url` 为空时（离线文件、文件夹、空间等），写成 `- 文件名`，不得编造链接。副行可展示 `path` / `update_time` / 可读的 `file_size`（如 `2.4 MB`），字段之间用 `·` 或空格分隔。
- **禁止**直接展示原始 JSON、`creator_userid` / `space_id` / `folder_id` / `id` 等内部 ID。

## 跨技能依赖

| 依赖技能 | 何时触发 | 使用被依赖 skill 做什么 |
|---|---|---|
| `wecomcli-doc` | 搜索命中项 `type=word` / `doc`，用户要"读一下内容" | 拿返回的 `docid` 交给 `wecom-cli doc 'contents get'` 读取正文（`docid` 以 `a1_` / `b1_` 开头的除外，走 `wecomcli-smartpage`） |
| `wecomcli-sheet` | 搜索命中项 `type=sheet`（在线表格），用户要读内容 | 拿返回的 `docid` 交给 `wecomcli-sheet` 对应读取接口 |
| `wecomcli-smartsheet` | 搜索命中项 `type=smartsheet`（智能表格），用户要读内容 | 拿返回的 `docid` 交给 `wecomcli-smartsheet` 对应读取接口 |
| `wecomcli-smartpage` | 搜索命中项 `type=smartpage`（智能主页），或 `type=word` 且 `docid` 以 `a1_` / `b1_` 开头，用户要读内容 | 拿返回的 `docid` 交给 `wecomcli-smartpage` 对应读取接口 |
| `wecomcli-doc-manage` | 命中项是 word/sheet/smartsheet/smartpage 且用户要求改文档权限 / 加成员 / 改文档名 | 交由 `wecomcli-doc-manage` 处理；其余在线/离线类型（file/collect/mind/flow/journal/ppt/pdf 等）的改名走本 skill 的 rename；`folder`（文件夹）不支持重命名（见【适用范围】），告知用户暂未支持，建议前往企业微信客户端手动操作 |

> 参数缺失 / 多候选 / 意图确认时，用自然语言追问让用户明确。
