@xdxer/dingtalk-agent 0.1.2 → 0.1.4-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +223 -53
- package/dist/bin/dingtalk-agent.js +81 -3
- package/dist/bin/dingtalk-agent.js.map +1 -1
- package/dist/src/doctor.js +166 -0
- package/dist/src/doctor.js.map +1 -0
- package/dist/src/setup.js +101 -0
- package/dist/src/setup.js.map +1 -0
- package/dist/src/skill-manager.js +15 -0
- package/dist/src/skill-manager.js.map +1 -1
- package/docs/ARCHITECTURE.md +12 -2
- package/docs/INSTALLATION.md +135 -0
- package/evals/evals.json +23 -0
- package/evals/run-contract-evals.mjs +76 -1
- package/package.json +1 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dingtalk-agent contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,79 +1,135 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
1
3
|
# dingtalk-agent
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
**让 AI Agent 像钉钉里的可靠同事一样感知、判断、行动与留痕。**
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/@xdxer/dingtalk-agent)
|
|
8
|
+
[](https://github.com/D1-2004/dingtalk-agent/actions/workflows/ci.yml)
|
|
9
|
+
[](https://nodejs.org/)
|
|
10
|
+
[](LICENSE)
|
|
11
|
+
|
|
12
|
+
[快速开始](#两分钟开始) · [核心模型](#核心模型) · [架构](#架构) · [行为协议](#数字员工行为协议) · [评测](#评测与验证)
|
|
13
|
+
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
`dingtalk-agent` 是一个 **Skill-first 的钉钉数字员工行为框架**。它不内置模型,也不复制 DWS;它把“像同事一样工作”拆成三层:
|
|
17
|
+
|
|
18
|
+
- **Basic Behavior Skill**:判断何时响应、追问、确认或保持沉默;
|
|
19
|
+
- **CLI Runtime**:冻结身份、目标和事务边界,提供可审计的员工级原子动作;
|
|
20
|
+
- **DWS**:执行钉钉消息、文档、待办、日历等具体产品能力。
|
|
21
|
+
|
|
22
|
+
它可以被 Claude Code、Codex 或其他 Agent Host 使用,也可以作为更完整数字员工系统的基础蓝本。
|
|
23
|
+
|
|
24
|
+

|
|
25
|
+
|
|
26
|
+
## 为什么需要它
|
|
4
27
|
|
|
5
|
-
|
|
28
|
+
“会调用钉钉 API”不等于“会像员工一样工作”。真实协作还要求 Agent:
|
|
6
29
|
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
30
|
+
- 群里未被提及时默认不抢话,被 `@` 或私聊时才获得响应资格;
|
|
31
|
+
- 信息完整就直接交付,只有真正阻塞时才问一个问题;
|
|
32
|
+
- 不从消息正文猜收件人、身份、文档 ID 或权限;
|
|
33
|
+
- 长任务能确认收到、等待依赖、从下一条事件继续,而不是假装一直在线;
|
|
34
|
+
- 区分“命令执行过”“平台写入成功”“回读可见”和“对方确认”;
|
|
35
|
+
- 将任务状态、长期记忆、运行时锁和幂等回执放在正确的存储层。
|
|
10
36
|
|
|
11
|
-
|
|
37
|
+
本项目把这些约束从一段巨型 Prompt 中拆出来:**Skill 负责判断,CLI 负责硬边界,DWS 负责平台能力。**
|
|
12
38
|
|
|
13
|
-
##
|
|
39
|
+
## 两分钟开始
|
|
40
|
+
|
|
41
|
+
> 要求 Node.js 18.3+。不需要先全局安装命令;`npx` 是不会受 PATH 影响的 bootstrap 入口。
|
|
14
42
|
|
|
15
43
|
```bash
|
|
16
|
-
|
|
17
|
-
dingtalk-agent skill install
|
|
44
|
+
npx --yes --registry=https://registry.npmjs.org @xdxer/dingtalk-agent@beta setup
|
|
18
45
|
```
|
|
19
46
|
|
|
20
|
-
|
|
47
|
+
`setup` 会按顺序完成四件事:
|
|
48
|
+
|
|
49
|
+
1. 将 CLI 安装到用户目录 `~/.local/bin`,必要时幂等补充 shell PATH;
|
|
50
|
+
2. 检查 Node.js、DWS 版本和 `dws auth status`;
|
|
51
|
+
3. 安装并验证 Basic Behavior Skill;
|
|
52
|
+
4. 报告 Claude Code、Codex、OpenCode 是否能够发现 Skill。
|
|
53
|
+
|
|
54
|
+
当前终端尚未加载新 PATH 时,setup 会打印一条可直接执行的 `export PATH=...`。验证结果:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
dingtalk-agent doctor
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
安装后,Skill 只有一份 canonical copy:
|
|
21
61
|
|
|
22
62
|
```text
|
|
23
|
-
~/.agents/skills/dingtalk-basic-behavior/ # Codex 直接发现
|
|
24
|
-
~/.claude/skills/dingtalk-basic-behavior #
|
|
63
|
+
~/.agents/skills/dingtalk-basic-behavior/ # Codex、OpenCode 直接发现
|
|
64
|
+
~/.claude/skills/dingtalk-basic-behavior # Claude Code → canonical 相对链接
|
|
25
65
|
```
|
|
26
66
|
|
|
27
|
-
|
|
67
|
+
如果只想临时运行、不做用户级安装,任何命令都可以通过 npm exec 执行:
|
|
28
68
|
|
|
29
69
|
```bash
|
|
30
|
-
dingtalk-agent
|
|
70
|
+
npx --yes --registry=https://registry.npmjs.org @xdxer/dingtalk-agent@beta doctor
|
|
71
|
+
npx --yes --registry=https://registry.npmjs.org @xdxer/dingtalk-agent@beta skill install
|
|
31
72
|
```
|
|
32
73
|
|
|
33
|
-
|
|
74
|
+
也兼容开放的 `skills` CLI。仓库有访问权限时,可只安装 Skill 到三个客户端:
|
|
34
75
|
|
|
35
|
-
|
|
76
|
+
```bash
|
|
77
|
+
npx skills add D1-2004/dingtalk-agent \
|
|
78
|
+
--skill dingtalk-basic-behavior --global --yes \
|
|
79
|
+
--agent claude-code --agent codex --agent opencode
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
从本地 checkout 安装则使用:
|
|
36
83
|
|
|
37
84
|
```bash
|
|
38
|
-
dingtalk-
|
|
85
|
+
npx skills add ./skills/dingtalk-basic-behavior \
|
|
86
|
+
--global --yes --agent claude-code --agent codex --agent opencode
|
|
39
87
|
```
|
|
40
88
|
|
|
41
|
-
|
|
89
|
+
`npx skills` 只安装行为说明,不安装 `dingtalk-agent` CLI,也不检查 DWS;需要真实执行钉钉动作时仍应运行 `setup` 或 `doctor`。完整排障见 [安装与首次使用](docs/INSTALLATION.md)。
|
|
42
90
|
|
|
43
|
-
|
|
91
|
+
普通 Agent 会话无需初始化项目。进入任意目录后可直接发现上下文:
|
|
44
92
|
|
|
45
93
|
```bash
|
|
46
|
-
|
|
47
|
-
|
|
94
|
+
dingtalk-agent bootstrap --json
|
|
95
|
+
```
|
|
48
96
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
97
|
+
只有可信事件宿主需要冻结目标并建立 Prepared Run:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
mkdir fde-coach && cd fde-coach
|
|
101
|
+
dingtalk-agent init
|
|
102
|
+
dingtalk-agent prepare --event-file event.json --json
|
|
54
103
|
```
|
|
55
104
|
|
|
56
|
-
##
|
|
105
|
+
## 核心模型
|
|
57
106
|
|
|
58
|
-
|
|
59
|
-
|---|---:|---|
|
|
60
|
-
| Direct Session | 否 | 普通 Claude Code/Codex 会话;应用同事行为,按需使用 DWS |
|
|
61
|
-
| Mounted Session | 否 | 读取已有本地或钉钉文档中的身份、记忆、知识 |
|
|
62
|
-
| Prepared Run | 是,一次 | 可信事件宿主冻结目标、身份、Session/Run、Wait、预算和回执 |
|
|
107
|
+
### 三种运行模式
|
|
63
108
|
|
|
64
|
-
|
|
109
|
+
| 模式 | 初始化 | 上下文 | 适用场景 |
|
|
110
|
+
|---|---:|---|---|
|
|
111
|
+
| **Direct Session** | 不需要 | 当前请求与宿主提供的信息 | 普通 Claude Code / Codex 会话 |
|
|
112
|
+
| **Mounted Session** | 不需要 | 本地 Markdown 或钉钉文档快照 | 带身份、记忆和知识的长期员工 |
|
|
113
|
+
| **Prepared Run** | Workspace 一次性初始化 | 可信事件冻结的目标、身份与策略 | 自动化事件处理和强可靠外发 |
|
|
114
|
+
|
|
115
|
+
本地内容直接挂载,不复制:
|
|
65
116
|
|
|
66
117
|
```bash
|
|
67
|
-
|
|
68
|
-
dingtalk-agent init # contextId 可省略,由目录名稳定派生
|
|
69
|
-
dingtalk-agent prepare --event-file event.json --json
|
|
118
|
+
dingtalk-agent bootstrap --storage local-dir:/path/to/workspace --json
|
|
70
119
|
```
|
|
71
120
|
|
|
72
|
-
|
|
121
|
+
远端内容由 DWS 探测并拉成隐藏的只读快照:
|
|
73
122
|
|
|
74
|
-
|
|
123
|
+
```bash
|
|
124
|
+
dingtalk-agent bootstrap \
|
|
125
|
+
--storage 'dingtalk-doc:<node-id-or-url>' \
|
|
126
|
+
--state-dir /path/to/session-state \
|
|
127
|
+
--json
|
|
128
|
+
```
|
|
75
129
|
|
|
76
|
-
|
|
130
|
+
### 四个消息原子行为
|
|
131
|
+
|
|
132
|
+
Prepared Run 只开放四个消息动作:
|
|
77
133
|
|
|
78
134
|
```bash
|
|
79
135
|
dingtalk-agent act ack
|
|
@@ -82,31 +138,110 @@ dingtalk-agent act ask --text "一个真正阻塞的问题"
|
|
|
82
138
|
dingtalk-agent act silence --reason unmentioned
|
|
83
139
|
```
|
|
84
140
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
141
|
+
| 动作 | 员工语义 | 关键边界 |
|
|
142
|
+
|---|---|---|
|
|
143
|
+
| `ack` | 看到了,确实需要时间处理 | 不等于接单、承诺或完成 |
|
|
144
|
+
| `reply` | 已有可交付结果 | 只回复原消息,CLI 没有 `--to` |
|
|
145
|
+
| `ask` | 缺少阻塞信息 | 一次只问一个问题,随后释放沙箱等待事件 |
|
|
146
|
+
| `silence` | 有意识地不打扰 | 仍留下结构化 reason 和本地回执 |
|
|
147
|
+
|
|
148
|
+
文档写入、待办创建等能力继续由 DWS 提供。只有当一个员工意图需要固定作用域、权限、幂等、回读、状态迁移或跨产品组合时,才值得包装成新的 CLI 动作。
|
|
149
|
+
|
|
150
|
+
## 架构
|
|
151
|
+
|
|
152
|
+
```mermaid
|
|
153
|
+
flowchart TB
|
|
154
|
+
SIGNAL["钉钉消息 / @ / DM / 心跳"] --> HOST["Claude Code / Codex / Agent Host"]
|
|
155
|
+
BASIC["Basic Behavior Skill\n响应资格与员工协议"] --> HOST
|
|
156
|
+
ROLE["岗位 / Workflow Skill\nFDE、周报、事故处理"] --> HOST
|
|
157
|
+
HOST --> BOOT["bootstrap\n按需水合身份、记忆与知识"]
|
|
158
|
+
BOOT --> LOCAL["Local Markdown"]
|
|
159
|
+
BOOT --> DOC["DingTalk Doc Snapshot"]
|
|
160
|
+
HOST --> MODE{"可信事件?"}
|
|
161
|
+
MODE -- "否" --> DIRECT["Direct / Mounted Session"]
|
|
162
|
+
MODE -- "是" --> RUNTIME["Prepared Run Runtime\nSession / Run / Wait / Gate"]
|
|
163
|
+
RUNTIME --> ACTION["ack / reply / ask / silence"]
|
|
164
|
+
DIRECT --> DWS["DWS"]
|
|
165
|
+
ACTION --> DWS
|
|
166
|
+
DWS --> PRODUCTS["消息 / 文档 / 待办 / 日历"]
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### 事件驱动的异步进程
|
|
170
|
+
|
|
171
|
+
每条新信号可以启动一个新沙箱,但同一件事仍回到同一个 Session:
|
|
172
|
+
|
|
173
|
+
```text
|
|
174
|
+
Field / Workspace = 长期身份、知识与 Skill(Heap)
|
|
175
|
+
Session = 一件工作的显式上下文(Stack)
|
|
176
|
+
Run = 一次事件唤醒的新沙箱
|
|
177
|
+
Wait = await continuation,由宿主持久化和恢复
|
|
178
|
+
Action = 受约束的系统调用
|
|
179
|
+
Receipt = 可审计的外部效果证据
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
`ask` 后当前 Run 结束;匹配事件到达时,宿主恢复原 Session 并创建新 Run。系统持久化显式 checkpoint,而不是序列化 JavaScript 或模型的隐藏调用栈。
|
|
183
|
+
|
|
184
|
+
### 存储边界
|
|
185
|
+
|
|
186
|
+
| Markdown / 钉钉文档 | 宿主状态存储 |
|
|
187
|
+
|---|---|
|
|
188
|
+
| 身份、长期知识、社交记忆、任务 checkpoint、Skill 候选 | EventIndex、Wait、锁、generation、幂等键、Action intent/receipt |
|
|
189
|
+
|
|
190
|
+
Why:文档适合人和 Agent 共同审查,但没有可靠 CAS;请求超时也不能证明写失败,因此不能承担并发控制或副作用去重。
|
|
191
|
+
|
|
192
|
+
## 数字员工行为协议
|
|
193
|
+
|
|
194
|
+
新任务遵循:
|
|
89
195
|
|
|
90
|
-
|
|
196
|
+
```text
|
|
197
|
+
UNDERSTAND → CLARIFY → PLAN → EXECUTE → WAIT → VERIFY → COMPLETE
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
- **UNDERSTAND**:从当前消息和可信 continuation 还原目标、交付物、范围、完成条件、权限与时点;
|
|
201
|
+
- **CLARIFY**:先查线程、附件、Workspace 和岗位 Skill;信息足够就做,真阻塞才问;
|
|
202
|
+
- **PLAN**:单步任务不表演计划,多步任务建立 2~5 个可观察检查点;
|
|
203
|
+
- **EXECUTE**:外部副作用前重新核对对象、权限、幂等和最新状态;
|
|
204
|
+
- **WAIT**:记录等待谁、什么输入、从哪里继续,然后释放沙箱;
|
|
205
|
+
- **VERIFY**:通过工具结果和必要回读区分生成、保存、送达与确认;
|
|
206
|
+
- **COMPLETE**:回到原线程交付结果、证据、遗留项和下一责任人。
|
|
91
207
|
|
|
92
|
-
|
|
208
|
+
只有跨消息、等待依赖、已经产生副作用、需要换沙箱接手或用户明确要求跟踪的事项才创建 checkpoint。单轮问答不制造“伪任务”。
|
|
93
209
|
|
|
94
|
-
|
|
210
|
+
## Skill、CLI 与 DWS 如何组合
|
|
95
211
|
|
|
96
|
-
|
|
212
|
+
```text
|
|
213
|
+
Basic Behavior Skill 每个钉钉员工共享的社交与安全底座
|
|
214
|
+
+
|
|
215
|
+
Role / Workflow Skill 某个岗位如何完成 FDE 评价、周报、事故处理
|
|
216
|
+
+
|
|
217
|
+
Agent Definition 身份、服务对象、知识源、记忆与权限
|
|
218
|
+
+
|
|
219
|
+
dingtalk-agent CLI 需要强约束的员工级事务边界
|
|
220
|
+
+
|
|
221
|
+
DWS 钉钉标准产品能力
|
|
222
|
+
```
|
|
97
223
|
|
|
98
|
-
|
|
224
|
+
这意味着一个 FDE 教练只需在基础行为之上叠加教练身份、评价方法与学员资料;基础层无需知道任何 FDE 业务细节。
|
|
99
225
|
|
|
100
|
-
|
|
226
|
+
## 常用命令
|
|
101
227
|
|
|
102
228
|
```bash
|
|
229
|
+
dingtalk-agent --help
|
|
230
|
+
dingtalk-agent doctor
|
|
231
|
+
dingtalk-agent setup
|
|
232
|
+
dingtalk-agent skill install
|
|
233
|
+
dingtalk-agent skill status
|
|
234
|
+
dingtalk-agent bootstrap --json
|
|
235
|
+
dingtalk-agent init
|
|
236
|
+
dingtalk-agent prepare --event-file event.json --json
|
|
103
237
|
dingtalk-agent help runtime
|
|
104
238
|
dingtalk-agent help adapters
|
|
239
|
+
dingtalk-agent eval contract
|
|
105
240
|
```
|
|
106
241
|
|
|
107
|
-
|
|
242
|
+
`listen` 是可选的开发联调 Adapter,不是 Agent 主进程。云端 Driver、Claude Code 插件或本地 DWS 都可以提供事件,并从标准化事件之后复用同一 Session / Run / Action 内核。
|
|
108
243
|
|
|
109
|
-
##
|
|
244
|
+
## 评测与验证
|
|
110
245
|
|
|
111
246
|
```bash
|
|
112
247
|
npm ci
|
|
@@ -114,13 +249,48 @@ npm run typecheck
|
|
|
114
249
|
npm run eval:contract
|
|
115
250
|
```
|
|
116
251
|
|
|
117
|
-
当前确定性合同包含
|
|
252
|
+
当前确定性合同包含 **28 个场景**,覆盖:
|
|
253
|
+
|
|
254
|
+
- 全局 Skill 安装、发现、升级和漂移保护;
|
|
255
|
+
- 首次 setup、用户级 PATH、DWS 版本/认证和三端客户端发现;
|
|
256
|
+
- 无 init bootstrap、本地/远端 Storage 与类型闸门;
|
|
257
|
+
- Direct Session 外发边界;
|
|
258
|
+
- Session continuation、Wait、幂等和目标防篡改;
|
|
259
|
+
- Skill 冻结、动作预算和 Receipt。
|
|
260
|
+
|
|
261
|
+
模型行为还可通过 Claude shadow 做 with-skill / baseline 对照;它只允许读取冻结输入并输出 ActionRequest,不产生任何钉钉副作用。完整晋级门禁见 [自测与持续进化](docs/SELF-TEST.md)。
|
|
262
|
+
|
|
263
|
+
## 项目结构
|
|
264
|
+
|
|
265
|
+
```text
|
|
266
|
+
bin/ CLI composition root
|
|
267
|
+
src/ TypeScript runtime
|
|
268
|
+
skills/dingtalk-basic-behavior/ 可安装的基础行为 Skill
|
|
269
|
+
templates/ Workspace 与行为模板
|
|
270
|
+
evals/ 合同、fixture 与 shadow runner
|
|
271
|
+
docs/ 架构、决策和调研文档
|
|
272
|
+
.github/ CI 与协作模板
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## 深入阅读
|
|
118
276
|
|
|
119
277
|
- [代码与运行架构](docs/ARCHITECTURE.md)
|
|
278
|
+
- [安装与首次使用](docs/INSTALLATION.md)
|
|
120
279
|
- [最小 Workspace 决策记录](docs/MINIMAL-WORKSPACE-V1.md)
|
|
121
280
|
- [自测与持续进化](docs/SELF-TEST.md)
|
|
122
281
|
- [开源项目差异与共同范式](docs/OPEN-SOURCE-REFERENCES.md)
|
|
282
|
+
- [贡献指南](CONTRIBUTING.md)
|
|
283
|
+
- [安全策略](SECURITY.md)
|
|
284
|
+
|
|
285
|
+
## 当前边界
|
|
286
|
+
|
|
287
|
+
- 不把 `listen` 作为 Agent 的强制主入口;
|
|
288
|
+
- 不自动初始化或污染任意代码仓库;
|
|
289
|
+
- 不复制整个 DWS 命令面;
|
|
290
|
+
- 不把钉钉文档当锁、事务数据库或副作用回执;
|
|
291
|
+
- 不允许在线 Run 自动扩大身份、权限或启用新 Skill;
|
|
292
|
+
- 当前 `dingtalk-doc` 只读水合,远端写入必须经过显式授权 Provider 并回读。
|
|
123
293
|
|
|
124
294
|
## License
|
|
125
295
|
|
|
126
|
-
MIT
|
|
296
|
+
[MIT](LICENSE)
|
|
@@ -23,8 +23,11 @@ import { readEventFile, consumeNdjson, heartbeatEvent } from '../src/driver.js';
|
|
|
23
23
|
import { findRun, previewAction, executeAction } from '../src/actions.js';
|
|
24
24
|
import { resolvePackageRoot } from '../src/package-root.js';
|
|
25
25
|
import { bootstrap } from '../src/bootstrap.js';
|
|
26
|
+
import { doctor } from '../src/doctor.js';
|
|
27
|
+
import { setup } from '../src/setup.js';
|
|
26
28
|
import { installGlobalSkill, skillStatus, uninstallGlobalSkill, upgradeGlobalSkill, } from '../src/skill-manager.js';
|
|
27
29
|
const PACKAGE_ROOT = resolvePackageRoot(import.meta.url);
|
|
30
|
+
const PACKAGE_JSON = JSON.parse(readFileSync(join(PACKAGE_ROOT, 'package.json'), 'utf8'));
|
|
28
31
|
// ROOT = **你的工作区**(当前目录),不是包所在的目录。
|
|
29
32
|
// 全局装 / npx 跑的时候,包住在 node_modules 里 —— 那不是 agent 的家。
|
|
30
33
|
const ROOT = process.env.DTA_ROOT
|
|
@@ -33,8 +36,12 @@ const ROOT = process.env.DTA_ROOT
|
|
|
33
36
|
const HELP = `
|
|
34
37
|
dingtalk-agent —— Skill-first 的钉钉数字员工行为容器
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
|
|
39
|
+
首次使用(无全局命令时: npx --yes --registry=https://registry.npmjs.org @xdxer/dingtalk-agent@${PACKAGE_JSON.version} setup)
|
|
40
|
+
setup 用户级安装 CLI、修复 PATH、安装 Skill、检查 DWS
|
|
41
|
+
doctor 检查 PATH / Node / DWS / Skill / Agent 客户端
|
|
42
|
+
|
|
43
|
+
Skill(不要求 Workspace)
|
|
44
|
+
skill install 安装全局 Basic Behavior(Claude Code + Codex + OpenCode)
|
|
38
45
|
skill status 检查版本、漂移和客户端可发现性
|
|
39
46
|
skill upgrade 升级本工具管理的全局 Skill
|
|
40
47
|
skill uninstall 安全卸载本工具管理的全局 Skill
|
|
@@ -126,6 +133,47 @@ async function main() {
|
|
|
126
133
|
console.log(HELP);
|
|
127
134
|
return;
|
|
128
135
|
}
|
|
136
|
+
if (cmd === '--version' || cmd === '-V' || cmd === 'version') {
|
|
137
|
+
console.log(PACKAGE_JSON.version);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
// ── setup / doctor:npx 永远可启动的首次使用入口。──
|
|
141
|
+
if (cmd === 'setup') {
|
|
142
|
+
const { values: o } = parseArgs({
|
|
143
|
+
args: argv.slice(1),
|
|
144
|
+
options: {
|
|
145
|
+
prefix: { type: 'string' }, 'dry-run': { type: 'boolean' },
|
|
146
|
+
'no-shell-write': { type: 'boolean' }, 'skip-cli-install': { type: 'boolean' },
|
|
147
|
+
json: { type: 'boolean' },
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
const out = setup(PACKAGE_ROOT, {
|
|
151
|
+
prefix: o.prefix,
|
|
152
|
+
dryRun: o['dry-run'],
|
|
153
|
+
writeShell: !o['no-shell-write'],
|
|
154
|
+
skipCliInstall: o['skip-cli-install'],
|
|
155
|
+
});
|
|
156
|
+
if (o.json)
|
|
157
|
+
console.log(JSON.stringify(out, null, 2));
|
|
158
|
+
else
|
|
159
|
+
printSetup(out);
|
|
160
|
+
if (!out.doctor.ready)
|
|
161
|
+
process.exitCode = 2;
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
if (cmd === 'doctor') {
|
|
165
|
+
const { values: o } = parseArgs({
|
|
166
|
+
args: argv.slice(1), options: { json: { type: 'boolean' } },
|
|
167
|
+
});
|
|
168
|
+
const out = doctor(PACKAGE_ROOT);
|
|
169
|
+
if (o.json)
|
|
170
|
+
console.log(JSON.stringify(out, null, 2));
|
|
171
|
+
else
|
|
172
|
+
printDoctor(out);
|
|
173
|
+
if (!out.ready)
|
|
174
|
+
process.exitCode = 2;
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
129
177
|
// ── skill:唯一一次性的主入口;完全不依赖 Workspace。──
|
|
130
178
|
if (cmd === 'skill') {
|
|
131
179
|
const { values: o } = parseArgs({
|
|
@@ -674,7 +722,9 @@ function printSkillStatus(out, action, dryRun) {
|
|
|
674
722
|
console.log(` canonical=${out.canonical.path}`);
|
|
675
723
|
console.log(` installed=${out.canonical.exists} managed=${out.canonical.managed} ` +
|
|
676
724
|
`modified=${out.canonical.modified} current=${out.canonical.current}`);
|
|
677
|
-
|
|
725
|
+
for (const client of out.clients) {
|
|
726
|
+
console.log(` ${client.label}=${client.state} (${client.discovery}: ${client.path})`);
|
|
727
|
+
}
|
|
678
728
|
if (out.legacyCodex.conflict) {
|
|
679
729
|
console.log(` ⚠️ legacy Codex 同名路径存在: ${out.legacyCodex.path}`);
|
|
680
730
|
}
|
|
@@ -682,4 +732,32 @@ function printSkillStatus(out, action, dryRun) {
|
|
|
682
732
|
console.log(' 新 Agent 会话将自动发现;当前会话未发现时请重启 Claude Code/Codex。');
|
|
683
733
|
}
|
|
684
734
|
}
|
|
735
|
+
function printDoctor(out) {
|
|
736
|
+
console.log(`dingtalk-agent doctor · ${out.ready ? 'READY' : 'NOT READY'}`);
|
|
737
|
+
for (const check of out.checks) {
|
|
738
|
+
const mark = check.level === 'pass' ? '✅' : check.level === 'warn' ? '⚠️' : '❌';
|
|
739
|
+
console.log(`${mark} ${check.summary}`);
|
|
740
|
+
if (check.detail)
|
|
741
|
+
console.log(` ${check.detail}`);
|
|
742
|
+
if (check.fix)
|
|
743
|
+
console.log(` 修复: ${check.fix}`);
|
|
744
|
+
}
|
|
745
|
+
if (out.nextSteps.length) {
|
|
746
|
+
console.log('\n下一步:');
|
|
747
|
+
for (const step of out.nextSteps)
|
|
748
|
+
console.log(` ${step}`);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
function printSetup(out) {
|
|
752
|
+
console.log(`${out.dryRun ? 'DRY-RUN' : '✅'} dingtalk-agent setup`);
|
|
753
|
+
console.log(` CLI: ${out.cli.executable}`);
|
|
754
|
+
console.log(` Skill: ${out.skill.canonical.path}`);
|
|
755
|
+
if (!out.shell.pathReady) {
|
|
756
|
+
console.log(` 当前 shell 尚未加载 PATH;本次终端执行: ${out.shell.activateCommand}`);
|
|
757
|
+
if (out.shell.rcFile)
|
|
758
|
+
console.log(` 新终端会从 ${out.shell.rcFile} 自动加载`);
|
|
759
|
+
}
|
|
760
|
+
printDoctor(out.doctor);
|
|
761
|
+
console.log(`\n开始使用: ${out.nextCommand}`);
|
|
762
|
+
}
|
|
685
763
|
//# sourceMappingURL=dingtalk-agent.js.map
|