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

