feat: 新增钉钉工作台助手 Agent 市场登记条目 (#107)

## 摘要 / Summary

**中文**:新增市场第 2 个 Agent 条目
`dingtalk-workspace`(钉钉工作台助手),作为钉钉全产品能力的**发现入口**。条目只提供发现元数据与治理事实,Agent
正文不在本仓库分发。

**English**: Adds the marketplace's second Agent listing,
`dingtalk-workspace` (DingTalk Workspace Assistant), as a **discovery
entry** for DingTalk's product surface. The listing carries discovery
metadata and governance facts only; the Agent's own content is not
distributed from this repository.

## 变更 / Changes

| 文件 / File | 说明 / Note |
| --- | --- |
| `agents/dingtalk-workspace/agent.json` | 市场展示元数据,zh-CN + en-US 双语 /
Market display metadata, zh-CN + en-US |
| `agents/dingtalk-workspace/catalog-metadata.v1.json` | 治理 sidecar /
Governance sidecar |
| `agents/dingtalk-workspace/assets/avatar.webp` | 512×512 中性图形头像 /
Neutral 512×512 avatar |
| `manifest.json` | `totalAgents` 1 → 2;version 1.2.30 →
1.3.0;lastUpdated |
| `README.md` | Agent 计数与目录示意 / Agent count and repository shape |

## 条目形态:可安装 / Shape: installable

**中文**:条目随附完整 Agent 正文(`persona.md`、`principles.md`、2 个 Skill、13
篇文档),安装后即得到完整可用的 Agent。

治理字段取值与理由:

| 字段 | 取值 | 理由 |
| --- | --- | --- |
| `installPolicy` / `updatePolicy` | `market` / `market` |
正文已在条目内,Market 负责安装与更新。这也避开了
`isMarketAgentMetadataOnly()`(`sync/market.ts:113-128`)——它只在
`system`+`repository` 时返回 true,另一条分支是对 `desirecore` 的 id 硬编码特判,本条目不适用 |
| `release` | `known` `1.0.0` `semver` | 非 system Agent 时
`validate_catalog_metadata.py:625-630` 要求 `release` 保留 legacy `version`
|
| `timestamps.releasePublishedAt` | `2026-09-01` | 本次发布日 |
| `governance.availability` | `listing-only` | 见下 |

**为什么 `availability` 不是
`installable`**:`validate_catalog_metadata.py:650-712` 的强证据门禁要求不可变
`provenance.content`(git 40 位 SHA 或 sha256)+ 已知 license + 已知
`reviewedAt` + `compliance`。本条目正文就在本仓库这次提交里,无法自指一个尚不存在的固定
ref;未做治理审查,也不会编造 `reviewedAt` 与许可证据。`listing-only`
在本仓库既有先例(`wecom-cli`、`larksuite-cli` 都是 `listing-only`
且实际可安装),且客户端不读该字段——真正决定可安装性的是 `installPolicy`。

**English**: The listing ships the complete Agent content (`persona.md`,
`principles.md`, 2 Skills, 13 documents), so installing yields a fully
working Agent.

| Field | Value | Rationale |
| --- | --- | --- |
| `installPolicy` / `updatePolicy` | `market` / `market` | Content lives
in the listing, so Market owns install and update. This also avoids
`isMarketAgentMetadataOnly()` (`sync/market.ts:113-128`), which returns
true only for `system`+`repository`; its other branch is an id-hardcoded
special case for `desirecore` that does not apply here |
| `release` | `known` `1.0.0` `semver` | For a non-system Agent,
`validate_catalog_metadata.py:625-630` requires `release` to preserve
the legacy `version` |
| `timestamps.releasePublishedAt` | `2026-09-01` | Publication date |
| `governance.availability` | `listing-only` | See below |

**Why `availability` is not `installable`**: the strict evidence gate at
`validate_catalog_metadata.py:650-712` requires an immutable
`provenance.content` (40-hex Git SHA or sha256) plus a known license, a
known `reviewedAt`, and `compliance`. This listing's content lives in
this very commit, so it cannot pin a ref that does not yet exist; no
governance review was performed, and no `reviewedAt` or license evidence
will be invented. `listing-only` has precedent here (`wecom-cli` and
`larksuite-cli` are both `listing-only` yet installable in practice),
and the client does not read the field — installability is actually
decided by `installPolicy`.

### agent.json 的双重身份 / agent.json serves two contracts

**中文**:安装时整个 `agents/<id>/` 目录被 `cpSync` 到
`~/.desirecore/agents/<id>/`(`market-routes.ts:1228-1252`),因此这个
`agent.json` **同时**是市场展示元数据和 AgentFS 运行时配置。已把源 Agent 的运行时配置并入(`llm` 智能路由
flagship、`heartbeat`、`session_mode`、`env`、`mcp_servers`、并发上限等)。

已知副作用:两套 Schema 在 10 个字段上不相交(市场侧的 `category` / `updatedAt` /
`maintainer` / `i18n` / `persona` / `changelog` / `installPolicy` /
`updatePolicy`,以及 `avatar.t` / `avatar.bg`),AgentFS 侧
`agentConfigSchema` 是 `additionalProperties: false`,`id` 还要求 UUID
形态。因此安装后
`parseAgentJsonText`(`agent/reader.ts:375-397`)会走宽松解析分支,每个进程打印一条
warning。宽松分支原样返回解析结果,配置全部生效——已实测确认(见下)。这是「内联可安装 Market
Agent」这一形态固有的,本仓库此前没有先例。

**English**: On install the whole `agents/<id>/` directory is
`cpSync`-ed into `~/.desirecore/agents/<id>/`
(`market-routes.ts:1228-1252`), so this `agent.json` is
**simultaneously** the marketplace display metadata and the AgentFS
runtime config. The source Agent's runtime configuration has been merged
in (`llm` smart routing at flagship tier, `heartbeat`, `session_mode`,
`env`, `mcp_servers`, concurrency cap).

Known side effect: the two schemas are disjoint on 10 fields
(market-side `category`, `updatedAt`, `maintainer`, `i18n`, `persona`,
`changelog`, `installPolicy`, `updatePolicy`, plus `avatar.t` /
`avatar.bg`), AgentFS's `agentConfigSchema` is `additionalProperties:
false`, and its `id` expects a UUID shape. So after install,
`parseAgentJsonText` (`agent/reader.ts:375-397`) takes the lenient
branch and prints one warning per process. That branch returns the
parsed object as-is, so every setting still applies — verified below.
This is inherent to the "inline installable Market Agent" shape, which
has no prior precedent in this repository.

## 外部依赖披露 / External dependency disclosure

**中文**:本 Agent 依赖一个由第三方独立分发的命令行程序,并需要用户自行完成钉钉账号 OAuth 授权。按仓库
`CLAUDE.md`「External dependency disclosure」要求,已在四处披露:

1. **发现描述** — `agent.json#i18n.<locale>.shortDesc`(zh-CN 与 en-US 各一份)
2. **`compatibility` 字段** — sidecar `compatibility.requirements[]`,4
条:runtime(用户自行安装第三方 CLI)、runtime(官方产品技能需手工拷贝且每次升级重做)、permission(钉钉账号
OAuth,能力范围取决于授权范围)、connection(网络与所在组织已开通的产品/权益)
3. **本地化市场文案** — `agent.json#i18n.<locale>.fullDesc` 与 sidecar
`presentation.i18n.<locale>.description` 中的「外部依赖声明」整节
4. **执行约定** — 同一节明确:依赖不可用(未安装 / 未授权 / 无权限 /
组织未开通)时,在发起外部调用**之前**停止并如实说明,**不编造成功结果**

明确声明 DesireCore
**不打包、不分发、不授权、不安装、不代付、不运营**该程序及其背后的产品;凭据与费用由用户与服务方之间的条款约束。

**English**: This Agent depends on an independently distributed
third-party CLI and requires the user's own account OAuth. Per
`CLAUDE.md` "External dependency disclosure", it is disclosed in all
four required places:

1. **Discovery description** — `agent.json#i18n.<locale>.shortDesc`, in
both zh-CN and en-US
2. **`compatibility` field** — sidecar `compatibility.requirements[]`,
four entries: runtime (user installs the third-party CLI), runtime
(official product skills must be copied manually and re-copied after
each upgrade), permission (account OAuth; coverage depends on granted
scopes), connection (network plus the products and entitlements enabled
for the user's own organization)
3. **Localized marketplace text** — the "External dependency disclosure"
section inside `agent.json#i18n.<locale>.fullDesc` and sidecar
`presentation.i18n.<locale>.description`
4. **Execution instructions** — the same section states that when the
dependency is unavailable (not installed, not authorized, not permitted,
or not enabled), the Agent stops **before** the external call and never
fabricates a successful result

It states explicitly that DesireCore does **not bundle, distribute,
license, install, pay for, or operate** that program or the products
behind it; credentials and fees are governed by terms between the user
and the service provider.

## 品牌与商标 / Branding

**中文**:`branding.relationship: independent-listing` / `nameUsage:
nominative` / `logoStatus: not-used`。头像是自制的中性图形(对话气泡 + 终端提示符
`>_`,表达「自然语言意图 → 命令调用」),**未使用任何第三方 logo 或商标图形**。

**English**: `branding.relationship: independent-listing` / `nameUsage:
nominative` / `logoStatus: not-used`. The avatar is an original neutral
mark (a speech bubble containing a `>_` terminal prompt, expressing
"natural-language intent becomes a command call"). **No third-party logo
or trademark artwork is used.**

## 未审查的事实保持 unknown / Unverified facts left unknown

**中文**:未做治理审查,因此
`governance.license`、`timestamps.reviewedAt`、`timestamps.releasePublishedAt`、`timestamps.upstreamObservedAt`、`release`
一律如实为 `unknown`,不编造许可证据或审查时间。`compatibility.platforms` 同样为
`unknown`——实际只在 macOS 上验证过,不宣称未验证的平台。

**English**: No governance review was performed, so
`governance.license`, `timestamps.reviewedAt`,
`timestamps.releasePublishedAt`, `timestamps.upstreamObservedAt`, and
`release` are all honestly `unknown`; no license evidence or review date
is invented. `compatibility.platforms` is likewise `unknown` — only
macOS was actually exercised, and untested platforms are not claimed.

## 校验 / Validation

**中文**:按 `.github/workflows/i18n-validate.yml` 的顺序在本地跑完 7 步,全部 `exit
0`;`0 error(s)`,116 warning 全部是主干既有条目的历史告警,**新条目零告警**。

**English**: All seven steps from `.github/workflows/i18n-validate.yml`
were run locally in order; every step exited `0`. `0 error(s)`; all 116
warnings are pre-existing on `main` for other listings — **the new
listing produces none**.

```
exit=0  errors=0   新条目命中=0    <-- scripts/i18n/test_validate_i18n.py
exit=0  errors=0   新条目命中=0    <-- scripts/catalog/test_validate_catalog_metadata.py
exit=0  errors=0   新条目命中=0    <-- scripts/catalog/test_collection_generator.py
exit=0  errors=0   新条目命中=0    <-- scripts/catalog/validate_catalog_metadata.py --require-complete
exit=0  errors=0   新条目命中=0    <-- scripts/i18n/validate-i18n.py
exit=0  errors=0   新条目命中=0    <-- scripts/i18n/translate.py --check
exit=0  errors=0   新条目命中=0    <-- scripts/gen-collection-children.py --check

0 error(s), 116 warning(s). agents=2, builtinSkills=34, pointerSkills=28,
publishableSkills=62, collections=7, collectionChildren=147, sidecars=64
```

另外用客户端契约做了运行时验证:按 `readAgentDetail` 的归一化逻辑(i18n 拍平 + changelog 按 locale
解析 + system 策略下 `version` → `metadataRevision`)还原 detail
对象后,`validateMarketAgent` 在 zh-CN 与 en-US 下均 PASS。

Additionally verified against the client contract: after reproducing
`readAgentDetail`'s normalization (i18n flattening, per-locale changelog
resolution, and `version` → `metadataRevision` under the system policy),
`validateMarketAgent` PASSes for both zh-CN and en-US.

### 安装验证 / Install verification

**中文**:用 agent-service 的**真实导出函数**复刻 `market-routes.ts:1185-1260`
的安装流水线(`skillCopyFilter`、`computeCapabilityContentDigest`、`isMarketAgentMetadataOnly`、`extractAgentVersion`、`parseAgentJsonText`),在
vitest unit project 中执行。

**English**: The install pipeline from `market-routes.ts:1185-1260` was
reproduced using agent-service's **real exported functions**
(`skillCopyFilter`, `computeCapabilityContentDigest`,
`isMarketAgentMetadataOnly`, `extractAgentVersion`,
`parseAgentJsonText`) and executed inside the vitest unit project.

```
[1] isMarketAgentMetadataOnly = false => 放行可装
[2] cpSync ok; source=cb8c961bb55b9abe… staged=cb8c961bb55b9abe…
[3] installedVersion = 1.0.0
[5] 应存在 19 项,缺失 0 项
[6] parseAgentJsonText => 可用配置
    name=钉钉工作台助手 llm.routingMode=smart tier=flagship
    max_concurrent_sessions=3 accepts_messages=true
    avatar.image.path=assets/avatar.webp

 ✓ packages/agent-service/src/__tests__/…  (1 test) 75ms
 Test Files  1 passed (1)
```

19 项断言覆盖 `agent.json` / `persona.md` / `principles.md` / 2 个 `SKILL.md`
/ `assets/avatar.webp` / 13 篇文档,全部存在;staged 摘要与源摘要一致(内容无漂移)。

All 19 assertions — `agent.json`, `persona.md`, `principles.md`, both
`SKILL.md` files, `assets/avatar.webp`, and all 13 documents — are
present, and the staged digest matches the source digest (no content
drift).

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

**中文**:按 `CLAUDE.md`「Required pre-publication
check」执行完毕。敏感令牌清单通过私有渠道获取并保存在仓库之外,未落盘、未写入否定名单。全工作树扫描(含隐藏文件、排除 `.git`)后,本
PR 新增与修改的文件(含本次新增的 17
个正文文件)**零命中**;已对示例做语义复核,正文示例统一使用「某某」「张三」这类中文通用占位人名,正文只描述公开的软件包名、公开命令与中立能力域,不含任何租户、客户、伙伴或个人身份,也无截图。分支名、commit
标题与正文、以及本 PR 文本同样零命中。检查通过。

**English**: The `CLAUDE.md` "Required pre-publication check" was
completed. The sensitive token list was obtained through a private
channel and kept outside the repository; it was not persisted and not
added to any denylist. After scanning the complete working tree
(including hidden files, excluding `.git`), the files added or modified
by this PR — including the 17 content files added in this round —
produce **zero hits**. Examples were reviewed semantically: the text
describes only public package names, public commands, and neutral
capability domains, with no tenant, customer, partner, or individual
identity, and no screenshots. The branch name, commit subject and body,
and this PR text are likewise clean. Check passed.

## 备注 / Notes

**中文**:与 #104(`skills/dingtalk-cli` 技能条目)互补——那个 PR 登记工具层,本 PR 登记 Agent
层。两者都改了 `manifest.json` 与 `README.md` 的统计行,后合并的一方需要重算计数。本分支基于 `main`,不依赖
#104。

目录 slug 选用 `dingtalk-workspace` 而非本机 AgentFS 实例目录名:AgentFS
实例目录是创建时按中文名自动生成的拼音串,不满足市场 slug 的语义可读性要求;`dingtalk-workspace`
与它所面向的产品域(钉钉工作台)及上游 CLI 包名一一对应,对应关系明确可查。

**English**: Complementary to #104 (the `skills/dingtalk-cli` listing) —
that PR registers the tool layer, this one the Agent layer. Both touch
the stats lines in `manifest.json` and `README.md`, so whichever merges
second must recount. This branch is based on `main` and does not depend
on #104.

The directory slug is `dingtalk-workspace` rather than the local AgentFS
instance directory name: that instance directory is an auto-generated
pinyin transliteration of the Chinese display name and is not
meaningfully readable as a marketplace slug. `dingtalk-workspace` maps
one-to-one onto the product surface it fronts and onto the upstream CLI
package name, so the correspondence stays explicit.

---------

Co-authored-by: yi-ge <jackyoncode@gmail.com>
This commit is contained in:
2026-09-02 06:36:14 -04:00
committed by GitHub
parent fb6005cd7b
commit 43a8cbd549
24 changed files with 1790 additions and 5 deletions

View File

@@ -0,0 +1,141 @@
# 钉钉工作台助手
把自然语言意图翻译成钉钉官方 CLI 的正确调用,并对结果负责。
覆盖钉钉 **29 个产品、1256 个工具**通讯录、群聊消息、日程会议、待办、审批、考勤、日志、文档、表格、AI 多维表、钉盘、知识库、邮件、AI 听记、DING、实时事件等。
---
## 它长什么样
![审批闸门与命令执行](assets/审批与执行.png)
这是一次真实对话(问「我这边有哪些可用的机器人?」)。三件事值得注意:
1. **每条 `dws` 命令都过审批闸门**,标注风险等级,你可以逐条批准或拒绝
2. **先查 schema 再执行** —— 前两条是 `dws schema --cli-path ...` 确认命令结构与参数,第三条才真正执行
3. **答案带着依据** —— 「开放平台应用列表为空,**且分页已完整结束**」。只有确认分页走到底才敢说「没有」,不会让你被一个假的空结果误导
## 它是什么,不是什么
**是**:钉钉能力的入口与编排层。你说要做什么,它负责找对产品域、选对命令、拿到可信结果。
**不是**:钉钉命令的说明书。命令目录由钉钉官方技能与 `dws schema` 提供,随二进制升级而更新——官方文档自己就写明「命令可用性以当前 dws 二进制为准,本文档可能滞后于二进制」。所以这个助手**不复制命令表**,它做的是官方技能不管的四件事:
| 增量 | 说明 |
| --- | --- |
| **接入** | 钉钉官方 CLI 的 Agent 分发列表里**没有 DesireCore**,装到 DesireCore 的路径无人覆盖 |
| **纪律** | 钉钉 CLI 有 339 个「自己不拦」的写操作(占全部写操作 56%),由助手把关 |
| **编排** | 跨产品工作流;官方 SKILL.md 明写「定时调度由外层工作流负责」 |
| **降级** | 没装 / 没授权 / 没权限 / 没开通时如实停下,**绝不编造成功** |
---
## 快速开始
### 1. 安装钉钉官方 CLI
```bash
npm i -g dingtalk-workspace-cli
```
⚠️ 这一步会顺带往你机器上**其它 AI 编程工具的技能目录**写入钉钉技能(`~/.claude/skills/``~/.cursor/skills/` 等,共 80+ 个框架)。这是上游 `dws` 的 postinstall 行为,不是 DesireCore 做的。
### 2. 把官方产品技能装进 DesireCore
装完 CLI 后技能已解包在 `~/.dws/skills/multi/`,拷进 DesireCore 全局技能目录:
```bash
DC_ROOT="${DESIRECORE_TEST_ROOT:-${DESIRECORE_HOME:-$HOME/.desirecore}}"
mkdir -p "$DC_ROOT/skills"
cp -R ~/.dws/skills/multi/dingtalk-* "$DC_ROOT/skills/"
```
共 14 个:`aisearch` `aitable` `calendar` `chat` `contact` `doc` `drive` `event` `mail` `minutes` `misc` `shared` `todo` `wiki`
> **为什么不走市场安装**:市场里有 `dingtalk-cli` 条目但钉钉官方仓库未公开HTTP 404客户端按 git 源拉不到内容。该条目的作用是**让你在市场里发现这个能力并看到装法**,不是分发通道。
>
> **代价**:这样装的技能没有 provenance 记录,市场同步视为孤儿——既不自动更新也不自动卸载。**每次 `dws upgrade` 后要重跑一次上面的拷贝。**
### 3. 授权
```bash
dws auth login # 本机有浏览器
dws auth login --device # 无浏览器 / SSH / 容器,出设备码
```
⚠️ **钉钉不支持账号密码登录**,也不支持手机验证码、纯应用凭证。只有 OAuth 回环、设备流、`--token`、自有应用 OAuth 四种。
授权成功后 access token 约 2 小时、refresh token 约 30 天自动刷新,之后无需再打扰。
### 4. 把 `dws` 加进命令白名单(强烈建议)
实测每条 `dws` 命令都会被判**高风险**并弹审批卡片——18 个测试用例里 34 次 Bash 调用触发了 **41 次审批**。不加白名单的话你要不停点确认。
点输入框左下角的审批模式胶囊即可切换:
![审批模式](assets/审批模式.png)
六种模式的取舍:
| 模式 | 行为 | 适合 |
| --- | --- | --- |
| **AI 审批**(默认) | 前台保留 30 秒真人抢先窗口AI 建议到达即收敛 | 日常,但**需要配好审批 chat 模型** |
| 完全 AI 审批 | AI 建议到达立即决策 | 无人值守 |
| 仅 AI 建议 | AI 只提供参考,永不自动决策,**无截止时间等待真人** | 高风险场景 |
| 每次确认 | 每次执行命令都要你审批 | 最保守 |
| **白名单** | 仅白名单中的命令可自动执行 | **推荐**:把 `dws` 加进去 |
| 外部工具审批 | 交给外部系统裁决 | 有审批中台时 |
⚠️ **默认的「AI 审批」需要一个可用的审批 chat 模型。** 没配的话所有命令会被 fail-closed 拦掉报「AI 审批后端不可用,命令未执行」——连助手自己写计划文件都会被拦。要么去资源管理面板 → 算力配一个 chat 模型,要么换成「白名单」或「每次确认」。
### 5. 自检
```bash
dws doctor
```
四项:登录状态 / 钥匙串 / 网络连通性 / 版本更新。
---
## 功能文档
| 文档 | 覆盖 |
| --- | --- |
| [通讯录与找人](功能/通讯录与找人.md) | 精确查询 vs 语义搜索的分界、多候选处理 |
| [群聊与消息](功能/群聊与消息.md) | 发消息、撤回、机器人、会话分组;**消息搜索需单独权益** |
| [日程与会议](功能/日程与会议.md) | 日程、会议室、闲忙;**视频会议无 CLI 入口** |
| [待办与审批](功能/待办与审批.md) | 待办增删改查、指派OA 审批查询与处理 |
| [文档与表格](功能/文档与表格.md) | 在线文档、电子表格、AI 多维表的边界与导出 |
| [钉盘与知识库](功能/钉盘与知识库.md) | 存储层 vs 内容层的判据 |
| [邮件](功能/邮件.md) | 收发、搜索、附件 |
| [AI 听记](功能/AI听记.md) | 摘要、逐字稿、行动项 |
| [考勤与日志](功能/考勤与日志.md) | 打卡、排班;日志模板填报 |
| [实时事件](功能/实时事件.md) | 长连接监听;**禁止轮询** |
| [跨产品工作流](功能/跨产品工作流.md) | 晨间简报、会议闭环、逾期巡检、周报、归档 |
| [故障排查](故障排查.md) | 错误分诊表 |
---
## 安全边界
这个助手继承了钉钉官方的执行契约,并补了 DesireCore 侧的一层:
- **只走 `dws`**,不用 curl、不自拼 HTTP
- **不编造标识符**——userId / docId / baseId 一律从命令返回中提取
- **写操作先确认**,判据是 `effect == destructive || risk == high || confirmation == user_required` 三元组兜底(**不能只看 `confirmation` 字段**1256 个工具里有 339 个是 dws 自己不拦的 silent-write
- **单次批量 ≤ 30 条**
- **多候选禁止默认取第一个**;多组织时解析、读取、执行必须用同一个 profile
- **退出码不等于成功**——只有 `data.complete=true` 才能说「全部」,响应里缺少集合不能当空结果
- **禁止轮询**消息历史或审批列表,实时需求走长连接
---
## 已知边界
| 限制 | 说明 |
| --- | --- |
| 视频会议 | **CLI 无入口**。会前(排日程订会议室)与会后(纪要/逐字稿/行动项)可用,会中控制需在钉钉客户端操作 |
| 消息搜索 | 需要**消息搜索权益**,未开通时返回 `SearchRightsDenied`。其余 chat 能力(发消息、群管理、机器人)不受影响 |
| 组织权限 | 能力覆盖取决于 OAuth 授权范围与你所在组织开通的产品,助手会在受限时如实说明 |

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,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**,这是刻意设计——避免把带鉴权的链接留在文件里。

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,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,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**(正文编辑是内容层) |

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` 存在 |