dsh-lark-bot 0.2.8 → 0.4.0
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/README.md +52 -18
- package/SECURITY.md +46 -0
- package/dist/cli.js +3734 -1156
- package/dist/cli.js.map +1 -1
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -42,7 +42,7 @@ npm install -g dsh-feishu-bot
|
|
|
42
42
|
|
|
43
43
|
安装完成后,对应命令分别为 `dsh-lark-bot` 和 `dsh-feishu-bot`。
|
|
44
44
|
|
|
45
|
-
### 2.
|
|
45
|
+
### 2. 启动后台服务并绑定飞书
|
|
46
46
|
|
|
47
47
|
```bash
|
|
48
48
|
dsh-lark-bot start
|
|
@@ -54,7 +54,7 @@ dsh-lark-bot start
|
|
|
54
54
|
dsh-feishu-bot start
|
|
55
55
|
```
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
`start` 会自动在本机安装一个**后台服务**:加入系统开机自启列表,并在进程退出、崩溃或出错时自动重启。首次启动会:
|
|
58
58
|
|
|
59
59
|
1. 在终端显示二维码。
|
|
60
60
|
2. 用飞书 / Lark App 扫码。
|
|
@@ -62,6 +62,8 @@ dsh-feishu-bot start
|
|
|
62
62
|
4. 绑定成功后,bot 会向你的私聊发送欢迎卡片。
|
|
63
63
|
5. 私聊直接发消息;群聊或话题里 `@bot`。
|
|
64
64
|
|
|
65
|
+
绑定完成后 bot 转入后台运行,终端可以随时关闭。
|
|
66
|
+
|
|
65
67
|
如果你已经有 PersonalAgent 应用,也可以跳过扫码:
|
|
66
68
|
|
|
67
69
|
```bash
|
|
@@ -71,7 +73,18 @@ dsh-lark-bot start \
|
|
|
71
73
|
--tenant feishu
|
|
72
74
|
```
|
|
73
75
|
|
|
74
|
-
### 3.
|
|
76
|
+
### 3. 服务管理命令
|
|
77
|
+
|
|
78
|
+
| 命令 | 作用 |
|
|
79
|
+
| :--- | :--- |
|
|
80
|
+
| `dsh-lark-bot start` | 安装后台服务、加入开机自启并启动(首次运行会先扫码绑定) |
|
|
81
|
+
| `dsh-lark-bot status` | 查看服务状态(退出码 0=运行中,1=未运行) |
|
|
82
|
+
| `dsh-lark-bot restart` | 重启后台服务(保留开机自启) |
|
|
83
|
+
| `dsh-lark-bot stop` | 停止后台服务并移出开机自启 |
|
|
84
|
+
|
|
85
|
+
后台服务的运行日志写入 `~/.dsh-lark/profiles/<profile>/logs/bot.log`。
|
|
86
|
+
|
|
87
|
+
### 4. 基本使用
|
|
75
88
|
|
|
76
89
|
在飞书里向 bot 发送普通消息即可开始工作,常用命令:
|
|
77
90
|
|
|
@@ -82,18 +95,22 @@ dsh-lark-bot start \
|
|
|
82
95
|
| `/ws list` | 查看命名工作空间 |
|
|
83
96
|
| `/ws save <name>` | 保存当前工作空间 |
|
|
84
97
|
| `/ws use <name>` | 切换到命名工作空间 |
|
|
98
|
+
| `/ws remove <name>` | 删除命名工作空间 |
|
|
85
99
|
| `/status` | 查看当前状态 |
|
|
86
100
|
| `/resume` | 查看当前会话最近上下文 |
|
|
87
101
|
| `/stop` | 终止当前任务 |
|
|
88
|
-
| `/timeout [N
|
|
89
|
-
| `/
|
|
102
|
+
| `/timeout [N\|off\|default]` | 查看或设置当前会话运行超时 |
|
|
103
|
+
| `/density [compact\|standard\|detailed]` | 查看或设置卡片密度 |
|
|
104
|
+
| `/ask <问题>` | 发送问答卡,回答写入会话上下文 |
|
|
105
|
+
| `/invite user\|admin\|group <id>`、`/invite list`、`/invite remove user\|group <id>` | 管理访问白名单 |
|
|
90
106
|
| `/help` | 查看帮助 |
|
|
91
107
|
|
|
92
108
|
飞书消息中的图片会下载到本地 media 目录并传给 dsh;文本类文件会读取内容并注入任务上下文。
|
|
93
109
|
|
|
94
|
-
###
|
|
110
|
+
### 5. 卸载
|
|
95
111
|
|
|
96
112
|
```bash
|
|
113
|
+
dsh-lark-bot stop
|
|
97
114
|
npm uninstall -g dsh-lark-bot
|
|
98
115
|
rm -rf ~/.dsh-lark
|
|
99
116
|
```
|
|
@@ -114,8 +131,8 @@ rm -rf ~/.dsh-lark
|
|
|
114
131
|
|
|
115
132
|
## 目标 · Goals
|
|
116
133
|
|
|
117
|
-
- **一条命令启动**:clone 后一键安装运行,最终发布到 npm,`
|
|
118
|
-
- **飞书原生体验**:流式卡片、交互按钮、图片 /
|
|
134
|
+
- **一条命令启动**:clone 后一键安装运行,最终发布到 npm,`npm i -g dsh-lark-bot && dsh-lark-bot start` 即可拉起后台服务。
|
|
135
|
+
- **飞书原生体验**:流式卡片、交互按钮、图片 / 文件,全程双语(文档评论为规划中能力)。
|
|
119
136
|
- **完整工作区管理**:多项目隔离、git worktree、项目级规则注入、上下文持久化。
|
|
120
137
|
|
|
121
138
|
- **One-command start**: clone and run in one step, eventually published to npm as `npx dsh-lark-bot`.
|
|
@@ -124,10 +141,14 @@ rm -rf ~/.dsh-lark
|
|
|
124
141
|
|
|
125
142
|
## 兼容性 · Compatibility
|
|
126
143
|
|
|
127
|
-
- **DeepSeek Harness(`dsh
|
|
128
|
-
-
|
|
144
|
+
- **DeepSeek Harness(`dsh`)**:已验证 **dsh 0.1.0-rc.6**(2026-08-14:SDK JSON-RPC / ACP runtime 握手 +
|
|
145
|
+
真实任务流式验证),通过官方 `@deepseek-ai/dsh-sdk-client` / `@deepseek-ai/dsh-acp` 接入;
|
|
146
|
+
具体锁定版本与漂移策略见 [`docs/adapter-notes.md`](docs/adapter-notes.md)。
|
|
147
|
+
- **运行时**:Node.js ≥ 22.19(见 `package.json` engines)。
|
|
129
148
|
- **平台**:Linux / macOS / Windows(飞书 WebSocket 出站长连接,免公网服务器 / 域名 / 内网穿透)。
|
|
130
|
-
-
|
|
149
|
+
- 默认 adapter 为官方 **`@deepseek-ai/dsh-sdk-client`**(SDK JSON-RPC runtime,原生 session 续跑 +
|
|
150
|
+
token 级流式事件);`DSH_LARK_ADAPTER=acp` 切到官方 **ACP server**(审批卡);`headless` 保留旧版
|
|
151
|
+
子进程 fallback。首次启动自动在 `~/.dsh/profiles/dsh-lark`(或 `dsh-lark-acp`)创建 runtime profile。
|
|
131
152
|
|
|
132
153
|
## 配置 · Configuration
|
|
133
154
|
|
|
@@ -138,7 +159,8 @@ rm -rf ~/.dsh-lark
|
|
|
138
159
|
|
|
139
160
|
会话运行在 Git 仓库中时,会自动在 `~/.dsh-lark/profiles/<profile>/worktrees/<scope>/` 创建隔离 worktree,并复制项目级 `AGENTS.md`。
|
|
140
161
|
|
|
141
|
-
每个飞书 scope 会保存最近 40
|
|
162
|
+
每个飞书 scope 会保存最近 40 条对话消息;SDK 模式下 dsh 原生 session 续跑,headless 模式
|
|
163
|
+
则把历史注入下一次 prompt 实现近似记忆。
|
|
142
164
|
|
|
143
165
|
当前核心环境变量:
|
|
144
166
|
|
|
@@ -146,10 +168,15 @@ rm -rf ~/.dsh-lark
|
|
|
146
168
|
| :--- | :--- | :--- |
|
|
147
169
|
| `DSH_LARK_HOME` | `~/.dsh-lark` | 本地状态根目录 |
|
|
148
170
|
| `DSH_LARK_TENANT` | `feishu` | `feishu` 或 `lark` |
|
|
171
|
+
| `DSH_LARK_WORKSPACE` | 未设置 | 新会话默认工作目录 |
|
|
149
172
|
| `DSH_LARK_DSH_COMMAND` | `自动发现` | dsh 启动命令;通常无需设置 |
|
|
150
173
|
| `DSH_LARK_DSH_ARGS` | `自动发现` | dsh 启动参数,逗号分隔;通常无需设置 |
|
|
174
|
+
| `DSH_LARK_ADAPTER` | `sdk` | `sdk`(默认)/ `acp`(审批)/ `headless`(legacy) |
|
|
151
175
|
| `DSH_LARK_PROVIDER` | `deepseek-official` | 模型 provider |
|
|
152
176
|
| `DSH_LARK_MODEL` | `deepseek-v4-flash` | 默认模型 |
|
|
177
|
+
| `DSH_LARK_MAX_TOKENS` | 未设置 | SDK agent 每请求输出 token 上限 |
|
|
178
|
+
| `DSH_LARK_ACCESS_DEFAULT_DENY` | `false` | 无白名单时拒绝私聊 |
|
|
179
|
+
| `DSH_LARK_EVENT_FRESHNESS_MS` | `600000` | 过期消息拒绝窗口(0 关闭) |
|
|
153
180
|
| `DSH_LARK_RUN_TIMEOUT_MS` | `300000` | 单次运行墙钟超时 |
|
|
154
181
|
| `DSH_LARK_STOP_GRACE_MS` | `5000` | SIGTERM 后等待优雅退出再 SIGKILL 的宽限期 |
|
|
155
182
|
|
|
@@ -162,7 +189,7 @@ rm -rf ~/.dsh-lark
|
|
|
162
189
|
- **飞书凭据**:PersonalAgent 应用的 `app_id` / `app_secret`,明文写入本机 `~/.dsh-lark/config.json`(文件权限 600)。
|
|
163
190
|
- **文件系统**:读取 / 写入你通过 `/cd`、`/ws` 指定的工作目录(含执行 shell 命令、修改文件)。
|
|
164
191
|
- **网络**:向飞书开放平台建立 WebSocket 出站长连接收发消息;向 DeepSeek API 发送任务上下文。
|
|
165
|
-
- **进程**:spawn 本机 `dsh`
|
|
192
|
+
- **进程**:spawn 本机 `dsh` runtime 子进程(`dsh-sdk-jsonrpc-server` / `dsh-acp` profile)执行 agent 任务。
|
|
166
193
|
|
|
167
194
|
所有数据仅在本机与飞书、DeepSeek 之间流转,不收集、不上传任何遥测。密钥不会提交进仓库(见 `.gitignore`)。
|
|
168
195
|
|
|
@@ -176,7 +203,8 @@ rm -rf ~/.dsh-lark
|
|
|
176
203
|
- **agent 无响应**:发送 `/status` 查看当前 scope、cwd 和 active run;发送 `/stop` 终止当前任务;超过 `DSH_LARK_RUN_TIMEOUT_MS` 时看门狗会自动终止。
|
|
177
204
|
- **首次扫码失败**:确认本机时间准确、网络可访问飞书开放平台;已拿到 App ID/Secret 时可用 `--app-id` / `--app-secret` 跳过扫码。
|
|
178
205
|
|
|
179
|
-
|
|
206
|
+
以后台服务方式运行时,日志写入 `~/.dsh-lark/profiles/<profile>/logs/bot.log`(JSON Lines,
|
|
207
|
+
stdout 与 stderr 合并);当前进程的 stderr 仍为 JSON Lines。
|
|
180
208
|
|
|
181
209
|
## 开发 · Development
|
|
182
210
|
|
|
@@ -205,6 +233,8 @@ pnpm publish:dual
|
|
|
205
233
|
|
|
206
234
|
- **许可证**:GNU Affero General Public License v3.0(见 `LICENSE`)。
|
|
207
235
|
- **安全报告**:如发现安全漏洞,请通过 GitHub Security Advisory 私下报告,勿公开 issue。
|
|
236
|
+
- **安全模型**:默认拒绝、密钥脱敏、路径 containment、SSRF 防护、过期事件拒绝与交互工具
|
|
237
|
+
默认禁用——详见 [`SECURITY.md`](SECURITY.md)。
|
|
208
238
|
|
|
209
239
|
## 文档 · Documentation
|
|
210
240
|
|
|
@@ -223,6 +253,7 @@ pnpm publish:dual
|
|
|
223
253
|
| [`docs/ECOSYSTEM.md`](docs/ECOSYSTEM.md) | 生态兼容与交付标准(实现工程师必读)<br>Ecosystem & delivery standards (for engineers) |
|
|
224
254
|
| [`docs/roadmap.md`](docs/roadmap.md) | 路线图与里程碑<br>Roadmap & milestones |
|
|
225
255
|
| [`docs/PLAN.md`](docs/PLAN.md) | 主线开发计划与验收标准<br>Development plan & acceptance criteria |
|
|
256
|
+
| [`SECURITY.md`](SECURITY.md) | 安全模型与报告渠道<br>Security model & reporting |
|
|
226
257
|
| [`AGENTS.md`](AGENTS.md) | AI Agent 开发工作流规范<br>AI agent workflow spec |
|
|
227
258
|
|
|
228
259
|
## 架构 · Architecture
|
|
@@ -233,9 +264,9 @@ pnpm publish:dual
|
|
|
233
264
|
飞书 / Lark ──WebSocket 长连接──▶ bridge/ ──▶ session/ ──▶ workspace/ ──▶ adapters/ ──▶ dsh ──▶ DeepSeek V4
|
|
234
265
|
```
|
|
235
266
|
|
|
236
|
-
核心思路:**飞书通道与 agent 后端解耦**。桥接层复刻 `lark-channel-bridge` 的成熟做法(WebSocket 长连接 + 流式卡片 + 会话路由),agent 后端通过 adapter
|
|
267
|
+
核心思路:**飞书通道与 agent 后端解耦**。桥接层复刻 `lark-channel-bridge` 的成熟做法(WebSocket 长连接 + 流式卡片 + 会话路由),agent 后端通过 adapter 抽象,默认挂接官方 DeepSeek Harness SDK(`DSH_LARK_ADAPTER=sdk`),可选 ACP 审批模式与 legacy headless。
|
|
237
268
|
|
|
238
|
-
The core idea: **decouple the Feishu channel from the agent backend**. The bridge layer follows the battle-tested `lark-channel-bridge` approach (WebSocket long-connection + streaming cards + session routing); the agent backend is abstracted behind an adapter, defaulting to DeepSeek Harness (
|
|
269
|
+
The core idea: **decouple the Feishu channel from the agent backend**. The bridge layer follows the battle-tested `lark-channel-bridge` approach (WebSocket long-connection + streaming cards + session routing); the agent backend is abstracted behind an adapter, defaulting to the official DeepSeek Harness SDK (`DSH_LARK_ADAPTER=sdk`), with an optional ACP approval mode and the legacy headless fallback.
|
|
239
270
|
|
|
240
271
|
## 目录结构 · Directory Structure
|
|
241
272
|
|
|
@@ -245,13 +276,16 @@ The core idea: **decouple the Feishu channel from the agent backend**. The bridg
|
|
|
245
276
|
| `src/onboard/` | 首次扫码创建 / 绑定 PersonalAgent 应用<br>First-run QR onboarding |
|
|
246
277
|
| `src/session/` | 会话路由、排队、访问控制<br>Session routing, queueing, access control |
|
|
247
278
|
| `src/workspace/` | 项目工作区、git worktree 隔离与规则注入<br>Project workspace, git worktree isolation & rule injection |
|
|
248
|
-
| `src/adapters/` | agent 后端适配器(
|
|
279
|
+
| `src/adapters/` | agent 后端适配器(sdk 默认 / acp 审批 / headless legacy)<br>Agent backend adapters (sdk / acp / headless) |
|
|
249
280
|
| `src/card/` | 流式卡片状态与渲染<br>Streaming card state & rendering |
|
|
250
|
-
| `src/bot/` |
|
|
281
|
+
| `src/bot/` | 运行注册、消息排队、审批/问答注册表<br>Run registry, queueing, approval/question registries |
|
|
251
282
|
| `src/commands/` | 斜杠命令(/cd /ws /new …)<br>Slash commands |
|
|
283
|
+
| `src/cli/` | CLI 入口与 start / status / restart / stop / doctor 命令<br>CLI entry & service commands |
|
|
252
284
|
| `src/config/` | profile / 配置管理<br>Profile & config |
|
|
253
285
|
| `src/core/` | 结构化日志<br>Structured logging |
|
|
286
|
+
| `src/media/` | 附件下载与文本注入<br>Attachment download & text injection |
|
|
254
287
|
| `src/platform/` | 跨平台原子写入<br>Cross-platform atomic writes |
|
|
288
|
+
| `src/service/` | 后台服务管理(systemd / launchd / 计划任务 / 便携 supervisor)<br>Background service management |
|
|
255
289
|
| `docs/` | 架构、路线图等文档<br>Architecture, roadmap & docs |
|
|
256
290
|
| `reference/` | 参考研究用的克隆仓库(不提交)<br>Cloned reference repos (not committed) |
|
|
257
291
|
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# 安全说明 · Security
|
|
2
|
+
|
|
3
|
+
> dsh-lark-bot 把本机 DeepSeek Harness(`dsh`)暴露给飞书 / Lark IM。本文件说明威胁模型、
|
|
4
|
+
> 默认安全姿态与报告渠道。Security model for a bridge that exposes a local coding agent to Feishu / Lark.
|
|
5
|
+
|
|
6
|
+
## 威胁模型 · Threat model
|
|
7
|
+
|
|
8
|
+
- **凭据泄露**:飞书 `app_id` / `app_secret`、DeepSeek API key、会话内容可能在日志、卡片或进程环境中出现。
|
|
9
|
+
- **越权访问**:未授权用户 / 群聊驱动本机 coding agent 执行命令、读写文件。
|
|
10
|
+
- **路径逃逸 / 符号链接逃逸**:附件、worktree、`/cd` 相关路径穿越到 bot 状态目录之外。
|
|
11
|
+
- **SSRF**:agent 或桥接层被诱导访问内网 / 环回地址。
|
|
12
|
+
- **消息重放 / 过期事件**:旧消息或重复事件被当作新指令处理。
|
|
13
|
+
- **交互工具不可达**:`ask_user_question`、终端类工具在 IM 场景下无法回达,应默认禁用。
|
|
14
|
+
|
|
15
|
+
## 安全姿态 · Security posture
|
|
16
|
+
|
|
17
|
+
1. **默认拒绝**:
|
|
18
|
+
- 群聊 / 话题必须 `@bot` 才响应(传输层强制,`requireMention: true`)。
|
|
19
|
+
- 配置了白名单后,私聊切换为 allowlist 模式(`dmMode: 'allowlist'`)。
|
|
20
|
+
- 可通过 `DSH_LARK_ACCESS_DEFAULT_DENY=1` 在无白名单时也拒绝私聊(默认关闭以兼容首次扫码绑定)。
|
|
21
|
+
2. **密钥脱敏**:结构化日志按字段名(`secret/token/password/api_key`)脱敏;
|
|
22
|
+
自由文本日志与卡片文本对 `Bearer …`、`sk-…`、`api_key=…` 做正则脱敏(`src/config/security.ts`)。
|
|
23
|
+
3. **路径 containment**:媒体下载目标、git worktree 目标必须落在各自根目录内
|
|
24
|
+
(realpath 校验,拒绝符号链接逃逸,`isPathWithin`)。
|
|
25
|
+
4. **UTF-8 安全截断**:附件文本、卡片摘要按字节截断且不切断多字节字符(`truncateUtf8Safe`)。
|
|
26
|
+
5. **过期事件拒绝**:消息时间戳超出窗口即拒绝(`isEventFresh`)。
|
|
27
|
+
6. **SSRF 防护**:仅允许 http(s) 公网地址;环回、私有、链路本地、CGNAT、IPv6 ULA 全部拒绝
|
|
28
|
+
(`isSafeHttpUrl`)。
|
|
29
|
+
7. **交互工具默认禁用**:SDK / ACP runtime profile 禁用 `user-questions`;
|
|
30
|
+
`DEFAULT_DENIED_INTERACTIVE_TOOLS` 提供工具级黑名单。
|
|
31
|
+
8. **审批**:ACP 模式下敏感操作通过 `session/request_permission` 以飞书审批卡一问一答;
|
|
32
|
+
run 结束 / dispose 时所有挂起审批卡结算为拒绝(`src/bot/approvals.ts`)。
|
|
33
|
+
|
|
34
|
+
## 数据与凭据 · Data & credentials
|
|
35
|
+
|
|
36
|
+
- 本地配置 `~/.dsh-lark/config.json` 以 `0600` 权限写入。
|
|
37
|
+
- 飞书凭据明文保存在本机配置文件;日志与卡片不输出真实密钥。
|
|
38
|
+
- 后台服务把 `DEEPSEEK_API_KEY`、`DSH_LARK_*`、`PATH` 等环境快照到
|
|
39
|
+
`~/.dsh-lark/service/service.env`(`0600`);systemd / launchd 单元文件中的 `EnvironmentFile`
|
|
40
|
+
只引用该文件,不内联密钥。
|
|
41
|
+
- 后台运行日志写入 `~/.dsh-lark/profiles/<profile>/logs/bot.log`(JSON Lines,密钥字段脱敏后输出)。
|
|
42
|
+
- 所有数据仅在本机、飞书开放平台与 DeepSeek API 之间流转;无遥测。
|
|
43
|
+
|
|
44
|
+
## 报告渠道 · Reporting
|
|
45
|
+
|
|
46
|
+
发现安全漏洞请通过 GitHub Security Advisory 私下报告,**不要**公开 issue。
|