mirror of
https://git.openapi.site/https://github.com/desirecore/market.git
synced 2026-09-05 22:24:06 +08:00
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:
157
agents/dingtalk-workspace/skills/dingtalk-onboarding/SKILL.md
Normal file
157
agents/dingtalk-workspace/skills/dingtalk-onboarding/SKILL.md
Normal file
@@ -0,0 +1,157 @@
|
||||
---
|
||||
name: dingtalk-onboarding
|
||||
description: 钉钉能力接入与健康自检。Use when 首次使用钉钉能力、报「dws 未找到 / 未登录 / 权限不足 / 权益未开通」、需要授权或换组织、或钉钉命令报错需要定位是环境问题还是业务问题。负责安装检测、授权引导、doctor 解读、多组织 profile 切换。**不做任何钉钉业务操作**——业务命令走 dingtalk-* 官方技能。
|
||||
metadata:
|
||||
category: onboarding
|
||||
requires:
|
||||
bins:
|
||||
- dws
|
||||
tools:
|
||||
- Bash
|
||||
---
|
||||
|
||||
# 钉钉接入与自检
|
||||
|
||||
本技能只管**能不能用**,不管**做什么**。任何钉钉业务操作都交给官方 `dingtalk-*` 技能。
|
||||
|
||||
## 为什么需要这个技能
|
||||
|
||||
钉钉官方 CLI `dws` 自带一套 Agent 技能分发机制,会把 14 个产品技能装到它认识的 80+ 个 Agent 框架目录里(`~/.claude/skills/`、`~/.cursor/skills/`、`~/.agents/skills/` 等)。
|
||||
|
||||
**但它的目标枚举里没有 DesireCore。** `dws skill install <id> <target>` 和 `dws skill setup --target` 的 target 都是固定枚举,`--source` 只能改源不能改目标。所以 DesireCore 用户拿不到官方的自动分发,必须走 DesireCore 自己的市场条目。
|
||||
|
||||
这就是本技能存在的理由。
|
||||
|
||||
## 自检顺序
|
||||
|
||||
首次执行钉钉操作前按顺序确认。后续轮次可复用结论,**除非出错**。
|
||||
|
||||
### 第 1 步:装了吗
|
||||
|
||||
```bash
|
||||
command -v dws
|
||||
```
|
||||
|
||||
无输出 = 未安装。**立刻停止**,告诉用户:
|
||||
|
||||
```
|
||||
钉钉能力需要先安装官方 CLI:
|
||||
|
||||
npm i -g dingtalk-workspace-cli
|
||||
|
||||
装完我再继续。
|
||||
```
|
||||
|
||||
**不要**假装执行了钉钉操作,**不要**用 curl 或其它方式绕过。
|
||||
|
||||
### 第 2 步:授权了吗
|
||||
|
||||
```bash
|
||||
dws auth status --format json
|
||||
```
|
||||
|
||||
`authenticated: false` = 未授权。**立刻停止**,引导授权:
|
||||
|
||||
```bash
|
||||
dws auth login # 本机有浏览器:OAuth 回环,自动完成
|
||||
dws auth login --device # 无浏览器 / SSH / 容器:出设备码
|
||||
```
|
||||
|
||||
⚠️ **钉钉不支持账号密码登录,也不支持手机验证码、纯应用凭证。** 只有 OAuth 回环、设备流、`--token`、自有应用 OAuth 四种。用户给你账号密码时要说明这一点。
|
||||
|
||||
设备流会打印授权链接和一个形如 `XXXX-XXXX` 的码,**原样转给用户**,不要改写。码 15 分钟过期,过期后 dws 会自动重新出码。
|
||||
|
||||
授权成功后 token 自动刷新(access token 约 2 小时,refresh token 约 30 天),之后无需再打扰用户。
|
||||
|
||||
### 第 3 步:出错时才跑 doctor
|
||||
|
||||
```bash
|
||||
dws doctor
|
||||
```
|
||||
|
||||
四项:登录状态 / 钥匙串 / 网络连通性 / 版本更新。
|
||||
|
||||
**这是排障工具,不是心跳。** 不要每轮都跑。
|
||||
|
||||
## 错误分诊
|
||||
|
||||
拿到错误先判断是**环境问题**还是**业务问题**——这决定了要不要打扰用户。
|
||||
|
||||
| 特征 | 类型 | 处理 |
|
||||
|---|---|---|
|
||||
| `command not found` | 环境 | 回第 1 步 |
|
||||
| `authenticated: false` / `resolve access token` 失败 | 环境 | 回第 2 步 |
|
||||
| `category: validation` + `缺少必填参数 X` | **参数问题,不是权限** | 补上参数重试,不要打扰用户 |
|
||||
| `category: validation` + `unknown flag` / `blocked_flag` | **参数问题** | 查 `--help` 用正确的 flag。注意有些 flag 被显式屏蔽了自动归一化 |
|
||||
| `category: api` + `server_error_code` 带 `RightsDenied` / `权益` | **权益未开通**(要买/要开通,不是配权限) | 停止,说明缺哪项权益,指向钉钉管理后台 |
|
||||
| `category: api` + 权限点相关 | **权限不足** | 停止,说明缺哪个权限点 |
|
||||
| `subtype: missing_collection` | **不是错误也不是空** | 响应结构未知,dws 拒绝把它当空结果。换个入口交叉确认,**不要报告「没有数据」** |
|
||||
| 网络超时 / `doctor` 网络项失败 | 环境 | 停止说明;**不要重试写操作**——可能已生效 |
|
||||
|
||||
### 一个真实样本
|
||||
|
||||
```
|
||||
server_error_code: SearchRightsDenied
|
||||
message: 当前用户暂无消息搜索权益,无法执行本次搜索。请提示用户开通消息搜索权益后重试。
|
||||
```
|
||||
|
||||
这是**权益**问题:`chat` 域里一切依赖消息检索的能力(搜聊天记录、@我汇总、拉历史消息)不可用,但发消息、群管理、机器人、会话分组等非检索能力**仍然可用**。
|
||||
|
||||
正确处理:告诉用户「消息搜索需要开通权益」,并说明哪些 chat 能力仍可用。**不要**换个命令硬试,**不要**把整个 chat 域报成不可用。
|
||||
|
||||
## 多组织
|
||||
|
||||
```bash
|
||||
dws profile list --format json
|
||||
```
|
||||
|
||||
单组织时无需关心。多组织时:
|
||||
|
||||
- **禁止默认取第一个**,也禁止取「最近登录」或「最近使用」
|
||||
- 没有 `isOrgCurrent=true` 时必须**问用户**
|
||||
- **解析目标、读取上下文、最终执行必须使用同一个 profile**——跨 profile 混用会拿到错的 userId 和错的文档
|
||||
|
||||
一次性指定用 `--profile <corpId>:<userId>`(推荐用 `profile list` 返回的完整形式)。
|
||||
|
||||
## 安装官方产品技能
|
||||
|
||||
钉钉的 14 个产品技能:`dingtalk-aisearch` / `aitable` / `calendar` / `chat` / `contact` / `doc` / `drive` / `event` / `mail` / `minutes` / `misc` / `shared` / `todo` / `wiki`。
|
||||
|
||||
### 当前唯一可用的安装路径
|
||||
|
||||
装完 `dws` 后,技能已经在本机了——postinstall 会把它们解包到 `~/.dws/skills/multi/`。从那里拷进 DesireCore 的全局技能目录即可:
|
||||
|
||||
```bash
|
||||
# 目标目录随运行时根变化,不要写死 ~/.desirecore
|
||||
DC_ROOT="${DESIRECORE_TEST_ROOT:-${DESIRECORE_HOME:-$HOME/.desirecore}}"
|
||||
mkdir -p "$DC_ROOT/skills"
|
||||
for s in ~/.dws/skills/multi/dingtalk-*; do
|
||||
cp -R "$s" "$DC_ROOT/skills/"
|
||||
done
|
||||
```
|
||||
|
||||
拷完让用户重启 DesireCore 或等下一轮技能发现(每轮 query 重新发现)。
|
||||
|
||||
**必须同时告诉用户这个代价**:这样装的技能**没有 provenance 记录**(`skills.lock` 里没有 `providerId` / `contentDigest`),所以:
|
||||
- DesireCore 的市场同步会把它们当作孤儿条目——**既不会自动更新,也不会自动卸载**
|
||||
- `dws upgrade` 升级二进制后,`~/.dws/skills/multi/` 里的技能会更新,但 **DesireCore 里的副本不会跟着变**,需要重新拷一次
|
||||
|
||||
所以每次 `dws upgrade` 之后,提醒用户重跑一遍上面的拷贝。
|
||||
|
||||
### 为什么不能走市场安装
|
||||
|
||||
市场里有 `dingtalk-cli` 条目,但**它现在装不了**:钉钉官方仓库 `open-dingtalk/dingtalk-workspace-cli` 未公开(HTTP 404),市场客户端按 git 源拉取会失败。该条目的作用是**让用户在市场里发现钉钉能力并看到安装说明**,不是实际分发通道。
|
||||
|
||||
如果用户在市场点了安装并报错,这是预期行为,按上面的手工路径引导即可,**不要说市场坏了**。
|
||||
|
||||
### 为什么不能用 `dws skill setup`
|
||||
|
||||
`dws skill setup --target` 和 `dws skill install <id> <target>` 的 target 是**固定枚举**(80+ 个 Agent 框架),**里面没有 DesireCore**;`--source` 只能改源不能改目标。所以官方的自动分发对 DesireCore 用户不生效。
|
||||
|
||||
⚠️ 注意 `dws` 的 postinstall 会**自动**往它认识的框架目录写技能(`~/.claude/skills/`、`~/.cursor/skills/`、`~/.agents/skills/` 等)。如果用户同时用别的 AI 编程工具,装 dws 会顺带修改那些目录——这是上游行为,值得提前告知。
|
||||
|
||||
## 边界
|
||||
|
||||
本技能**不做**:任何钉钉业务操作、命令目录说明、产品能力介绍。
|
||||
|
||||
那些属于官方 `dingtalk-*` 技能。用 `dws schema --compact` 做能力发现,用官方技能的 description 做产品路由。
|
||||
180
agents/dingtalk-workspace/skills/dingtalk-workflows/SKILL.md
Normal file
180
agents/dingtalk-workspace/skills/dingtalk-workflows/SKILL.md
Normal file
@@ -0,0 +1,180 @@
|
||||
---
|
||||
name: dingtalk-workflows
|
||||
description: 钉钉跨产品编排。Use when 用户要的东西需要串起两个以上钉钉产品——晨间简报(日程+待办+审批+邮件)、会议闭环(听记→待办→文档→日程)、逾期待办巡检并通知、周报生成(日志模版+本周待办+会议)、产物归档(文档→钉盘→知识库)。单产品内的操作不用本技能,直接走对应 dingtalk-* 官方技能的 shortcut。
|
||||
metadata:
|
||||
category: workflow
|
||||
requires:
|
||||
bins:
|
||||
- dws
|
||||
tools:
|
||||
- Bash
|
||||
---
|
||||
|
||||
# 钉钉跨产品编排
|
||||
|
||||
## 什么时候用本技能
|
||||
|
||||
**只有跨 ≥2 个钉钉产品时才用。** 单产品内的复合任务(比如 AI 表格批量导入、文档创建后写内容)官方 shortcut 和官方脚本已经覆盖,直接用它们,不要在这里重造。
|
||||
|
||||
官方执行契约明确把两件事留给外层:
|
||||
|
||||
> 「定时调度由**外层工作流**负责」
|
||||
> 「无界任务**需要宿主管理进程并持续读取 stdout**」
|
||||
|
||||
本技能就站在这个位置。
|
||||
|
||||
## 所有 recipe 共用的执行纪律
|
||||
|
||||
### 1. 先探可用性,再编排
|
||||
|
||||
编排最怕跑到一半发现某个产品没权限,产生半成品。**每个 recipe 开始前先确认它依赖的产品都可用**——用只读命令探一次,失败就提前告诉用户「这个 recipe 缺 X,要么跳过这一步、要么换个做法」。
|
||||
|
||||
### 2. Ledger 是强制的
|
||||
|
||||
多步编排里**任何一步失败都不能静默跳过**。维护一份步骤台账,最后如实汇报:
|
||||
|
||||
```
|
||||
步骤 状态 说明
|
||||
今日日程 ok 3 条
|
||||
我的待办 ok 4 条
|
||||
待我审批 skipped 响应缺少集合,无法确认是「没有」还是「不可用」
|
||||
未读邮件 ok 12 封
|
||||
```
|
||||
|
||||
**不要**把 skipped 写成 0,**不要**把不确定写成确定。
|
||||
|
||||
### 3. 只读优先,写操作逐条确认
|
||||
|
||||
recipe 里的读步骤可以连续跑。**写步骤(建待办、发消息、写文档、排日程)必须先把要写什么完整列给用户,等确认。** 判据用三元组:`effect == destructive || risk == high || confirmation == user_required`。
|
||||
|
||||
批量写不超过 30 条。
|
||||
|
||||
### 4. ID 只在流程内传递
|
||||
|
||||
前一步返回的 ID 直接喂给下一步,**不要**让模型重新"想"一个 ID,也不要用名称当标识符。跨步骤时保持同一个 profile。
|
||||
|
||||
---
|
||||
|
||||
## Recipe 1 · 晨间简报
|
||||
|
||||
**跨产品:** calendar + todo + oa + mail
|
||||
**性质:** 纯只读,无写操作,可安全自动执行
|
||||
|
||||
**步骤**
|
||||
|
||||
1. `dws calendar +agenda --format json` —— 今日日程(不传时间默认今天)
|
||||
2. `dws todo +get-my-tasks --format json` —— 我的待办
|
||||
3. `dws oa +list-pending --start <今日0点epoch毫秒> --end <现在epoch毫秒> --format json` —— 待我审批
|
||||
4. `dws mail +recent-mail --format json` —— 收件箱近期会话
|
||||
|
||||
**汇总规则**
|
||||
|
||||
按「今天必须处理的」优先排序:已过期待办 > 今日会议 > 待审批 > 未读邮件。日程给出时间和标题,待办给出截止时间,审批给出发起人和类型。
|
||||
|
||||
**已知失败态**
|
||||
|
||||
- `oa +list-pending` 可能返回 `subtype: missing_collection`(响应缺少 `result.values`)。这**不是空结果**——ledger 里记 `skipped`,并说明「审批项无法确认」。可用 `oa +list-forms` 交叉确认该组织是否启用了 OA 审批
|
||||
- `mail` 返回量可能很大,只取标题/发件人/时间做摘要,不要把正文全灌进上下文
|
||||
|
||||
---
|
||||
|
||||
## Recipe 2 · 会议闭环
|
||||
|
||||
**跨产品:** minutes → todo + doc + calendar
|
||||
**性质:** 读 + 写,**每个写步骤都要确认**
|
||||
|
||||
**步骤**
|
||||
|
||||
1. `dws minutes +latest --format json`(或 `+list-mine` 后让用户选)—— 定位目标听记
|
||||
2. `dws minutes +action-items --format json` —— 取已抽取的行动项
|
||||
- ⚠️ **用官方已抽取的行动项,不要自己从逐字稿里"理解"出行动项**。听记产品自己做了这件事,重做会不一致
|
||||
3. **列给用户确认**:打算建哪几条待办、指派给谁、截止什么时候
|
||||
4. 确认后 `dws todo +assign`(单人)或 `+assign-multi`(多人)—— 按姓名自动解析 userId
|
||||
- 姓名有多个候选时**必须问**,禁止取第一个
|
||||
5. 可选:`dws doc` 把会议纪要写成文档
|
||||
6. 可选:`dws calendar +book` 排跟进会议
|
||||
|
||||
**回滚语义**
|
||||
|
||||
步骤 4 建了一半失败时:**不要自动回滚已建的待办**(用户可能已经看到通知)。改为在 ledger 里列出「已建 N 条 / 失败 M 条」,把失败的原因和参数给用户,让用户决定重试还是手工补。
|
||||
|
||||
`calendar +book` 自带回滚(邀请参会人失败时会自动删除日程),这是官方行为,不要重复实现。
|
||||
|
||||
---
|
||||
|
||||
## Recipe 3 · 逾期待办巡检并通知
|
||||
|
||||
**跨产品:** todo + contact/aisearch + ding 或 chat
|
||||
**性质:** 读 + **对外发通知**,风险最高,确认要求最严
|
||||
|
||||
**步骤**
|
||||
|
||||
1. `dws todo +get-related-tasks --format json` —— 与我相关的全部待办(创建人/执行人/参与人三种角色并集,已按 taskId 去重)
|
||||
2. 本地筛出逾期项(对比截止时间与当前时间)
|
||||
3. 解析负责人:已有 userId 直接用;只有姓名时走 `dws aisearch +search-person --query <姓名>`,**多候选必须问**
|
||||
4. **完整列出**:要给谁、发什么内容、走什么通道,等用户确认
|
||||
5. 确认后发送:
|
||||
- 常规提醒 → `dws chat` 单聊
|
||||
- 强提醒(应用内/短信/电话)→ `dws ding +send-personal`
|
||||
|
||||
**红线**
|
||||
|
||||
- **对外发消息是不可逆的。** 没有明确确认绝不发送
|
||||
- 不要群发。逐个发,每个人的内容单独列出
|
||||
- `ding` 是强打扰(会响铃/发短信/打电话),除非用户明确要求「紧急」,否则默认用 `chat`
|
||||
- 一次不超过 30 人
|
||||
|
||||
---
|
||||
|
||||
## Recipe 4 · 周报生成
|
||||
|
||||
**跨产品:** report + todo + calendar + minutes
|
||||
**性质:** 读 + 写(提交日志),提交前必须确认
|
||||
|
||||
**步骤**
|
||||
|
||||
1. `dws report +template-search --format json` —— 找到可用的日志模板(周报模板名称各组织不同,**不要猜**)
|
||||
2. `dws todo +get-related-tasks --format json` —— 本周完成的待办
|
||||
3. `dws calendar +agenda --start <本周一> --end <本周日> --format json` —— 本周会议
|
||||
4. 可选 `dws minutes +list-mine` —— 本周听记,补充关键结论
|
||||
5. 按模板字段组织内容,**完整展示给用户确认**
|
||||
6. 确认后按模板提交
|
||||
|
||||
**注意**
|
||||
|
||||
- 日志模板的字段是组织自定义的,必须先读模板结构再填,**禁止猜字段名**
|
||||
- `report` 的时间参数是 ISO-8601,跨度不得超过 180 天(与 `oa` 的 epoch 毫秒不同,别搞混)
|
||||
|
||||
---
|
||||
|
||||
## Recipe 5 · 产物归档
|
||||
|
||||
**跨产品:** doc/minutes → drive → wiki
|
||||
**性质:** 读 + 写
|
||||
|
||||
**步骤**
|
||||
|
||||
1. 定位产物:`dws doc +find-doc --keyword <词>` 或 `dws minutes +export-pack`
|
||||
2. `dws drive +list` / `+create-folder` —— 确认或创建归档目录
|
||||
3. 移动/复制到归档位置
|
||||
4. 可选:`dws wiki space list` → `wiki +node-*` 挂到知识库
|
||||
|
||||
**边界提醒**
|
||||
|
||||
这条最容易走错产品域。判据:
|
||||
- **文档正文**的编辑与导出 → `doc`
|
||||
- **文件的存储管理**(移动/复制/权限/回收站)→ `drive`
|
||||
- **知识库空间与节点组织** → `wiki`
|
||||
|
||||
问自己「换个文件类型这个操作还成立吗」——成立就是存储层(drive),不成立就是内容层(doc)。
|
||||
|
||||
---
|
||||
|
||||
## 定时与事件驱动
|
||||
|
||||
recipe 本身只描述**做什么**,**什么时候做**交给 DesireCore:
|
||||
|
||||
- 固定时间(如每天早上的晨间简报)→ DesireCore 的调度
|
||||
- 事件触发(如收到审批就提醒)→ `dws event consume --flatten` 长连接
|
||||
|
||||
⚠️ **禁止用轮询模拟事件驱动。** 官方契约明文禁止「写脚本轮询消息历史或审批列表」。长连接需要宿主持续读取 stdout——这是 DesireCore 平台侧的能力,不要在技能里用 `while true` + `sleep` 硬凑。
|
||||
Reference in New Issue
Block a user