npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@linjianyu/dsh-bridge-runner

v0.1.0

Published

面向 bridge/客户端的通用常驻会话运行层:固定 sessionId、跨重启 resume、stdio 帧协议,会话管理/工作区/模型切换/agent 编排

Readme

@linjianyu/dsh-bridge-runner —— 面向 bridge/客户端的通用常驻会话运行层

把 DSH 变成一个常驻进程,用固定 sessionId 维护同一条持久 agent session, 跨进程重启也能凭 sessionId 恢复(resume),从 stdin 逐行喂 followup、把最终回复写回 stdout。

定位:介于 headless 与 web 之间的「会话运行层」

| 层次 | 会话持久 | 接口 | 面向 | |---|---|---|---| | dsh-headless | ❌ 每次全新 session | 一次性子进程 + CLI 参数 | 脚本、单发任务 | | dsh-bridge-runner(本包) | ✅ 固定 sessionId + resume | 常驻子进程 + stdio 帧协议 | bridge/客户端(微信、IM、桌面壳…) | | DSH Web | ✅ session | HTTP/WebSocket BFF | 浏览器 UI |

相比 headless,本层额外提供:会话管理(固定 id、create/resume、换新)、 工作区--workspace 指定 cwd)、模型切换(热切,不丢上下文)、 权限切换--permission 热切 + 运行时指令)、agent 编排(followup/whenIdle,未来 extend subagent)。

相比 web,本层无 HTTP/Host/浏览器层,只有一个 stdio 帧协议,任何外部组件 (wechat-bridge、telegram bridge、桌面客户端……)都能用 spawn 一个子进程的方式接入。

为什么需要它

dsh --profile headless 每次运行都硬编码 session-${randomUUID()}(见 @deepseek-ai/dsh-headless/lib/index.js),即每条消息都是全新 session。 本层复用 DSH 底层的 agents.create / agents.resume / agent.followup() 真实 API (@deepseek-ai/dsh-agent@deepseek-ai/dsh-agent-loop,web 的 host BFF 也走同一套), 让一条 agent session 真正跨消息、跨进程延续。

目录结构

packages/dsh-bridge-runner/
  package.json              插件包清单(dsh.bundle.patch + devDeps)
  cordis.patch.yml          bundle patch:插入 resident-startup + resident-runner
  lib/startup.js            解析 --session-id,发布 residentStartup 服务
  lib/index.js              常驻 runner:create/resume + stdin 循环 + stdout 帧输出
  lib/types/*.d.ts          类型声明
  test-resident.mjs         POC 验证脚本

stdio 帧协议(UTF-8,逐行)

  • 输入(stdin 每行 = 一条用户消息):
    <文本>\n
    空行视为心跳/分隔(回一帧 okreply 为空、skipped:true)。
  • 输出(每条消息处理后输出一行 JSON):
    {"id":1,"ok":true,"reply":"<最终 assistant 文本>"}
    {"id":2,"ok":false,"error":"..."}
  • stdin 关闭(EOF)→ 优雅退出;SIGINT/SIGTERM → 优雅退出。

安装(走 DSH 官方插件机制,远程 npm)

本包已发布到 npm(@linjianyu/dsh-bridge-runner),直接远程安装:

# 远程拉取 @linjianyu/dsh-bridge-runner 并 reconcile 进 resident profile 的 bundles
dsh plugin --profile resident add @linjianyu/dsh-bridge-runner

dsh plugin add 内部转发到 pnpm,在 profile 目录 pnpm add <pkg>;随后自动 reconcile (检测到插件声明了 dsh.bundle,便把它追加进 profile 的 dsh.profile.bundles 层列表)。 pnpm 把 plugin 与 commander 装入 .pnpm 虚拟仓库,@deepseek-ai/* peer 经 profile 父目录向上在 $DSH_HOME/profiles/node_modules(DSH 内置包扁平回退)解析。

前置依赖:dsh 已安装、pnpm 可用(未装用 npm i -g pnpmcorepack enable pnpm)。

使用

$env:DSH_HOME = "$env:USERPROFILE\.dsh"
dsh --profile resident --session-id wx:[email protected]

之后保持进程常驻,把消息按行写进 stdin、从 stdout 读回复帧即可。 weixin-bot.mjs--resident 模式会为每个微信会话维护一个这样的常驻子进程。

关键实现机制

  • 固定 sessionIdagents.create({ sessionId }) 首次建立;进程内 agents.get(id) 直接复用 live agent。
  • 跨重启恢复session-persistence-jsonl(dsh-base 默认装载,落盘 $DSH_HOME/sessions/)持久化 session; runner 启动时先 agents.resume({ resumeSessionId }),失败(session 不存在)才 create
  • 喂 followupagent.followup(createUserMessage(...))await agent.whenIdle() → 聚合本轮的 assistant/message 文本 → sessions.flush() 落盘 → 回帧。
  • 模型热切--model/--provider 初始化 selection.current@model 指令帧 / set_model tool 运行时改 selection.current,下一次请求即用新模型(复用 session,不丢上下文)。
  • 权限热切permissionPresets.set(session, preset) 下 sandbox/mode + approval/policy 事件。
  • 工作区--workspace 决定 SessionHeader.cwd(不可变),换工作区由桥侧 rotate 新 session 实现。
  • 换新会话(/clear):桥接侧用 <chatId>@<epoch> 作为 sessionId,/clear 时 epoch+1, 旧 DSH session 归档保留、新 session 从零开始(不清除、不删除文件)。

验证结果

test-resident.mjs 实测(DSH 0.1.0-rc.6deepseek-v4-pro):

  • 进程内两轮:第二条回复正确反映第一条("你的名字是张三")。
  • 跨进程重启:新进程 resume 同一 session,问"我上一轮说的名字"回答"你叫张三"——证明真·持久复用。
  • /clear 换新 session:epoch 轮换后新 session 不再记得旧上下文。
P1: 我的名字叫张三。请复述我的名字。            → "你的名字是张三。"
P2(新进程): 我在上一轮对话里告诉过你我的名字…  → "你叫张三。"   ← 跨进程记住
/clear → 换 sessionId@+1 → 问"我叫什么" → "我不知道。"      ← 上下文已清空