安装
在 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 插件契约重写。
截图
快捷开关就在侧栏底部,与「设置」一样占满一行,点开是管理面板:

编辑器是 CodeMirror 6 —— 行号、CSS/JS 高亮、搜索替换 —— 按视口自适应,并支持 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,与设置轨道里的圆形按钮一致。
数量信息由展开态的文字承担,悬停提示仍会报出总数与已启用数。
- 展开态是一整行:高 42px、内边距
展开态那 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—— 插件挂载(导出的Configschema、解包后的 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
评论
评论存放在 GitHub Discussions。用 GitHub 账号登录后可发表评论或点表情。