dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
对 DSH 投放到侧边栏顶部、侧边栏底部、对话标签、输入框停靠行与设置页导航的插件按钮做拖拽排序、官方/第三方分隔线与按钮收纳。只改变显示位置,不改动插件注册表。
English: README.en.md
一个 DSH 客户端插件:帮你把插件按钮拖到想要的位置、在官方与第三方之间画一条分隔线、把不常用的收起。它只改变按钮的显示位置——不卸载、不启停任何插件。DSH 自带「更多」菜单里的按钮同样可以整理。
适配 DSH>=0.1.7-rc.2:0.1.7-rc.2起的每个0.1.x、0.2.x构建(含全部 rc 与0.2.1正式版)都用同一份代码,不需要为版本切换装不同包。
与「更多」菜单相关的能力(「进更多」「出更多」、「分开收纳」、「更多菜单里的分隔线」)只在宿主自带「更多」的版本上出现——那是 0.2.1-rc.3 起才有的东西。更早的宿主上这些入口直接不画,其余功能照常。DSH 把插件按钮投放到五处槽位,本插件对这五处一视同仁;侧边栏顶部与对话页右上角各自的「更多」菜单里的按钮也能整理(见第 3 节):
位置 · 槽位 · 说明 侧边栏顶部按钮 · sidebar.panellist · 侧边栏「插件 / 定时任务 / SSH / MCP 连接器」那一列 侧边栏底部按钮 · sidebar.footer.action · 侧边栏底部、设置入口上方的图标按钮 对话标签按钮 · conversation.view · 对话页顶部「对话 / 轨迹 / 上下文 / 编队」那一排 对话输入框停靠行按钮 · conversation.composer.dock · 输入框下方那一行 设置导航按钮 · settings.section · 设置弹窗左侧的导航行
z-index 1010),其余在 body 级(z-index 90),不会压过官方弹窗。Ctrl/Cmd + Shift + O;网页端 Windows / macOS 为 Ctrl/Cmd + Shift + Alt + O,Linux 为 Ctrl/Cmd + Shift + ,;均可在设置里重绑);屏幕右缘、顶栏正下方的悬浮启动器(可拖到任意位置,松手吸附到较近的左 / 右边缘并保留纵向位置);设置页「已收起的按钮」区域。min(520px, 92vw)、高 min(720px, 84vh)):标题、搜索、排序与「全部恢复」钉在顶部,只有列表区滚动,条目再多也不会把面板撑高。设置 → 插件布局整理(本插件在插件管理器的详情面板里也有同一设置页):
SegmentedControl——整条是浅灰圆角槽(--dsw-alias-interactive-bg-hover),选中项是浮起的药丸(--dsw-alias-bg-layer-1 加 --dsw-elevation-soft 阴影、加粗近黑字),未选中项只有灰字、悬停才转近黑。两组——位置管理(已收起的按钮入口与五张位置卡片)与通用设置(各项开关与快捷键),默认停在位置管理。点击只渲染当前那一组,滚动位置与搜索词在切换时保留;搜索期间已收起的按钮入口卡片让位。v1.2.3);再往右是 导出配置(整个持久化状态写成 JSON 文件)、导入配置(版本不符的整体拒绝,不会半套用)、GitHub 仓库、问题反馈(打开本仓库的 Issues 页面)。放得下时四个按钮与标题同行靠右;窗口太窄放不下时整组掉到第二行、从左边开始与标题左边缘齐,不会甩到右侧留一片空档。本包是标准 DSH bundle,用内置插件管理器安装:
dsh plugin add dsh-plugin-layout-organizer或让 agent 调用 plugin_manager(action=install_bundle,target 指向本目录)。
装好后刷新页面。
需要 Node.js `>=24`(package.json 的 engines.node;构建依赖 Node 自带的 module.stripTypeScriptTypes,CI 与发版工作流也都用 Node 24)。
node build.mjs # 按 BUILD_ORDER 把 src/ 拼成 lib/client.js,并内联 assets/icons/ 图标
node --check lib/client.js
node test/smoke.mjs # 无头冒烟测试(伪造 DOM / React / ctx)
node test/navigate.mjs # 「设置」两步路由的行为测试
node test/accept.mjs # 源码形态验收探针(等价于 npm run build / npm run check / npm test。)
开 PR 或推送 master 会触发 .github/workflows/ci.yml,跑一遍与发版相同的闸门:构建 → 语法检查 → 校验已提交的 lib/client.js 与源码一致 → 三个测试,最后再加一次类型检查(npx -y --package typescript@6.0.3 tsc -p tsconfig.json,版本与 tools/ts-check.mjs 用的编辑器内置 TS 一致,按需下载,不写进 package.json、不产生锁文件);工作流只读,不发布也不建 Release。screenshots/ 由插件市场从仓库直接读取,改动要一并提交。
推送 v* tag 即可,.github/workflows/publish.yml 会自动构建、校验构建产物与源码一致、跑测试、发布到 npm(Trusted Publishing / OIDC,无需 token),并用 tools/release-notes.mjs 从 CHANGELOG.md 抽出对应段落创建同名 GitHub Release:
git tag vX.Y.Z && git push origin vX.Y.Z工作流是幂等的:npm 上已有该版本就跳过发布,Release 已存在就改写说明,可安全重跑。发版前记得三件事——package.json 升号、CHANGELOG.md 新增版本段与底部链接定义行、tag 名与版本号一致(CI 会校验,不一致直接失败)。
客户端包只能 require 启动图里已注册的种子词或包,不能按相对路径在运行时分块加载,因此本项目采用模块化源码 + 构建期拼接:
src/ 按职责拆成 types/、shared/、core/、drag/、ui/;build.mjs 持有显式 BUILD_ORDER 清单并按序拼接;var / function,所以显式列出而不是目录遍历推断(types/globals.d.ts 仅供类型检查,不参与拼接);module.stripTypeScriptTypes(transform 模式)擦除——没有打包器,也没有要装的依赖;lib/client.js,包裹在 window.__ModuleLoader__.load({ id, factory }) 里;assets/icons/ 存放从 iconfont 下载的 15 个图标 SVG,是构建输入:源码不手写 path,只写 @@svg:file.svg@@ 占位符(shared/icons.ts 七个菜单图标 + 四个标题行动作图标 + 两个搜索行图标 + 一个「出更多」动作图标;core/dom-project.ts 设置行自身图标为 @@svg:layout.svg@16@@)。build.mjs 归一化每个素材——viewBox 取自源文件、宽高默认 14(占位符可指定,标题行四个动作图标为 16、搜索行两个为 13 与 12)、写死的颜色改写为 currentColor、补 aria-hidden / focusable——再把 ` 内联进 lib/client.js。动作素材的画布留白差别较大,styles.ts 按素材名(data-ico)做光学校正,让一排按钮的图标看起来等高。layout.svg 同时是 package.json "icon" 指向的包图标;该目录在 files` 白名单里,装包后仍可重新构建。模块 · 职责 types/state.ts · DSH 服务(槽位 / locale / 布局 / 快捷键)与本插件状态的 TypeScript 形状,构建期擦除 types/globals.d.ts · 构建前言注入的全局声明(React、h、各 hook),仅供类型检查,不参与拼接 shared/constants.ts · 插件 id、存储键、五处槽位表、官方 id 白名单、DOM 标记名、z-index 常量等 shared/icons.ts · 七个右键菜单图标 + 四个标题行动作图标 + 两个搜索行图标 + 一个「出更多」动作图标的 @@svg:…@@ 构建占位符,构建时从 assets/icons/ 归一化内联 shared/locale.ts · 中英文案字典 core/store.ts · 状态形状(v5)、持久化、纯查询与命令(顺序、分组、收起、进更多与两级收纳) core/dom-rows.ts · 各槽位的行发现、账本读取、行打标与配对、几何计算 core/dom-line.ts · body 级官方 / 第三方分隔线的创建、定位与隐藏 core/dom-menu.ts · 仿 DSH 官方样式的右键菜单及其窗口级事件委托(排序、官方 / 第三方改判、进更多 / 出更多与收起 / 恢复) core/dom-project.ts · 投影:写标记与 style.order、收纳隐藏、分隔线调度、设置行自身图标 core/dom-navigate.ts · 重新打开被收起的按钮,含「设置」两步路由 core/organizer.ts · 调度中枢:rAF 合帧、MutationObserver、槽位订阅 core/plugin-icons.ts · 插件图标查询:把插件 id 对到宿主插件清单里登记的图标地址,供行首图标兜底 drag/drag-frame.ts · 两个拖拽控制器共用的手势管线:一帧最多重算一次的节流,加一组固定在 capture 阶段的监听 drag/drag-rows.ts · 界面行(DSH 各槽位按钮)的指针拖拽控制器 drag/drag-list.ts · 本插件设置页列表的指针拖拽控制器 ui/styles.ts · 样式注入与全部 CSS 规则 ui/kit.ts · React 基础控件(Icon / Switch / Field / Card / Chip / Btn / RowItem / ConfirmBtn) ui/search.ts · 搜索框与匹配判定(设置页与面板共用) ui/config-actions.ts · 配置导出 / 导入(版本校验)与仓库、Issues 地址 ui/scope-card.ts · 单张位置卡片:行列表、上下移、改判、收起、进更多与恢复本组 ui/shortcut-card.ts · 快捷键编辑器(录制、冲突提示、恢复默认) ui/settings-page.ts · 设置页外壳:标题行、顶部分页导航、两组内容装配 ui/stash.ts · 已收起的按钮面板(固定尺寸 + 搜索 + 列表滚动)与启动器 ui/more-menu.ts · 「更多」菜单里的本插件行:注册进宿主的菜单槽位,行可拖动 / 右键 / 点开;宿主自画的两项(浏览更多插件 / 创建你的插件)不参与整理,原样留给宿主 main.ts · 接线层:样式、locale、存储、槽位注册、快捷键、清理
register() 时一次性按 priority → order 排序槽位,事后改 order 不会重排;本插件直接给真实 DOM 行写 style.order 与标记属性,因此依赖官方 UI 结构,DSH 大版本升级后可能需要适配。registrant 不可靠(多个第三方包冒用官方标记),本插件内置官方 id 白名单,并允许在设置页手动改判任意行。data-composer-stats(旧宿主)或 data-composer-stat="activity"/"usage"(0.2.1 起把一条拆成了两条),token-saver 认 .st-strip。官方读数(旧宿主的 stats、新宿主的 activity 与 usage)与 7% 用量百分比(context-meter)各自收起、互不牵连,用量百分比分类归官方。ROW_LABELS,跟着界面语言走),不是把 id 直译成中文。ROW_HOOKS 的记录——这两条记录在停靠行容器里认不到元素,于是既不进卡片、也不留给已收起的按钮一条永远恢复不出来的影子行;同理,以后再有「注册在这个槽位、渲染在别处」的插件也自动适用。对话框内插件的隐藏与收起尚未实现。MIT