🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

飞书常驻智能体 shoxiy-danny/dsh-feishu

DeepSeek Harnessv0.0.1
shoxiy-danny12 天前有提交已提供中文文档扫描:含敏感能力

在飞书聊天框里设定目标、查看进度并审批高危操作

30.2/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/11/3 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

自动兼容检查有告警:npm 同名包「dsh-feishu」归属 omdsh-dev/dsh-lark,装到的可能不是本插件。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add shoxiy-danny/dsh-feishu
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · platform
装得上吗
本站已在 dsh 0.2.1-rc.5 下真实安装成功
非静态推断
L5 · 运行时冒烟等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 12 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意
要求 Node:>=22(dsh 本身要求 Node ≥ 22.19)

npm 同名包「dsh-feishu」归属 omdsh-dev/dsh-lark,装到的可能不是本插件

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包dsh-feishu @ 0.0.1
✓Node 引擎要求 >=22 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/7 10:40:11

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件读取剪贴板或密钥环境变量发起外部网络请求
查看扫描证据(共 69 处,展示前 63 条)
  • 读取本地文件
    src/index.js:107
    raw = readFileSync(file, 'utf8')
  • 写入本地文件
    src/index.js:111
    try { writeFileSync(file, JSON.stringify({ consumed: true }) + '\n') } catch { }
  • 读取本地文件
    src/index.js:137
    const pkg = JSON.parse(readFileSync(join(dirname(real), '..', 'package.json'), 'utf8'))
  • 读取密钥环境变量
    src/index.js:148
    [process.env.FEISHU_APP_ID, process.env.FEISHU_APP_SECRET],
  • 读取密钥环境变量
    src/index.js:149
    [process.env.FEISHU_APP_ID_2, process.env.FEISHU_APP_SECRET_2],
  • 读取密钥环境变量
    src/index.js:150
    [process.env.FEISHU_APP_ID_3, process.env.FEISHU_APP_SECRET_3],
  • 读取密钥环境变量
    src/index.js:151
    [process.env.FEISHU_APP_ID_4, process.env.FEISHU_APP_SECRET_4],
  • 读取本地文件
    src/vision.js:22
    return existsSync(path)
  • 写入本地文件
    src/inbox.js:22
    mkdirSync(dir, { recursive: true })
  • 读取本地文件
    src/inbox.js:30
    if (existsSync(path)) {
  • 写入本地文件
    src/inbox.js:35
    writeFileSync(path, buf)
  • 写入本地文件
    src/bridge.js:110
    mkdirSync(dirname(mapPath), { recursive: true })
  • 写入本地文件
    src/bridge.js:111
    writeFileSync(mapPath, JSON.stringify(chats, null, 2) + '\n')
  • 写入本地文件
    src/bridge.js:115
    mkdirSync(dirname(historyPath), { recursive: true })
  • 写入本地文件
    src/bridge.js:116
    writeFileSync(historyPath, JSON.stringify({ items: history.items }, null, 2) + '\n')
  • 读取本地文件
    src/bridge.js:799
    const raw = JSON.parse(readFileSync(path, 'utf8'))
  • 读取本地文件
    src/bridge.js:820
    return JSON.parse(readFileSync(path, 'utf8'))
  • 发起网络请求
    src/lark.js:41
    const resp = await client.request({
  • 发起网络请求
    src/lark.js:112
    const resp = await client.request({
  • 执行外部命令固定命令
    src/lark.js:217
    execFileSync('ffmpeg', ['-y', '-i', filePath, '-c:a', 'libopus', '-b:a', '32k', opusPath], {
  • 读取本地文件
    src/lark.js:230
    file: createReadStream(uploadPath),
  • 删除本地文件
    src/lark.js:246
    try { unlinkSync(uploadPath) } catch {}
  • 读取本地文件
    src/lark.js:255
    image: createReadStream(filePath),
  • 读取本地文件
    src/lark.js:277
    file: createReadStream(filePath),
  • 读取本地文件
    src/cli-lark.js:81
    return readFileSync(path)
  • 删除本地文件
    src/cli-server.js:10
    try { unlinkSync(socketPath) } catch { }
  • 写入本地文件
    src/cli-server.js:32
    try { chmodSync(socketPath, 0o600) } catch { }
  • 删除本地文件
    src/cli-server.js:108
    try { unlinkSync(socketPath) } catch { }
  • 读取本地文件
    src/prompts.js:18
    return readFileSync(join(PROMPTS, name), 'utf8').trim()
  • 读取本地文件
    src/outbound.js:39
    if (!filePath || !existsSync(filePath)) {
  • 读取本地文件
    src/outbound.js:42
    const st = statSync(filePath)
  • 读取本地文件
    src/usage.js:126
    if (statSync(file).mtimeMs < since) {
  • 读取本地文件
    src/usage.js:268
    projects = readdirSync(root, { withFileTypes: true })
  • 读取本地文件
    src/usage.js:276
    sessions = readdirSync(join(root, project.name), { withFileTypes: true })
  • 读取本地文件
    src/usage.js:295
    names = readdirSync(dir)
  • 读取本地文件
    src/usage.js:304
    if (!statSync(file).isFile()) continue
  • 执行外部命令固定命令
    src/usage.js:327
    return execFileSync('zstd', ['-dc', file], { encoding: 'utf8', maxBuffer: MAX_LOG })
  • 读取本地文件
    src/usage.js:333
    return readFileSync(file, 'utf8')
  • 读取本地文件
    src/models.js:42
    if (path && existsSync(path)) {
  • 读取本地文件
    src/models.js:44
    const parsed = normalize(JSON.parse(readFileSync(path, 'utf8')))
  • 读取本地文件
    src/status.js:35
    for (const project of readdirSync(sessionsRoot, { withFileTypes: true })) {
  • 读取本地文件
    src/status.js:50
    const st = statSync(join(dir, name))
  • 读取本地文件
    src/status.js:69
    return parseMeminfo(readFileSync('/proc/meminfo', 'utf8'))
  • 执行外部命令固定命令
    src/status.js:89
    return parseDf(execFileSync('df', ['-k', path], { encoding: 'utf8' }))
  • 读取本地文件
    src/memory.js:9
    if (existsSync(join(dir, 'MEMORY.md'))) return realpathSync(dir)
  • 读取本地文件
    src/memory.js:20
    const text = readFileSync(join(root, 'MEMORY.md'), 'utf8').trim()
  • 读取本地文件
    src/headers.js:36
    if (!existsSync(candidate)) continue
  • 读取本地文件
    src/headers.js:52
    const buf = readFileSync(abs)
  • 读取本地文件
    src/inbox.test.js:38
    assert.equal(readFileSync(path, 'utf8'), 'zip')
  • 删除本地文件递归
    src/inbox.test.js:40
    rmSync(root, { recursive: true, force: true })
  • 写入本地文件
    src/models.test.js:27
    writeFileSync(path, JSON.stringify({
  • 写入本地文件
    src/models.test.js:44
    writeFileSync(path, JSON.stringify({
  • 写入本地文件
    src/progress.test.js:10
    writeFileSync(modelsPath, JSON.stringify({
  • 写入本地文件
    src/status.test.js:31
    mkdirSync(dir, { recursive: true })
  • 写入本地文件
    src/status.test.js:32
    writeFileSync(join(dir, 'session.jsonl.zstd'), Buffer.alloc(3400))
  • 写入本地文件
    src/usage.test.js:83
    writeFileSync(file, JSON.stringify(spec))
  • 写入本地文件
    src/usage.test.js:110
    mkdirSync(dir, { recursive: true })
  • 写入本地文件
    src/usage.test.js:114
    writeFileSync(join(dir, 'session.jsonl'), [
  • 写入本地文件
    src/usage.test.js:121
    writeFileSync(join(root, 'feishu-chats.json'), JSON.stringify({
  • 写入本地文件
    src/usage.test.js:148
    mkdirSync(dir, { recursive: true })
  • 写入本地文件
    src/usage.test.js:150
    writeFileSync(join(dir, 'session.jsonl'), msgLine(t, 1, 'grok-4.6', { inputTokens: 9, outputTokens: 1 }) + '\n')
  • 执行外部命令固定命令
    src/usage.test.js:151
    execFileSync('touch', ['-d', '2026-08-01 10:00:00', join(dir, 'session.jsonl')])
  • 执行外部命令固定命令
    src/usage.test.js:188
    execFileSync('zstd', ['-q', '-f', '-o', zstd, plain])
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 飞书内设定目标
  • 查看实时进度
  • 审批高危操作

这套 harness 跑在飞书里、跑在 Linux 服务器上,有目标卡片、实时进度、多机器人,不是网页版的遥控器。

README

由 DeepSeek 最新模型翻译生成
dsh-feishu Harness 长在飞书里,不是飞书遥控网页 中文 · English · 功能 · 适合谁 · 五分钟 插件市场里 feishu / lark 已经三十多个。多数是通知器、多 IM 网关,或者 dsh plugin --profile web add 之后挂在官方网页旁边的桥。飞书只是遥控器:网页还在,关掉浏览器,产品就少了一半。不少还默认你坐在个人 PC 前,终端里弹二维码。 这套是跑在飞书里的 harness,部署面是 无头常驻:macOS、Linux、WSL 都能跑,主打一台能出网的机器当守护进程,不是笔记本终端扫码。一个 dsh --profile feishu 常驻,日志进文件,没有要人盯着的 TTY。飞书长连接进、飞书卡片出。模型、斜杠命令、进度、Goal、会话,全部发生在聊天框。没有 3080,没有给本机用的 TUI。高危操作出飞书审批卡,不是网页弹窗。 首个 bot 只能在开放平台建好,把 App ID / Secret 写进环境变量再启动。服务器上没处可贴二维码。已经通了的 bot 再开第二个,码可以打回飞书;那是后话,不是第一次上手。 不跟货架比按钮数量。没有打字机答案卡。
展开完整文档(README 剩余 1 节)
dsh-feishu
Harness 长在飞书里,不是飞书遥控网页

中文 · English · 功能 · 适合谁 · 五分钟

插件市场里 feishu / lark 已经三十多个。多数是通知器、多 IM 网关,或者 dsh plugin --profile web add 之后挂在官方网页旁边的桥。飞书只是遥控器:网页还在,关掉浏览器,产品就少了一半。不少还默认你坐在个人 PC 前,终端里弹二维码。

这套是跑在飞书里的 harness,部署面是 无头常驻:macOS、Linux、WSL 都能跑,主打一台能出网的机器当守护进程,不是笔记本终端扫码。一个 dsh --profile feishu 常驻,日志进文件,没有要人盯着的 TTY。飞书长连接进、飞书卡片出。模型、斜杠命令、进度、Goal、会话,全部发生在聊天框。没有 3080,没有给本机用的 TUI。高危操作出飞书审批卡,不是网页弹窗。

首个 bot 只能在开放平台建好,把 App ID / Secret 写进环境变量再启动。服务器上没处可贴二维码。已经通了的 bot 再开第二个,码可以打回飞书;那是后话,不是第一次上手。

不跟货架比按钮数量。没有打字机答案卡。要比的四件事:

1. 长在飞书里 — harness 的面就是飞书,不是遥控网页
2. Goal 卡片 — 设定、改目标、暂停、恢复、清除,点卡片就能做;重启不偷着续
3. 一进程多 bot — 2~3 个飞书身份共用一套 Agent,同一条 session 不能两头同时握
4. 会变的进度头 — [dsf-23% G1/3] Using bash...(2),不是「正在思考…」四个字一直挂着

GitHub 上另有一个 PGZXB/dsh-feishu,飞书控制台 + 卡内审批,官方 Web 还在。owner 不同,产品也不同。

卖点

完全不依赖 Web

不装 dsh-web-app,不开 3080,不跑 headless 一次性进程。Cordis 插件直接 create / followup / steer / cancel / resume。飞书是面,不是壳外面再套的壳。

Goal:一张卡片管到底

发 /goal,或直接在卡片里填目标点「设定并开始」。句末可写「最多跑 3 轮」。

Agent 自己多轮推进。进程重启后 不会 偷偷接着烧,要在卡片上点「恢复自动续跑」,或发 /goal resume。

卡片上能做的事:

- 设定 / 修改目标(卡内表单)
- 暂停 / 恢复自动续跑
- 清除当前目标
- 完成变绿、阻塞变红,原地改,不另刷一堆纯文字

斜杠命令仍然全部可用。先到的算数。

会变的进度头

进度卡片原地改:

[dsf-23% G1/3] Using bash...(2)

模型别名、上下文占比、Goal 轮次(快到上限标 near)。跑完变 Done,失败变 Failed,正文另发一条,不跟进度糊在一起。

一进程多 Bot

同一个进程挂 2~3 个独立飞书应用。会话按 (appId, chat_id) 分开。历史可以互相 /resume,同一条 session 不能被两个窗口同时握住。

斜杠命令就在聊天框

/stop /clear /model /status /usage /compact /resume /rename /goal /bye

不支持的 / 会直接告诉你本期有哪些。完整表见 docs/handbook.md。

高危审核卡 / 提问卡

未点名的 rm、find -delete、破坏性 git、杀自己的进程会挂起,飞书出一张橙卡。点「允许这一次」才跑;打字同意不算批准。目标路径里带未展开的 shell 变量($TMP_FILE、$(mktemp))不会被误判。

需要选择时模型调 ask_user_question,出蓝卡。选项两列一排带序号,说明是灰字菜单;可以点选项,也可以在卡内填空提交(输入框默认一行),也可以直接打字。先到的算数。多选问题出勾选表单,勾完点「提交选择」。开放平台须订 card.action.trigger。

模型切换卡片

发 /model 不填参数,出一张按档位分组的选型卡(DSH_FEISHU_MODELS 里给每个模型标 tier 和 short),点一下切过去。卡上还能点「保持当前」。/model <别名> 照旧一行文字回执。
切到不吃图(vision 不为 true)的模型时,会话里已有的图片块就地换成路径文字,避免下一轮请求 400。

用量面板

/usage 扫 $DSH_HOME/sessions/ 下的会话日志,按模型和 bot 汇总 token:总量、请求数、输入、输出、缓存命中率,默认近 7 天。/usage today、/usage all 换窗口。Bot 名走 DSH_FEISHU_BOT_LABELS。

会话卡翻页

/resume 每页 8 条,超过就出翻页按钮。翻页只换卡片内容,不新开对话。

重启自己接上

进程重启后不用你先说话:插件主动 resume 所有已知会话,发一张绿卡(会话名 + 模型名)。重启包装脚本可以把一句「续跑指令」写进 $DSH_HOME/restart-continue.json——绿卡里直接显示这条指令,并作为新消息投进会话,模型自己接着干。指令 10 分钟过期、读后即焚。

上下文会自己收

累计过 100K 之后,名单内(read / glob / grep / bash / 搜索读页)且超过 8K 的工具结果,完整进模型 3 次,第 4 次发送前走官方头 4K 尾 1K。skill 不过。冷启动和开门前的历史不回砍。glob 自动滤掉 node_modules / .git / .pnpm。可选:生图 / 多步浏览类 MCP 藏到 enable_mcp 之后。规格见 PRUNE.md。

多模态按飞书的方式走

图 / 语音 / 文件落到本地 inbox(保留原文件名),把路径写给模型。不无条件把图片塞进 session image block:只有模型在 DSH_FEISHU_MODELS 里标了 vision: true 才原生收图,其余仍走路径 + OmniCore 识图。回图、回文件、回语音走 send_file。

收新图 / 压缩包之前会先把历史里的图片块换成路径,避免旧图串到新一轮。图片对象在磁盘上已经没了的话,引用它的历史块降级成一行路径文字,不再整轮失败。

富文本(post)里的图片和附件文件都会被解析出来,不会漏收。

适合谁 / 不适合谁

适合:有一台能出网的机器,要把 dsh 做成 7×24 云端同事;已经在飞书办公、不想再为 Agent 开网页或守着笔记本终端;同一套 Agent 多个飞书身份;Goal 这种「交代完让它自己盯」,但中断和续跑必须自己说了算。

不适合:个人 PC 上扫码 30 秒上手、还想留官方 Web 控制台、需要打字机流式答案卡、或只把飞书当通知渠道。那些货架上已经很多,去搜 feishu 即可。

安装(给 Agent / 人类逐步做)

面向一台已经能出网的机器(Linux / macOS / WSL;Windows 原生机也能起进程,Agent 调 bash 会别扭)。按顺序做,缺一步后面会起不来。

0. 前置(先齐这四样)

1. Node 22+。node -v 以 v22 开头。不够就先装 Node,不要用 18/20。
2. DeepSeek Harness CLI。
npm i -g @deepseek-ai/dsh
dsh --version

应印出版本号。没有 dsh 命令就检查 npm prefix -g 是否在 PATH。
3. DeepSeek API key。到 platform.deepseek.com 建一把,环境变量名 DEEPSEEK_API_KEY。默认模型只有官方 dsf = deepseek-flash。
4. 飞书企业自建应用(开放平台手建,无头机器不能扫码)。打开 open.feishu.cn/app:
- 创建企业自建应用,记下 App ID / App Secret
- 权限:获取与发送单聊/群组消息、获取群组信息、以应用身份发消息、上传图片/文件、给消息加表情
- 事件订阅选 长连接 / WebSocket,不要 webhook
- 事件勾 im.message.receive_v1;回调勾 card.action.trigger(审核卡、提问卡;没订则按钮点了没反应)
- 打开「机器人」能力;要进群就把应用加进目标群

逐步截图级说明:docs/feishu-setup.md。

1. 装插件

dsh plugin --profile feishu add github:shoxiy-danny/dsh-feishu

想锁死版本、以后不被上游改动影响,就钉 commit(git ls-remote 取最新 sha):

dsh plugin --profile feishu add github:shoxiy-danny/dsh-feishu#<sha>

以后怎么升级、怎么回滚,见 docs/upgrade.md。

要钉某次提交(推荐给别人装):

dsh plugin --profile feishu add github:shoxiy-danny/dsh-feishu#<sha>

2. 写环境变量后启动

export FEISHU_APP_ID=cli_xxx
export FEISHU_APP_SECRET=xxx
export DEEPSEEK_API_KEY=sk-xxx
dsh --profile feishu

日志出现 ready bots=... 再在这个应用的单聊打一句。应先收到表情,再看到进度头,然后是正文。发 /goal 会出一张可点的目标卡。

工作目录默认家目录;附件落 workspace/inbox/。第二个 bot 再填 FEISHU_APP_ID_2 / FEISHU_APP_SECRET_2。

3. 加非官方模型(可选)

内置只有 dsf。要接 OpenAI 兼容网关或其它厂商:把 examples/profile.cordis.patch.yml 抄进 ~/.dsh/profiles/feishu/cordis.patch.yml,把 examples/models.json 拷到某处并 export DSH_FEISHU_MODELS=/绝对路径/models.json,再 export 样例里的 MY_OPENAI_KEY。样例别名是 oa = gpt-4.1。字段说明见 docs/handbook.md「模型」。

从本仓脚本装(开发 / 自托管)

git clone https://github.com/shoxiy-danny/dsh-feishu.git
cd dsh-feishu
cp .env.example .env
填 FEISHU_APP_ID / FEISHU_APP_SECRET / DEEPSEEK_API_KEY
chmod +x scripts/.sh scripts/dsh-feishu-cli
./scripts/setup.sh
./scripts/start.sh

文档

| 文件 | 内容 |
| docs/install.md | 从零装一遍:前置、飞书应用、启动、验收、常见失败 |
| docs/upgrade.md | 已经在用的人看这个:确认装法、升级、0.1.9 → 0.2.0 迁移、回滚 |
| docs/env.md | 全部环境变量一张表,标了默认值和「不设会怎样」 |
| docs/handbook.md | 斜杠命令、Goal 卡片、模型、多 bot、MCP、假 bot |
| docs/feishu-setup.md | 飞书应用、权限、长连接(逐步截图级) |
| docs/publish.md | 作者:GitHub topic 和市场收录 |
| examples/ | 模型表、记忆/项目模板、bye 与 note skill |

已经在跑老版本?直接看 docs/upgrade.md。

默认模型只有 DeepSeek 官方 dsf。加自己的供应商:抄 examples/ 里的 yaml + json(样例别名 oa),字段说明在手册「模型」。

需要 DeepSeek Harness。发现页:dsh-plugin.market。

harness 住在飞书里,不是网页的遥控器。

插件市场里已经有三十多个 feishu / lark 条目。多数是通知器、多 IM 网关,或者用 dsh plugin --profile web add 加进来的桥。飞书只是个遥控器:网页还在那儿,一关浏览器,半个产品就没了。

这是跑在飞书里的 harness,定位是无头守护进程,装在一台常开的机器上:Linux、macOS 或 WSL。不是让你拿笔记本扫终端二维码。一条 dsh --profile feishu。日志写进文件。没人需要盯着 TTY。飞书 WebSocket 进,飞书卡片出。模型、斜杠命令、进度、Goal、会话:全在聊天里。没有 3080 端口。没有桌面 TUI。高风险命令停在飞书审批卡片上,不是网页弹窗。

第一个 bot 必须在开放平台创建,再填进环境变量。无头服务器没地方放二维码。额外的 bot 之后可以从已经跑通的聊天里开;但那不是启动方式。

我们不比按钮数量。没有打字机式回答卡片。换成四件事:

1. 住在飞书里 —— harness 的界面是聊天,不是网页的遥控器
2. Goal 卡片 —— 在卡片上设置、编辑、暂停、恢复、清除;重启后不会继续烧 token,直到你恢复
3. 多个 bot,一个进程 —— 2–3 个飞书身份,一个智能体;一个会话不能被两个窗口同时持有
4. 会变的进度头 —— [dsf-23% G1/3] Using bash...(2),不是卡住的「Thinking…」

下面三张卡片取自真实卡片 JSON。不是飞书截图。
另有一个 GitHub 仓库叫 PGZXB/dsh-feishu:一个飞书控制台,支持卡片内审批,官方 Web 端仍然保留。所有者不同,产品也不同。

特性

不依赖 Web

不需要 dsh-web-app,不需要 3080 端口,也不需要一次性的无头运行器。Cordis 插件在进程内调用 create / followup / steer / cancel / resume。飞书是交互界面,不是包装器外面再套一层包装器。

目标:一张卡片,跑完整个循环

发送 /goal,或者在卡片上写下目标,点 Set and start。你可以在末尾追加「最多 3 轮」。

智能体会跨轮次继续执行。进程重启后,它不会继续消耗 token,直到你点 Resume 或发送 /goal resume。

卡片上可以:创建 / 编辑(表单)、暂停、恢复、清除。完成显示绿色,阻塞显示红色。斜杠命令依然可用。

会实时变化的进度头

卡片原地编辑:

[dsf-23% G1/3] Using bash...(2)

显示模型别名、上下文百分比、Goal 轮次(接近上限时显示 near)。卡片上显示 Done / Failed;回复是单独一条消息。

多个机器人,一个进程

同一个进程承载 2–3 个飞书应用。会话按 (appId, chat_id) 区分。历史可以跨机器人 /resume;同一个会话不能同时被两个窗口持有。

输入框里的斜杠命令

/stop /clear /model /status /usage /compact /resume /rename /goal /bye

输入未知的 / 会回复支持的命令列表。完整表格见 docs/handbook.md。不带编号的 /resume 会发一张会话卡片。模型可以通过 SlashCommand({ command: "/rename …" }) 重命名。

上下文自动裁剪

超过 100K token 后,大的 read / glob / grep / bash / search 结果会完整保留 3 次模型查看,之后按官方规则保留头部 4K + 尾部 1K。技能结果永不裁剪。规范见 PRUNE.md。

审批卡片 / 询问用户卡片

未命名的 rm、find -delete、破坏性 git 操作,以及杀掉守护进程本身,都会暂停在橙色卡片上。点 Allow once 才会执行。输入 yes 不算批准。路径里含未展开的 shell 变量($TMP_FILE、$(mktemp))时,不会被误判为家目录目标。选项通过 ask_user_question 呈现(蓝色卡片):选项排成编号的两列网格,带灰色描述菜单,点一个,提交单行表单,或者直接输入回复。多选问题会渲染成带提交按钮的复选框表单。需要在开放平台订阅 card.action.trigger。

模型选择卡片

不带参数的 /model 会发一张选择卡片,按 tier 分组(来自 DSH_FEISHU_MODELS,带 short 标签)。点一个即可切换;还有「保持当前」按钮。/model <alias> 仍然一行回复。

切换到没有 vision: true 的模型时,会把会话里已有的图片块改写成路径文本,避免下一次请求返回 400。

用量面板

/usage 扫描 $DSH_HOME/sessions/ 下的会话日志,按模型和按 bot 汇总 token:请求数、输入、输出、缓存命中率。默认窗口是最近 7 天;/usage today 和 /usage all 可以切换。bot 名称来自 DSH_FEISHU_BOT_LABELS。

恢复分页

/resume 每页显示 8 个会话,超过一页时带翻页按钮。翻页只改同一张卡片,不新开话题。

重启后自动重新挂载

重启之后你不用先说话:插件会恢复所有已知会话,并发出绿色卡片(会话标题 + 模型)。重启包装脚本可以往 $DSH_HOME/restart-continue.json 里放一条由 LLM 撰写的继续指令;卡片会内联显示这条指令,并把它作为新消息投递进会话,智能体就能接着上次的进度继续。10 分钟后过期,读取即消费。

安装(分步进行,智能体或人都适用)

面向能上网的机器(Linux / macOS / WSL;裸 Windows 机器能启动,但智能体的 bash 调用会跟你较劲)。按顺序执行。

0. 前置条件

1. Node 22+。node -v 必须以 v22 开头。
2. DeepSeek Harness 命令行:
npm i -g @deepseek-ai/dsh
dsh --version

3. DEEPSEEK_API_KEY,从 platform.deepseek.com 获取。唯一内置别名是 dsf = deepseek-flash。
4. 飞书企业自建应用(无头机器上没法扫码)。在 open.feishu.cn/app:创建应用;复制 App ID / Secret;授予消息、群信息、以应用身份发消息、上传、表情回应权限;用 WebSocket 订阅,不要用 webhook;事件订阅 im.message.receive_v1,回调订阅 card.action.trigger;开启机器人能力。详情见 docs/feishu-setup.md。

1. 添加插件

dsh plugin --profile feishu add github:shoxiy-danny/dsh-feishu

想固定版本(避免上游改动带来意外),改用 commit:

dsh plugin --profile feishu add github:shoxiy-danny/dsh-feishu#<sha>

升级与回滚:docs/upgrade.md。

在意某个已知快照时,固定到 commit:

dsh plugin --profile feishu add github:shoxiy-danny/dsh-feishu#<sha>

2. 导出凭据并启动

export FEISHU_APP_ID=cli_xxx
export FEISHU_APP_SECRET=xxx
export DEEPSEEK_API_KEY=sk-xxx
dsh --profile feishu

等日志里出现 ready bots=...,然后用该应用在 p2p 会话里发一条消息。你应该会先收到表情回应,再收到进度标题,最后是回复。

3. 额外模型(可选)

把 examples/profile.cordis.patch.yml 复制到 ~/.dsh/profiles/feishu/cordis.patch.yml,并让 DSH_FEISHU_MODELS 指向 examples/models.json 的副本。示例别名是 oa = gpt-4.1。字段表见手册 §模型。

从本仓库安装(开发 / 自托管)

git clone https://github.com/shoxiy-danny/dsh-feishu.git
cd dsh-feishubash
cp .env.example .env

fill FEISHU_APP_ID / FEISHU_APP_SECRET / DEEPSEEK_API_KEY

chmod +x scripts/.sh scripts/dsh-feishu-cli
./scripts/setup.sh
./scripts/start.sh

默认工作目录是主目录;附件落在 workspace/inbox/。第二个机器人用 FEISHU_APP_ID_2 / FEISHU_APP_SECRET_2。

适合谁 / 不适合谁

适合:你有一台常开的机器,想让 dsh 当 24/7 的同事;你本来就泡在飞书里,不想再开一个 Agent 网页或盯着笔记本终端;一个智能体,多个飞书身份;Goal(「让它一直跑」)支持你开口就能暂停 / 恢复。

不适合:在个人电脑上扫码 30 秒就能装好;还想要官方网页控制台或打字机流式卡片;或者只把飞书当通知渠道。这些市面上已经有了。搜 feishu。

文档

| 文件 | 内容 |
| docs/install.md | 从零开始:前置条件、飞书应用、启动、验收、故障 |
| docs/upgrade.md | 已经在跑了?先看这里。 判断安装类型、升级、0.1.9 → 0.2.0、回滚 |
| docs/env.md | 每个环境变量、默认值,以及不设置会怎样 |
| docs/handbook.md | 命令、Goal 卡片、模型、多机器人、MCP、假命令行机器人 |
| docs/feishu-setup.md | 飞书应用、权限范围、长连接 |
| docs/publish.md | 作者:GitHub topics 与市场上架 |
| examples/ | 模型表、记忆 / 项目模板、bye 与 note 技能 |

还在用旧版本?直接看 docs/upgrade.md。

自带一个 DeepSeek 官方别名:dsf。要加服务商:复制 examples/(示例别名 oa);字段表见手册 §模型。

依赖 DeepSeek Harness。发现渠道:dsh-plugin.market。

MIT。欢迎提 Issue 和 PR。
预览分享卡片长什么样 ↓shoxiy-danny/dsh-feishu
分享 · DeepSeek Harness Hub
shoxiy-danny/dsh-feishu

在飞书聊天框里设定目标、查看进度并审批高危操作

这是你的仓库?认领条目

回到顶部