跳到正文
dsh-market 浏览插件 GitHub EN

zhang24xiao/dsh-snippets

管理 DSH Web 界面的 CSS 与 JS 代码片段:启用的 CSS 注入为 style 元素,启用的 JS 在页面内执行;提供侧栏底部快捷开关,并在设置导航里有自己的页面,并可选本地文件夹监听与 Gist 同步。

Star 数 ★ 0 分类 UI 增强 收录于 2026-09-18

安装

在 DeepSeek Harness 里通过 dsh-market 安装

dsh plugin --profile web add dshmarket

或使用命令行

dsh plugin --profile web add github:zhang24xiao/dsh-snippets

装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络。请先审阅源码,并尽量锁定 commit(github:owner/repo#sha)。

截图

README

给 DeepSeek Harness Web 界面用的 CSS / JS 代码片段管理器。

侧边栏底部有一个整行的快捷开关,与设置行同一列对齐(左侧 </> 图标,右侧「代码片段」),点开就是管理面板; 本插件在插件管理里自己的页面上带一张可折叠的设置卡片,包含全部偏好项。启用的 CSS 会立即注入到页面,启用的 JS 会在页面加载后执行。

参考思源笔记的 TCOTC/snippets,按 DSH 插件契约重写。

English

截图

快捷开关就在侧栏底部,与「设置」一样占满一行,点开是管理面板:

从侧栏底部打开的代码片段管理面板

编辑器是 CodeMirror 6 —— 行号、CSS/JS 高亮、搜索替换 —— 按视口自适应,并支持 CSS 实时预览:

代码片段编辑器,正在编辑一段 CSS 并带语法高亮

功能

管理代码片段

  • CSS / JS 标签页与实时计数,每种类型一个总开关,搜索可覆盖标题、代码或两者
  • 在插件管理里本插件自己的页面上有一张设置卡片,点开折叠箭头即可展开
  • 新增、编辑、创建副本、删除、启用/停用、拖拽排序
  • 十种排序方式(自定义、已开启优先、名称字母/自然序、创建时间等)
  • 每行的编辑 / 副本 / 删除按钮都可以单独隐藏
  • 一键「重新加载界面」,处理只有重载才能生效的改动

编辑器

  • CodeMirror 6:行号、CSS/JS 语法高亮、括号匹配、折叠、搜索替换、撤销历史
  • 缩进单位、字号、自动换行均可配置;配色跟随界面主题(含暗色)
  • CSS 实时预览:边写边看效果,不保存也能看到
  • 编辑器弹窗按视口自适应(最大 1040×760),不再套用外壳那个 380px 的表单卡片宽度; 代码区会吃掉剩余高度,长片段在卡片内部滚动,而不会把弹窗顶出窗口
  • 保守的格式化:只重写行首空白,绝不改动行的内容
  • 内容校验:含 </style 或 <script 的 CSS 会被拒绝,JS 保存前先解析

浏览器之外

  • 本地文件夹监听:把一个放 .css / .js 的文件夹镜像成代码片段库,可持续监听或仅在启动时加载一次
  • 导入 / 导出:整库导出 JSON,覆盖导入前自动备份
  • GitHub Gist 同步:勾选片段发布,或以「合并更新 / 覆盖镜像 / 仅新增」导入,并先看逐文件差异

安装

要求 DeepSeek Harness 0.1.7-rc.1 或更高:0.1.7 重写了设置线,更早的版本既没有 configForms 服务,也没有可供插件绑定的、按 entry id 取配置的设置接口。

dsh plugin --profile web add github:zhang24xiao/dsh-snippets

然后重启 Web 界面。从本地检出安装:

git clone git@github.com:zhang24xiao/dsh-snippets.git
dsh plugin --profile web add link:$PWD/dsh-snippets

构建产物 lib/index.js 与 client/client.js 已入库,所以用 github: 安装不需要任何构建步骤。

各部分的位置

界面 DSH 席位
快捷开关 + 管理面板 sidebar.footer.action,展开时是一整行:</> 图标 + 「代码片段」
设置 plugins.bundle.config —— 插件管理里本包页面上的可折叠设置卡片
编辑器、确认框、提示条 shell.overlay
代码片段库 profile 设置文档里的 dsh-snippets 命名空间
备份、Gist Token、监听映射 $DSH_HOME/dsh-snippets/

布局说明

  • 侧栏底部的开关按列宽分两种形态,两种都对着设置行量尺寸:

    • 展开态是一整行:高 42px、内边距 0 10px 0 8px、图标与文字间距 8px、圆角 12px、 字号 14px / 行高 22px —— 与设置行逐字段相同,所以两行的图标与文字落在同一列上。
    • 收起态是一个 36×36 的圆形图标,外边距 8px 0 10px,与设置轨道里的圆形按钮一致。

    数量信息由展开态的文字承担,悬停提示仍会报出总数与已启用数。

  • 展开态那 4px 的左右外扩(width: calc(100% + 4px); margin: 4px -2px)是从设置行自己的容器抄来的: 少了它,本行整体会比设置行右移 2px。「图标、文字对齐」在像素上就是这两条。

  • 侧栏外壳把底部区域排成纵向,但 sidebar.footer.action 这一行在收起为 56px 轨道时仍然是横向的。 只有一个条目时看不出来,有两个就会并排溢出。因此本插件注入了一条范围很窄的规则,把收起状态下的这一行改回纵向; 同一容器在展开态还得允许换行,否则一个整行宽的条目(本插件,或 dsh-mobile 的「移动访问」) 会把邻居挤到侧栏边缘之外,被外壳的 overflow 裁掉:

    html [class*='_footerActions']             { gap: 6px; flex-wrap: wrap; }
    html [class*='_collapsed'] [class*='_footerActions'] { flex-direction: column; gap: 4px; … }
    

    用属性子串选择器是有意的:外壳的类名哈希一旦变化,这条规则只是不再命中(轨道回到官方布局), 不会把界面弄坏。

CSS 与 JS 如何生效

  • 每条启用的 CSS 片段对应 <head> 里一个 <style data-dsh-snippet="<id>"> 元素。 切换开关只会增删那一个元素,所以 CSS 立即生效、立即还原,无需重载。
  • 每条启用的 JS 片段在每次页面加载时用 new Function 编译并执行一次。 没有沙箱,也无法撤销 —— 这与「把代码粘进浏览器控制台」是同一套信任模型,而这正是该功能的意义。 所以停用、修改或删除 JS 片段时会提示需要重载;autoReloadAfterJsEdit 可以自动完成重载。
  • window.__dshSnippets 暴露 { version, log, reload },供片段使用。
  • 卸载插件会移除它注入的全部 <style>;已执行的 JS 无法撤销 —— 它本来就无法撤销。

安全说明

  • 代码片段数据只走官方设置通道。插件没有为浏览器新增任何可写片段接口, 因此在局域网或隧道部署下,未配对的访问者无法通过某个路由往别人的页面注入代码。
  • 插件自己的接口(/snippets/api/*)只做浏览器做不到的三件事:读监听目录、调用 GitHub、打开备份目录。 这些接口只响应本机(loopback)请求;通过局域网或隧道访问时,对应设置分区会自行禁用并说明原因。
  • GitHub Token 存在宿主本机的 $DSH_HOME/dsh-snippets/gist-token.json,权限 0600。 它不会进入设置文档,不会到达浏览器,界面只知道「是否已配置」。

与 TCOTC/snippets 的差异

三项设置描述的是 DSH 没有的思源功能:

思源 DSH
代码片段的「发布服务」开关 移除 —— DSH 没有发布概念
「打开原生代码片段窗口」 替换为「打开备份文件夹」
监听目录仅支持相对路径 支持绝对路径与 ~(DSH 宿主就是普通 Node 进程)

开发

pnpm install
pnpm run check     # 类型检查 + 构建 + 四套测试
pnpm run watch     # 改动后自动重建

npm run test 运行四套测试:

  • test/host.test.mjs —— 插件挂载(导出的 Config schema、解包后的 volatile 字段、设置 presentation 的 owner、路由、两个配置提交信号)、监听设置变化后文件夹监听器的重新武装、每条路由的 loopback 围栏、 备份、文件夹镜像(含多次扫描的 ID 稳定性)、Gist 导入计划、内容校验。
  • test/cordis.test.mjs —— 把构建好的宿主产物挂进真实的 @deepseek-ai/cordis, 并复刻 loader 自己的 volatile 提交,让 Context.filter 真正参与投递判定。它钉住两件假 ctx 证明不了的事: loader 过滤后的 loader/volatile-update 能到达本插件、而挂在 root 上的监听器收不到(阴性对照); 真正重新武装监听器的是 settings/document-updated,并且按命名空间放行。
  • test/client.test.mjs —— 在 jsdom 里按 window.__ModuleLoader__.load 的真实方式加载构建产物 client/client.js, 并驱动片段运行时:启用的 CSS 片段恰好产生一个 <style>,启用的 JS 片段恰好执行一次, 停用只移除对应元素,类型总开关能拦截注入,卸载后不留残留; 随后对三个已注册席位做服务端渲染,渲染路径的问题会在这里暴露而不是等到界面上。
  • test/client-modules.test.mjs —— 把本包清单交给真实的 @deepseek-ai/dsh-client-modules 注册表 (用一个临时的 node_modules/dsh-snippets 软链还原 profile 的解析环境),把浏览器半的整条契约钉住: 合成出的 boot graph 里有 dsh-snippets、clientPath() 指到本包的 client/client.js、 dsh.client.inject 原样穿过清单解析且保持顺序、按公布的 rev 能从 /plugins 取到真实 bundle (换个 rev 则 404)。它同时证明这张图由 Loader 记录驱动,而不是"磁盘上有包"就会进去。

许可证

MIT

内容来自项目 README(GitHub)↗

评论

评论存放在 GitHub Discussions。用 GitHub 账号登录后可发表评论或点表情。