DeepSeek Harness plugin

dsh-plugin-tg-bridge

DSH <-> Telegram bridge as a profile plugin: forward session activity, replies, and question/approval button flows to Telegram, with a persistent GUI card in 插件配置.

Jump to install

Source facts

Repository
Nicotinamide/dsh-plugin-tg-bridge
Latest update
Aug 17, 2026
Category
Remote & Mobile
GitHub stars
0
Format
plugin
Catalog evidence
Upstream dsh.bundle evidence
Evidence path
package.json#dsh.bundle
Checked against
0.1.0-rc.8
Upstream check date
2026-08-20

This evidence comes from the upstream catalog. This site has not installed, run, or security-reviewed the plugin.

Install

Start with a prompt that asks an agent to review the GitHub repository and source. Switch to the command if you want to install it yourself.

Copy this prompt into DSH, Codex, or another agent and ask it to review the GitHub repository and source first.

Do not install or run any commands yet. Read this plugin's GitHub repository, README, and relevant source code. Then answer the questions below clearly and directly so I can decide whether it fits my needs:

1. What is this plugin, and what problem does it solve?
2. Who is it for, and what are its typical use cases?
3. How is it used after installation? Include one minimal example.
4. What known limitations or privacy, security, compatibility, or maintenance risks does it have?
5. Give a clear recommendation: recommend, conditionally recommend, or do not recommend, with reasons.

Distinguish statements documented by the repository, inferences from source code, and unknowns. If evidence is insufficient, say so explicitly. Do not guess or simply repeat the README.

GitHub: https://github.com/Nicotinamide/dsh-plugin-tg-bridge
Plugin: dsh-plugin-tg-bridge
Author: Nicotinamide

Check the source files

Read the README and other files from this plugin directory before installing.

File explorer2 files
README.mdSource · read only

dsh-plugin-tg-bridge

DSH ↔ Telegram 遥控桥接,作为 Cordis profile 插件使用。

在 Telegram 里遥控 DSH agent:发消息触发任务、实时接收回复与工具进度、审批/提问变成可点按钮、切换会话、切换模型与推理强度、调整权限预设、查看 token 统计,甚至远程重启 DSH。自带持久化 GUI 卡片(插件配置页,双语)。

安装

前置:一台已运行 DSH(dsh web)的机器(本插件是 DSH 的 Cordis profile 插件,不是独立程序)。$DSH_HOME 默认 ~/.dsh(即 %USERPROFILE%\.dsh)。

插件以自包含单文件发布:dist/index.js 已把插件本体和全部运行时依赖(schemastery 等)用 esbuild 打进一个文件,安装时不需要在插件目录里跑 npm install——dsh plugin add / 软链之后即可直接加载。这就是对 ERR_MODULE_NOT_FOUND 的根治:dsh plugin add 只做软链 + bundle 注册,不会安装插件自己的依赖,所以运行时依赖必须跟插件一起打包。

方式 1:dsh plugin add(推荐)

dsh plugin add <路径或URL>   # 例如克隆下来的本地目录,或
dsh plugin add https://github.com/Nicotinamide/dsh-plugin-tg-bridge.git

dsh plugin add 会在 $DSH_HOME/profilespnpm add 并自动注册 bundle 层;随后把插件行写进 profile 的 cordis.patch.yml(见「配置」)并重启 dsh web。

方式 2:手动软链(等价于 pnpm link)

# Linux / macOS
ln -s /path/to/dsh-plugin-tg-bridge $DSH_HOME/profiles/node_modules/dsh-plugin-tg-bridge
# Windows(管理员 PowerShell;或直接改用方式 1)
New-Item -ItemType Junction -Path "$env:USERPROFILE\.dsh\profiles\node_modules\dsh-plugin-tg-bridge" -Target C:\path\to\dsh-plugin-tg-bridge

从源码开发

git clone https://github.com/Nicotinamide/dsh-plugin-tg-bridge.git
cd dsh-plugin-tg-bridge
npm install    # 只需开发依赖(esbuild、schemastery)
npm run build  # 改完 lib/ 后重新生成 dist/index.js(dist 已提交,普通安装无需构建)

Windows 从零安装(新机器)

# 0) 安装 Node.js LTS(https://nodejs.org);国内加速建议先切镜像
npm config set registry https://registry.npmmirror.com
# 1) 全局安装 dsh(比 npx 快:npx 每次都要现场下载整套依赖树,主包虽只有 ~110KB)
npm install -g @deepseek-ai/dsh
dsh web        # 首次初始化 profile,确认能打开 Web 界面(端口以启动日志为准)
# 2) 把本插件 clone/拷贝到本机,按「方式 1 或 2」链接,写入 cordis.patch.yml,重启 dsh web

配置(二选一,env 优先)

方式 A:cordis.patch.yml(推荐日常使用)

<profile>/cordis.patch.yml(默认 $DSH_HOME/profiles/web/cordis.patch.yml)追加:

- insert:
    - id: tg-bridge
      name: 'dsh-plugin-tg-bridge'
      config:
        botToken: '<你的BOT_TOKEN>'        # @BotFather 创建 bot 后获取
        allowedChat: '<你的CHAT_ID>'       # 和 bot 私聊后 @userinfobot 可查
        tgApiBase: 'https://api.telegram.org' # 默认官方;被墙时换成自己的代理
        pollTimeoutSeconds: 25                # 官方长轮询 25 正常;走代理建议 2

方式 B:环境变量(token 不进文件,适合分享/部署)

export TG_BOT_TOKEN='<你的BOT_TOKEN>'
export TG_ALLOWED_CHAT='<你的CHAT_ID>'
export TG_API_BASE='https://api.telegram.org'   # 被墙时换成自己的代理
export TG_POLL_TIMEOUT_SECONDS=25               # 走代理建议 2
dsh web   # 或你的启动脚本

优先级:环境变量 > settings 用户层 > patch 配置 > 默认值。

配置项

字段环境变量必填默认说明
botTokenTG_BOT_TOKENTelegram bot token(@BotFather)
allowedChatTG_ALLOWED_CHAT允许的 chat id(旧版单用户写法;配置了 allowedUsers 可留空)
allowedUsers[]多用户:[{chatId, label?}],每个 chat id 拥有独立的会话空间;label 仅为可选备注(显示名默认取 Telegram 真实名称,无需配置)
adminChatIds[]管理员 chat id:可查看/操作所有用户的会话,可执行 /restart
askerRequiredtrue提问/审批按钮只能由发起者本人点击,群组里其他人点击会被拒绝
tgApiBaseTG_API_BASEhttps://api.telegram.orgBot API 基址(被墙时换成自己的代理)
pollTimeoutSecondsTG_POLL_TIMEOUT_SECONDS25getUpdates 轮询超时;走代理建议 2
dshBaseUrlTG_DSH_BASE_URL自动检测DSH 客户端 API 基址;默认自动使用运行进程的实际端口(端口每次启动可能变化),显式配置(env/patch)优先
muxUrlTG_MUX_URL自动检测DSH 事件流地址;同样默认随实际端口自动推导,显式配置优先
stateFileTG_STATE_FILE$DSH_HOME/tg-bridge-state.json状态持久化文件
turnTimeoutMsTG_TURN_TIMEOUT_MS600000回合超时提醒
tgTimeoutMsTG_TG_TIMEOUT_MS30000Telegram API 超时
dshTimeoutMsTG_DSH_TIMEOUT_MS15000DSH API 超时

Telegram 命令

| 命令 | 作用 | |---|---| | /start | 在线检查 | | /sessions | 列出所有会话(标题 + 状态 + 模式;管理员含 Web 端会话并标来源) | | /use <编号\|ID\|标题\|new> | 切换 / 新建会话(标题关键字模糊匹配,多匹配列候选;/use new 先弹模式选择,创建即定模式) | | /models | 列出模型 + 当前选择与推理强度 | | /model <编号> | 切换当前会话模型(弹窗选择推理强度,不会静默丢失) | | /rename <新标题> | 重命名当前会话(session.rename) | | /effort | 按钮修改推理强度 | | /permission | 按钮切换当前会话权限预设 | | /permission default <name> | 修改全局默认权限 | | /status | 在线状态、模型/模式、token、缓存、上下文占用、回合统计 | | /users | 授权列表(仅管理员) | | /grant <chatId> | 添加用户/群组(仅管理员;群里直接 /grant 授权当前群) | | /revoke <chatId> | 移除授权(仅管理员) | | /admin [off] <chatId> | 设置/取消管理员(仅管理员;设为管理员会自动授权) | | /restart | 远程重启 DSH web(仅管理员;按启动参数自动重建命令,零配置;重启后自动汇报状态) | | /help | 命令列表(按角色差异化:管理员看到全部命令,普通用户只看到日常命令) |

普通消息发给 agent;引用回复会把被引用的原消息一并带给 agent([引用回复]... [新消息]...)。全量双语:TG 命令菜单(/ 按钮,setMyCommandslanguage_code 变体)、/help、所有命令回复、按钮消息(审批/提问/模式/权限/推理强度)、错误与超时提示,都按用户语言(from.language_code,英文客户端显示英文、其余默认中文)自动切换。

agent 回复:文字即时转发、工具调用合并成单条实时进度(回合结束自动删除)、期间显示"正在输入…"、approval/requestedquestion/requested 变成可点按钮。按钮默认只有发起者本人能点:群组里其他人点击只会收到"⚠️ 只有提问者可以回答本题"提示,答案不会提交、状态不变(askerRequired: false 可关闭校验)。

GUI(插件配置页)

包内自带持久 client 半部:设置 → 插件 → 插件配置 出现「Telegram 遥控 / Telegram Remote」双语卡片(跟随系统语言),可编辑 Bot Token(留空保持不变)、Allowed Users/Groups(每行一个 chatId,即授权用户/群组)、Admin Chat IDs(每行一个)、提问/审批按钮归属开关、Telegram API Base、Poll Timeout;保存即热重载,无需重启。重启后依然存在(无需重新激活)。注意:GUI 列表字段留空保存不会清空已有条目(与 token 的"留空不变"一致)——移除授权请在 TG 用 /revoke

模块结构

dist/index.js     发布入口:esbuild 自包含打包(插件 + schemastery 等依赖内联,安装零依赖)
lib/index.js      插件入口源码:官方模板 + settings 命名空间 + /api/tg-bridge/config HTTP 端点(信任校验 + token 打码)
lib/bridge.js     核心:轮询队列 + mux 事件 + 按钮回传 + 会话/权限/模型命令 + 状态持久化 + 远程重启
lib/markdown.js   Markdown -> MarkdownV2 转换(表格/标题/代码/转义/回退)
lib/telegram.js   Telegram Bot API 客户端(可配置代理基址)
lib/client.js     持久 GUI 卡片(__ModuleLoader__ 格式,双语,重启不消失)
lib/settings-local.js  vendored:installSettingsSection/settingsNamespace(避免把 cordis 打进 bundle)
lib/home-local.js     vendored:dshHomePath(省掉 dsh-home-paths 依赖)

当前能力与演进方向

多用户(已实现)

一个 bot 服务多个 chat:allowedUsers 列出允许的 chat id(label 仅作显示),每个 chat 有自己独立的会话空间(perUserSessions);管理员 adminChatIds 能看到/操作所有用户的会话。群组(chat id 为负)同样支持:只响应 @bot 提及或回复 bot 的消息,忽略 bot 自己的消息,群组整体绑定自己的会话空间。群组为"只读 + 提问"白名单:群里只能发普通消息提问、/start/status/help(精简版),其余命令一律提示「请私聊使用」——群成员无法改动群组共享会话的模型/权限/强度/标题。

按钮归属(已实现)

提问/审批按钮按 chatId + 消息 id 精确定位(避免不同 chat 消息 id 撞号)。默认 askerRequired: true:按钮只能由发起该轮的用户点击,群组里其他成员点击只会收到"只有提问者可以回答本题"提示,不提交答案、不改变状态。Web 端发起的轮次不产生按钮,因此有按钮必有归属人;若因升级/重启导致归属人丢失,私聊(单用户)信任点击者,群组拒绝。

授权管理(已实现)

第一个管理员在配置文件 adminChatIds 里指定;之后管理员可以全程在 TG 里管理授权,无需再改配置:

  • /users 查看授权列表(管理员 🛡 / 普通用户 👤;显示名默认取 Telegram 真实名称——私聊 @用户名/名字、群组群名,无需手动维护);
  • /grant <chatId> 添加用户或群组;在群里直接 /grant 授权当前群;群组会自动记录群名作内部备注(会话标题/兜底显示用),显示名以 Telegram 实时名称为准;
  • /revoke <chatId> 移除授权(不能移除自己或最后一个管理员,防止锁死);
  • /admin [off] <chatId> 设置/取消管理员(设为管理员会自动授权该 chat)。

未授权用户在私聊发 /start 会收到自己的 Chat ID,并提示发给管理员开通;其他未授权消息保持静默(日志记录)。/help 按角色差异化:管理员看到全部命令(含管理命令与 /restart),普通用户只看到日常命令;群组里 /help 只显示群组可用的精简列表。

授权数据写入 settings 命名空间(与 GUI 卡片同一来源),TG 命令与 GUI 保存互相同步;访问类变更(授权列表/管理员/按钮归属开关)只更新运行中的 bridge,不重建轮询器(无 409、不丢进行中的回合)。Token/API 地址/超时等核心字段变更才重建。

多 agent(已实现)

agentPreset.list 列出全部模式(标准模式 standard / PTC 模式 code / 极简模式 minimal / 创造模式 cordis,默认 cordis),/use new 创建会话时弹模式选择(创建即定模式,session.createagentPreset);/sessions 每行标注会话模式,/renamesession.rename 重命名当前会话。模式名按语言显示:英文用户看到模式 id(standard/cordis…),中文用户看到名称(标准模式/创造模式…)。

限制:DSH 规定已开始过的会话模式固定agent-preset-locked),只能在空会话上切换——所以模式在 /use new 时一次选定。DSH 官方 API 也没有「删除会话」接口(apiproxy 无 session.remove),也没有会话分组/文件夹概念(session.list 无 group 字段,Web 端分组是前端 UI 行为)——TG 侧按「模式 + 来源(TG/Web)」维度展示分类。

平台兼容

  • Linux / macOS:完整支持。/restart 用纯 Node 看门狗重启(不依赖 bash),日志重定向到当前 stdout 目标或 $DSH_HOME/dsh-web.log
  • Windows 11:核心功能(消息、按钮、会话、权限、模型、状态、GUI)可用。/restart 的看门狗同样是纯 Node(跨平台),但依赖 dsh web 能从 process.argv 原样重建——Windows 上请确认你的 dsh 启动方式支持;loadavg() 在 Windows 恒为 0(/status 负载显示 0,其余正常)。路径全部走 $DSH_HOME%USERPROFILE%\.dsh),无硬编码绝对路径。

排障(踩过的坑)

1. ERR_MODULE_NOT_FOUND: @deepseek-ai/dsh-settings(旧版)dsh plugin add / 软链只做链接和 bundle 注册,不会安装插件自己的依赖。v0.1.1 起运行时依赖全部打进 dist/index.js,安装不再需要 npm install;升级后确认链接的包是以 dist/index.js 为入口(require('<包名>/package.json').main)。 2. 409 Conflict / "terminated by other getUpdates request":同一 bot token 只能有一个轮询器。插件和独立脚本不能同时跑;也不要手工 curl getUpdates。日志里 Conflict 只在重启瞬间新旧进程重叠时出现一次,几秒后自愈。 3. 代理长轮询(timeout≥25)会 self-conflict:如果走代理,用 pollTimeoutSeconds: 2 短轮询。 4. /restart 不工作/restart 从当前进程的启动参数重建命令(node <dsh-bin> ...)拉起看门狗重启,零配置;若用非标准方式启动 dsh(如容器 supervisor),需自行确认进程能被该命令重建。 5. /permission 报"权限服务不可用":host 未注入 permissionPresets/sessions(base 层已含,正常不会出现)。 6. GUI 卡片不显示:确认 dsh.client 声明和 exports["./client"] 存在,重启 dsh web 后 client-modules 自动扫描加载。