# dsh-lark

> 把 DSH Agent 接进飞书/Lark：在聊天里派任务、看过程、切换工作区和模型；提问、计划、工具审批用卡片回到聊天处理。

## Metadata

- Author: [@omdsh-dev](https://github.com/omdsh-dev)
- Repo: <https://github.com/omdsh-dev/dsh-lark.git>
- GitHub: [omdsh-dev/dsh-lark](https://github.com/omdsh-dev/dsh-lark)
- Stars: 39
- Language: TypeScript
- License: [BSD-3-Clause](https://spdx.org/licenses/BSD-3-Clause.html)
- Topics: `cordis`, `deepseek-harness`, `dsh`, `dsh-plugin`, `feishu`, `lark`
- Forks: 8
- Open Issues: 9
- Last push: 2026-08-19T09:02:20.000Z
- Added: 2026-08-16T00:00:00.000Z

## Install

```bash
dsh plugin --profile web add github:omdsh-dev/dsh-lark
```

## Wiki

## 一句话定位
把 DeepSeek Harness (DSH) Agent 接到飞书/Lark 聊天里——在聊天中派任务、看思考与工具调用过程、切换工作区与模型，提问/计划/审批都回到当前聊天处理；必要时还能让多个机器人同群按 @ 接力协作。

## 核心能力
- 在飞书聊天里直接给 Agent 派任务，思考过程、工具调用和结果以原生思维过程形式回写到聊天，最终答案单独成消息
- 用 `/ws` 列出可选工作区、用 `/cd` 切换到指定目录，每个对话 × 当前目录对应一个独立 Agent 会话
- 用 `/model` 卡片切换当前对话的模型（保留上下文），也可一行命令 `/model use <provider/model>` 直切
- 用 `/new` 原地开一个新会话（清空上下文，保留工作区和模型），用 `/sessions` 列出本工作区可接续的会话并一键接续
- 用 `/permission` 卡片选择权限预设，提问、计划确认、工具审批全部以交互卡片在聊天中答复（单选/多选/文字均可）
- 文件收发：用户发进聊天的文件落到工作区的 `.dsh-lark/inbox/<时间戳>-<消息哈希>/` 供 Agent 读取；Agent 发回文件在私聊直接发，群聊每发一张都弹审批卡片
- 多机器人协作：`dsh-lark-channel add <name>` 加挂第二个机器人实例，它们在同一群里用 @ 交接回合，连续机器人轮次上限默认 6 轮

## 技术实现
- **语言**: TypeScript（ESM，`package.json:5`），通过 `tsdown` 打包成 `lib/index.js`，同时提供 `dsh-lark-channel` CLI
- **关键依赖**: `@deepseek-ai/cordis` ^4.0.1（peer dep，插件宿主框架）、`@larksuite/channel` ^0.4.1（飞书 IM 长连接传输层）、`@deepseek-ai/schemastery` ^3.18.1（配置 Schema 校验）、`qrcode-terminal` ^0.12.0（首次扫码）
- **架构模式**: Cordis function-plugin 形态——`src/index.ts` 导出 `name='lark-channel'`、`inject=['agents']`、`Config` Schema 和 `apply(ctx, config)`；`cordis.patch.yml` 把这一行插入 DSH profile 的 bundles，由宿主启动时挂载；CLI `dsh-lark-channel` 是独立进程，用自带的 provision 脚本为单实例机器人写独立的 profile + launchd/systemd 用户服务
- **入口文件**: DSH profile 内入口 `src/runtime.ts`（apply + 引导启动），CLI 入口 `src/cli.ts`（仅 re-export `provision.ts` 的 main），扫描二维码 + 凭据落盘见 `src/onboarding.ts`

## 适用场景
适合**已经在 DSH 里跑 Agent、想用手机/飞书客户端继续推进任务**的用户：让 DSH Agent 在飞书私聊或群里替你推进工作，不用守在终端前；或**让多个 Agent 共用一组项目目录**——把工作区切换和多 Bot 协作结合，让一个机器人做改动、另一个机器人评审。需要即时聊天分发、文件互传、审批回收的人会常用；如果只是想跑本地命令或纯 Web 端界面，这个插件不起作用。

## 前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| DeepSeek Harness | >=0.1.0-rc.6 | README 明确要求；低于此版本 DSH 找不到此插件的 bundle 行 |
| Node.js | ^22.19.0 \|\| >=24.0.0 | `package.json` engines 字段 |
| 平台 | macOS / Linux / Windows | 跨平台；macOS 用 launchd，systemd Linux 用 systemd --user，Windows / 无 systemd 的 Linux CLI 降级为前台运行（`src/provision.ts:11-14,290-296`） |
| 飞书客户端 | PC 7.70 / 移动 7.74+（推荐） | 用思维过程渲染需要较新的客户端；旧客户端可设 `output: 'stream'` 走整段打字机卡片 |
| 原生模块 | 无 | 纯 JS/TS 实现，不依赖 node-gyp 编译模块 |

## 安装方式
```bash
dsh plugin --profile web add github:omdsh-dev/dsh-lark
```

也可通过 `npm i -g dsh-lark-channel` + `dsh-lark-channel start` 命令在终端生成二维码走单机模式。

## 配置项
| 配置 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| appId / appSecret / appSecretRef | 字符串 | 飞书应用凭据；扫码完成后由插件落进宿主 credentials/secrets 服务；也可通过 `LARK_APP_ID` / `LARK_APP_SECRET` 环境变量直接提供 | 未设时首次启动打印二维码 |
| domain | URL | 飞书开放平台域名，飞书默认 `https://open.feishu.cn`，国际版 Lark 用 `https://open.larksuite.com` | 飞书 |
| cwd | 路径 | 聊天 Agent 的默认工作区目录 | 宿主进程 cwd |
| workspaceRoots | 字符串数组 | 限制 `/cd` 可切换到的目录前缀；空表示不限 | [] |
| provider / model | 字符串 | Agent 使用的模型路由；为单个聊天用 `/model` 切换此字段 | 宿主 `agentDefaultModel` |
| sessionScope | chat \| chat-thread \| chat-sender | 会话粒度：整聊一个、按话题分、按人分 | chat |
| output | cot \| stream | 思维过程形态；`cot` 用原生思维过程消息，`stream` 一段打字机卡片（旧客户端） | cot |
| showProcess | 布尔 | 是否在飞书中展示推理与工具调用过程 | true |
| attachImages | 布尔 | 把聊天图片作为内容块送给模型；只在你确认模型支持视觉时打开 | false |
| receiveFiles / maxReceiveFileBytes | 布尔 / 字节数 | 入站文件是否落工作区，单文件上限 | true / 20 MiB |
| sendFiles / maxSendFileBytes | 布尔 / 字节数 | Agent 主动出站文件是否放行，单文件上限 | true / 20 MiB |
| hideProcessWhenDone | 布尔 | 任务结束后让平台把思维过程消息收起（只 cot） | false |
| syncSlashCommands | 布尔 | 把插件提供的斜杠命令同步到飞书 `/` 面板 | true |
| denyTools | 字符串数组 | 在 Agent 端禁用某些工具（用 Agent 影子问答替代） | [] |
| botPeers | open_id 数组 | 限制只回应哪些机器人发送的消息 | [] |
| botHops | 数字 | 连续机器人轮次上限；人发言恢复额度 | 6 |
| requireMention | 布尔 | 群聊是否必须 @ 才回应 | true |
| senderAllowlist / groupAllowlist / approvers | open_id 数组 | 进一步收窄私聊可发者、可服务群、可回答审批者 | [] |
| instance | 字符串 | 给插件行起名（多机器人场景）；第一个机器人必须留空以保持兼容 | — |
| chatWorkspaces / chatModels / chatEpochs / chatSessions | 对象 | 每个对话的状态映射（工作区、模型、新开会话计数、绑定会话），由 `/cd` `/new` `/model` `/session` 写回 | {} |

## 常见问题

**Q: 安装之后要怎么让机器人在飞书里活起来？**

A: 用 `dsh plugin --profile web add github:omdsh-dev/dsh-lark` 加进 DSH profile 后通过 `dsh web` 启动即可；或 `npm i -g dsh-lark-channel` + `dsh-lark-channel start`，终端打印二维码，用飞书 App 扫码完成应用创建。凭据会落进宿主 secrets 服务而不是明文 settings。

**Q: 机器人默认只在群里 @ 才回话，怎么改成群里也被动回应？**

A: 在配置里把 `requireMention` 设为 `false` 后重启服务。注意这是会话级别的开关，谁能把机器人加进去仍由飞书应用的可见性范围决定；改此项不会扩大可见范围。

**Q: 我中途切换了工作区或工作区里 git 历史不想要 .dsh-lark 这个目录，怎么办？**

A: 第一次有文件落盘时插件会提醒把 `.dsh-lark/` 加进 `.gitignore`，但插件本身不会去改这个文件。入站文件按消息分组只增不删（`src/files.ts:42-46`），清理由你自己决定——这是显式设计，渠道不替你清。

**Q: 群聊里 Agent 想把文件发回去，每次都要我点审批卡烦不烦？**

A: 私聊直接发，群聊每次都弹审批卡，并且**没有关闭群聊审批的开关**——这是源码层面固定死的（`src/config.ts:177-180`、README:159），被定位成"提示注入外泄链的官方后门"。

**Q: 我能一次配多个机器人，让它们互相协作吗？**

A: 能。`dsh-lark-channel add reviewer` 添加第二个飞书应用，形成独立 profile 行；扫码后机器人各自有设置、凭据和会话。把它们加到同一个群，用 @ 接力回合，连续机器人轮次上限默认 6 轮到 9 轮（任一人发言即重置）。`dsh-lark-channel remove <name>` 可移除，名称和凭据保留以便下次再加回来。

**Q: 我想清掉上下文重新开始，但保留工作区和模型，怎么做？**

A: 用 `/new`。它会原地开一个新会话、清空消息历史，工作区和当前模型保持不变。要彻底切上下文（连工作区一起换）用 `/cd <新路径>`。

**Q: 修改配置项后多久生效？**

A: 配置在启动时读取，修改后需要重启服务生效（`README.md:165`）。macOS 上是 `launchctl kickstart -k`、systemd Linux 上 `systemctl --user restart dsh-lark`。

## 上手难度
入门 — 用一条 DSH 插件命令即可启用，或 `npm i -g` 后一条 `start` 命令即可上手；最常见的"扫个码就能用"路径不需要理解内部结构。要调高级选项才需要了解白名单、会话粒度、思维过程形态这些概念。

## 已知问题与限制
- **群聊文件审批数量固定写死 3**：群聊里同时最多挂 3 个待审批文件，第 4 个会被直接拒绝并提示等前面先有结果；此上限不可配置（`README.md:161-162` / `src/config.ts:179-182`）
- **群聊审批始终保留，无开关**：私聊直发、群聊每发一张都弹审批卡（`src/config.ts:177-180`），源码明确拒绝提供关闭项以避免提示注入外泄链后门
- **macOS / Linux 行为差异**：macOS 用 launchd、systemd Linux 用 systemd-user；Windows 和无 systemd 的 Linux CLI 入口 `start` 会降级为前台运行（`src/provision.ts:11-14,290-296`）
- **图片附件默认不送进模型**：聊天里发的图片默认只落盘不作为视觉内容传给模型，需要确认模型支持视觉后再在配置中开 `attachImages`——否则一次截图就能拖累整个会话（`src/config.ts:128-143`）
- **文档类附件无在线预览**：pdf / xlsx / docx 上传后只能下载不能预览，这是上游 `@larksuite/channel` 把普通文件固定按 `stream` 类型上传带来的固有限制（`README.md:163`）
- **语音消息只落盘不转写**：插件不做语音识别（README:164）
- **出站文件路径会被截断到工作区内**：任何给人或给模型看的文案都只说"工作区内相对路径"，包括 `send_file` 失败时文件系统自身那行报错；这是有意为之以避免提示注入时外泄宿主页前缀
- **维护命令排队为每会话一队**：两个用户在空闲期点维护命令会按每个 Agent 一条队列依次执行，超时会失败（`src/maintenance.ts:1-19`）
- **修改配置需重启生效**：Cordis 启动期读取配置，运行时改 `cordis.patch.yml` 不会自动 reload，需要重启宿主服务（`README.md:165`）

---

This document is auto-generated by [deepseek-plugin.org](https://deepseek-plugin.org). HTML page: [dsh-lark](https://deepseek-plugin.org/plugins/omdsh-dev/dsh-lark)
Wiki generated by AI (model: `MiniMax-M3`)
