在桌面侧边栏一键重启应用并加载新插件
29.9/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/20 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add DONGBIN007/dsh-sidebar-restart该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
在桌面应用侧边栏底部、设置旁边加一行「重启」,用来重启应用并把页面重新加载到刚安装的插件包上。
README
由 DeepSeek 最新模型翻译生成dsh-sidebar-restart
侧边栏底部有一行,就在设置齿轮旁边:点一下就能重启 DSH 桌面应用,不用再从托盘退出、手动重新启动。
桌面应用里 Restart 行位于 Settings 上方
移动端抽屉里的同一行,带文字标签
三种形态
安装
dsh plugin --profile desktop add dsh-sidebar-restart # once it is on npm
或者直接从仓库安装:
dsh plugin --profile desktop add github:DONGBIN007/dsh-sidebar-restart
然后手动重启一次应用,让插件加载 —— 这是你最后一次手动重启,之后都用这个按钮。
仅限桌面端。 在普通的 dsh web 配置档下,这一行会渲染成禁用状态并说明原因;那里没有桌面进程可替换。如果你想重启的是 Web 服务器,那是另一个插件(dsh-restart-button)。
一句话说明它做什么
在桌面应用侧边栏底部、Settings 旁边加一行 Restart。点击后向 Host 请求重启;一个独立的后台辅助进程按 PID 杀掉 Electron 主进程和 Host,等两者都退出后重新启动应用,替换进程用新的 boot id 应答后,标签页自行刷新 —— 这样你刚安装的插件在重启后确实在运行。
展开完整文档(README 剩余 1 节)
dsh-sidebar-restart
侧边栏底部有一行,就在设置齿轮旁边:点一下就能重启 DSH 桌面应用,不用再从托盘退出、手动重新启动。
桌面应用里 Restart 行位于 Settings 上方
移动端抽屉里的同一行,带文字标签
三种形态
安装
dsh plugin --profile desktop add dsh-sidebar-restart # once it is on npm
或者直接从仓库安装:
dsh plugin --profile desktop add github:DONGBIN007/dsh-sidebar-restart
然后手动重启一次应用,让插件加载 —— 这是你最后一次手动重启,之后都用这个按钮。
仅限桌面端。 在普通的 dsh web 配置档下,这一行会渲染成禁用状态并说明原因;那里没有桌面进程可替换。如果你想重启的是 Web 服务器,那是另一个插件(dsh-restart-button)。
一句话说明它做什么
在桌面应用侧边栏底部、Settings 旁边加一行 Restart。点击后向 Host 请求重启;一个独立的后台辅助进程按 PID 杀掉 Electron 主进程和 Host,等两者都退出后重新启动应用,替换进程用新的 boot id 应答后,标签页自行刷新 —— 这样你刚安装的插件在重启后确实在运行。
外观
| 桌面应用(宽侧边栏) | 移动端抽屉 |
| desktop | mobile |
两者都遵循宿主自己的规则,而不是我设的断点:文字标签出现的位置,正好是宿主给齿轮显示标签的位置,也就是侧边栏较宽时。在 56px 宽的窄栏里,这一行只显示图标,并保持齿轮的 36×36 点击区域。
控件是旁边齿轮行的复刻
位置是 sidebar.footer.action —— 「侧边栏底部 Settings 旁的可选操作」。内置侧边栏把它渲染为 footerActions,一个 flex 行,由 footArea 排在 settingsArea(齿轮行)上方。所以在原生宿主底部,这个控件正好位于齿轮上方。
它刻意做成齿轮的孪生样式,每个值都取自内置的 .wCInkW_trigger(ui-settings-general)和该位置自己的兄弟节点 .dsh-mobile-control__trigger,两者一致:
| 属性 | 值 | 原因 |
| 颜色 | --dsw-alias-label-primary | 齿轮用的是 primary 标签色;旁边放一个 secondary 色的图标会明显不搭 |
| 高度 | 42px | 宿主两个底部控件都用这个行高 |
| 内边距 | 0 10px 0 8px,gap 8px | 齿轮自己的内边距和图标/标签间距 |
| 圆角 | --dsw-radius-md | 齿轮的圆角,不是小号那个 |
| 标签 | 14px / 22px,font: inherit | 齿轮标签的排版 |
| 行盒子 | calc(100% + 4px)、margin 4px -2px | 齿轮所在行是 .wCInkW_triggerRow{width:calc(100% + 4px);margin:4px -2px}——它向两侧各溢出列 2px,所以内容起点是 parentLeft − 2 + 8 = +6。不做同样的溢出,这一行的图标和标签就会比齿轮的右移 2px,两者永远对不齐。这个按钮本身就是一行,所以溢出和内边距都由它自己承担。 |
在真机截图上验证过(1216×2640,约合每 CSS px 3.5 设备 px),直接测量每一行的深色墨迹:
| 设备上的行 | 图标墨迹左缘 | 标签墨迹左缘 | 图标墨迹 | 行中心 |
| 溢出前:重启 | 73 | 157 | 50 | 2356.5 |
| 溢出前:设置 | 67 | 150 | 48 | 2531.5 |
| 溢出后:重启 | 66 | 150 | 50 | — |
| 溢出后:设置 | 67 | 150 | 48 | — |
所以旧几何比齿轮右移了 +6 设备 px(≈2 CSS px)——正是 CSS 预测的 2px——而交付的几何在图标上落在 1 设备 px 以内,在标签上恰好为 0。两个行中心相距 175 设备 px,即 175 / 3.5 = 50.0 CSS px——正好是设计值 21 + 4 + 4 + 21。
真机对齐:橙色线为齿轮图标左缘
橙色线是齿轮自己图标的左缘。改动前,↻ 图标和重启标签都落在它右侧;改动后,两者都落在线上。
在受控的 340px 列中,对宿主交付的 CSS 做同样的校验,结果精确到百分位也一致:
| 行 | 图标左缘 | 标签左缘 |
| 齿轮 | 5.67 | 29.67 |
| 本按钮,溢出前 | 7.67(+2.00) | 31.67(+2.00) |
| 本按钮,溢出后 | 5.67(0.00) | 29.67(0.00) |
受控 CSS 校验
有一处残留不是 CSS 不匹配,是刻意保留的:设备上 ↻ 的墨迹是 50px,齿轮是 48px。两个图标都是宿主自己的基础图形,都用宿主自己的 wide ? 16 : 18,画在同一个 16px 盒子里,描边同为 1.3——接近整圆的图形本来就比紧凑的齿轮墨迹更多。要让两者墨迹一致,就得把交付的图形画得比宿主要求的尺寸更小,而这是这一行绝不能做的事。
标签遵循宿主自己的 wide 约定——没有自创断点。齿轮的 TriggerContent 渲染 wide ? <icon size 16> + label : <icon size 18>,而 dsh-mobile——这个位置的另一位占用者——做的是 wide ? : undefined。
两个图标永远不会不一致,因为两个位置拿到的是同一个 wide。交付的侧边栏里只有一个来源:
const wide = windowsTitlebar ? !collapsed : !collapsed || !settled;
renderSlot("sidebar.footer.action", { wide }) // this plugin
renderSlot("sidebar.settings", { wide }) // the gear
齿轮把它原样转发给 settings.trigger。所以本插件的 wide ? 16 : 18 就是齿轮的 wide ? 16 : 18,这是构造使然。
注册的组件必须转发 seat 的 props。如果组件不接收参数,就会丢掉 wide,控件在任何状态下都停留在纯图标形态,却仍然「渲染正常」——这种缺陷在代码评审里看不出来,在手机上却一目了然。第一张移动端截图正是如此:打开的宽抽屉里只有一个光秃秃的图标,下面是一个带文字的 设置。test/client.test.mjs 现在会固定住转发行为,而且这个检查是重新引入 bug、看它失败来确认的,不是靠一次绿色的运行结果就信了。
- 宽列(桌面侧边栏;移动端抽屉在打开时也是):图标 + 文字 重启 / Restart,字体和颜色与齿轮一致。
- 折叠的 56px 轨道:36×36,图标放大到 18px,无标签——即齿轮的轨道状态。注意这是两个宿主参考唯一不同之处,以齿轮为准:.wCInkW_trigger.wCInkW_rail 保留 --dsw-radius-md(12px),而 dsh-mobile 的 .is-rail 换成 border-radius: 50%。圆形挨着圆角方形,看起来就像两个不同的控件家族,所以本插件采用齿轮的圆角方形。
具体到移动端(dsh-mobile,覆盖断点 (max-width:720px),抽屉宽度为 min(88vw, 340px)):移动端 bundle 的 !important 规则只针对 composer、设置选项页和侧边栏行菜单——没有一条碰到 sidebar.footer.action 或齿轮,移动端也没有定义图标尺寸变量。它只是读取宿主侧边栏自己的 _collapsed 类,来判断抽屉是否打开。所以两个图标靠构造保持一致,而不是靠移动端专用覆盖。
同一份代码服务两种皮肤/布局,没有任何分支:如果皮肤把页脚折进账号弹层(例如 dsh-claude-style 的 collapseFooter,默认开启),皮肤会把同一个条目提升到自己的菜单里,渲染成菜单行——在那里,一模一样的图标依然读起来像同一套图标的一部分。
字形用的是 @deepseek-ai/dsh-client-ui-primitives 里随包发布的 IconRefreshOutlineArtwork,是复制而非导入(纯 JS bundle 可能加载不了 Harness Client 包,而导入一个正是插件规则禁止的)。同样的 16×16 盒子、同样的 1.3 中等描边、同样的 currentColor 和默认端点,所以它读起来就像宿主自带图标集的一部分。
重启为什么这样实现
显而易见的实现方式不可用,而且每个死胡同都是对着已安装的构建验证过的,不是凭空假设:
- 按钮不能放进账号菜单。 它的条目(settings、contact、signout)是 @deepseek-ai/dsh-client-ui-settings-account 里硬编码的数组;菜单没有暴露任何插件 seat。
- 插件没有重启 API。 window.dshDesktop 只暴露 browser、deviceInfo、keyboard、shortcuts 和 updates;25 个 dsh-desktop:* IPC 通道里没有一个能重启任何东西。Host 是一个普通的 Node 子 Electron 主进程(ELECTRON_RUN_AS_NODE=1)无法调用 app.relaunch()。内置的「Restart App and Host」菜单项确实存在,但受 !app.isPackaged 限制,正式发布的版本永远不会显示它。
- 关闭窗口不会退出应用。 window.on('close') 只是把窗口隐藏到托盘。再次启动应用同样无效:单实例锁会把第二次启动变成「聚焦已有窗口」。
所以重启走的是进程外交接:Host 先返回 202,然后一个分离的辅助进程按 PID 杀掉 Electron 主进程和 Host,等两者真正退出(正是这一步让重新启动不会被单实例锁降级),再移除 Node 模式标记,重新启动应用。
交接期间标签页做什么
连接正在被拆除,没法用它告诉页面「重启完成」,所以页面收到 202 后轮询状态路由,比对 boot id。boot id 变了,说明应答的是新进程,标签页随即调用 location.reload()。这次刷新正是整个功能的意义所在:它让浏览器加载新安装的 bundle,而不是停留在旧代码上——也正因如此,进度对话框可以关闭(Escape、遮罩或按钮),而不是在交接始终没落地时变成困住用户的模态框。轮询是只读的,尝试 POLL_LIMIT 次后停止,把界面交还给用户。
端点
两个端点都同源,且只监听回环地址。
| 路由 | 方法 | 用途 |
| /dsh-desktop-restart/status | GET | boot id、PID,以及此处能否重启(不能时给出原因) |
| /dsh-desktop-restart/restart | POST | 执行重启;在应用被杀掉之前返回 202 |
POST 会拒绝以下请求:携带转发头、不来自回环地址、Origin 与 Host 不一致,或内容类型不是 application/json(跨站页面发不出这种内容类型,除非先发预检请求,而本服务器不应答预检)。单飞闩锁让重启期间的第二次点击变成空操作,而不是启动第二个应用。
配置
| 键 | 默认值 | 含义 |
| handoffDelayMs | 400 | 辅助进程在杀进程前等待多久,好让 202 送达浏览器。 |
日志
每次重启都会往系统临时目录写一个 dsh-desktop-restart-<timestamp>.log;路径会显示在进度对话框里,也由 202 返回。
限制
- 这是硬重启。它不执行 shell 的退出检查,运行中的任务会被中断——所以按钮会先确认。
- 刚安装的 bundle 可能仍需手动重启一次才能加载。之后,这个按钮就是重启的方式。
- 如果未来的 DSH 版本改变了进程模型,插件会退化为一个禁用的按钮并说明原因,而不是损坏应用。
开发
node --check index.js && node --check client.js
npm test
test/client.test.mjs 固定住客户端这一半里那些不出错就看不见的部分:它加载 React,不加载任何 Harness 包;图标用的是官方素材,不是重绘;控件与齿轮行在颜色、尺寸、字体上保持一致;标签遵循宿主机的 wide 约定;每个可见颜色都是主题 token;它唯一的写操作是 JSON 重启 POST。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
DONGBIN007/dsh-sidebar-restart
在桌面侧边栏一键重启应用并加载新插件
相关插件 · 市场 / 管理
插件精选列表awesome-dsh-plugin/awesome-dsh-plugin
DeepSeek Harness(dsh)插件精选列表
★ 22,399未汉化DSH
73.6
新词雷达zhuyansen/new-term-radar
new-term-radar新词雷达
★ 2,049已汉化MCP
72.8
插件生态导航0xsline/awesome-deepseek-harness
安装 贡献指南 DeepSeek Docs 公开插件目录 Issues
★ 1,188已汉化DSH
72.6
技能注册中心iflytek/skillhub
企业级开源智能体技能注册中心——发布、发现并管理组织内可复用的技能包。
★ 5,384已汉化DSH
71.9
插件市场目录imsai-sh/awesome-deepseek-harness-plugins
面向 DeepSeek Harnessdsh生态的社区插件目录,共收录 13950 个插件含 PR 收录与…
★ 360已汉化DSH
71.9
插件精选清单Anil-matcha/awesome-dsh-plugin
DeepSeek Harnessdsh精选指南——DeepSeek…
★ 1,013已汉化DSH
71.7
这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。