@zhangzhian/dsh-devtools-terminal

中文文档
0.3.1发布于 2026/11/03MITTypeScriptES Module

DSH 开发工具:右侧栏终端(Ctrl/Cmd+点击打开输出里的 URL)

原始使用文档
文档目录9 节
  1. 安装
  2. 提供什么
  3. 为什么优先右栏浏览器(而不是系统浏览器)
  4. 要求
  5. English
  6. Install
  7. What it provides
  8. Why the Sidebar browser comes first
  9. Requirements

English | 简体中文

@zhangzhian/dsh-devtools-terminal

DSH 开发工具的右侧栏终端:接管平台内置的 terminal 页签,输出里的 URL 支持 Ctrl/Cmd + 点击在 DSH 右栏的浏览器页签里打开(普通点击仍然是选择/光标, 与 VSCode 终端同一套语义)。

为什么必须接管:平台终端把 xterm 实例和 UI 做进了 @deepseek-ai/dsh-client-ui-sidebar-terminal 的私有懒加载块,第三方插件拿不到实例、也换不掉那块 UI;平台自己提供的干净扩展点是 页签类型注册表——同 kind 的 extension 注册会顶掉内置类型。接管的是「怎么画」, PTY 仍然是平台的 ctx.webTerminals(并发上限、空闲回收、崩溃恢复、关闭 handler 照旧)。

安装

不要单独装它。装清单包——它会作为依赖自动拉下来,并在插件页上给你一个可开关的组件行:

dsh plugin --profile web add @zhangzhian/dsh-devtools

清单包同时用 browser.patch.yml 打开了平台默认在 web 上关掉的右栏浏览器 (@deepseek-ai/dsh-client-ui-sidebar-browser),所以终端链接点下去就落在那里。

本仓库开发回路:

pnpm install
pnpm --filter @zhangzhian/dsh-devtools-terminal build
node scripts/profile-link.mjs     # 把声明了 dsh.client 的包接进 ~/.dsh/profiles/web
node scripts/smoke-terminal-links.mjs   # 真浏览器 + 真 PTY 冒烟(链接落在右栏浏览器里)

装完/改完都要让运行中的 dsh web 重新发现插件(重启 dsh web,或等 dsh-hmr 重载)。 不需要改 DSH 安装本身——换机器、换版本、远端 SSH 环境,装一次插件即可。

提供什么

  • 右侧栏终端(多页签),悬停 URL 出现下划线 + 手型;
  • Ctrl / Cmd + 点击在右栏浏览器页签里打开链接—— ctx.sidebarRight.openTab('browser', { params: { url } }),载体由平台决定: web / 移动端是 iframe,桌面端(dsh-electron 的 carrier)是原生 <webview>; 地址栏、后退/前进/刷新和「在系统浏览器中打开」都由那个面板提供;
  • 右栏浏览器页签不可用时(profile 关掉了那一行、或平台版本没有这个页签类型) 自动回退 window.open(..., 'noopener,noreferrer'):浏览器里是新标签页, 桌面端由 carrier 交给系统浏览器——回退不会吞掉这次点击;
  • 普通点击不打开(选择/光标原样);
  • 折行 URL、宽字符、中文标点、成对括号都按终端真实 buffer 处理;
  • OSC 8 超链接走同一套逻辑(替掉 xterm 默认「单击 + confirm + 空白页」的兜底);
  • 终端服务缺席时正文显示提示,插件其余部分不崩。

为什么优先右栏浏览器(而不是系统浏览器)

开发工具用户的日常恰好是面板能打开的那一类页面:自己起的 dev server(vite / next / storybook、后端预览页……),本地回环端口几乎都不发反嵌头。起完服务直接在右栏看, 不用离开 DSH 再开一个浏览器标签页。公网站点仍可能因为 X-Frame-Options / CSP frame-ancestors 白屏——那是 iframe 的物理上限,用面板工具栏右侧的 「在系统浏览器中打开」(↗)即可。

落点规则是纯函数(src/link-target.ts),单元测试钉住「面板优先 / 面板抛错回退 / 非 http(s) 一律不打开」;真浏览器里的点击语义由 scripts/smoke-terminal-links.mjs 核对(普通点击不开、Cmd/Ctrl+点击在右栏浏览器里打开且 window.open 零次)。

要求

  • DSH 0.2.0-rc.2 或更新(peer 区间写在 package.json 里);
  • 浏览器侧运行时:dsh.client.platform 是 web;
  • 宿主的终端服务(@deepseek-ai/dsh-api-terminal-controller)默认随 dsh web 提供; 没有它时正文显示「不可用」,不报错。

English

@zhangzhian/dsh-devtools-terminal

The right-sidebar terminal for DSH devtools: takes over the platform's built-in terminal tab kind so URLs in terminal output open on Ctrl/Cmd + click in the DSH right-Sidebar browser tab (a plain click still selects text — the same semantics as the VS Code terminal).

Why it takes over instead of extending: the platform terminal keeps its xterm instance and UI inside a private lazy chunk of @deepseek-ai/dsh-client-ui-sidebar-terminal, so third-party plugins can neither reach the instance nor replace that UI. The clean extension point the platform does offer is the tab-type registry: an extension registration with the same kind takes precedence over the built-in one. Only rendering is taken over; the PTY still comes from the platform's ctx.webTerminals (concurrency limits, idle reclaim, crash recovery and the close handler keep working).

Install

Do not install it directly. Install the manifest package — it pulls this in as a dependency and gives you a switchable component row on the plugin page:

dsh plugin --profile web add @zhangzhian/dsh-devtools

The manifest package also enables the right-Sidebar browser (@deepseek-ai/dsh-client-ui-sidebar-browser) that the platform ships disabled on Web, through its browser.patch.yml — so a terminal link lands right there.

Local development loop of this repository:

pnpm install
pnpm --filter @zhangzhian/dsh-devtools-terminal build
node scripts/profile-link.mjs     # link every package declaring dsh.client into ~/.dsh/profiles/web
node scripts/smoke-terminal-links.mjs   # real browser + real PTY smoke (link lands in the Sidebar browser)

After installing or rebuilding, let the running dsh web rediscover the plugin (restart it, or wait for dsh-hmr to reload). No change to the DSH installation itself is needed — a new machine, a new version or a remote SSH environment only needs the plugin installed once.

What it provides

  • Right-sidebar terminal (multiple tabs); hovering a URL shows an underline and a pointer cursor;
  • Ctrl / Cmd + click opens the link in the right-Sidebar browser tab — ctx.sidebarRight.openTab('browser', { params: { url } }); the platform picks the carrier: an iframe on Web and mobile, a native <webview> on Desktop (dsh-electron's carrier). Address bar, Back/Forward/Reload and "Open in system browser" all come from that panel;
  • When the browser tab is unavailable (the profile disabled that row, or the platform version has no such tab kind) it falls back to window.open(..., 'noopener,noreferrer') — a new browser tab on the Web, the system browser through the desktop carrier. The fallback never swallows the click;
  • Plain click does not open (selection and cursor behave as before);
  • Wrapped URLs, wide characters, CJK punctuation and balanced brackets are all handled from the real terminal buffer;
  • OSC 8 hyperlinks follow the same rules (replacing xterm's default "single click + confirm + blank page" fallback);
  • If the terminal service is absent, the body shows a notice and the rest of the plugin keeps working.

Why the Sidebar browser comes first

Dev-server pages are exactly what the panel handles best: vite / next / storybook and backend preview pages on a loopback port almost never refuse framing. Start the server and watch it in the Sidebar instead of leaving DSH for another browser tab. Public sites can still show a blank frame because of X-Frame-Options / CSP frame-ancestors — that is the physical limit of an iframe, and the panel's "Open in system browser" (↗) is the way out.

The destination rule is a pure function (src/link-target.ts) with unit tests pinning "panel first / fall back when the panel throws / never open non-http(s)"; the real click semantics are checked in a real browser by scripts/smoke-terminal-links.mjs (plain click opens nothing, Ctrl/Cmd+click opens in the Sidebar browser with zero window.open calls).

Requirements

  • DSH 0.2.0-rc.2 or newer (peer range lives in package.json);
  • Browser-side runtime: dsh.client.platform is web;
  • The host's terminal service (@deepseek-ai/dsh-api-terminal-controller) ships with dsh web by default; without it the body shows "unavailable" instead of failing.

版本与发布记录

@zhangzhian/dsh-devtools-terminal 共发布 3 个版本,首次发布于 2026/11/01;过去 12 个月发布了 3 个版本。

版本发布日期距今
0.3.1latest2026/11/03今天
0.3.02026/11/012 天前
0.0.0-stage2026/11/012 天前

关于 @zhangzhian/dsh-devtools-terminal 的常见问题

@zhangzhian/dsh-devtools-terminal 是什么?

DSH 开发工具:右侧栏终端(Ctrl/Cmd+点击打开输出里的 URL)

如何安装 @zhangzhian/dsh-devtools-terminal?

在项目目录运行 npm install @zhangzhian/dsh-devtools-terminal,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@deepseek-ai/cordis(~4.0.4)、@deepseek-ai/dsh-host-webserver(^0.2.0-rc.2)、@deepseek-ai/dsh-client-ui-slots(^0.2.0-rc.2)、@deepseek-ai/dsh-client-ui-primitives(^0.2.0-rc.2)、@deepseek-ai/dsh-client-ui-sidebar-right(^0.2.0-rc.2)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@zhangzhian/dsh-devtools-terminal 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@zhangzhian/dsh-devtools-terminal 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@zhangzhian/dsh-devtools-terminal 可以商用吗?

@zhangzhian/dsh-devtools-terminal 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@zhangzhian/dsh-devtools-terminal 还在维护吗?

最新版本 0.3.1 发布于 2026/11/03(今天);至今共发布 3 个版本,其中过去 12 个月发布了 3 个;首次发布于 2026/11/01。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。