feat(dingtalk-workspace): add USAGE.md and wire feature docs into skill references (#113)

## 背景 / Background

`agents/dingtalk-workspace` 条目把 13 篇使用文档放在 `docs/` 目录,但**两侧都读不到**:

- 市场详情页只渲染 `agent.json` 的元数据字段,不扫描条目目录下的 `docs/`
- Agent 自身的上下文只挂载 `persona.md` / `principles.md` / `memory/` /
`skills/`,`docs/` 不在其中

The listing kept 13 usage documents under `docs/`, but nothing consumed
them: the
market detail page only projects `agent.json` metadata, and the agent's
own context
mounts `persona.md` / `principles.md` / `memory/` / `skills/` only.

## 变更 / Changes

配合 DesireCore 主仓库的 `USAGE.md` 平台约定(ADR-143)与既有技能 `references` 机制,分别解决两侧。
Pairs with the new `USAGE.md` platform convention (ADR-143) in the
DesireCore repo.

| 变更 / Change | 说明 / Detail |
| --- | --- |
| 新增 `USAGE.md` | 安装前该知道的内容:第三方 CLI 依赖声明、5
步快速开始、六种审批模式取舍、安全与已知边界。**刻意不含图片**——详情页的 markdown 渲染器会移除普通 `img src` |
| 新增私有技能 `dingtalk-guide` | 只做索引,正文用 `${SKILL_DIR}/references/` 绝对路径指向
13 篇文档,Agent 按需 `Read`。单产品问题(如「钉盘同步怎么用」)可触发查文档再作答,不占每轮上下文 |
| `docs/` → `dingtalk-guide/references/` | 整体移入并拍平。原 12
篇无交叉链接、无图片,移动无需改写正文 |
| `docs/README.md` 拆分 | 安装部分 → `USAGE.md`;界面与审批部分连同两张截图 →
`references/界面与审批.md` |
| `README.md` | 补 `USAGE.md` 约定说明与目录树条目 |
| `manifest.json` | 1.5.0 → 1.5.1(条目内容新增;计数不变,经校验器实跑确认) |

**单一真相源 / Single source of truth**:每篇文档只有一份,归 `dingtalk-guide` 技能所有;
不存在 `docs/` 与 `references/` 两份副本。`dingtalk-onboarding` 与
`dingtalk-workflows`
两个既有技能不变。

## 校验 / Validation

README 记录的 7 条 CI 校验命令全部实跑通过(改动前后各一轮):

```
scripts/i18n/test_validate_i18n.py                              exit=0
scripts/catalog/test_validate_catalog_metadata.py               exit=0
scripts/catalog/test_collection_generator.py                    exit=0
scripts/catalog/validate_catalog_metadata.py --require-complete  exit=0
scripts/i18n/validate-i18n.py                                   exit=0
scripts/i18n/translate.py --check                               exit=0
scripts/gen-collection-children.py --check                      exit=0
```

`manifest.json#stats` 由 `validate_catalog_metadata` 输出实跑确认(agents=3,
teams=1,
publishableSkills=69),非算术推导,故不变。

## 公开信息边界 / Public information boundary

全树扫描零命中:改动文件、新增路径名、分支名、commit 主题与正文、本 PR 文本均不含
租户/客户/伙伴/个人身份。两张截图已逐张目视复核——仅含 DesireCore 自身界面、Agent 名称与
通用 `dws` 命令,返回结果为空列表,不含组织名或任何组织形态。

Full-tree scan returned zero results. Both screenshots were reviewed
individually:
they show only DesireCore's own UI, the agent name, and generic `dws`
commands.

## 依赖 / Dependency

`USAGE.md` 的详情页渲染依赖 DesireCore 主仓库的配套 PR。在其发布前,本条目的
`USAGE.md` 仍是仓库内可读的普通文件,不影响现有行为。

Detail-page rendering depends on the companion PR in the DesireCore
repository.
Until it ships, `USAGE.md` is simply a readable file in the listing and
changes nothing.
This commit is contained in:
2026-09-04 00:08:53 -04:00
committed by GitHub
parent aec2e7c28b
commit a8361009b9
20 changed files with 250 additions and 143 deletions

View File

@@ -0,0 +1,50 @@
---
name: dingtalk-guide
description: >-
钉钉能力覆盖与边界查询。Use when 用户问某个钉钉产品「怎么用 / 支不支持 / 能不能做 /
有什么限制 / 为什么不行」,或需要按产品域查功能覆盖、权益门槛、已知边界(如「钉盘同步怎么用」
「消息搜索为什么返回受限」「视频会议能做到哪一步」「为什么每条命令都要审批」)。也用于 dws
报错后的分诊。本技能只回答「能力与边界」,不执行钉钉业务操作——具体命令走 dingtalk-* 官方技能,
安装与自检走 dingtalk-onboarding跨产品编排走 dingtalk-workflows。
metadata:
category: reference
requires:
tools: [Read]
---
# 钉钉能力说明查询
本技能不含答案正文,只含**索引**。回答前先 Read 下表中匹配的参考文件,按文件内容作答;
不要凭记忆回答产品边界与权益门槛——这些随钉钉侧开通状态变化,写死会误导用户。
## 使用方式
1. 从用户问题里识别产品域,在下表定位文件
2. `Read` 该文件的绝对路径(`${SKILL_DIR}` 会被替换成本技能目录)
3. 按文件内容作答;文件没覆盖的,如实说不确定,并给出 `dws schema` 的自查方式
4. 命中多个产品域时按需读多个文件,不要只读第一个
## 参考文件索引
| 问题涉及 | Read 这个文件 |
| --- | --- |
| 找人、通讯录、语义搜索、多候选 | `${SKILL_DIR}/references/通讯录与找人.md` |
| 发消息、撤回、群管理、机器人、**消息搜索权益** | `${SKILL_DIR}/references/群聊与消息.md` |
| 日程、会议室、闲忙、**视频会议边界** | `${SKILL_DIR}/references/日程与会议.md` |
| 待办、TODO、OA 审批查询与处理 | `${SKILL_DIR}/references/待办与审批.md` |
| 在线文档、电子表格、AI 多维表、导出 | `${SKILL_DIR}/references/文档与表格.md` |
| 钉盘、知识库、文件与节点的分界 | `${SKILL_DIR}/references/钉盘与知识库.md` |
| 邮件收发、搜索、附件 | `${SKILL_DIR}/references/邮件.md` |
| AI 听记、摘要、逐字稿、行动项 | `${SKILL_DIR}/references/AI听记.md` |
| 考勤打卡、排班、日志日报周报 | `${SKILL_DIR}/references/考勤与日志.md` |
| 实时事件、长连接、**为什么禁止轮询** | `${SKILL_DIR}/references/实时事件.md` |
| 跨产品工作流、晨间简报、会议闭环、周报 | `${SKILL_DIR}/references/跨产品工作流.md` |
| 审批闸门、审批模式、命令一直被拦 | `${SKILL_DIR}/references/界面与审批.md` |
| 报错分诊、`dws` 命令失败 | `${SKILL_DIR}/references/故障排查.md` |
## 边界
- 本技能**不执行**任何钉钉命令。用户确认要做某件事时,交回对应的 `dingtalk-*` 官方技能
- 命令目录(有哪些命令、参数是什么)不在这些文件里,也不该写进来——那由 `dws schema`
与官方技能提供,随二进制升级变化。这里只写**能力覆盖、边界与权益门槛**
- 参考文件里的结论若与 `dws schema` 实际输出冲突,以 schema 为准,并如实告知用户文档可能滞后

View File

@@ -0,0 +1,57 @@
# AI 听记
钉钉的会议录音转写与智能摘要产品(原「妙记」)。
## 能做什么
| 场景 | 命令 |
| --- | --- |
| 我创建的听记 | `minutes +list-mine` |
| 他人共享给我的 | `minutes +list-shared` |
| 我有权访问的全部 | `minutes +list-all` |
| 最新一条详情 | `minutes +latest` |
| 批量聚合详情(摘要+关键词+逐字稿+行动项) | `minutes +detail` |
| **已抽取的行动项** | `minutes +action-items` |
| 下载音视频 | `minutes +download` |
| 导出完整产物 | `minutes +export-pack` |
| 申请访问权限 | `minutes +apply-permission` |
还支持:关键词、思维导图、发言人洞察、录音、上传、分享权限。
## 一条重要纪律:用官方抽取的行动项
```
最新那条听记里有哪些行动项?
```
助手走 `minutes +action-items`**不会自己从逐字稿里"理解"出行动项**。
原因:听记产品自己做了行动项抽取,重做一遍会与钉钉界面里显示的不一致——用户在钉钉里看到 5 条,助手说 7 条,谁对?这种不一致比少给几条更糟。
真机实测(用例 b6确认助手走的是官方入口。
## 与会议的关系
```
会前 calendar 排日程、订会议室
会中 ✗ CLI 无入口,需在钉钉客户端
会后 minutes 纪要、逐字稿、行动项
```
听记是**会后**产物。想约会议走 `calendar`,想发起视频会议钉钉 CLI 不支持。
## 跨产品编排里的位置
听记是「会议闭环」recipe 的起点:
```
minutes +action-items → todo +assign建待办并指派
→ doc写纪要文档
→ calendar +book排跟进会
```
其中建待办是写操作,助手会**先把要建哪几条、指派给谁、截止什么时候完整列出来等你确认**。姓名有多个候选时必须问。
## 安全提醒
`+download``+export-pack` 会把音视频和逐字稿落到本地。听记内容通常包含会议原话,**注意落盘位置和后续处置**。`+export-pack` 生成的 manifest **不含签名 URL**,这是刻意设计——避免把带鉴权的链接留在文件里。

Binary file not shown.

After

Width:  |  Height:  |  Size: 289 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 332 KiB

View File

@@ -0,0 +1,73 @@
# 实时事件
## 能做什么
通过 DingTalk Stream 长连接实时监听:
| 类别 | 事件 |
| --- | --- |
| 个人 IM | 收到消息、@我、已读回执、消息撤回、表情回应 |
| 群生命周期 | 成员加入 / 退出、群改名、群解散 |
| OA 审批 | 实例发起 / 抄送 / 终止 / 完成;任务创建 / 完成 / 转交 |
## 为什么不能轮询
钉钉官方执行契约**明文禁止**
> 不要写脚本轮询消息历史或审批列表。
原因不只是效率——轮询拿不到「已读」「撤回」这类**只在发生瞬间存在**的事件,而且会撞限流。
助手会正确识别「关心未来会发生的事」与「查已经发生的事」:
| 你说 | 助手判定 | 走哪 |
| --- | --- | --- |
| 「盯着发给我的消息,有新的通知我」 | 未来事件 | `event +listen-im` 长连接 |
| 「我最近收到哪些消息」 | 已有数据 | 对应产品的查询命令 |
真机实测(用例 e4助手查了 `dws schema --cli-path "event +listen-im" --compact --format json`,并用 `TerminalControl` 管理长驻进程——**没有用 `while true` + `sleep` 轮询模拟**。
## 实际用法
### 监听发给我的消息
```
帮我盯着发给我的钉钉消息,有新的就通知我
```
普通 IM 消息、reaction、已读、撤回走
```bash
dws event +listen-im ...
```
### 监听审批与群生命周期
OA 审批、群成员变化、明确的原始 EventKey、Filter DSL、subscribe_id 走:
```bash
dws event consume ... --flatten
```
输出是 NDJSON 长连接流。
## 平台侧依赖
长连接需要**宿主管理进程并持续读取 stdout**——这是钉钉官方明确留给宿主的职责:
> 无界任务需要宿主管理进程并持续读取 stdout。
> 定时调度由外层工作流负责。
DesireCore 侧对应的能力是**长驻输出流事件接收器**(把长驻子进程 stdout 按行分帧后触发 Agent。该能力目前在 PR 阶段,尚未接上工具入口。
**在它落地前**,助手会如实说明实时监听能力受限,**不会用轮询假装实现**。
## 握手协议
`+listen-im` 启动后会在 stderr 打 ready marker
```
[event] ready event_key=... bus_pid=... subscribe_id=...
```
**必须等这个 marker 再认为订阅生效**,不要用 sleep 猜。停止时不要 `kill -9`,走正常的取消订阅路径(`dws event stop`),否则服务端订阅会残留。

View File

@@ -0,0 +1,70 @@
# 待办与审批
## 待办
| 场景 | 命令 |
| --- | --- |
| 查我的待办 | `todo +get-my-tasks` |
| 查与我相关的全部待办 | `todo +get-related-tasks` |
| 查我创建的待办 | `todo +created-todos` |
| 创建待办 | `todo +create`(建完回读验证) |
| 指派给某人 | `todo +assign`(按姓名自动解析 userId |
| 一次指派给多人 | `todo +assign-multi` |
| 标记完成 | `todo +complete`(回读验证) |
| 加评论 | `todo +comment` |
| 附件 | `todo +list-attachment` |
### 「我的」和「与我相关的」不是一回事
这是最容易漏数据的地方:
- `+get-my-tasks` —— 当前组织下**分配给我执行**的待办
- `+get-related-tasks` —— 我作为**创建人 / 执行人 / 参与人**三种角色的**并集**,已按 taskId 去重
- `+created-todos` —— 只有我**创建**的(我是 creator不一定是执行人
问「我有哪些待办」用第一个;问「跟我相关的都列出来」用第二个。实测用例 c2 走的是第二个。
### 创建与指派
```
帮我建个待办:明天下午三点前检查部署,指派给某某
```
助手会**先把要建什么、指派给谁、截止时间完整列出来等你确认**,确认后才创建,然后回读验证。
姓名有多个候选时**必须问**,不会默认取第一个——指派错人的代价很高。
批量指派一次不超过 30 条。
## OA 审批
| 场景 | 命令 |
| --- | --- |
| 待我处理 | `oa +list-pending --start <epoch毫秒> --end <epoch毫秒>` |
| 我已处理 | `oa +list-executed` |
| 我发起的 | `oa +my-initiated` / `+list-submitted` |
| 抄送我的 | `oa +list-cc` |
| 可见的审批表单 | `oa +list-forms` |
⚠️ **`oa` 的时间参数是 epoch 毫秒**,而 `report`(日志)用的是 **ISO-8601**。两者不通用,助手会按各自产品的要求转换。
### 一个重要的结果解读
实测 `oa +list-pending` 可能返回:
```json
{ "error": { "subtype": "missing_collection",
"message": "成功响应缺少 result.values 数组;不能把未知响应结构当作空结果" } }
```
**这不是「没有待审批」,也不是报错。** 是 dws 在执行「缺少集合不能当空结果」的纪律——响应结构未知时它拒绝伪装成空列表。
助手遇到这种情况会说**「无法确认」**而不是「你没有待审批」,并用 `oa +list-forms` 之类的入口交叉确认该组织是否启用了 OA 审批。这一条直接关系到你会不会漏掉审批。
### 高频入口只在 schema 里可见
`oa +pending``oa +done-approvals``oa +approve-by` 这三个**不在 `dws oa --help` 里**,只能通过 `dws schema` 发现。助手的能力发现走 schema 而不是只看 `--help`,所以不会以为这些能力不存在。
## 考勤类审批走别处
补卡、请假、加班、外出、出差**不走 `oa`**,走 `attendance` 的审批模板(`+get-approve-template`)。助手会按这个判据分流。

View File

@@ -0,0 +1,97 @@
# 故障排查
## 先分清是环境问题还是业务问题
这决定了要不要打扰你。助手按下表分诊:
| 特征 | 类型 | 处理 |
| --- | --- | --- |
| `command not found` | 环境 | 装 CLI`npm i -g dingtalk-workspace-cli` |
| `authenticated: false` / `resolve access token` 失败 | 环境 | 跑 `dws auth login` |
| `category: validation` + `缺少必填参数 X` | **参数问题,不是权限** | 补参数重试,不打扰你 |
| `category: validation` + `unknown flag` / `blocked_flag` | **参数问题** | 查 `--help` 换正确 flag |
| `category: api` + `server_error_code``RightsDenied` / 「权益」 | **权益未开通**(要买/要开通) | 说明缺哪项权益,指向管理后台 |
| `category: api` + 权限点相关 | **权限不足** | 说明缺哪个权限点 |
| `subtype: missing_collection` | **既不是错误也不是空** | 换入口交叉确认,**不报告「没有数据」** |
| 网络超时 / `doctor` 网络项失败 | 环境 | 停止说明,**不重试写操作**(可能已生效) |
## 常见问题
### 「AI 审批后端不可用,命令未执行」
**现象**:任何 `dws` 命令都跑不起来,报这句。
**原因**Agent 的执行审批模式默认是 `ai-approve`,它需要一个**可用的审批 chat 模型**。没配的话所有命令被 fail-closed 拦截。
**这个问题比看起来严重**DesireCore 强制要求 Agent 执行前先写 `PLAN.md`,而 `Write` 也被拦 ⇒ 助手连自己的计划文件都写不了。
**解法二选一**
- 在资源管理面板 → 算力,配一个可用的 chat 模型
- 或把审批模式改成 `allow-listed` / `ask-always`
合法取值:`ai-approve` `ai-auto` `ai-assist` `ask-always` `allow-listed` `ask-external` `allow-all`
### 每条命令都弹审批卡片,点到手软
**现象**:每个 `dws` 命令都被标**高风险**并要求确认。实测 18 个用例里 34 次 Bash 调用触发了 **41 次审批**
**原因**`dws` 不在命令白名单里。fail-closed 本身是对的(钉钉 CLI 有 339 个自己不拦的写操作),但日常用起来太重。
**解法**:聊天页 → 资源管理面板 → 审批模式,把 `dws` 加入允许列表。
### 「未登录」但我明明授权过
先看 token 是不是过期了:
```bash
dws auth status --format json
```
access token 约 2 小时、refresh token 约 30 天。refresh token 过期需要重新 `dws auth login`
⚠️ **钉钉不支持账号密码登录**。给助手账号密码它会告诉你这一点,不会去尝试。
### 无浏览器环境怎么授权
```bash
dws auth login --device
```
会打印授权链接和一个形如 `XXXX-XXXX` 的码15 分钟过期。过期后 dws 会**自动重新出码**,不用手动重启。
### 助手说某个能力不可用,是真的吗
助手区分三种「不可用」,措辞不同:
- **权益未开通** —— 需要在钉钉侧购买/开通(如消息搜索)
- **权限不足** —— 需要管理员配权限点
- **CLI 无此入口** —— 钉钉 CLI 根本没有这个能力(如视频会议发起)
第三种是硬边界,配什么都没用。
### 装了 CLI 但助手找不到技能
官方 `dws` 的技能分发列表里**没有 DesireCore**(它认识 80+ 个别的 Agent 框架)。需要手工拷:
```bash
DC_ROOT="${DESIRECORE_TEST_ROOT:-${DESIRECORE_HOME:-$HOME/.desirecore}}"
cp -R ~/.dws/skills/multi/dingtalk-* "$DC_ROOT/skills/"
```
**每次 `dws upgrade` 后要重拷一次**——这样装的技能没有 provenance不会自动更新。
## 遇到文档矛盾时以什么为准
钉钉官方技能文档内部有自相矛盾之处(实测发现三处)。官方 `SKILL.md` 自己声明:
> 命令可用性以当前 dws 二进制为准。本文档随内置 skill 发布,**可能滞后于二进制**。
**所以一律以 `dws <cmd> --help` 与 `dws schema --cli-path "<路径>" --compact` 的实际输出为准**,不要在文档之间做逻辑推理。
已实测定论的三处(官方各错一处):
| 冲突 | 实测结论 |
| --- | --- |
| 视频会议是否走 misc | **不走**。29 个产品里没有会议类产品CLI 无入口 |
| 个人身份能否撤回消息 | **能**`chat +messages-recall` 存在 |
| 在线表格能否导出 xlsx | **能**`dws sheet export` 存在 |

View File

@@ -0,0 +1,85 @@
# 文档与表格
钉钉把「文档类」拆成了五个独立产品,**分不清就会用错命令**。这是助手最重要的边界判断之一。
## 五个产品的分界
| 产品 | 对应什么 | 命令前缀 |
| --- | --- | --- |
| 在线文字文档adoc | 正文、块、评论、导入导出、模板、版本 | `dws doc` |
| 在线电子表格axls | 单元格读写、工作表、区域、图表 | `dws sheet` |
| AI 表格 / 多维表able | Base、数据表、字段、记录、视图、仪表盘 | `dws aitable` |
| 知识库空间与节点 | 空间管理、节点层级、成员权限 | `dws wiki` |
| 钉盘 / 文档空间的**文件管理** | 查找、上传下载、移动、权限、回收站 | `dws drive` |
| 原生 `.md` 文件 | 创建、读取、覆盖、局部修补 | `dws markdown`(归 misc |
### 怎么判断该走哪个
助手用两层判据:
1. **看 URL 路径模式和 token不看域名。** 钉钉文档链接的路径段决定类型
2. 没有链接时问自己:**「换个文件类型这个操作还成立吗?」**
- 成立 → **存储层**(走 `drive`)。移动、复制、改名、删除、权限、回收站对任何文件都成立
- 不成立 → **内容层**(走 `doc` / `sheet` / `aitable`)。编辑正文、读单元格、加字段只对特定类型成立
## 实际用法
### 找文档
```
帮我找一下标题带「测试」的钉钉文档
```
真机实测助手的三步(用例 d1
```bash
dws doc +search --query '测试' --format json
dws schema --cli-path 'doc +search' --compact --format json
dws doc +search --query '测试' --page-all --max-pages 20 --max-items 500 --format json
```
第一次拿到结果后,它查了 schema 确认分页参数,再带上分页上限重查——因为**只有确认分页真的走到底,才能说「全部」**。
### AI 多维表
```
我有哪些 AI 多维表?
```
```bash
dws schema --cli-path "aitable base list" --compact --format json
dws aitable base list --limit 10 --format json
```
组织内没有 Base 时返回:
```json
{ "data": { "bases": [] }, "error": {}, "status": "success", "success": true }
```
⚠️ **注意 `"error": {}` 是空对象**——这是成功响应的正常形态,**不是错误**。判据必须是 `ok === false``error` 是**非空对象**。用 `grep '"error"'` 判失败会把这条误判成报错(我在写测试脚本时就踩过这个坑)。
### 导出表格
```
把那个在线表格导出成 xlsx
```
```bash
dws sheet export # 异步任务一站式:提交 → 轮询 → 可选下载
dws sheet export-csv # 单个工作表导出 CSV同步可落盘
```
> **官方文档纠错**`url-patterns.md` 说 xlsx 导出「暂未暴露」,这是**错的**(或已过时)。实测 `dws sheet --help` 里 `export` 与 `export-csv` 都存在。
## 常见误判
| 你说 | 容易被误判成 | 实际该走 |
| --- | --- | --- |
| 「把文档移到某个文件夹」 | doc | **drive**(移动是存储操作) |
| 「给文档加个协作者」 | drive | **doc**`+access-grant`,权限属内容层协作) |
| 「在多维表里加一列」 | sheet | **aitable**(多维表 ≠ 电子表格) |
| 「读取表格 A1 单元格」 | aitable | **sheet**(单元格是电子表格概念) |
| 「我最近编辑过哪些文件」 | ❌ 写操作 | **查询**(疑问句里的「编辑过」是筛选条件) |
最后一条是真机测出来的实际缺陷,已写进助手的判断规则。

View File

@@ -0,0 +1,70 @@
# 日程与会议
## 能做什么
| 场景 | 状态 |
| --- | --- |
| 查日程(今天/本周/指定区间) | ✅ |
| 创建日程、按姓名邀请参会人 | ✅ 自动解析 userId失败自动回滚删除日程 |
| 改期、取消日程 | ✅ |
| 加/移除参会人 | ✅ |
| 查自己或多人的闲忙、找共同空闲 | ✅ |
| 会议室查询与预订 | ✅ |
| **发起视频会议、邀请入会、会中控制** | ❌ **无 CLI 入口** |
## 视频会议:一条必须说清的边界
**钉钉 CLI 没有视频会议产品。** 实测证据:
- `dws --help` 的 29 个服务里只有 `calendar`(日历日程/会议室/闲忙)和 `minutes`AI 听记/会议纪要),**没有任何会议类产品**
- `dws schema` 的 29 个产品 id 里,正则 `/conf|meet|video|vc/i` **零命中**
- `dingtalk-misc` 的产品索引表里也没有 conference 行
> **官方文档纠错**`dingtalk-calendar` 的 description 写「不做视频会议发起/邀请入会/会中控制(**走 dingtalk-misc**)」——这是**错的**。同文件正文与 `intent-guide.md §4` 写的「CLI 不支持,请在客户端操作」才是对的。
**CLI 能覆盖的是会前与会后**
```
会前 calendar 排日程、订会议室、查共同空闲
会中 ✗ 需在钉钉客户端操作
会后 minutes 纪要、逐字稿、行动项、录音、思维导图
```
助手遇到「帮我发起视频会议」会如实说明并引导到客户端(实测用例 b7不会去 misc 里瞎找。
## 实际用法
### 查今天安排
```
我今天有什么安排?
```
`calendar +agenda`——**不传时间参数默认就是今天**,助手不会多此一举地拼日期。
### 找共同空闲并约会
```
帮我和某某、某某约个明天下午的会,找个大家都有空的时间
```
助手会:查多人闲忙 → 给出候选时段 → **把要建的日程完整列给你确认** → 建日程并邀请。
`calendar +book` **自带回滚**:邀请参会人失败时会自动删除已建的日程。这是官方行为,助手不会重复实现。
### 取消
```
取消明天那个会
```
`+cancel-event` 会**先确认目标日程真实存在**再删除。多个候选时会让你选,不会默认删第一个。
## 与其他产品的分界
| 你的诉求终点 | 走哪 |
| --- | --- |
| 占一个时间格子、约人、订会议室 | `calendar` |
| 会中音视频控制 | 钉钉客户端CLI 不支持) |
| 会后纪要/逐字稿/行动项 | `minutes` |
| 一条待办事项 | `todo` |

View File

@@ -0,0 +1,53 @@
# 界面表现与审批闸门
用户问「为什么每条命令都要我点确认」「这个审批模式该选哪个」「怎么关掉」时读这篇。
---
## 一次真实对话长什么样
![审批闸门与命令执行](assets/审批与执行.png)
上图是问「我这边有哪些可用的机器人?」的完整过程。三件事值得注意:
1. **每条 `dws` 命令都过审批闸门**,标注风险等级,用户可以逐条批准或拒绝
2. **先查 schema 再执行** —— 前两条是 `dws schema --cli-path ...` 确认命令结构与参数,第三条才真正执行
3. **答案带着依据** —— 「开放平台应用列表为空,**且分页已完整结束**」。只有确认分页走到底才敢说「没有」,不会让用户被一个假的空结果误导
---
## 为什么每条命令都触发审批
实测每条 `dws` 命令都会被判**高风险**并弹审批卡片——18 个测试用例里 34 次 Bash 调用触发了 **41 次审批**。这不是配置错误,是默认行为。
出路是把 `dws` 加进命令白名单,而不是降低风险判定。
---
## 六种审批模式
点输入框左下角的审批模式胶囊即可切换:
![审批模式](assets/审批模式.png)
| 模式 | 行为 | 适合 |
| --- | --- | --- |
| **AI 审批**(默认) | 前台保留 30 秒真人抢先窗口AI 建议到达即收敛 | 日常,但**需要配好审批 chat 模型** |
| 完全 AI 审批 | AI 建议到达立即决策 | 无人值守 |
| 仅 AI 建议 | AI 只提供参考,永不自动决策,**无截止时间等待真人** | 高风险场景 |
| 每次确认 | 每次执行命令都要用户审批 | 最保守 |
| **白名单** | 仅白名单中的命令可自动执行 | **推荐**:把 `dws` 加进去 |
| 外部工具审批 | 交给外部系统裁决 | 有审批中台时 |
---
## 最常见的踩坑:默认模式需要审批模型
**默认的「AI 审批」需要一个可用的审批 chat 模型。** 没配的话所有命令会被 fail-closed 拦掉报「AI 审批后端不可用,命令未执行」——连助手自己写计划文件都会被拦。
两条出路:
- 去资源管理面板 → 算力,配一个 chat 模型
- 或换成「白名单」/「每次确认」
用户报「命令一直执行不了 / 一直说后端不可用」时,先问这一条。

View File

@@ -0,0 +1,85 @@
# 群聊与消息
## 能做什么
| 场景 | 状态 |
| --- | --- |
| 发单聊 / 群消息 | ✅ |
| 撤回自己发的消息 | ✅ |
| 建群、群成员管理、群昵称 | ✅ |
| 会话分组管理 | ✅ |
| 机器人查询、机器人群发 | ✅ |
| Webhook 通知 | ✅ |
| 话题回复、收藏消息、@消息 | ✅ |
| 发送/下载消息图片与文件 | ✅ |
| **搜索聊天记录、@我汇总、拉历史消息** | ⚠️ **需要「消息搜索」权益** |
## 一个必须知道的限制:消息搜索是单独权益
真机实测,未开通时返回:
```json
{
"server_error_code": "SearchRightsDenied",
"message": "当前用户暂无消息搜索权益,无法执行本次搜索。请提示用户开通消息搜索权益后重试。",
"category": "api",
"reason": "business_error"
}
```
**助手的行为**(实测用例 a4识别出这是**权益问题**而非权限配置问题,如实告诉你需要开通,并说明**哪些 chat 能力仍然可用**。它不会换个命令硬试,也不会把整个 chat 域报成不可用。
这是设计上的硬规则——降级时必须区分四种失败态(没装 / 没授权 / 没权限或权益 / 网络不可达),每种给出不同的下一步。
## 实际用法
### 查可用机器人
```
我这边有哪些可用的机器人?
```
真机实测助手的探索过程6 条命令):
```bash
dws schema --cli-path "dev +list-bots" --compact --format json
dws dev --help
dws dev app --help
dws schema --cli-path "dev app list" --compact --format json
dws dev app robot --help
dws dev app list --page-size 30 --format json
```
最终回答:**「当前组织下没有查询到可用机器人(应用列表为空,且已确认分页结束)。」**
> 注意「**且已确认分页结束**」这半句。助手的纪律是:只有拿到 `data.complete=true` 才能说「全部/没有」,响应里缺少集合**不能**当空结果。这样你不会被一个假的"没有"误导。
### 发消息
```
给某某发条消息说「会议改到下午三点」
```
助手会:解析收件人 → **把要发给谁、发什么完整列给你** → 等你确认 → 才发送 → 回读验证。
**对外发消息是不可逆的,没有明确确认绝不发送。** 多人时逐个列出,不群发。
### 撤回
```
把刚才那条消息撤回
```
`chat +messages-recall`
> **文档纠错**:钉钉官方的 `capability-limits.md` 写「无法通过 API 撤回」,这是**错的**(或已过时)。实测 `dws chat --help` 里存在 `+messages-recall`(撤回当前用户发送的消息)、`+messages-recall-by-bot`、`+messages-batch-recall-by-bot`,另有 `ding +recall-personal`。
## 通道选择
| 你想要 | 走哪 |
| --- | --- |
| 钉钉会话里的普通消息 | `chat` |
| 邮件 | `mail` |
| 强提醒(应用内 / 短信 / 电话) | `ding` —— 会响铃、发短信、打电话 |
**`ding` 是强打扰**,除非你明确说「紧急」,助手默认用 `chat`

View File

@@ -0,0 +1,69 @@
# 考勤与日志
两个独立产品,都容易和 OA 审批混。
## 考勤
| 场景 | 命令 |
| --- | --- |
| 打卡流水(时间/地点/定位方式) | `attendance +check-record` |
| 打卡结果(迟到/早退/缺卡) | `attendance +check-result` |
| 签到记录 | `attendance +get-checkin-record` |
| 假期余额变更 | `attendance +get-leave-records` |
| 补卡规则详情 | `attendance +get-adjustment-rule` |
| **补卡/请假/加班/外出/出差的审批链接** | `attendance +get-approve-template` |
还覆盖排班、班次、考勤组、报表、个人规则。
### 考勤类审批不走 OA
这是最容易搞错的一条:
| 审批类型 | 走哪 |
| --- | --- |
| 补卡、请假、加班、外出、出差 | **`attendance`** 的审批模板 |
| 其余通用审批 | **`oa`** |
助手按这个判据分流。
### 参数提醒
多数考勤命令需要 `--users`userId 列表,**最多 100 个,逗号分隔,不能重复**)。助手会先解析出 userId 再调用,不会把「缺少必填参数」这种内部错误抛给你看。
## 日志(日报/周报)
| 场景 | 命令 |
| --- | --- |
| 我收到的日志 | `report +inbox-list` |
| 我发出的日志 | `report +outbox-list` |
| 我最近提交的一篇 | `report +report-latest` |
| 按名称搜模板 | `report +template-search` |
### 时间参数ISO-8601不是 epoch
⚠️ **`report` 用 ISO-8601`oa` 用 epoch 毫秒。** 两者不通用。
```bash
dws report +inbox-list --start 2026-08-25T00:00:00Z --end 2026-09-01T00:00:00Z --format json
```
且**跨度不得超过 180 天**。
### 模板字段是组织自定义的
写周报时助手会**先读模板结构再填**,不会猜字段名——各组织的日志模板字段完全不同,猜错会填到错的格子里。
流程:
1. `+template-search` 找到模板
2. 读模板字段结构
3. 收集内容(本周待办 + 本周会议 + 可选听记结论)
4. **按模板字段组织后完整展示给你确认**
5. 确认后提交
## 实际用法
```
我最近收到哪些日志?
```
真机实测(用例 c7助手正确用了 ISO-8601 时间参数,没有和 `oa` 的 epoch 毫秒搞混。

View File

@@ -0,0 +1,83 @@
# 跨产品工作流
单产品内的操作由钉钉官方技能覆盖,**跨两个以上产品的编排**才走这里。
官方执行契约明确把两件事留给外层:
> 定时调度由**外层工作流**负责。
> 无界任务**需要宿主管理进程并持续读取 stdout**。
## 通用纪律
### 先探可用性再编排
编排最怕跑到一半发现某个产品没权限,留下半成品。每个 recipe 开始前先用只读命令探一次依赖的产品,缺了就提前告诉你「这个 recipe 缺 X要么跳过这步、要么换做法」。
### Ledger 是强制的
多步编排里任何一步失败都不会静默跳过,最后如实汇报:
```
步骤 状态 说明
今日日程 ok 3 条
我的待办 ok 4 条
待我审批 skipped 响应缺少集合,无法确认是「没有」还是「不可用」
未读邮件 ok 12 封
```
**不会把 skipped 写成 0不会把不确定写成确定。**
### 写步骤逐条确认
读步骤可以连续跑;**写步骤(建待办、发消息、写文档、排日程)必须先把要写什么完整列出来等你确认**。批量写不超过 30 条。
## Recipe
### 1 · 晨间简报
**跨产品**calendar + todo + oa + mail **性质**:纯只读,可安全自动执行
按「今天必须处理的」排序:已过期待办 > 今日会议 > 待审批 > 未读邮件。
已知失败态:`oa +list-pending` 可能返回 `missing_collection`——这**不是空结果**ledger 记 `skipped` 并说明「审批项无法确认」。
### 2 · 会议闭环
**跨产品**minutes → todo + doc + calendar **性质**:读 + 写,每个写步骤都确认
1. 定位听记 → 2. 取**官方已抽取的**行动项(不自己从逐字稿"理解")→ 3. 列给你确认 → 4. 建待办并按姓名指派 → 5. 可选写纪要文档 → 6. 可选排跟进会
**回滚语义**:步骤 4 建到一半失败时**不自动回滚已建的待办**(你可能已经看到通知)。改为在 ledger 里列出「已建 N 条 / 失败 M 条」,把失败原因和参数给你,由你决定重试还是手工补。
### 3 · 逾期待办巡检并通知
**跨产品**todo + aisearch/contact + chat 或 ding **风险最高**
1. 取与我相关的全部待办 → 2. 本地筛逾期 → 3. 解析负责人(多候选必须问)→ 4. **完整列出要给谁发什么** → 5. 确认后逐个发送
**红线**:对外发消息不可逆,没有明确确认绝不发;不群发,逐个列出;`ding` 是强打扰(响铃/短信/电话),除非你说「紧急」否则默认用 `chat`;一次不超过 30 人。
### 4 · 周报生成
**跨产品**report + todo + calendar + minutes
1. 找可用日志模板(模板名各组织不同,**不猜**)→ 2. 本周完成的待办 → 3. 本周会议 → 4. 可选补听记结论 → 5. 按模板字段组织并**完整展示确认** → 6. 提交
⚠️ 日志模板字段是组织自定义的,**必须先读模板结构再填**。时间参数是 ISO-8601跨度 ≤180 天(与 `oa` 的 epoch 毫秒不同)。
### 5 · 产物归档
**跨产品**doc/minutes → drive → wiki
定位产物 → 确认或创建归档目录 → 移动/复制 → 可选挂到知识库。
边界提醒:**文档正文**编辑导出走 `doc`**文件存储管理**走 `drive`**知识库空间与节点组织**走 `wiki`
## 定时与事件驱动
recipe 只描述**做什么****什么时候做**交给 DesireCore
- 固定时间(如每天早上的简报)→ DesireCore 调度
- 事件触发(如收到审批就提醒)→ `dws event consume` 长连接
⚠️ **禁止用轮询模拟事件驱动。** 官方契约明文禁止轮询消息历史或审批列表。

View File

@@ -0,0 +1,70 @@
# 通讯录与找人
## 能做什么
| 场景 | 说明 |
| --- | --- |
| 查自己 | 姓名、userId、部门、组织、角色、手机号 |
| 按姓名找人 | 语义搜索,支持模糊;多候选会列出让你选 |
| 按手机号反查 | 完整手机号 → 用户 |
| 按部门列成员 | 本部门 / 含下级 |
| 角色与标签 | 企业角色列表、角色下成员 |
| 花名册档案 | 学历、家庭、银行卡、合同等(需 HR 权限) |
| 离职员工 | 离职记录查询 |
## 两个产品域的分界(最容易搞错的地方)
钉钉把「找人」拆成了两个产品,助手会按下面的判据自动分流:
| 你的输入 | 走哪个 | 为什么 |
| --- | --- | --- |
| 完整手机号 | `contact` 精确查询 | 手机号是唯一键,直接反查 |
| 已经有 userId | `contact` 补详情 | 有主键就不需要搜索 |
| 姓名、工号、职责、上下级关系 | `aisearch` 语义搜索 | 模糊匹配,可能多候选 |
**语义搜索拿到 userId 后会回到 `contact` 补详情**——这是官方推荐的链路,助手不会用搜索结果里的残缺字段直接作答。
## 实际用法
### 查自己
```
我在钉钉里是谁?
```
真机实测助手执行了两条命令:
```bash
dws schema --cli-path "contact +me" --compact --format json # 先确认参数
dws contact +me --format json # 再执行
```
返回姓名、userId、部门、组织、角色、手机号、企业邮箱。
> **注意这个模式**:助手先查 schema 确认参数再执行,而不是凭记忆拼命令。官方 CLI 会随版本变化,这一步能避免用过时的参数。
### 按姓名找人
```
帮我找一下姓王的同事,列出来。
```
`aisearch +search-person --query <关键词>`
⚠️ **flag 是 `--query` 不是 `--name`**——`--name` 被显式屏蔽了自动归一化,写错会报 `blocked_flag`。助手会先查 schema 所以不会踩,但你手工调用时要注意。
**多候选时助手会列出让你选,不会默认取第一个。** 这是硬规则:搞错人的代价(发错消息、约错会)远大于多问一句。
### 按手机号反查
```
查一下手机号 138xxxxxxxx 是谁
```
`contact` 而不是 `aisearch`——完整手机号是精确查询。
## 边界
- 语义搜索的维度限于 `all` / `name` / `department` / `position` / `duty` / `supervisor` / `subordinate` / `phone` / `jobNumber``all` 不能与其他维度并用
- 花名册档案需要 HR 相关权限,无权限时助手会说明缺哪个权限点,不会换个命令硬试
- 返回结果只包含**你有权限查看的**成员,不是全量通讯录

View File

@@ -0,0 +1,56 @@
# 邮件
## 能做什么
| 场景 | 命令 |
| --- | --- |
| 列出邮箱 | `mail mailbox list` |
| 收件箱近期会话 | `mail +recent-mail`(投影主题/发件人/时间/threadId |
| 读一封邮件完整正文与附件元数据 | `mail +message` |
| 批量读多封(逐封验证身份) | `mail +messages` |
| 文件夹列表 | `mail +folder-list` |
| 邮件联系人 | `mail +contact-list` / `+find-mail-user` |
| 发送、回复、转发 | ✅ |
| 搜索 | ✅ |
| 附件 | ✅ |
## 实际用法
### 看最近邮件
```
我最近的邮件有哪些?只要标题和发件人。
```
真机实测助手走了三步(用例 e1
```bash
dws mail mailbox list --format json # 先确定邮箱
dws mail message list --email <邮箱> --limit 10 --format json # 再列邮件
dws mail message list --email <邮箱> --limit 10 --verbose --format json # 补详情
```
**注意它只投影了标题/发件人/时间**,没有把正文全部灌进上下文——邮件正文体量大,全量拉进来既慢又挤占上下文。你明确要正文时才会去读。
### 发邮件
```
帮我给某某发封邮件,说下周一的评审推迟到周三
```
助手会:
1.`contact` 解析收件人并**跟你确认是不是这个人**
2. 把**收件人、主题、正文完整列出来**
3. 等你确认后才发送
**对外发邮件是不可逆的**,没有明确确认绝不发送。
## 与其他通道的分界
| 你想要 | 走哪 |
| --- | --- |
| 钉钉会话里的消息 | `chat` |
| 邮件 | `mail` |
| 强提醒(应用内/短信/电话) | `ding` |
一句话发邮件时,助手会**先用 `contact` 解析并确认收件人**再发——邮箱地址写错的代价比多问一句大。

View File

@@ -0,0 +1,83 @@
# 钉盘与知识库
这两个是**不同的产品**,最容易混。
| | 钉盘 / 文档空间 | 知识库 |
| --- | --- | --- |
| 是什么 | 文件的**存储层** | 有层级结构的**知识组织** |
| 命令前缀 | `dws drive` | `dws wiki` |
| 典型操作 | 查找、上传下载、移动、复制、改名、删除、回收站、权限、评论 | 空间管理、节点层级、成员权限、动态 |
## 判据
问自己:**「换个文件类型这个操作还成立吗?」**
- **成立** → 存储层,走 `drive`。移动、复制、改名、删除、权限对任何文件都成立
- **不成立** → 内容层,走 `doc` / `sheet` / `aitable`
另一条:**只说「文档空间」「我的文档」不触发 wiki**。必须明确提到「知识库 / wiki / 知识空间」才走 wiki。
## 钉盘
| 场景 | 命令 |
| --- | --- |
| 最近访问/编辑的文档 | `drive +recent` |
| 按名称搜文件 | `drive +find-file` / `+search` |
| 分页列出文件和文件夹 | `drive +list` |
| 建文件夹 | `drive +create-folder`(建完读回验证) |
| 复制 | `drive +copy` |
| 下载 | `drive +download`**会验 `sizeBytes > 0`** |
| 删除(移入回收站) | `drive +delete` —— 危险操作,先确认目标存在 |
| 建快捷方式 | `drive +create-shortcut` |
| 封面/缩略图 | `drive +cover` |
还支持本地与钉盘文件夹的**比较、拉取、推送、双向同步**。
### 实际用法
```
我最近编辑过哪些钉盘文件?
```
真机实测:
```bash
dws drive +recent --operate-type 1 --limit 20 --format json
```
`--operate-type 1` 是「编辑过」这个筛选条件的落地——助手把疑问句里的动词正确转成了参数,而不是理解成「要你去编辑」。
## 知识库
| 场景 | 命令 |
| --- | --- |
| 列出知识空间 | `wiki space list` |
| 按名称解析唯一 spaceId | `wiki +resolve-space` |
| 分页列节点 | `wiki +node-list` |
| 空间动态 | `wiki +feed-list` |
| 成员管理 | `wiki +member-list` / `+member-add` / `+member-remove` / `+member-update` |
| 删除知识库 | `wiki +delete-space` —— **高危**,必须强确认 |
### 实际用法
```
我有哪些知识库?
```
真机实测助手**分别查了两类**
```bash
dws wiki +space-list --type orgWikiSpace --limit 50 --page-all --format json
dws wiki +space-list --type myWikiSpace --limit 50 --page-all --format json
```
组织知识库和个人知识库是两个不同的 type——助手一次查全再合并呈现不会反问你「要查哪一类」。
## 常见误判
| 你说 | 容易误判 | 实际 |
| --- | --- | --- |
| 「把文档移到某文件夹」 | doc | **drive**(移动是存储操作) |
| 「上传文件到知识库节点下」 | wiki | **drive**(上传是存储操作) |
| 「知识库里有哪些文档」 | drive | **wiki**(明确提了知识库) |
| 「编辑知识库里那篇文档的正文」 | wiki | **doc**(正文编辑是内容层) |