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

dsh-single-terminal

v0.1.4

Published

Interactive terminal drawer plugin (dual-face): bottom drawer with real PTY terminals (xterm.js), multi-tab, Windows shell picker (PowerShell default / pwsh / CMD / Git Bash / WSL + custom), docked (occupies page height) or overlay mode, keep-alive sessio

Readme

dsh-single-terminal

dsh-single-terminal 是 DeepSeek Harness(DSH)宿主的真实终端抽屉插件。它在 Web 应用底部挂一条交互式 PTY 终端(xterm.js)——可以正常敲命令、Ctrl-C、拖拽 改大小、开任意多个标签。

  • 真 PTY,非模拟 —— 每个标签是一条真实伪终端(Windows 为 ConPTY,POSIX 为 forkpty),由 node-pty 驱动;交互式 REPL、全屏程序、Ctrl-C 与原生终端一致
  • Shell 选择 —— Windows:PowerShell(默认)/ pwsh 7 / CMD / Git Bash / WSL (未安装的自动隐藏)+ config 自定义 shell;POSIX:$SHELL / bash / zsh / fish
  • 两种抽屉模式 —— 占高度 把页面内容顶起(无遮挡),浮层 悬浮于内容之上; 顶边可拖拽调高度,模式与高度自动记忆。两种模式共用同一磨砂玻璃样式 (半透明背景 + backdrop-filter 高斯模糊)——模式只决定停靠行为。开合带 滑入滑出动画(沿用宿主缓动曲线,尊重系统减动效设置)。
  • 主题跟随 —— 抽屉与终端配色实时跟随宿主主题(浅色 / 深色 / 自定义主题), 无需单独配置。
  • 会话保活 —— 终端在页面刷新、抽屉开合后继续存活;重连后从环形缓冲回放 近期输出。打开抽屉时若还没有任何终端,会自动用默认 shell 新建一个。
  • 工作区路径感知 —— 当前会话归属某个工作区时,新建终端(含自动新建)直接 落在该工作区根目录,无需手动 cd;无会话 / 无工作区时回退 defaultCwd 规则。
  • 双语 UI —— 跟随宿主界面语言(中文 / English);Alt+C 开关抽屉

English

预览

终端抽屉截图(暗色主题跟随、磨砂玻璃样式):见 preview.md。

功能

  • 抽屉把手入口(渲染在 shell.overlay 的抽屉内部):>_ 提示符小标签 吸附在抽屉右上角外沿——即终端入口按钮。它随抽屉自身的滑动动画移动: 展开时像抽屉把手一样吸附在终端右上角;最小化后落在页面右下角。点击开合 抽屉;Alt+C 全局开合,焦点在终端输入区内时放行(Alt+C 作为 ESC c 发给 shell)。
  • 隐形会话桥(conversation.session.header.utilities):渲染 null 的 组件,只负责把当前会话的工作区根目录同步给 controller(新建终端落在该 目录);会话头部不显示本插件任何可见 UI。
  • 抽屉(shell.overlay):frame 级底部抽屉,包含
    • 标签条 —— 每标签一条独立 PTY 会话,可独立选择 shell;每标签有关闭按钮 (终止整棵进程树,已实测 pid 消失);
    • 单一 + 按钮 —— 下拉列出本机探测到的全部 shell(不可用的不显示), 默认 shell 置顶并标记;
    • 模式切换(占高度 / 浮层)、连接状态点、最小化(−)按钮;
    • 顶边拖拽条(pointer capture 拖拽,最小 140px)。
  • 占高度模式 通过对框架根元素设 padding-bottom 把内容顶起(宿主没有底部 停靠钩子);找不到锚点元素时静默降级为浮层。
  • 模型工具:无——本插件刻意只做 UI。

配置

Schemastery Config(宿主 Plugins 设置页自动渲染),和 / 或 profile 的 cordis.patch.yml:

- insert:
    - id: dsh-single-terminal
      name: dsh-single-terminal
      config:
        defaultShell: powershell   # powershell | pwsh | cmd | gitbash | wsl | <自定义 id>
        defaultCwd: home           # home | workspace | 绝对路径
        scrollbackLimit: 200000    # 每会话回放环形缓冲字节上限
        fontSize: 13
        fontFamily: Consolas, "Cascadia Mono", "Courier New", monospace
        customShells:
          - id: nu
            name: Nushell
            command: nu            # 支持从 PATH 解析
            args: []
  • defaultShell —— + 下拉菜单中预选的 shell(置顶并标记「默认」);不可用 时自动回退(Windows 回退 powershell,POSIX 回退 $SHELL/bash)。
  • defaultCwd —— 无工作区上下文时的启动目录:home(默认)从用户主目录启动; workspace 预留(当前等同 home);绝对路径必须存在。当前会话归属工作区时 优先使用工作区根目录(见上)。
  • customShells —— 额外启动器;command 可为绝对路径或从 PATH 解析的名称 (Windows 上叠加 PATHEXT)。

安装

# 本地开发
dsh plugin --profile web add ./dsh-single-terminal

# 已发布:npm / tarball / GitHub
dsh plugin --profile web add dsh-single-terminal
dsh plugin --profile web add ./dsh-single-terminal-0.1.0.tgz
dsh plugin --profile web add github:you/dsh-single-terminal#<sha>

dsh --profile web                 # 启动(宿主半边需重启后生效)

node-pty 是宿主半边的原生依赖(dependencies,构建时保持 external, 运行时经 createRequire 加载)。常见平台有预编译产物;特殊平台 pnpm install 时需要 C/C++ 工具链编译。浏览器半边完整内联 xterm.js, 无运行时依赖。

发布

构建工具链为 tsc + tsdown(无 vite):tsc -b 负责类型检查并产出声明文件, tsdown(Rolldown 内核)打包宿主半(lib/index.js,ESM)与浏览器半 (lib/client.js,单文件 CJS __ModuleLoader__ 工厂,自动 banner 包裹)。 依赖管理使用 pnpm 10(pnpm-lock.yaml 入库,CI 按 --frozen-lockfile 安装)。构建产物随 git 提交,git 安装无需本地构建:

pnpm install     # 按 pnpm-lock.yaml 安装
pnpm run build   # 清空 lib → tsc -b(声明)→ tsdown(双半产物)
pnpm run verify  # 模拟宿主模块表检查 lib/client.js(可选)
pnpm run release # check + build + verify + npm version patch + 推送 tag(触发发布工作流)

自动发布(GitHub Actions)

推送 v* tag(pnpm run release 会自动 bump 补丁版本、重建并打 tag 推送)会 触发 .github/workflows/publish.yml——单个 release job:Setup Node 26 → pnpm install --frozen-lockfile → pnpm run check → pnpm run build → pnpm run verify → pnpm pack → 创建 GitHub Release(自动生成 changelog,附带 tarball)→ 经 Trusted Publishing(OIDC --provenance,无需 NPM_TOKEN secret)发布到 npm (需先在 npmjs.com 把该包的本仓库配置为 Trusted Publisher)。

开发

环境要求:Node ≥ 22.19(或 ≥ 24)+ pnpm 10(packageManager 固定 pnpm 版本)。

pnpm install           # node-pty + ws(运行时)、@xterm/*(内联进 client)
pnpm run check         # 全树 TypeScript 类型检查(tsc -b)
pnpm run build         # 清空 lib → tsc -b(声明文件)→ tsdown(双半产物)
pnpm run watch         # tsdown watch 模式
pnpm run verify        # 模拟宿主 seed 表检查 lib/client.js 可加载
├── src/                # 源码
│   ├── host/           # 宿主半边:index.ts(入口,ws 路由 + 配置)、hub.ts(会话 Hub + 帧协议)、shells.ts(注册表 + 探测)、types.ts
│   └── client/         # 浏览器半边:plugin.tsx(slots)、drawer.tsx(抽屉 + 入口把手)、term.tsx、controller.ts、ws.ts、styles.ts、theme.ts、scope.tsx(会话桥)、i18n.ts ...
├── lib/                # 构建产物(入库:git 安装无需本地构建)
│   ├── index.js        # 宿主半边(tsdown,ESM)
│   ├── client.js       # 浏览器半边(tsdown → __ModuleLoader__ 工厂,xterm 已内联)
│   └── types/          # 类型声明(tsc -b 生成)
├── assets/preview/     # README / preview.md 引用的截图
├── scripts/            # verify-client.mjs(宿主 seed 表模拟检查)、gen-xterm-css.mjs(重新生成 src/client/xterm-css.ts)
├── tsdown.config.ts    # tsdown 构建配置(node 半 + client bundle banner 包裹)
├── tsconfig.json       # solution:引用 tsconfig.host.json / tsconfig.client.json
├── cordis.patch.yml    # Bundle patch:按包名引用的插件行(无路径)
├── package.json        # dsh.bundle + dsh.client(web) manifests + peerDependencies
├── README.md           # 英文文档
├── README.zh.md        # 本文件(中文)
└── preview.md          # 截图预览(引用 assets/preview/*.png)

实现说明

  • 插件为何自带 node-pty:宿主 subprocess 的终端原语 (SubprocessTerminalHandle)不暴露 resize,而尺寸跟随是终端抽屉的刚需; 插件自持 node-pty 即可获得与宿主同底座(ConPTY/forkpty)的完整 write / resize / kill 控制。
  • 传输:经 ctx.webServer.registerUpgrade 注册独立 WebSocket 路由 (/api/dsh-single-terminal.ws),ctx.connection.requestRejection 鉴权(与宿主 API gateway 同一信任围栏)。客户端同源连接,自动携带 dsh-auth cookie。
  • 会话模型:会话保存在 Hub 的 Map 中,与 socket 解耦——页面刷新 / 重连后 重新 list、adopt 存活会话并 attach 回放环形缓冲。已退出的会话从快照中 修剪,死标签不会复活。多个浏览器标签可同时 attach 同一会话(输出广播、 输入合并)。
  • 帧协议:JSON 文本帧;客户端 → 宿主 open / input / resize / close / list / attach / ping,宿主 → 客户端 hello / shells / opened / data / replay / exit / error / pong。input/resize 在服务端限长并钳制尺寸。
  • Windows 进程树:关闭标签执行 pty.kill() 后追加 taskkill /T /F —— 仅关 ConPTY 时 PowerShell(+PSReadLine)可能存活;POSIX 杀前台进程组 (kill(-pid))。
  • 主题跟随:插件 CSS 全部消费宿主语义 alias token(--dsw-alias-*,定义在 body 上,随 body[data-ds-dark-theme] 翻转),浅色 / 深色 / 自定义主题 无需插件侧逻辑即可生效。xterm 调色板在运行时现算:经隐藏探针元素读取 alias token 的 computed 值,按磨砂 alpha 重组背景色,并用 MutationObserver 监听 body 属性重新套用——主题切换(含宿主 ThemePresenter 投影的自定义主题) 实时生效。
  • 渲染器策略:xterm 5 默认仅有 DOM 渲染器(allowTransparency 在此有效, WebGL canvas 不支持 alpha)。两种模式共用磨砂样式,因此统一保持 DOM 渲染器 + 半透明终端背景置于磨砂模糊之上——不做运行时渲染器切换,WebGL 插件已移除。
  • 不修改官方 deepseek-harness 项目;全部 UI 落在既有插槽 (抽屉与其入口把手在 shell.overlay,隐形会话桥在 conversation.session.header.utilities)。