@zhangzhian/dsh-devtools-settings

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

dsh-devtools 的设置外壳:设置左栏的一条「开发工具」导航项 = 控制台首页(介绍 + 版本与更新 + 功能插件卡片)+ 点卡片下钻到各插件设置页(正文由组件包注册进 devtools.settings.tab)

原始使用文档
文档目录7 节
  1. 安装
  2. 提供什么
  3. 要求
  4. English
  5. Install
  6. What it provides
  7. Requirements

English | 简体中文

@zhangzhian/dsh-devtools-settings

dsh-devtools 的设置外壳:设置左栏里的一条「开发工具」导航项。点进去是一个 控制台首页(一句话介绍 + 版本与更新 + 功能插件卡片),点一张卡片就下钻到那个 插件的设置页 —— 像跳一个路由,而不是在一个常驻菜单里切页签。

它自己只有控制台这一页 —— 其余页面正文由其它组件包注册进 devtools.settings.tab。

安装

dsh plugin add @zhangzhian/dsh-devtools

@zhangzhian/dsh-devtools 是清单包,装它会带齐所有组件(包括这个)。只想装外壳:

dsh plugin add @zhangzhian/dsh-devtools-settings

提供什么

  • 设置左栏的一条「开发工具」导航项(settings.section,id: devtools, order: 30),带自己的图标。
  • 控制台首页(devtools-home,order: 10,默认打开的第一页):标题 + 一句介绍 + 配套软件入口 + 「版本与更新」卡(当前版本 / 最新版本 / 升级 / 右上角刷新)+「功能 插件」卡片网格。卡片跟着账本自动长:任何包往 devtools.settings.tab 注册页面, 控制台就多一张卡。
  • 配套软件入口(控制台里一条 63px 横条):在「版本与更新」卡上面、介绍之后 —— 左侧「DSH Remote / 专属配套软件」+ 三个卖点,右侧浅蓝胶囊「官网下载」(悬停转实心品牌 蓝,键盘聚焦有 focus 环)。整条是一个 <a>(官网下载、 target="_blank"、rel="noopener noreferrer"),position: sticky; top: 0:默认普通 一条,超一屏滚动时钉在顶部。
  • 下钻视图:点一张卡切到那一页;页头是「返回控制台 + 图标 + 名字 + 一句话说明」,正文 全宽,返回控制台按钮和 Esc 都能回来。页头吸顶 —— 正文往下滚时钉在顶部不动 (滚动容器是平台设置弹层,页头整块 sticky、底色不透明)。 页头高度写成自定义属性 --dsh-devtools-page-bar-h(91px)并用 min-height 钉住:正文里 也有要吸顶的东西(远程接入的两个 tab),得知道从哪儿开始吸。
  • 版本与更新(真能升级):宿主半身提供 dshDevtoolsUpdate Remote 服务 (status / check / upgrade)。自动检查默认执行(打开卡片时若从没查过 / 距上次 超过 6 小时就查一次),面板上没有开关。判据只有一条:npm registry 上的 latest 比现在 装的更新吗;动作也只有一种:在 profile 目录里 pnpm add @zhangzhian/dsh-devtools@<版本> --config.minimum-release-age=0(回读版本一致 才算成功,见 src/update-service.ts 顶部)。link: 安装同样按 npm 判据、装 npm 发布版,只多一句提醒(升级会把依赖换成发布版)。所有包锁步同版本,所以"当前版本"读 自己那份 package.json 就等于读聚合包。
  • 子槽 devtools.settings.tab:其它包把设置页注册进来,就会出现在控制台的卡片网格里 ({ kind: 'list', scope: 'root' })。
  • 「dsh 管理终端」:宿主半身在 $DSH_HOME/devtools/bin/ 下生成 wrapper (dsh-shell)+ 环境文件 + rc 垫片,清单 patch 把它追加进终端控制器的 shellCandidates —— 新建终端的 shell 下拉里多一项 dsh-shell。选了它的终端里就有 dsh 的运行环境:DSH_HOME / DSH_PROFILE / DSH_PROFILE_DIR,以及和宿主 同一套的 dsh / pnpm / node(PATH 前缀),可以在里面 dsh plugin add/remove、升级 dsh、跑 pnpm。

它是自家配套软件的固定入口,不是广告位。 DSH Remote 是这个插件的专属配套软件:没有 「推广」字样、没有第三方免责声明;不来自页签账本、不随插件增减变化、不参与下钻;地址写死在 PROMO_URL,文案在 locale 的 7 个 promo.* 键。

为什么需要这个终端。 平台的终端起 PTY 时只传 { DSH_SESSION_ID },而子进程环境是 scrubbedParentEnv() 的产物 —— 所有 DSH_* 都被剥掉(平台原话:"harness identity never leaks implicitly")。所以不选这一项时,在终端里敲 dsh plugin --profile web add ... 会去操作 ~/.dsh,而不是这个 dsh 真正用的 home/profile。模型用的 bash 工具走平台的受信任 注册表,终端这条链路没接它。

它影响不到宿主机。 环境变量只是"起这个终端时"传给子进程的一份 map:宿主 process.env 不被写回,别的终端拿不到,也没有任何文件级环境(/etc/profile、 ~/.zshrc)被修改。rc 垫片解决反方向的坑:交互式 shell 会先 source 你自己的 ~/.zshrc / ~/.bashrc(提示符、补全、别名照旧),垫片再 source 环境文件、把 PATH 前缀强制挪回最前 —— ⚠️ 只做"缺了才补"不够:rc 里常见的 export PATH="$HOME/xxx/bin:$PATH" 不删前缀、只把它挤到后面,node / pnpm 就变成你 自己那套了(真机上发现的)。前缀不会重复出现。

三个已知边界。 ① wrapper 名字不是 bash/zsh,平台的活动探测 (prepareShellActivity)不生效:它不会被"未看管 72 小时"自动清理误杀,代价只是 空闲判定不准。② wrapper 不存在时下拉里静默少一项(平台把"可执行文件不存在"当跳过), 所以 dshShell: false 或宿主半身没起来时不报错。③ Windows 上不生成(wrapper 是 POSIX sh 脚本)。

配置(这一行的 config: 段):dshShell(默认 true,关掉就不生成、下拉里也没了)、 shell(留空 = 按 zsh → bash → sh 探测)、inheritShellRc(默认 true;设 false 就是 zsh -f -i / bash --noprofile --norc -i,环境确定但没有你的补全与别名)、env(额外 注入的变量,保留键被丢弃)、pathExtra(追加进 PATH 前缀的目录)。不想让下拉出现这一项, 也可以在 profile 的 cordis.patch.yml 里写一条同 id 的 terminal-controller 行把 shellCandidates 盖回默认值。

交互与无障碍。 控制台的插件菜单是一组按钮(整卡可点,悬停/聚焦有反馈);下钻页是 role="region" + aria-label。不再是 role="tablist":两屏互斥、点卡片就是"跳转", 硬套标签页语义会念出屏幕上不存在的控件(见 src/client/index.tsx)。焦点跟着路由:下钻进新页面、返回回到那张卡;只挂载 访问过的页(keep-alive)。

导航图标是怎么换上的。 平台的设置导航按 section id 硬编码图标,未知 id 一律给齿轮, 而 settings.section 只有 id / order / label —— 没有"贡献图标"的槽。所以本包不改 平台界面:给自己的那一行打 data-dsh-devtools-nav,用本包 CSS 藏掉平台 SVG、::before + CSS mask 画自己的图标(形状取自 IconApiOutlineMedium,颜色跟导航行文字走,选中/悬停变主 色)。整段包在 @supports 里:不支持 mask 的浏览器保留齿轮而非空白。平台哪天长出图标槽, 这段可以删掉。

要求

  • DSH 0.2.0-rc.2 或更新。
  • 没有别的依赖。没有贡献方时控制台显示空态。
  • 「dsh 管理终端」需要 POSIX 系统(macOS / Linux)和带终端控制器的 profile (web 形态)。它靠清单 patch 改 terminal-controller 那一行,所以本 bundle 必须排在 @deepseek-ai/dsh-web-app 之后(dsh plugin add 的追加顺序就是如此)。

English

@zhangzhian/dsh-devtools-settings

The settings shell of dsh-devtools: one "Dev tools" entry in the Settings sidebar. It opens a console home (one-line intro, version & updates, plugin cards); clicking a card drills into that plugin's settings page — a route, not tabs in a permanent menu.

The shell ships only that console page — every other page body is registered into devtools.settings.tab by the component packages.

Install

dsh plugin add @zhangzhian/dsh-devtools

@zhangzhian/dsh-devtools is the manifest package; installing it pulls in every component, including this one. To install the shell alone:

dsh plugin add @zhangzhian/dsh-devtools-settings

What it provides

  • One "Dev tools" entry in the Settings sidebar (settings.section, id: devtools, order: 30), with its own icon.
  • A console home page (devtools-home, order: 10, the first page you land on): heading + one-line intro + the companion-app bar + a "Version & updates" card (installed / latest / upgrade / refresh) + a "Plugins" card grid. The grid grows by itself: any package registering into devtools.settings.tab gets a card.
  • A companion-app bar (63px, inside the console): right above the "Version & updates" card, after the intro — "DSH Remote / Companion app" plus the three selling points on the left, a pale-blue "Official download" pill on the right (solid brand blue on hover, focus ring on keyboard focus). The strip is one <a> (download, target="_blank", rel="noopener noreferrer"), position: sticky; top: 0 — plain by default, pinned to the top once the content scrolls.
  • A drill-down view: clicking a card opens that page; its header is "back to console + icon + name + one-line description", body at full width. Both the back to console button and Esc return you. The header is sticky — pinned while the body scrolls (the scroller is the platform's settings pane; the header sits in one position: sticky wrapper with an opaque background). Its height is published as --dsh-devtools-page-bar-h (91px) and pinned with min-height: the body has sticky things of its own (the two remote-access tabs) and must know where the header ends.
  • The devtools.settings.tab child slot: any package registering a page into it appears in the console's grid ({ kind: 'list', scope: 'root' }).
  • A "dsh management terminal": the host half generates a wrapper (dsh-shell) plus an env file and rc shims under $DSH_HOME/devtools/bin/, and the bundle patch appends its path to the controller's shellCandidates — so the shell dropdown gets one more entry, dsh-shell. The one terminal you pick it for carries the dsh runtime environment: DSH_HOME / DSH_PROFILE / DSH_PROFILE_DIR and the same dsh / pnpm / node the host runs with (PATH prefix) — where you can dsh plugin add/remove, upgrade dsh or run pnpm.

A fixed entry to our own companion app, not an ad slot. DSH Remote is this plugin's dedicated companion app — no "Promoted" wording, no third-party disclaimer. It never comes from the tab ledger and takes no part in the drill-down; the URL is hardcoded in PROMO_URL, the copy lives in seven promo.* keys.

Why it is needed. The platform spawns a terminal PTY with { DSH_SESSION_ID } only, and the child environment comes from scrubbedParentEnv() — every DSH_* variable is stripped ("harness identity never leaks implicitly"). Without this entry, dsh plugin --profile web add ... in a terminal operates on ~/.dsh, not the home/profile this dsh uses. The model's bash tool uses the platform's trusted registry; this terminal path was never wired to it.

It cannot affect the host. Env vars are a per-child map for that terminal: the host's process.env is never written back, other terminals do not see it, and no file-level environment (/etc/profile, ~/.zshrc, …) is modified. The rc shims solve the opposite problem: an interactive shell sources your ~/.zshrc / ~/.bashrc first, then the shim sources the environment file and forces the PATH prefix back to the front — ⚠️ "prepend only if missing" is not enough: a common export PATH="$HOME/xxx/bin:$PATH" does not delete the prefix, it pushes it back, and node / pnpm there become yours instead of the host's (found on a real machine). The prefix never appears twice.

Three known edges. (1) The wrapper is not named bash/zsh, so the platform's activity probe (prepareShellActivity) does not apply: it is never reaped by the "unattended for 72 hours" rule, only idle state gets imprecise. (2) When the wrapper is missing, the dropdown silently loses that entry (the platform treats "executable not found" as a skip), so dshShell: false or a failed host half is never an error. (3) Nothing is generated on Windows (the wrapper is a POSIX sh script).

Configuration (this row's config:): dshShell (default true; off = no generation, no dropdown entry), shell (empty = probe zsh → bash → sh), inheritShellRc (default true; false = zsh -f -i / bash --noprofile --norc -i, deterministic but without your completion and aliases), env (extra variables; reserved keys dropped) and pathExtra (extra PATH-prefix dirs). To keep it out of the dropdown, add a terminal-controller row with the same id in the profile's cordis.patch.yml restoring platform defaults.

  • Version & updates (actually upgrades): the host half exposes a dshDevtoolsUpdate remote service (status / check / upgrade). Auto-check runs by default (on open, if it never checked or the last check is over 6 hours old); there is no toggle in the panel. One rule: is the npm registry latest newer than what is installed? — one action: pnpm add @zhangzhian/dsh-devtools@<version> --config.minimum-release-age=0 in the profile, then read the installed version back; only a match counts (see the top of src/update-service.ts). A link: install follows the same rule and installs the npm release too, with one note (upgrading replaces the link: dependency with the published package). Every package here shares one version, so its own package.json equals the aggregate package. On failure the panel shows the failing step's raw output.

Interaction and accessibility. The console's plugin menu is a set of buttons (whole card clickable, with hover/focus feedback); the drill-down page is a role="region" with an aria-label. It is no longer a role="tablist": the screens are mutually exclusive and clicking a card is navigation, so tab semantics would announce a control that is not on screen (see src/client/index.tsx). Focus follows the route: drilling in moves focus into the new page, returning puts it back on the original card; only visited pages stay mounted (keep-alive).

How the navigation icon gets there. The platform hardcodes nav icons by section id and falls back to a gear for unknown ids, while settings.section only accepts id / order / label — no icon slot. So this package never touches the platform UI: it marks its row with data-dsh-devtools-nav, hides the platform SVG via CSS and paints its icon with ::before plus a CSS mask (shape from IconApiOutlineMedium, colour riding the row's text colour). If the platform grows an icon slot, this block can be deleted.

Requirements

  • DSH 0.2.0-rc.2 or newer.
  • Nothing else. With no contributors the console shows its empty state.
  • The "dsh management terminal" needs a POSIX system (macOS / Linux) and a profile with the terminal controller (the web shape). It patches the terminal-controller row through the bundle patch, so this bundle must come after @deepseek-ai/dsh-web-app — as dsh plugin add appending it does.

版本与发布记录

@zhangzhian/dsh-devtools-settings 共发布 6 个版本,首次发布于 2026/10/20;过去 12 个月发布了 6 个版本。

版本发布日期距今
0.3.1latest2026/11/03今天
0.3.02026/11/011 天前
0.2.22026/10/2113 天前
0.2.12026/10/2014 天前
0.2.02026/10/2014 天前
0.0.0-stage2026/10/2014 天前

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

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

dsh-devtools 的设置外壳:设置左栏的一条「开发工具」导航项 = 控制台首页(介绍 + 版本与更新 + 功能插件卡片)+ 点卡片下钻到各插件设置页(正文由组件包注册进 devtools.settings.tab)

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

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

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

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

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

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

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

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

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

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