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

底部终端面板 btsd321/dsh-oh-my-terminal

DeepSeek Harnessv0.4.5
btsd32122 天前有提交已提供中文文档扫描:含敏感能力

DSH GUI 的底部终端面板插件,支持 Windows ConPTY 和 POSIX openpty,无需本地编译。

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

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

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add dsh-oh-my-terminal
npm 源 · dsh-oh-my-terminal 的发布者账号已校验与本仓库一致

状态速览

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

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

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过
展开查看检查明细 ↓

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

✓npm 包dsh-oh-my-terminal @ 0.4.5
✓Node 引擎要求 ^20.19.0 || >=22.0.0 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

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

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

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

可执行外部命令读写/删除本地文件
查看扫描证据(共 18 处,展示前 16 条)
  • 执行外部命令来自配置/变量
    lib/index.js:174
    const out = execSync(cmd, { encoding: "utf8", timeout: 3e3 });
  • 读取本地文件
    lib/index.js:178
    if (existsSync(candidate)) return candidate;
  • 执行外部命令固定命令
    lib/index.js:188
    const gitPath = execSync("where git", { encoding: "utf8", timeout: 3e3 }).trim().split(/ ? /)[0];
  • 读取本地文件
    lib/index.js:192
    return existsSync(bashPath) ? bashPath : null;
  • 写入本地文件
    lib/index.js:329
    mkdirSync(this.dataDir, { recursive: true });
  • 写入本地文件
    lib/index.js:339
    writeFileSync(this.metaPath, JSON.stringify(meta));
  • 写入本地文件
    lib/index.js:356
    mkdirSync(this.logDir, { recursive: true });
  • 写入本地文件
    lib/index.js:357
    writeFileSync(this.logPath(id), seed);
  • 删除本地文件
    lib/index.js:371
    unlinkSync(this.logPath(id));
  • 写入本地文件
    lib/index.js:387
    mkdirSync(this.logDir, { recursive: true });
  • 写入本地文件
    lib/index.js:388
    appendFileSync(this.logPath(record.id), chunk);
  • 读取本地文件
    lib/index.js:479
    meta = JSON.parse(readFileSync(this.metaPath, "utf8"));
  • 读取本地文件
    lib/index.js:487
    buffer = readFileSync(this.logPath(m.id), "utf8").slice(-SCROLLBACK_CHARS);
  • 执行外部命令来自配置/变量
    lib/index.js:593
    const out = execSync2(cmd, { encoding: "utf8", timeout: 3e3 });
  • 读取本地文件
    lib/index.js:597
    if (existsSync2(candidate)) return candidate;
  • 读取本地文件
    lib/index.js:705
    if (statSync(candidate).isDirectory()) return candidate;
扫描于 2026/10/31(1 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包

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

依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-brand@deepseek-ai/dsh-client-shortcuts@deepseek-ai/dsh-client-store@deepseek-ai/dsh-host-webserver@deepseek-ai/dsh-settings@deepseek-ai/cordis@deepseek-ai/schemastery
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 底部终端交互面板
v0.4.72026-10-28
· 中文 · 修复 · 🔴 Ctrl+Shift+V 粘贴两次(本地直连 SSH 场景):v0.4.7 初版的标志方案有根本性时序缺陷——readText() 是异步的,但原生 paste 事件在 keydown 后同步触发,标志永远来不及在原生 paste 之前设置,导致本地直连 SSH 场景仍然双发。改用原生 paste 优先方案(反转去重方向):不再用异步 readText 结果去压制同步的原生 paste,而是用同步的原生 paste 决定之后要不要做 readText。 - v 分支不调 preventDefault、不同步调 readText——让原生 paste 优先(Chromium Win/Linux 在 keydown 默认处理中同步派发 paste,由 xterm handlePasteEvent 单发,无需剪贴板权限) - keydown 时清零 nativePasteObserved,setTimeout(0) 延迟到宏任务检查:原生 paste 已发生 → 跳过 readText(单发);未发生(macOS 不映射该组合键)→ readText 兜底 - onNativePaste 从拦截者变为纯观察者,不再调 preventDefault / stopImmediatePropagation - Electron webview(readText 被权限拒绝)→ 原生 paste 单发,不再触发权限 reject · 🟢 同时修复 Electron webview 下 Ctrl+Shift+V 完全无法粘贴:v0.4.6 的 preventDefault() 方案在 readText 失败时无法撤销阻断,导致 webview 下彻底无法粘贴。原生 paste 优先方案不调 preventDefault,webview 下原生 paste 正常触发单发。 · 验证 · 类型检查(pnpm run typecheck)与构建(pnpm run build)均通过。 · 在本地 Chrome 直连 DSH + SSH 到 BJ-SF-Robot 场景下按 Ctrl+Shift+V 确认只粘贴一次。 · 在 dsh-remote-explorer 经 webview 远程 WSL 场景下按 Ctrl+Shift+V 确认能粘贴(原生 paste 兜底)。 · 无配置项、API 或协议变更,升级后刷新页面即生效。 完整变更日志:
v0.4.62026-10-28
· 中文 · 修复 · 🟢 Ctrl+Shift+V 会把文本粘贴两次:customKeyHandler 返回 false 时,xterm.js 的 _keyDown 直接 return false,不调用 ev.preventDefault()。Chromium 在 xterm 隐藏的 textarea 上把 Ctrl+Shift+V 当作「粘贴为纯文本」,触发原生 paste 事件,xterm 内部的 handlePasteEvent 又发一次,和我们调用的 term.paste() 重复,导致文本粘贴两次。SSH 连远程主机时更明显——远程 shell(bash/zsh)开启 bracketed paste mode,两次粘贴产生两段 \x1b[200~...\x1b[201~ 序列。现在 onCustomKey 在 readText 可用时调用 ev.preventDefault(),阻断浏览器原生 paste 事件;不安全上下文(远程 http 没有 navigator.clipboard)不阻断,交给原生 paste 单发兜底。 · 🟢 Ctrl+Shift+C 在不安全上下文也能复制:原代码没有 navigator.clipboard.writeText 就不复制;现改为 writeClipboard()(内含 legacyCopy / execCommand 回落),并加 preventDefault() 阻断 Chrome 的 DevTools 审查元素快捷键。keydown 属用户手势,execCommand 在不安全上下文下可用。 · 验证 · 类型检查(pnpm run typecheck)与构建(pnpm run build)均通过。 · 在本地 Chrome、DSH 桌面端、远程 http 三种场景各按一次 Ctrl+Shift+V,确认只粘贴一次。 · 无配置项、API 或协议变更,升级后刷新页面即生效。 完整更新日志:
v0.4.52026-10-24
· 中文 · 修复 · 🟢 统一表面/文字令牌配对,修复下拉菜单与面板「白底白字」:此前面板与浮层底色取 --dsw-specific-tip(宿主设计平台的 tip 档、且当前宿主已无任何消费方的孤儿令牌,浅色主题下为近白 #F5F6F7),条目文字取 --dsw-alias-label-secondary。第三方皮肤可以经宿主公开的 theme.overrideTokens() 把该角色令牌整体改写并内联到 body(例如 dsh-plugin-wallpaper-engine 的字体集把「次要文字」设为 #FAFAFA),两枚令牌来源不同、失去成对关系,于是出现白底白字,只有鼠标悬停(文字切换为 primary)才可见。现在面板/栏/头部/侧栏/右侧列表改用宿主面板语义令牌,下拉菜单/右键菜单/输入框改用宿主浮层语义令牌;文字一律由 --dsw-alias-label-primary 派生(Text / TextDim / TextMuted 三档),边框与 hover 面同样收口。内部令牌声明在 :root,body 并带宿主令牌回退,浅色/深色、有无皮肤、独立模式与 DSH-better-sidebar 兼容模式表现一致。 · 🟢 弱化文字同源收口:状态文字、图标、占位符与 focus 描边不再直接使用 --dsw-alias-label-tertiary(同样会被皮肤整体改写),改由主文字色派生的 --dshTermTextMuted 提供,避免浅色面板上对比度过低。 · 维护 · 构建产物 lib/ 在主工作区重新构建,修正经 git worktree 构建时带入的相对路径前缀(不影响运行行为)。 · 无配置项、API 或协议变更,升级后刷新页面即生效。 --- · English · Fixes · 🟢 Pair surface and text theme tokens — fixes white-on-white in the dropdown and panel: The panel/menu background used --dsw-specific-tip (a tip-tier token with no consumer left in the host, near-white #F5F6F7 in the light theme) while item text used --dsw-alias-label-secondary. Third-party skins can rewrite that role token wholesale through the host's public theme.overrideTokens() and have it inlined on body (for example, a dsh-plugin-wallpaper-engine font set setting "secondary text" to #FAFAFA). The two tokens then come from unrelated sources and lose their pairing, producing white on white that only became visible on hover (when the text switches to primary). Panels/bars/header/side list now use the host's panel-surface semantic token, and the dropdown/context menu/inputs use the host's overlay-surface token; all text is derived from --dsw-alias-label-primary (Text / TextDim / TextMuted tiers), with borders and hover surfaces unified as well. The internal tokens are declared on :root,body with host-token fallbacks, so light/dark, with or without skins, and both standalone and DSH-better-sidebar compatibility modes behave the same. · 🟢 Derive muted text from the same source: state text, icons, pl
数据来自仓库的 GitHub Release,可能与插件实际版本不一致。

README

由 DeepSeek 最新模型翻译生成
dsh-oh-my-terminal DSH Web GUI 的底部终端面板插件,基于 @lydell/node-pty 提供多终端交互式面板,经 WebSocket 与浏览器端的 xterm.js 通信。支持 Windows ConPTY 与 POSIX openpty,无需本地编译。 功能特性 - 多标签终端:同时管理多个会话,右侧列表替代水平 tab 栏,支持右键重命名 - 拆分终端:同组内水平并排,+号旁下拉菜单(新建 / 拆分 / 按种类新建),VSCode 风格操作 - 会话持久化:面板收起后会话保持存活,重新打开后自动恢复 - 快捷键开关:可配置快捷键呼出/收起面板;接入宿主统一快捷键系统,在设置界面改键后标签跟随更新 - 拖拽调高:拖拽面板上边缘调整高度 - 跨平台:Windows ConPTY / POSIX openpty,由 @lydell/node-pty 自动选择,二进制随 tarball 分发,安装即用 - 配置表驱动终端:终端配置表(type / name / path)驱动新建终端;启动时自动探测 $PATH 中的终端,可在设置界面新增、改名、编辑路径 - 字体可配置:字体族、字号、行高可配置,配置变更对已打开终端即时生效
展开完整文档(README 剩余 1 节)
dsh-oh-my-terminal

DSH Web GUI 的底部终端面板插件,基于 @lydell/node-pty 提供多终端交互式面板,经 WebSocket 与浏览器端的 xterm.js 通信。支持 Windows ConPTY 与 POSIX openpty,无需本地编译。

功能特性

- 多标签终端:同时管理多个会话,右侧列表替代水平 tab 栏,支持右键重命名
- 拆分终端:同组内水平并排,+号旁下拉菜单(新建 / 拆分 / 按种类新建),VSCode 风格操作
- 会话持久化:面板收起后会话保持存活,重新打开后自动恢复
- 快捷键开关:可配置快捷键呼出/收起面板;接入宿主统一快捷键系统,在设置界面改键后标签跟随更新
- 拖拽调高:拖拽面板上边缘调整高度
- 跨平台:Windows ConPTY / POSIX openpty,由 @lydell/node-pty 自动选择,二进制随 tarball 分发,安装即用
- 配置表驱动终端:终端配置表(type / name / path)驱动新建终端;启动时自动探测 $PATH 中的终端,可在设置界面新增、改名、编辑路径
- 字体可配置:字体族、字号、行高可配置,配置变更对已打开终端即时生效
- DSH-better-sidebar 兼容:运行时自动检测 DSH-better-sidebar,检测到时切换为兼容模式——通过 ctx.betterSidebar.registerTab() 注册"终端"tab 嵌入其底部工作台,替代独立底部面板;PTY 会话不绑定 DSH session 的 write handle,从根源消除与 DSH-better-sidebar 自带终端的冲突。当宿主支持 TabDescriptor.rightActions(v0.25.0+)时,终端操作按钮(新建 / 拆分 / 重启)注入 tab 标签条右端,VSCode 风格单层栏;不支持时回退为 tab 内容区顶部头部栏(两层显示)

安装

本仓库尚未发布到 npm,通过 GitHub 地址安装:

dsh plugin --profile web add github:btsd321/dsh-oh-my-terminal

配置

| 配置项 | 说明 | 默认值 |
| toggleShortcut | 呼出/收起终端面板的快捷键(仅旧宿主生效,见下方适配说明) | Ctrl+Shift+ |
| fontFamily | 终端字体族(CSS font-family 串);留空使用内置默认字体栈(含 CJK 回退) | '' |
| fontSize | 终端字号(像素) | 12.5 |
| lineHeight | 终端行高倍数 | 1.25 |
| terminalProfiles | 终端配置表(JSON 数组);留空 = 用启动时探测到的 $PATH 终端 | '' |

终端配置表

终端配置表是 { id, type, name, path, origin } 条目的 JSON 数组:

- type:决定 spawn 语义 — pwsh / powershell / cmd / bash / zsh / fish / gitbash / nushell / custom
- name:下拉菜单显示名(用户可改)
- path:可执行文件路径;留空 = 按 type 在 $PATH 中解析
- origin:auto(启动探测)/ user(手动新增)

自动探测项(origin: auto)不可删除、路径不可改,但名称始终可编辑。配置表可在设置界面内 inline 编辑、新增行、删除。

开发

安装依赖(@lydell/node-pty 自带各平台预编译二进制,装完即用,无需本地编译)
pnpm install

类型检查
pnpm run typecheck

构建(esbuild 双入口,产物输出到 lib/)
pnpm run build

单元测试
pnpm exec tsx --test tests/unit/*.test.ts

请使用 pnpm,不要用 npm。peer 依赖钉死具体版本,npm 在旧依赖树上做增量解析会报 ERESOLVE。

关于构建产物

lib/ 已纳入版本控制。DSH loader 通过纯 ESM import 加载插件,不走 tsx;同时本仓库不声明 prepare/postinstall 等生命周期脚本(pnpm 11 对声明了安装类脚本的 git-hosted 包直接报 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED),因此构建产物需开发者手动执行 pnpm run build 后随源码一起提交。

原生依赖说明

终端能力来自 @lydell/node-pty(microsoft/node-pty 的预编译分发版,API 同源),版本精确钉在 1.1.0:该包 dist-tags.latest 指向 1.2.0-beta 系列,用 ^ 会取到 beta。

它是 N-API 产物,二进制按平台拆成六个子包随 tarball 分发,安装期不下载、不编译,同一份二进制同时支持 Node 22 与 Node 24。其 package.json 中不存在 scripts 字段,pnpm 10/11/12 对没有脚本字段的包不进入构建授权判断分支,行为一致。

宿主半对它是懒加载(首次创建会话时才 await import()):原生绑定若加载失败,异常只影响会话创建,不会让插件模块本身导入失败。

架构概览

src/
├── index.ts # 宿主半入口(Cordis 插件 + settings + 会话生命周期) ├── routes.ts # HTTP 路由处理器 ├── ws-handler.ts # WebSocket 处理器(pty 数据转发) ├── client.tsx # 浏览器半入口(React 组件 + 插件注册) ├── client/ │ ├── types.ts # 共享类型 │ ├── hooks.ts # useReducer 状态管理 + 自定义 Hooks │ ├── term-pane.tsx # xterm.js 终端面板组件 │ ├── dropdown.tsx # +号旁下拉菜单 │ ├── side-list.tsx # 右侧终端列表 │ ├── styles.ts # CSS 常量 + Campbell 暗色主题 │ ├── icons.tsx # SVG 图标组件 │ ├── clipboard.ts # 剪贴板工具函数 │ ├── shortcut-bridge.ts # shortcuts 服务接入桥(命令注册 + 面板切换回调) │ ├── compat.ts # DSH-better-sidebar 兼容模式检测(软探测 ctx.betterSidebar + 服务最小接口声明) │ ├── sidebar-tab.tsx # 侧边栏终端 tab 组件(兼容模式:嵌入 DSH-better-sidebar 底部工作台,不绑定 DSH sessionId) │ ├── settings/ # 设置界面(types / store / card / profile-table / api / styles) │ └── terminal/ # 终端标签页状态(use-tabs / reducer / use-terminal-state / geometry) ├── persistence.ts # 会话持久化层(日志落盘 / 元数据 / 启动恢复) ├── platform.ts # 平台适配层(POSIX / Windows + shell 探测) ├── terminal/ # 终端种类、探测、解析、配置表校验 ├── settings/ # Settings 桥接层(命名空间 / 路由 / patch 操作) ├── constants.ts # 协议 / 尺寸 / 快捷键 / 环境变量常量 ├── server-command.ts # 命令行解析工具 ├── shortcut.ts # 快捷键解析工具 └── logger.ts # 统一日志工具

宿主半与浏览器半经 WebSocket 通信,路由前缀 /api/dsh-oh-my-terminal,不直接 import。

License

Apache-2.0
预览分享卡片长什么样 ↓btsd321/dsh-oh-my-terminal
分享 · DeepSeek Harness Hub
btsd321/dsh-oh-my-terminal

DSH GUI 的底部终端面板插件,支持 Windows ConPTY 和 POSIX openpty,无需本地编译。

回到顶部