dsh-lark-bot 0.5.1 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  <h1 align="center">dsh-lark-bot</h1>
2
2
 
3
3
  <p align="center">
4
- <strong>把 DeepSeek Harness 接入飞书 · Bridge DeepSeek Harness into Feishu / Lark</strong>
4
+ <strong>把 DeepSeek Harness 接入飞书 | Bridge DeepSeek Harness into Feishu / Lark</strong>
5
5
  </p>
6
6
 
7
7
  <p align="center">
@@ -26,29 +26,60 @@
26
26
 
27
27
  ---
28
28
 
29
- ## 快速开始 · Quick Start(普通用户先看这里)
29
+ ## 快速开始 | Quick Start(普通用户先看这里 | for end users)
30
30
 
31
- ### 1. 安装
31
+ ### 1. 安装 | Install
32
32
 
33
33
  两个包名内容完全一致,任选一个即可:
34
34
 
35
+ Both package names ship identical content — pick either one:
36
+
35
37
  ```bash
36
- # 推荐
38
+ # 推荐 | Recommended
37
39
  npm install -g dsh-lark-bot
38
40
 
39
- # 或飞书命名版本
41
+ # 或飞书命名版本 | or the Feishu-named edition
40
42
  npm install -g dsh-feishu-bot
41
43
  ```
42
44
 
43
45
  安装完成后,对应命令分别为 `dsh-lark-bot` 和 `dsh-feishu-bot`。
44
46
 
45
- ### 2. 启动后台服务并绑定飞书
47
+ After installation, the commands are `dsh-lark-bot` and `dsh-feishu-bot` respectively.
48
+
49
+ 也可以作为 **dsh 标准 profile bundle** 安装到任意 dsh profile(`dsh.bundle.patch` 已声明):
50
+
51
+ It is also installable as a **standard dsh profile bundle** (the package declares
52
+ `dsh.bundle.patch`):
53
+
54
+ ```bash
55
+ dsh plugin --profile <name> add dsh-lark-bot
56
+ ```
57
+
58
+ 安装后 profile 启动时会装配 `dsh-lark-bot/plugin`(在 `ctx.larkBridge` 暴露 bridge 后台服务的
59
+ status / start / restart / stop,不阻塞 profile 启动;`DSH_LARK_AUTOSTART=1` 可在 profile
60
+ 启动时自动拉起 bridge)。SDK / ACP runtime 还会自动装配 `lark_notify` 工具(见下文)。
61
+
62
+ The profile then mounts `dsh-lark-bot/plugin` on boot — it exposes `ctx.larkBridge`
63
+ (status / start / restart / stop of the standalone bridge service) without blocking boot; set
64
+ `DSH_LARK_AUTOSTART=1` to start the bridge when the profile boots. The SDK / ACP runtimes also
65
+ auto-mount the `lark_notify` tool (see below).
66
+
67
+ > pnpm ≥ 10 默认拒绝依赖构建脚本:若 `dsh plugin add` 报 `ERR_PNPM_IGNORED_BUILDS`
68
+ > (protobufjs 等),按官方指引在 profile 目录的 `pnpm-workspace.yaml` 加
69
+ > `allowBuilds:\n protobufjs: true` 后重试(与官方 `dsh-lark-channel` 相同的处理方式)。
70
+
71
+ > pnpm ≥ 10 blocks dependency build scripts by default: if `dsh plugin add` reports
72
+ > `ERR_PNPM_IGNORED_BUILDS` (e.g. protobufjs), add `allowBuilds:\n protobufjs: true` to the
73
+ > profile's `pnpm-workspace.yaml` and retry — the same handling as the official
74
+ > `dsh-lark-channel`.
75
+
76
+ ### 2. 启动后台服务并绑定飞书 | Start the background service and bind Feishu
46
77
 
47
78
  ```bash
48
79
  dsh-lark-bot start
49
80
  ```
50
81
 
51
- 或:
82
+ 或: | or:
52
83
 
53
84
  ```bash
54
85
  dsh-feishu-bot start
@@ -56,16 +87,29 @@ dsh-feishu-bot start
56
87
 
57
88
  `start` 会自动在本机安装一个**后台服务**:加入系统开机自启列表,并在进程退出、崩溃或出错时自动重启。首次启动会:
58
89
 
90
+ `start` automatically installs a **background service** locally: it joins the OS autostart
91
+ list and restarts automatically whenever the process exits, crashes or errors. On first launch:
92
+
59
93
  1. 在终端显示二维码。
60
94
  2. 用飞书 / Lark App 扫码。
61
95
  3. 选择或创建 PersonalAgent 应用。
62
96
  4. 绑定成功后,bot 会向你的私聊发送欢迎卡片。
63
97
  5. 私聊直接发消息;群聊或话题里 `@bot`。
64
98
 
99
+ 1. A QR code is shown in the terminal.
100
+ 2. Scan it with the Feishu / Lark app.
101
+ 3. Choose or create a PersonalAgent app.
102
+ 4. Once bound, the bot sends a welcome card to your private chat.
103
+ 5. Message it directly in private chat; use `@bot` in group chats or topics.
104
+
65
105
  绑定完成后 bot 转入后台运行,终端可以随时关闭。
66
106
 
107
+ After binding, the bot runs in the background; you can close the terminal anytime.
108
+
67
109
  如果你已经有 PersonalAgent 应用,也可以跳过扫码:
68
110
 
111
+ If you already have a PersonalAgent app, you can skip the QR step:
112
+
69
113
  ```bash
70
114
  dsh-lark-bot start \
71
115
  --app-id cli_xxx \
@@ -73,52 +117,105 @@ dsh-lark-bot start \
73
117
  --tenant feishu
74
118
  ```
75
119
 
76
- ### 3. 服务管理命令
120
+ ### 3. 服务管理命令 | Service management commands
77
121
 
78
- | 命令 | 作用 |
122
+ | 命令 Command | 作用 Description |
79
123
  | :--- | :--- |
80
- | `dsh-lark-bot start` | 安装后台服务、加入开机自启并启动(首次运行会先扫码绑定) |
81
- | `dsh-lark-bot status` | 查看服务状态(退出码 0=运行中,1=未运行) |
82
- | `dsh-lark-bot restart` | 重启后台服务(保留开机自启) |
83
- | `dsh-lark-bot stop` | 停止后台服务并移出开机自启 |
124
+ | `dsh-lark-bot start` | 安装后台服务、加入开机自启并启动(首次运行会先扫码绑定)<br>Install the background service, enable autostart and start it (first run prompts QR binding) |
125
+ | `dsh-lark-bot status` | 查看服务状态(退出码 0=运行中,1=未运行)<br>Show service status (exit code 0=running, 1=not running) |
126
+ | `dsh-lark-bot restart` | 重启后台服务(保留开机自启)<br>Restart the background service (keeps autostart) |
127
+ | `dsh-lark-bot stop` | 停止后台服务并移出开机自启<br>Stop the background service and remove autostart |
84
128
 
85
129
  后台服务的运行日志写入 `~/.dsh-lark/profiles/<profile>/logs/bot.log`。
86
130
 
87
- ### 4. 基本使用
131
+ Background service logs are written to `~/.dsh-lark/profiles/<profile>/logs/bot.log`.
132
+
133
+ ### 4. 基本使用 | Basic usage
88
134
 
89
135
  在飞书里向 bot 发送普通消息即可开始工作,常用命令:
90
136
 
91
- | 命令 | 作用 |
137
+ Just send a normal message to the bot in Feishu to get started. Common commands:
138
+
139
+ | 命令 Command | 作用 Description |
92
140
  | --- | --- |
93
- | `/new` `/reset` | 开始新会话 |
94
- | `/cd <path>` | 切换工作目录并重置会话 |
95
- | `/ws list` | 查看命名工作空间 |
96
- | `/ws save <name>` | 保存当前工作空间 |
97
- | `/ws use <name>` | 切换到命名工作空间 |
98
- | `/ws remove <name>` | 删除命名工作空间 |
99
- | `/status` | 查看当前状态 |
100
- | `/resume` | 查看当前会话最近上下文 |
101
- | `/stop` | 终止当前任务 |
102
- | `/timeout [N\|off\|default]` | 查看或设置当前会话运行超时 |
103
- | `/density [compact\|standard\|detailed]` | 查看或设置卡片密度 |
104
- | `/model` | 查看当前模型、dsh 默认模型与可用模型列表 |
105
- | `/model use <id>` | 热切换当前会话模型(下一轮生效,无需重启) |
106
- | `/model default <id>` | 写入 dsh 默认模型 `agent-default-model`(管理员) |
107
- | `/model add\|remove <provider> <modelId>` | 添加 / 删除 provider 的模型(管理员) |
108
- | `/providers` | 查看 dsh 已配置 providers、模型与凭据状态 |
109
- | `/provider add\|update\|remove <id>` | 管理 provider(管理员;deepseek-official 与自定义 pi-ai) |
110
- | `/key set\|remove\|list <引用名>` | 管理 dsh 凭据(set / remove 需管理员) |
111
- | `/ask <问题>` | 发送问答卡,回答写入会话上下文 |
112
- | `/invite user\|admin\|group <id>`、`/invite list`、`/invite remove user\|group <id>` | 管理访问白名单 |
113
- | `/help` | 查看帮助 |
141
+ | `/new` `/reset` | 开始新会话<br>Start a new session |
142
+ | `/cd <path>` | 切换工作目录并重置会话<br>Change working directory and reset the session |
143
+ | `/ws list` | 查看命名工作空间<br>List named workspaces |
144
+ | `/ws save <name>` | 保存当前工作空间<br>Save the current workspace |
145
+ | `/ws use <name>` | 切换到命名工作空间<br>Switch to a named workspace |
146
+ | `/ws remove <name>` | 删除命名工作空间<br>Remove a named workspace |
147
+ | `/status` | 查看当前状态<br>Show current status |
148
+ | `/resume` | 查看当前会话最近上下文<br>Show the session's recent context |
149
+ | `/stop` | 终止当前任务<br>Stop the current task |
150
+ | `/timeout [N\|off\|default]` | 查看或设置当前会话运行超时<br>View or set the current session run timeout |
151
+ | `/concurrency [N\|default]` | 查看或设置当前 scope 并行任务数(默认 2)<br>View or set the concurrent-run limit for this scope (default 2) |
152
+ | `/role list`、`/role show <id>` | 查看角色列表 / 详情<br>List roles / show a role |
153
+ | `/role set <id>`、`/role clear` | 为当前 scope 绑定 / 解除角色<br>Bind / unbind a role for this scope |
154
+ | `/role save <id> <name> [--persona 文案] [--model <id>] [--tools <csv>] [--rules 文案]` | 创建 / 更新角色(管理员)<br>Create / update a role (admin) |
155
+ | `/role remove <id>` | 删除角色(管理员)<br>Remove a role (admin) |
156
+ | `/notify <scope\|chatId> <text>` | 跨会话发送通知(管理员)<br>Push a cross-session notification (admin) |
157
+ | `/notify list` | 查看 bridge 已注册的 scope<br>List scopes known to the bridge |
158
+ | `/retention [N\|default]` | 查看或设置保留消息条数(超出自动归档)<br>View or set the live message retention window (overflow is archived) |
159
+ | `/archive [note]`、`/archive list [N]`、`/archive clean` | 手动归档 / 查看 / 清理会话记录<br>Archive / list / clean session transcripts |
160
+ | `/density [compact\|standard\|detailed]` | 查看或设置卡片密度<br>View or set card density |
161
+ | `/model` | 查看当前模型、dsh 默认模型与可用模型列表<br>View current model, dsh default model and available models |
162
+ | `/model use <id>` | 热切换当前会话模型(下一轮生效,无需重启)<br>Hot-switch the current session model (effective next message, no restart) |
163
+ | `/model default <id>` | 写入 dsh 默认模型 `agent-default-model`(管理员)<br>Write the dsh default model `agent-default-model` (admin) |
164
+ | `/model add\|remove <provider> <modelId>` | 添加 / 删除 provider 的模型(管理员)<br>Add / remove a provider model (admin) |
165
+ | `/providers` | 查看 dsh 已配置 providers、模型与凭据状态<br>View configured dsh providers, models and credential status |
166
+ | `/provider add\|update\|remove <id>` | 管理 provider(管理员;deepseek-official 与自定义 pi-ai)<br>Manage providers (admin; deepseek-official and custom pi-ai) |
167
+ | `/key set\|remove\|list <引用名>` | 管理 dsh 凭据(set / remove 需管理员)<br>Manage dsh credentials (set / remove require admin) |
168
+ | `/ask <问题>` | 发送问答卡,回答写入会话上下文<br>Send a Q&A card; the answer is written back to session context |
169
+ | `/invite user\|admin\|group <id>`、`/invite list`、`/invite remove user\|group <id>` | 管理访问白名单<br>Manage the access allowlist |
170
+ | `/help` | 查看帮助<br>Show help |
114
171
 
115
172
  飞书消息中的图片会下载到本地 media 目录并传给 dsh;文本类文件会读取内容并注入任务上下文。
116
173
 
117
- ### 模型 / Provider / 凭据管理
174
+ Images in Feishu messages are downloaded to the local media directory and passed to dsh; text files are read and their content is injected into the task context.
175
+
176
+ 同一 scope(私聊 / 群聊 / 话题)默认允许 **2 个任务并行**(`DSH_LARK_SCOPE_CONCURRENCY` 或
177
+ `/concurrency` 调整):连续发来的多条消息会以独立 run 并行推进,每个 run 使用独立的 dsh
178
+ session 与独立 runId,`/status` 展示全部运行中的 run,`/stop` 一次性终止全部任务。
179
+
180
+ Each scope (DM / group / topic) runs up to **2 tasks in parallel** by default (adjust with
181
+ `DSH_LARK_SCOPE_CONCURRENCY` or `/concurrency`): successive messages become independent runs,
182
+ each with its own dsh session and run id. `/status` lists every active run and `/stop` interrupts
183
+ them all.
184
+
185
+ **多角色 Agent**:管理员用 `/role save <id> <name> --persona <文案> [--model <id>] [--tools
186
+ <csv>] [--rules <文案>]` 定义 PM / 开发 / 文档等角色(persona、模型偏好、工具指引、角色规则),
187
+ `/role set <id>` 把角色绑定到当前 scope:下一轮起该 scope 的每个 run 都携带角色 persona 与
188
+ 规则,并优先使用角色模型(角色模型 < 每会话 `/model use`)。角色定义持久化在
189
+ `~/.dsh-lark/profiles/<profile>/roles.json`。
190
+
191
+ **Multi-role agents**: admins define roles (PM / dev / docs / …) with `/role save <id> <name>
192
+ --persona <text> [--model <id>] [--tools <csv>] [--rules <text>]` — persona, model preference,
193
+ tool guidance and role rules — then bind one to the current scope with `/role set <id>`. Every
194
+ run in that scope carries the role instructions, and the role model wins below the per-session
195
+ `/model use` override. Role definitions persist in
196
+ `~/.dsh-lark/profiles/<profile>/roles.json`.
197
+
198
+ **出站 @ 提及与跨会话通知**:bridge 出站契约支持 `mentions`(@ 提及)与跨 chat/thread 发送;
199
+ `/notify <scope|chatId> <text>` 可向其他会话推送汇报(管理员)。agent 侧还内置 `lark_notify`
200
+ dsh 工具(SDK / ACP 两种 runtime 均可装配):agent 完成任务后可主动向其他群 / 话题发消息并
201
+ @ 指定成员,桥接进程通过 127.0.0.1 本地回调端口 + 随机 token 校验,不暴露公网。
202
+
203
+ **Outbound mentions & cross-session notify**: the outbound contract supports `mentions` and
204
+ cross-chat/thread sends; `/notify <scope|chatId> <text>` pushes a report to another session
205
+ (admin). The agent also gets a built-in `lark_notify` dsh tool (wired into both SDK and ACP
206
+ runtime profiles): after a task finishes it can push messages to other groups/topics and @mention
207
+ members. The bridge listens on 127.0.0.1 with a random per-boot token — nothing is exposed to the
208
+ public network.
209
+
210
+ ### 模型 / Provider / 凭据管理 | Models / Providers / Credentials
118
211
 
119
212
  模型与 provider 的配置以 dsh 官方方式持久化(与 dsh Web **Settings → Models** 页面完全相同的
120
213
  存储协议),改动在下一个请求生效,无需重启 bot:
121
214
 
215
+ Model and provider configuration is persisted the official dsh way (the exact storage protocol
216
+ used by the dsh Web **Settings → Models** page); changes take effect on the next request without
217
+ restarting the bot:
218
+
122
219
  - `/model use <id>`:按会话热切换模型,下一轮消息即用新模型。
123
220
  - `/model default <id>`:写入 dsh 的 `agent-default-model`,作为新会话的默认模型。
124
221
  - `/providers`:展示 dsh 已配置的 provider、模型与凭据状态(DeepSeek 官方 + 自定义 pi-ai)。
@@ -128,10 +225,23 @@ dsh-lark-bot start \
128
225
  - `/key set|remove|list`:读写 `~/.dsh/.credentials.yaml`(0600)。settings 只保存 `apiKeyEnv`
129
226
  引用,字面密钥不进入 settings 或聊天记录。
130
227
 
228
+ - `/model use <id>`: hot-switch the model for this session; the next message uses it.
229
+ - `/model default <id>`: write the dsh `agent-default-model` as the default for new sessions.
230
+ - `/providers`: show configured providers, models and credential status (official DeepSeek + custom pi-ai).
231
+ - `/provider add|update|remove`: manage custom providers (`llm-pi-ai`) or `deepseek-official`;
232
+ a custom provider needs `--api` (`openai-completions` / `openai-responses` / `anthropic-messages`),
233
+ `--base-url` and at least one `--model`, matching the official schema.
234
+ - `/key set|remove|list`: read / write `~/.dsh/.credentials.yaml` (0600). Settings keep only
235
+ `apiKeyEnv` references; literal keys never enter settings or chat history.
236
+
131
237
  安全提醒:在飞书会话里输入密钥会对该会话的可见成员暴露密钥,建议仅在私聊中使用,或优先用
132
238
  `--api-key-env` 引用已配置的环境变量 / dsh Web 页面录入。bot 不会在任何回复中回显密钥值。
133
239
 
134
- ### 5. 卸载
240
+ Security note: typing a key in a Feishu conversation exposes it to everyone who can see that
241
+ chat; prefer private chats, `--api-key-env` references to existing environment variables, or the
242
+ dsh Web UI. The bot never echoes key values in any reply.
243
+
244
+ ### 5. 卸载 | Uninstall
135
245
 
136
246
  ```bash
137
247
  dsh-lark-bot stop
@@ -141,19 +251,22 @@ rm -rf ~/.dsh-lark
141
251
 
142
252
  更详细的安装、状态目录、日志和排障说明见 [`docs/QUICK_START.md`](docs/QUICK_START.md)。
143
253
 
254
+ See [`docs/QUICK_START.md`](docs/QUICK_START.md) for installation details, state directories,
255
+ logs and troubleshooting.
256
+
144
257
  ---
145
258
 
146
- ## 关键词 · Keywords
259
+ ## 关键词 | Keywords
147
260
 
148
261
  `dsh` · `deepseek` · `deepseek harness` · `feishu` · `lark` · `bridge` · `bot`
149
262
 
150
- ## 这是什么 · What it is
263
+ ## 这是什么 | What it is
151
264
 
152
265
  **dsh-lark-bot** 是一个轻量桥接工具,把本机的 DeepSeek Harness(`dsh`)接入飞书 / Lark,复刻当年 OpenCode Telegram Bot / MiMoCode Telegram Bot 的体验——在 IM 里与 coding agent 对话、收流式卡片、审阅 diff,并在此基础上叠加**完整的项目工作区管理**。
153
266
 
154
267
  **dsh-lark-bot** is a lightweight bridge that connects your local DeepSeek Harness (`dsh`) into Feishu / Lark, recreating the beloved OpenCode / MiMoCode Telegram-bot experience — chat with your coding agent, receive streaming cards, review diffs — and adds **full project workspace management** on top.
155
268
 
156
- ## 目标 · Goals
269
+ ## 目标 | Goals
157
270
 
158
271
  - **一条命令启动**:clone 后一键安装运行,已发布到 npm,`npm i -g dsh-lark-bot && dsh-lark-bot start` 即可拉起后台服务。
159
272
  - **飞书原生体验**:流式卡片、交互按钮、图片 / 文件,全程双语(文档评论为规划中能力)。
@@ -163,7 +276,7 @@ rm -rf ~/.dsh-lark
163
276
  - **Native Feishu experience**: streaming cards, interactive buttons, images / files, doc comments.
164
277
  - **Full workspace management**: multi-project isolation, git worktrees, per-project rules, persistent context.
165
278
 
166
- ## 兼容性 · Compatibility
279
+ ## 兼容性 | Compatibility
167
280
 
168
281
  - **DeepSeek Harness(`dsh`)**:已验证 **dsh 0.1.0-rc.6**(2026-08-14:SDK JSON-RPC / ACP runtime 握手 +
169
282
  真实任务流式验证),通过官方 `@deepseek-ai/dsh-sdk-client` / `@deepseek-ai/dsh-acp` 接入;
@@ -175,67 +288,145 @@ rm -rf ~/.dsh-lark
175
288
  token 级流式事件);`DSH_LARK_ADAPTER=acp` 切到官方 **ACP server**(审批卡);`headless` 保留旧版
176
289
  子进程 fallback。首次启动自动在 `~/.dsh/profiles/dsh-lark`(或 `dsh-lark-acp`)创建 runtime profile。
177
290
 
178
- ## 配置 · Configuration
291
+ - **DeepSeek Harness (`dsh`)**: verified against **dsh 0.1.0-rc.6** (2026-08-14: SDK JSON-RPC / ACP
292
+ runtime handshake + real streaming task verification), connected through the official
293
+ `@deepseek-ai/dsh-sdk-client` / `@deepseek-ai/dsh-acp`; see
294
+ [`docs/COMPATIBILITY.md`](docs/COMPATIBILITY.md) for pinned versions, the upgrade policy and
295
+ automated probing, and [`docs/adapter-notes.md`](docs/adapter-notes.md) for adapter details.
296
+ - **Runtime**: Node.js ≥ 22.19 (see `engines` in `package.json`).
297
+ - **Platform**: Linux / macOS / Windows (Feishu outbound WebSocket long connection; no public
298
+ server, domain or tunneling required).
299
+ - The default adapter is the official **`@deepseek-ai/dsh-sdk-client`** (SDK JSON-RPC runtime with
300
+ native session continuation and token-level streaming events); `DSH_LARK_ADAPTER=acp` switches
301
+ to the official **ACP server** (approval cards); `headless` keeps the legacy subprocess
302
+ fallback. On first start the bot creates the runtime profile at
303
+ `~/.dsh/profiles/dsh-lark` (or `dsh-lark-acp`).
304
+
305
+ ## 配置 | Configuration
179
306
 
180
307
  - 本地配置:`~/.dsh-lark/config.json`
181
308
  - 状态根目录可用 `DSH_LARK_HOME` 覆盖
182
309
  - 环境变量统一使用 `DSH_LARK_*` 前缀
183
310
  - 模板见 [`.env.example`](.env.example)
184
311
 
312
+ - Local config: `~/.dsh-lark/config.json`
313
+ - The state root can be overridden with `DSH_LARK_HOME`
314
+ - Environment variables use the `DSH_LARK_*` prefix
315
+ - Template: [`.env.example`](.env.example)
316
+
185
317
  会话运行在 Git 仓库中时,会自动在 `~/.dsh-lark/profiles/<profile>/worktrees/<scope>/` 创建隔离 worktree,并复制项目级 `AGENTS.md`。
186
318
 
187
- 每个飞书 scope 会保存最近 40 条对话消息;SDK 模式下 dsh 原生 session 续跑,headless 模式
188
- 则把历史注入下一次 prompt 实现近似记忆。
319
+ When the session runs inside a Git repository, an isolated worktree is created at
320
+ `~/.dsh-lark/profiles/<profile>/worktrees/<scope>/` and a project-level `AGENTS.md` is copied in.
321
+
322
+ 每个飞书 scope 默认保存最近 40 条对话消息(可用 `/retention` 或 `DSH_LARK_RETENTION_MSGS`
323
+ 调整);超出保留窗口的消息自动归档到 `~/.dsh-lark/profiles/<profile>/archives/`(Markdown +
324
+ JSONL,目录本身是 Git 仓库,每次归档独立 commit),支持 `/archive` 手动归档与保留策略清理。
325
+ SDK 模式下 dsh 原生 session 续跑,headless 模式则把历史注入下一次 prompt 实现近似记忆。
326
+
327
+ Each Feishu scope keeps the last 40 conversation messages by default (adjustable with
328
+ `/retention` or `DSH_LARK_RETENTION_MSGS`); messages beyond the retention window are archived to
329
+ `~/.dsh-lark/profiles/<profile>/archives/` (Markdown + JSONL inside a Git repository, one commit
330
+ per archive), and `/archive` exports the full session on demand. The SDK mode continues the native
331
+ dsh session, while headless mode approximates memory by injecting history into the next prompt.
189
332
 
190
333
  当前核心环境变量:
191
334
 
192
- | 变量 | 默认值 | 说明 |
335
+ Core environment variables:
336
+
337
+ | 变量 Variable | 默认值 Default | 说明 Description |
193
338
  | :--- | :--- | :--- |
194
- | `DSH_LARK_HOME` | `~/.dsh-lark` | 本地状态根目录 |
195
- | `DSH_LARK_TENANT` | `feishu` | `feishu` 或 `lark` |
196
- | `DSH_LARK_WORKSPACE` | 未设置 | 新会话默认工作目录 |
197
- | `DSH_LARK_DSH_COMMAND` | `自动发现` | dsh 启动命令;通常无需设置 |
198
- | `DSH_LARK_DSH_ARGS` | `自动发现` | dsh 启动参数,逗号分隔;通常无需设置 |
199
- | `DSH_LARK_ADAPTER` | `sdk` | `sdk`(默认)/ `acp`(审批)/ `headless`(legacy |
200
- | `DSH_LARK_PROVIDER` | `deepseek-official` | 模型 provider |
201
- | `DSH_LARK_MODEL` | `deepseek-v4-flash` | 默认模型 |
202
- | `DSH_LARK_MAX_TOKENS` | 未设置 | SDK agent 每请求输出 token 上限 |
203
- | `DSH_LARK_ACCESS_DEFAULT_DENY` | `false` | 无白名单时拒绝私聊 |
204
- | `DSH_LARK_EVENT_FRESHNESS_MS` | `600000` | 过期消息拒绝窗口(0 关闭) |
205
- | `DSH_LARK_RUN_TIMEOUT_MS` | `300000` | 单次运行墙钟超时 |
206
- | `DSH_LARK_STOP_GRACE_MS` | `5000` | SIGTERM 后等待优雅退出再 SIGKILL 的宽限期 |
339
+ | `DSH_LARK_HOME` | `~/.dsh-lark` | 本地状态根目录<br>Local state root directory |
340
+ | `DSH_LARK_TENANT` | `feishu` | `feishu` 或 `lark`<br>`feishu` or `lark` |
341
+ | `DSH_LARK_WORKSPACE` | 未设置 | 新会话默认工作目录<br>Default working directory for new sessions |
342
+ | `DSH_LARK_DSH_COMMAND` | `自动发现` | dsh 启动命令;通常无需设置<br>dsh launch command; usually not needed |
343
+ | `DSH_LARK_DSH_ARGS` | `自动发现` | dsh 启动参数,逗号分隔;通常无需设置<br>dsh launch args, comma-separated; usually not needed |
344
+ | `DSH_LARK_ADAPTER` | `sdk` | `sdk`(默认)/ `acp`(审批)/ `headless`(legacy)<br>`sdk` (default) / `acp` (approval) / `headless` (legacy) |
345
+ | `DSH_LARK_PROVIDER` | `deepseek-official` | 模型 provider<br>Model provider |
346
+ | `DSH_LARK_MODEL` | `deepseek-v4-flash` | 默认模型<br>Default model |
347
+ | `DSH_LARK_MAX_TOKENS` | 未设置 | SDK agent 每请求输出 token 上限<br>Per-request output token cap for SDK agents |
348
+ | `DSH_LARK_ACCESS_DEFAULT_DENY` | `false` | 无白名单时拒绝私聊<br>Reject private chats when no allowlist is configured |
349
+ | `DSH_LARK_EVENT_FRESHNESS_MS` | `600000` | 过期消息拒绝窗口(0 关闭)<br>Stale-message rejection window (0 disables) |
350
+ | `DSH_LARK_RUN_TIMEOUT_MS` | `300000` | 单次运行墙钟超时<br>Wall-clock timeout for a single run |
351
+ | `DSH_LARK_STOP_GRACE_MS` | `5000` | SIGTERM 后等待优雅退出再 SIGKILL 的宽限期<br>Grace period after SIGTERM before SIGKILL |
352
+ | `DSH_LARK_SCOPE_CONCURRENCY` | `2` | 每个 scope 的并行任务数(1=严格串行)<br>Concurrent runs per scope (1 = strictly serial) |
353
+ | `DSH_LARK_RETENTION_MSGS` | `40` | 每个 scope 保留的消息条数(0=全部保留)<br>Messages kept per scope (0 keeps everything) |
354
+ | `DSH_LARK_ARCHIVE_MAX` | `50` | 每个 scope 最多保留的归档数(0=不清理)<br>Max archives kept per scope (0 disables pruning) |
355
+ | `DSH_LARK_ARCHIVE_MAX_AGE_DAYS` | `90` | 归档最大保留天数(0=不清理)<br>Max archive age in days (0 disables pruning) |
207
356
 
208
357
  启动时会自动查找本机常见的 `@deepseek-ai/dsh` 安装位置。只有自动发现失败或需要指定特殊 profile 时,才需要设置这两个变量。
209
358
 
210
- ## 权限与数据 · Permissions & Data
359
+ On startup the bot auto-discovers common local `@deepseek-ai/dsh` installations. Set these two
360
+ variables only when auto-discovery fails or a special profile is required.
361
+
362
+ ## 权限与数据 | Permissions & Data
211
363
 
212
364
  本工具在**本机**运行,安装前请知悉它会访问:
213
365
 
366
+ This tool runs **locally**; before installing, be aware that it accesses:
367
+
214
368
  - **飞书凭据**:PersonalAgent 应用的 `app_id` / `app_secret`,明文写入本机 `~/.dsh-lark/config.json`(文件权限 600)。
215
369
  - **文件系统**:读取 / 写入你通过 `/cd`、`/ws` 指定的工作目录(含执行 shell 命令、修改文件)。
216
370
  - **网络**:向飞书开放平台建立 WebSocket 出站长连接收发消息;向 DeepSeek API 发送任务上下文。
371
+ - **本地回调**:运行 `lark_notify` 工具时,dsh runtime 子进程通过 `127.0.0.1` 随机端口 +
372
+ 每启动随机 token 回调 bridge 进程(仅本机回环,不监听公网)。
217
373
  - **进程**:spawn 本机 `dsh` runtime 子进程(`dsh-sdk-jsonrpc-server` / `dsh-acp` profile)执行 agent 任务。
218
374
  - **dsh 配置**:`/model` `/providers` `/provider` `/key` 命令按 dsh 官方存储协议读写
219
375
  `~/.dsh/settings.yaml` 与 `~/.dsh/.credentials.yaml`(仅管理员可写;settings 只存 `apiKeyEnv`
220
376
  引用,凭据文件权限 0600、目录 0700,字面密钥不进入 settings 或聊天记录)。
221
377
 
378
+ - **Feishu credentials**: the PersonalAgent app `app_id` / `app_secret`, stored in plaintext at
379
+ `~/.dsh-lark/config.json` (file mode 600).
380
+ - **File system**: reads / writes the working directories you choose with `/cd` and `/ws`
381
+ (including running shell commands and modifying files).
382
+ - **Network**: an outbound WebSocket long connection to the Feishu open platform for messages, and
383
+ task context sent to the DeepSeek API.
384
+ - **Local callback**: when the `lark_notify` tool runs, the dsh runtime subprocess calls the
385
+ bridge process back over a random 127.0.0.1 port with a per-boot token (loopback only).
386
+ - **Processes**: spawns local `dsh` runtime subprocesses (`dsh-sdk-jsonrpc-server` / `dsh-acp`
387
+ profiles) to run agent tasks.
388
+ - **dsh configuration**: `/model` `/providers` `/provider` `/key` read / write
389
+ `~/.dsh/settings.yaml` and `~/.dsh/.credentials.yaml` using the official dsh storage protocol
390
+ (admin-only writes; settings keep only `apiKeyEnv` references; credentials file mode 0600,
391
+ directory 0700; literal keys never enter settings or chat history).
392
+
222
393
  所有数据仅在本机与飞书、DeepSeek 之间流转,不收集、不上传任何遥测。密钥不会提交进仓库(见 `.gitignore`)。
223
394
 
224
- ## 排障 · Troubleshooting
395
+ All data flows only between this machine, Feishu and DeepSeek; nothing is collected or uploaded
396
+ as telemetry. Keys are never committed to the repository (see `.gitignore`).
397
+
398
+ ## 排障 | Troubleshooting
225
399
 
226
400
  先运行 `dsh-lark-bot doctor`,它会检查 profile、工作目录,并对当前 adapter 做真实可用性探测
227
401
  (`sdk` / `acp` / `headless` 对应 runtime 的初始化握手)。
228
402
 
403
+ Run `dsh-lark-bot doctor` first; it checks the profile and working directory and performs a real
404
+ availability probe for the current adapter (`sdk` / `acp` / `headless` runtime handshake).
405
+
229
406
  常见问题:
230
407
 
408
+ Common issues:
409
+
231
410
  - **bot 静默 / 长连接失败**:查看 stderr 上的 JSONL 日志,关注 `channel` 与 `channel-command` 类别;SDK 会自动重连。
232
411
  - **agent 无响应**:发送 `/status` 查看当前 scope、cwd 和 active run;发送 `/stop` 终止当前任务;超过 `DSH_LARK_RUN_TIMEOUT_MS` 时看门狗会自动终止。
233
412
  - **首次扫码失败**:确认本机时间准确、网络可访问飞书开放平台;已拿到 App ID/Secret 时可用 `--app-id` / `--app-secret` 跳过扫码。
234
413
 
414
+ - **Silent bot / long-connection failure**: check the JSONL logs on stderr, focusing on the
415
+ `channel` and `channel-command` categories; the SDK reconnects automatically.
416
+ - **Unresponsive agent**: send `/status` to view the scope, cwd and active run; send `/stop` to
417
+ terminate the current task; the watchdog terminates it automatically after
418
+ `DSH_LARK_RUN_TIMEOUT_MS`.
419
+ - **First QR binding fails**: make sure the local clock is accurate and the Feishu open platform
420
+ is reachable; with an existing App ID/Secret you can skip scanning via `--app-id` /
421
+ `--app-secret`.
422
+
235
423
  以后台服务方式运行时,日志写入 `~/.dsh-lark/profiles/<profile>/logs/bot.log`(JSON Lines,
236
424
  stdout 与 stderr 合并);当前进程的 stderr 仍为 JSON Lines。
237
425
 
238
- ## 开发 · Development
426
+ When running as a background service, logs go to `~/.dsh-lark/profiles/<profile>/logs/bot.log`
427
+ (JSON Lines, stdout and stderr merged); the current process's stderr is still JSON Lines.
428
+
429
+ ## 开发 | Development
239
430
 
240
431
  ```bash
241
432
  pnpm install
@@ -243,16 +434,24 @@ pnpm typecheck
243
434
  pnpm test
244
435
  pnpm build
245
436
  pnpm ci:local
246
- pnpm release:check # ci:local + 上游一致性检查
247
- pnpm compat:probe # 临时 DSH_HOME 安装锁定版 dsh,跑真实 SDK 握手
248
- pnpm dsh:upstream # 对比 npm 上游 stable 与锁定矩阵
437
+ pnpm release:check # ci:local + 上游一致性检查 | ci:local + upstream consistency check
438
+ pnpm compat:probe # 临时 DSH_HOME 安装锁定版 dsh,跑真实 SDK 握手 | installs pinned dsh into a temp DSH_HOME and runs a real SDK handshake
439
+ pnpm dsh:upstream # 对比 npm 上游 stable 与锁定矩阵 | compares npm upstream stable with the pinned matrix
249
440
  ```
250
441
 
251
442
  开发规范见 [`AGENTS.md`](AGENTS.md),模块契约见 [`docs/API.md`](docs/API.md),架构见 [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)。
252
443
  兼容矩阵的升级政策与自动化见 [`docs/COMPATIBILITY.md`](docs/COMPATIBILITY.md)。
253
444
 
445
+ See [`AGENTS.md`](AGENTS.md) for the development workflow, [`docs/API.md`](docs/API.md) for
446
+ module contracts, and [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) for the architecture. See
447
+ [`docs/COMPATIBILITY.md`](docs/COMPATIBILITY.md) for the compatibility matrix, upgrade policy
448
+ and automation.
449
+
254
450
  发布双包(`dsh-lark-bot` 与 `dsh-feishu-bot` 共享同一份 dist / 版本 / 依赖):
255
451
 
452
+ Publishing both packages (`dsh-lark-bot` and `dsh-feishu-bot` share the same dist / version /
453
+ dependencies):
454
+
256
455
  ```bash
257
456
  pnpm publish:dual:dry-run
258
457
  pnpm publish:dual
@@ -260,16 +459,30 @@ pnpm publish:dual
260
459
 
261
460
  `scripts/publish-dual-packages.mjs` 从根 `package.json` 生成两份仅 `name` / `bin` 不同的发布清单,避免两份源码漂移。GitHub tag `v*` 会触发 [`release.yml`](.github/workflows/release.yml) 自动发布两个 npm 包并创建 Release。
262
461
 
462
+ `scripts/publish-dual-packages.mjs` generates two publish manifests from the root
463
+ `package.json`, differing only in `name` / `bin`, so the two copies never drift. A GitHub tag
464
+ `v*` triggers [`release.yml`](.github/workflows/release.yml) to publish both npm packages and
465
+ create a Release automatically.
466
+
263
467
  同一份 dist 还会以 `@plutokeating/dsh-lark-bot` 和 `@plutokeating/dsh-feishu-bot` 发布到 GitHub Packages,便于在 GitHub Packages 页面查看。
264
468
 
265
- ## 许可与安全 · License & Security
469
+ The same dist is also published to GitHub Packages as `@plutokeating/dsh-lark-bot` and
470
+ `@plutokeating/dsh-feishu-bot`, viewable on the GitHub Packages page.
471
+
472
+ ## 许可与安全 | License & Security
266
473
 
267
474
  - **许可证**:GNU Affero General Public License v3.0(见 `LICENSE`)。
268
475
  - **安全报告**:如发现安全漏洞,请通过 GitHub Security Advisory 私下报告,勿公开 issue。
269
476
  - **安全模型**:默认拒绝、密钥脱敏、路径 containment、SSRF 防护、过期事件拒绝与交互工具
270
477
  默认禁用——详见 [`SECURITY.md`](SECURITY.md)。
271
478
 
272
- ## 文档 · Documentation
479
+ - **License**: GNU Affero General Public License v3.0 (see `LICENSE`).
480
+ - **Security reports**: report vulnerabilities privately via GitHub Security Advisory; do not
481
+ open a public issue.
482
+ - **Security model**: default-deny, secret redaction, path containment, SSRF protection, stale
483
+ event rejection and default-disabled interactive tools — see [`SECURITY.md`](SECURITY.md).
484
+
485
+ ## 文档 | Documentation
273
486
 
274
487
  > 接手本项目的工程师:**先读 [`docs/REQUIREMENTS.md`](docs/REQUIREMENTS.md) 和 [`docs/RESEARCH.md`](docs/RESEARCH.md)**,即可完整理解项目诉求与来龙去脉,无需线下沟通。
275
488
  > Engineers taking over this project: **read [`docs/REQUIREMENTS.md`](docs/REQUIREMENTS.md) and [`docs/RESEARCH.md`](docs/RESEARCH.md) first**.
@@ -290,9 +503,9 @@ pnpm publish:dual
290
503
  | [`SECURITY.md`](SECURITY.md) | 安全模型与报告渠道<br>Security model & reporting |
291
504
  | [`AGENTS.md`](AGENTS.md) | AI Agent 开发工作流规范<br>AI agent workflow spec |
292
505
 
293
- ## 架构 · Architecture
506
+ ## 架构 | Architecture
294
507
 
295
- > 详见 [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) · See [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) for details.
508
+ > 详见 [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) | See [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) for details.
296
509
 
297
510
  ```
298
511
  飞书 / Lark ──WebSocket 长连接──▶ bridge/ ──▶ session/ ──▶ workspace/ ──▶ adapters/ ──▶ dsh ──▶ DeepSeek V4
@@ -302,7 +515,7 @@ pnpm publish:dual
302
515
 
303
516
  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.
304
517
 
305
- ## 目录结构 · Directory Structure
518
+ ## 目录结构 | Directory Structure
306
519
 
307
520
  | 目录 Dir | 职责 Responsibility |
308
521
  | :--- | :--- |
@@ -323,19 +536,19 @@ The core idea: **decouple the Feishu channel from the agent backend**. The bridg
323
536
  | `docs/` | 架构、路线图等文档<br>Architecture, roadmap & docs |
324
537
  | `reference/` | 参考研究用的克隆仓库(不提交)<br>Cloned reference repos (not committed) |
325
538
 
326
- ## 路线图 · Roadmap
539
+ ## 路线图 | Roadmap
327
540
 
328
- 见 [`docs/roadmap.md`](docs/roadmap.md) · See [`docs/roadmap.md`](docs/roadmap.md).
541
+ 见 [`docs/roadmap.md`](docs/roadmap.md) | See [`docs/roadmap.md`](docs/roadmap.md).
329
542
 
330
- ## 参考项目 · References
543
+ ## 参考项目 | References
331
544
 
332
545
  | 项目 Project | 说明 About |
333
546
  | :--- | :--- |
334
- | [`zarazhangrui/lark-coding-agent-bridge`](https://github.com/zarazhangrui/lark-coding-agent-bridge) | 飞书 ↔ Claude Code / Codex 桥接,本项目的直接参照 |
335
- | [`deepseek-ai/deepseek-harness`](https://github.com/deepseek-ai/deepseek-harness) | DeepSeek Harness(`dsh`),agent 后端 |
336
- | [`grinev/opencode-telegram-bot`](https://github.com/grinev/opencode-telegram-bot) | OpenCode 的 Telegram 手机端,另一参照 |
547
+ | [`zarazhangrui/lark-coding-agent-bridge`](https://github.com/zarazhangrui/lark-coding-agent-bridge) | 飞书 ↔ Claude Code / Codex 桥接,本项目的直接参照<br>Feishu ↔ Claude Code / Codex bridge; the direct reference for this project |
548
+ | [`deepseek-ai/deepseek-harness`](https://github.com/deepseek-ai/deepseek-harness) | DeepSeek Harness(`dsh`),agent 后端<br>DeepSeek Harness (`dsh`), the agent backend |
549
+ | [`grinev/opencode-telegram-bot`](https://github.com/grinev/opencode-telegram-bot) | OpenCode 的 Telegram 手机端,另一参照<br>Telegram mobile client for OpenCode; another reference |
337
550
 
338
- ## 免责声明 · Disclaimer
551
+ ## 免责声明 | Disclaimer
339
552
 
340
553
  > [!NOTE]
341
554
  > 本项目为非官方社区工具,与 DeepSeek、字节跳动 / 飞书(Lark)无关联,亦未获得其背书。DeepSeek Harness、Feishu / Lark 及相关商标归各自权利人所有。
package/SECURITY.md CHANGED
@@ -33,6 +33,8 @@
33
33
  9. **管理操作鉴权**:飞书会话内对 dsh 配置的写操作(`/model default`、`/model add|remove`、
34
34
  `/provider add|update|remove`、`/key set|remove`)仅管理员可执行(管理员由
35
35
  `/invite admin <open_id>` 定义);查看类命令(`/model`、`/providers`、`/key list`)开放。
36
+ 10. **本地回调隔离**:`lark_notify` 工具的回调服务只绑定 `127.0.0.1`,每次启动生成随机
37
+ token 鉴权(不落盘、不进日志),请求体限 1MB;`/notify` 与角色 / 配置写命令同为管理员操作。
36
38
 
37
39
  ## 数据与凭据 · Data & credentials
38
40
 
@@ -0,0 +1,12 @@
1
+ # dsh-lark-bot as a profile bundle.
2
+
3
+ # Installed with `dsh plugin --profile <name> add dsh-lark-bot`. The row
4
+ # mounts the bridge-management plugin (`dsh-lark-bot/plugin`) and exposes
5
+ # `ctx.larkBridge` without blocking profile boot. Set DSH_LARK_AUTOSTART=1
6
+ # to start the standalone bridge when the profile boots.
7
+
8
+ - insert:
9
+ - id: dsh-lark-bot
10
+ name: 'dsh-lark-bot/plugin'
11
+ config:
12
+ autostart: !!js process.env.DSH_LARK_AUTOSTART === '1'