DSH 地址栏路由插件Web 与 Windows 桌面版——…
30.8/100
综合分
1
GitHub 星标
934
npm 周下载
—/5
用户评分
数据截至 2026/10/26 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add dsh-url-routernpm 源 · dsh-url-router 的发布者账号已校验与本仓库一致
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · chat
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 8 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✓npm 包dsh-url-router @ 0.2.0
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/10 21:29:03
安全扫描自动 · 静态分析源码v2.7.0🟢 扫描:未发现敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描未发现敏感能力:最多只发网络请求、读取自身元数据或只读文件,未发现执行命令、文件写入或敏感信息读取。
写入剪贴板(不计风险)
查看扫描证据(共 1 处,展示前 1 条)
- 写入剪贴板lib/client.js:4703
pending = Promise.resolve(clipboard.writeText(text))
扫描于 2026/11/2(1 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 界面与URL一一对应
- 地址栏显示当前界面
- 链接直达对应界面
最近更新
在 GitHub 查看全部 →v0.4.32026-10-29
· 新增
· #/power 打开电源菜单,#/power/shutdown / #/power/restart 执行关机 / 重启,这些与 dsh-power-menu-mac 联动,只有安装了 dsh-power-menu-mac 才能使用。
· 地址栏可设为「悬浮才显示」。
· 设置路线支持任意层:分区 → 页签 → 子行 → 筛选 → 模型编辑卡。
· 子代理会话的链接带上父会话标题。
· 没有 ARIA 标记、只有样式类的行也能写出链接。
· 修复
· 设置面板打不开的几种情况。
· 设置页签层与子行读不到。
· 「打不开」误报。
· 会话视图页签被折叠进「…」时写错视图段。
---
· Added
· #/power opens the power menu, and #/power/shutdown / #/power/restart perform shutdown / restart. These are integrated with dsh-power-menu-mac and are only available when dsh-power-menu-mac is installed.
· The address bar can be set to "show only on hover."
· Settings routes support arbitrary levels: partition → tab → sub-row → filter → model editing card.
· Links to sub-agent sessions include the parent session title.
· Rows that have no ARIA markup and only style classes can also have links written for them.
· Fixed
· Several cases where the settings panel could not be opened.
· The settings tab level and sub-rows could not be read.
· False positives for "cannot open."
· Incorrect view segment written when session view tabs are collapsed into "...".
v0.4.22026-10-26
相对 0.4.1:新增「首次点击全选 + 最近界面/粘贴链接列表」、「自动化任务」与「模型页提供商卡片」的链接、「兼容自检」;修复轮次跳转(rc.3 上静默失效)与 macOS 地址栏挡住页面控件的问题;并做了一轮性能优化。
· 新增
· 地址栏偏好(在插件管理器里本插件那一行的配置控件中调整)
- 首次点击地址栏全选链接,可关(像浏览器地址栏)
- 最近用过的界面与粘贴过的链接列表:默认 8 条,可设 0 关闭、不设上限;左键跳转、右键复制完整链接
· 自动化任务面板:#/panel/schedules,状态筛选(全部 / 已开启 / 已结束)、任务详情、规则 / 运行记录页签都进链接
· 模型页的提供商卡片:点「编辑」展开的那张卡写进地址栏(#/settings//provider/)
· 兼容自检:官方改了 DOM 契约时不再静默失效 —— 每类只警告一次,控制台与 report().compat 都能看到
· 修复
· 轮次跳转恢复:修掉官方 rc.3 上 loadThrough 方法绑定导致的静默失效;翻页回到目标轮后自动滚到它;链接落地后不再把轮次从 URL 里抹掉
· macOS 地址栏让位:没有电源按钮的界面(插件页 / 面板页 / 设置页)按当前那一行重新量空段,不再压住页面控件(例如任务详情的页签)
· 右栏 pane:收起时不再写进链接;kind 以控制器为准,不再出现 pane/client.js 这类错值
· 复制链接:右键复制给出完整 URL;剪贴板失败时的回退路径不再抢焦点、不再关掉列表
· 自动化任务:任务被当前筛选藏起来时,链接会先把筛选放宽,而不是干等到过期
· 性能
· DOM 通知合并到一帧一次(流式回答时不再每批重读整个页面)
· 标题行只在形状变化时重新测量;最近列表一次扫描侧栏
· report().work 给出 reconcile / 摆放次数,便于自查
测试 132 项通过。
---
Relative to 0.4.1: added "first-click select-all + recent interfaces/pasted links list", links for "automation tasks" and "provider cards on the model page", and "compatibility self-check"; fixed round jumping (silently failing on rc.3) and the macOS address bar blocking page controls; and did a round of performance optimization.
· Added
· Address bar preferences (adjusted in the configuration controls for this plugin's row in the plugin manager)
- First click on the address bar selects the entire link, can be disabled (like a browser address bar)
- List of recently used interfaces and pasted links: 8 by default, can be set to 0 to disable, no upper limit; left-click to jump, right-click to copy the full link
· Automation task panel: #/panel/schedules, status filters (all / enabled / ended), task details, and rules / run records tabs all included in the link
· Provider cards on the model page: the card expanded by clicking "Edit" is written into the address bar (#/settings//provider/)
· Compatibility self-check: no longer silently fails when the official DOM contract changes — warns only once p
v0.4.12026-10-26
macOS 兼容版,与 0.4.0 的 Windows 标题栏地址栏平行。
macOS 没有页面里画的标题栏 strip(标题栏是原生的),地址栏改画进会话页的常驻标题行:量出行内所有占位元素、取最宽空白段,右对齐贴住头部按钮,两侧各内缩 25px,宽度封顶 1150。
Windows 行为不变。测试 99 条通过。
---
macOS-compatible version, parallel to the Windows title-bar address bar in 0.4.0.
macOS has no title-bar strip drawn in the page (the title bar is native), so the address bar is instead drawn into the session page’s persistent title row: measure all inline placeholder elements, take the widest blank segment, right-align it flush against the header buttons, inset 25px on both sides, and cap the width at 1150.
Windows behavior is unchanged. 99 tests pass.
数据来自仓库的 GitHub Release,可能与插件实际版本不一致。
README
由 DeepSeek 最新模型翻译生成dsh-url-router
DSH 地址栏路由插件(Web 与 Windows 桌面版)—— 每个界面都有自己的链接:地址栏写着屏幕上的东西,链接点开就是那个界面。 给 DeepSeek Harness (dsh) 补上「可寻址」:点侧栏会话,地址栏变成 #/session/<id>;点插件面板,变成 #/panel/plugins;点进某个插件、某个组件、某个任务,地址栏跟着一起走。把这条链接贴到新标签页、或者对着侧栏任意一行右键,就是浏览器自己的行为——无需复制按钮、无需自定义菜单。桌面版(Windows)自己没有地址栏,本插件就把它画在标题栏那条空白里。
它是地址栏的唯一写者:只改 URL 的 fragment,路径与查询串(例如启动时的 ?token=…)原样保留;只用 replaceState,浏览面板不会往后退栈里塞历史。只有浏览器半区——零依赖、无宿主路由、无遥测。
展开完整文档(README 剩余 1 节)
dsh-url-router
DSH 地址栏路由插件(Web 与 Windows 桌面版)—— 每个界面都有自己的链接:地址栏写着屏幕上的东西,链接点开就是那个界面。 给 DeepSeek Harness (dsh) 补上「可寻址」:点侧栏会话,地址栏变成 #/session/<id>;点插件面板,变成 #/panel/plugins;点进某个插件、某个组件、某个任务,地址栏跟着一起走。把这条链接贴到新标签页、或者对着侧栏任意一行右键,就是浏览器自己的行为——无需复制按钮、无需自定义菜单。桌面版(Windows)自己没有地址栏,本插件就把它画在标题栏那条空白里。
它是地址栏的唯一写者:只改 URL 的 fragment,路径与查询串(例如启动时的 ?token=…)原样保留;只用 replaceState,浏览面板不会往后退栈里塞历史。只有浏览器半区——零依赖、无宿主路由、无遥测。
中文 · English
安装
通过插件管理器(推荐)
dsh plugin --profile web add dsh-url-router
重启 dsh web,之后硬刷新浏览器
开发时也可以直接挂工作树:
dsh plugin --profile web add "link:/path/to/dsh-url-router"
已登记进社区插件索引 ✓ —— zhu1090093659/dsh-community-plugins 的 community.json 是本插件在 DSH Workshop 商店与 dsh-market.com 清单里的唯一数据源 ✓(登记条目 dsh-url-router,ui/panel ✓)。
路由表
| 地址 | 界面 | 由谁打开 |
| #/session/<id> | 主视图里的那个会话 | uiWorkspace.openSession(id) |
| #/panel/<panelId> | 主面板(plugins、task-board、skill-explorer、ssh …) | layout.selectPanel(id) |
| #/panel/plugins/<包名> | 某个已安装插件的页面 | 面板自己的列表行控件 |
| #/panel/plugins/<官方项 id> | 某个官方内置插件的页面(shell、agent-loop、subagent、web-search) | 面板自己的列表行控件 |
| #/panel/plugins/<包名>/<组件 id> | 插件页面里的某个组件页 | 面板自己的组件行控件 |
| #/panel/task-board/task/<任务 id> | 任务看板里某个任务的详情 | 任务看板自己的 dsh-taskboard-open-task 窗口事件 |
| #/panel/task-board/new | 任务看板的新建任务表单 | 任务看板自己的 dsh-taskboard-new-task 窗口事件 |
| #/panel/schedules/filter/<all\|active\|inactive> | 自动化任务的状态筛选(已开启 / 已结束;默认的 all 不写进链接) | 面板自己的筛选按钮(按位置,语言无关) |
| #/panel/schedules/task/<任务 id> | 自动化任务里某条任务的详情(规则页) | 面板自己的任务行 |
| #/panel/schedules/task/<任务 id>/records | 同一条任务的「运行记录」页(默认的 rule 不写) | 面板详情里的页签 |
| #/settings/<分区>/provider/<提供商 id> | 模型页里点了「编辑」展开的那张提供商卡片(id 是配置里的 key,不是显示名) | 卡片自己的「编辑」按钮 |
| #/session/<子会话 id>/subagent-of/<父标题> | 子代理会话:一眼看出它是谁的子代理(父是装饰,打开的是子会话;父没标题时退回父 id) | 聊天里的子代理卡片 |
输入侧宽容:sessions/panels 复数、百分号编码都接受,一律规范化成上面的形式。不认识的段位不碰,只留一条诊断(留给以后的路由器,或者别的插件写的深链形态 ✓ —— 一个 fragment 只能有一个写者 ✓,所以读到不属于本插件的形态时会明确说一句,而不是静默 ✗)。
面板内部页是面板自己的词汇表,本插件不发明:插件管理器发布 data-plugin-detail / data-plugin-item-detail / data-plugin-row-detail,任务看板发布 data-dsh-taskboard-open-task / data-dsh-taskboard-new-task,并接受同名窗口事件;自动化任务面板的三态筛选只有 aria-pressed(按钮上没有值),所以链接里写的是官方那三个固定值的位置(all / active / inactive),换语言不影响;任务详情用行上的 aria-expanded 与 aria-describedby 末段的 id 认,页签用它自己的 data-detail-tab="rule|records"。
右栏 pane 是页面旁边的一层,不是页面本身 ✓:面板一旦有自己的页(任务详情、插件页…),地址栏就只写那一页(#/panel/schedules/task/<id>/records),旁边开着右栏也不会多出 pane/…;只有面板没有自己的页时才写 pane/<kind> ✓。右栏收起时那一层直接不写(收起的右栏会把页签留在 DOM 里,旧版因此把 pane/client.js 这种已经不在屏上的东西写进了地址栏);pane 的 kind 优先读右栏控制器里的 {kind},因为 Files 页签在打开文件后标题会变成文件名(client.js),拿标题当 kind 就是错的。
每一行都是真链接
侧栏的会话行、插件面板的列表行(已安装组与官方组)都是整行覆盖的透明真锚点:
- 右键 → 浏览器原生菜单(在新标签页中打开 / 复制链接 / 另存为)
- 中键、Cmd/Ctrl + 单击 → 原生新标签页
- 左键单击 → 在本页打开(preventDefault 后调官方导航,不新增历史记录)
桌面版的地址栏
DSH 桌面版(Windows)的标题栏画在网页里:preload 给 打上 data-windows-titlebar、给出 --dsh-windows-titlebar-height,菜单条本身是页面里的一个 shadow DOM 固定元素([data-windows-menu])。那条 strip 里的空白是页面空间,而桌面版自己没有地址栏 —— 于是本插件把地址栏放在那儿:
- 只在 html[data-windows-titlebar] 存在时出现 ✓(纯 Web 版什么都不画 ✓)。
- 位置:紧跟 shell 自己的菜单条右侧 ✓、右端避开窗口按钮 ✓;高度取 --dsh-windows-titlebar-height ✓;-webkit-app-region: no-drag 保证能点 ✓。
macOS 桌面的地址栏
macOS 的标题栏是原生的(左边红黄绿三个灯),页面里没有 Windows 那条 strip 可以借。但会话页顶部有一行常驻的标题行(面包屑 + 模式标签 + 右侧按钮 + 电源按钮),地址栏就落在那行里:
- 判定:shell 给 打上 data-platform=darwin(或 UA 是 Mac)并且(UA 里有 Electron/<x> 或页面跑在 dsh-app: 协议上)→ 只有桌面 App 满足,浏览器里开 Web 版不画 ✓。(实测桌面版会把 UA 里的 Electron/<x> 抹掉,所以真正生效的是 dsh-app: 那条 ✓。)
- 位置:先量这一行里所有真正占位的东西(有自己文字的元素、按钮、图标),按左边界排序并合并重叠 → 得到若干空白段 → 取最宽的那一段,右端贴着头部按钮、左端跟着走,两边各留 25px 内缩 ✓。
- 宽度封顶 1150px:空白段的左边界是跟着会话标题长度跑的 ✓,不封顶的话换个会话框就变一次宽 ✓;放不下时按实际空白缩 ✓。
- 和电源按钮同一行(垂直居中于它 ✓),position: fixed —— 所以既不遮挡也不挤压任何东西 ✓。
- 没有电源按钮的界面(插件页、设置页、面板页):按当前屏幕那一行重新量 ✓ —— 扫描这一行上的控件与标题,取最宽的空段放框(自动化任务详情的「规则 / 任务运行记录」页签不会再被压住 ✓);一段都不够宽就隐藏 ✓,宁可不画也不压在可点的东西上 ✓。窗口尺寸变过(> 8px)时旧数据一律不信 ✓,等回到会话页重新量 ✓。
- 只有一个框 ✓:挂载前先按 id 摘掉旧的 bar 和样式表 ✓,所以 effect 重跑多少次(热重载、重复 apply)都只有一个 ✓。
- Windows 那条路径完全不变,data-windows-titlebar 优先,两种形态互斥 ✓。
- 输入、反射、拒识、Escape 恢复的逻辑与 Windows 版共用同一份代码 ✓。
- 输入什么 ✓:任何 #/… 路由(会话 / 工作区 / 视图 / 轮次 / 行 / 面板 / 设置三层 / 右栏 pane)、裸会话 id、或整条链接(只取它的 fragment)✓;回车写 hash → 浏览器触发 hashchange → 落地走的就是"粘贴链接"那条已验证的路 ✓。
- 它同时是反映 ✓:本插件每次写地址栏都会同步进这个框 ✓,所以它显示的就是"现在在哪" ✓。Escape 还原 ✓;认不出的文本不动地址栏 ✓。
设置页:地址栏的两个偏好
在插件管理器里找到本插件那一行 → 右侧的配置箭头(也就是 #/panel/plugins/dsh-url-router/dsh-url-router)就是本插件的设置页。两个偏好跟着这台机器走(localStorage),改完立刻生效,不用重启:
| 偏好 | 默认 | 说明 |
| 首次点击地址栏时全选 | 开 | 像浏览器地址栏:第一次点进去,框里原来的链接整条选中,直接输入就替换它;已经聚焦时再点,才是放光标。关掉后就是一个普通文本框。 |
| 记住最近链接的条数 | 8 | 下拉框里能看到的条数(地址栏里正显示的那个界面不算 —— 它已经在你眼前了,离开之后才会回到列表)。最低 0(= 不记忆,地址栏也不再弹最近列表),没有上限。 |
最近列表的用法与浏览器一致:点地址栏就弹出来,输入即过滤,Esc 关掉;条目有两个来源 —— 用过的界面(本插件写进地址栏的每一个界面 ✓)和粘贴过的链接(在地址栏里粘贴任何本插件认得的链接或裸会话 id ✓,落地与否都先记住 ✓)。
左键 = 跳过去,右键 = 复制链接 ✓:右键那一下会吃掉浏览器菜单 ✓,直接把完整 URL(路径 + 启动 ?token=… + fragment ✓)放进剪贴板 ✓,粘到新标签页或发给别人就能开 ✓;被复制的那一条会短暂显示「已复制 ✓」✓,地址栏右端也会闪一下「已复制链接」✓(列表不会因此关掉、光标也不会跑 ✓)。
- 身份是界面,不是坐标 ✓:#/session/<id>/turn/3/row/… 这类点位链接归并到它所在的会话 ✓,不会用同一个对话把列表刷满 ✓;同一界面再次出现只是提到最前 ✓,不重复 ✓。
- 当前屏幕不列出来 ✓(它不是一个"回去"的地方)。
- 条数就是下拉框里能看到的条数 ✓:磁盘上多留一个缓冲位给"当前界面" ✓,所以设 8 就真能看到 8 条 ✓(不是 7 条 ✗)。调小会立刻裁掉多余的 ✓;调到 0 会清空并不再记录 ✓。
- 会话条目显示侧栏里的对话标题 ✓(读不到标题时才只显示链接 ✓);面板 / 设置等段位显示中文类别 + 链接本身 ✓。
- 页面里还有「清空记录」按钮 ✓。
- 存在这两个键里:dsh-url-router-settings 与 dsh-url-router-recent ✓ —— 换浏览器配置就没了,符合"这台机器、这个窗口"的语义 ✓。
- 粘链接不会按到开关 ✓:插件行的启用开关就在配置控件旁边,两个都是 ✓ —— 驱动组件页时只点非 role="switch" 的控件 ✓,所以开不到的组件页链接会按时过期并留一条诊断 ✓,不会顺手把插件关掉 ✓(实测踩到过 ✓)。
它守的规矩
- 只动 fragment:路径与查询串从不改写(启动 ?token=… 能活下来)。
- 唯一写者:本插件拥有 fragment,请不要和别的写 fragment 的插件同时启用(例如 dsh-session-url),两者会互相覆盖。
- 只用 replaceState:浏览面板不污染后退栈。
- 链接落地前,挡在前面的表面先让开 ✓:主面板选中时地址栏读到的就是面板 ✓,设置浮层在屏时读到的就是 #/settings/<分区> ✓ —— 这两种情况下会话其实已经在背后打开了 ✗,屏幕上却像“没反应” ✓。所以驱动任何非设置链接之前 ✓,先 beginNavigation() + selectPanel(null) 让面板退场 ✓,再用官方自己那条 document 级 Escape 把设置浮层请走 ✓(模态栈是官方内部的私有注册表 ✗ 外部拿不到 ⇒ Escape 是浏览器侧唯一可用的官方关闭路径 ✓,也就是你按 Esc 走的那条 ✓)。一条链接只按一次 ✓:不会在你正在操作页面时乱按键 ✓,代价只是万一那次没关掉、你再粘一次 ✓。设置自己的链接不动浮层 ✓。
- 轮次信息:能证明才写 ✓。助手行自己的身份里就带轮次(row/assistant/80/32 = 第 80 轮第 32 项 ✓);工具行不带 ✗(只有调用 id ✓)→ 于是我从视图的轮次边界 [data-turn-start] 反推 ✓,但只在行夹在两个已渲染边界之间时才写 ✓(turn/82/row/tool/call/… ✓)。视图是虚拟化的 ✓,边界可能只渲染了一侧 ✗ → 那时宁可不写轮次 ✓,也绝不猜一个错的轮次 ✗。
- 轨迹里的每一行都有自己的链接 ✓:#/session/<id>/row/<类>/<作用域>/<id>(例:row/tool/call/call_ce3a…、row/assistant/80/32 = 第 80 轮第 32 项 ✓;有工作区时跟在会话 id 之后 ✓)。身份来自视图自己发的 data-trajectory-row-key ✓(值是 <类>%00<作用域>%00<id> ✓,我把它拆成可读路径 ✓);你家 Trajectory Plus 发的是 data-dshts-turn(轮号 ✓)→ 那种行按轮次写(turn/<n> ✓)。点一行就反映进地址栏 ✓(纯被动:不 preventDefault ✓)。粘贴行链接会打开那个对话并尽力滚到那一行 ✓ —— 视图是虚拟化的 ✓,没渲染出来的行不会被假装滚到 ✗(不会骗你 ✓)。
- 会话视图(对话 / 轨迹 / 轨迹plus …)也进地址栏 ✓:#/session/<id>/view/<viewId>(有工作区时是 #/workspace/<名>/session/<id>/view/<viewId> ✓)。视图 id 是真的 id ✓(来自槽位 conversation.view 的 id 字段 ✓,按 order 排序后与头部页签一一对应 ✓):实测本机是 chat / trajectory / surface(Trajectory Plus ✓)/ plus2(Trajectory Plus 2 ✓)。默认视图(第一个 ✓)不写进链接 ✓,所以普通对话链接保持短 ✓。粘贴视图链接会真的切过去 ✓(与其它覆盖层不同:这是链接存在的意义 ✓)。
- 工作区是“它住在哪”,所以写在链接最前面 ✓:#/workspace/<工作区名>/session/<会话id>(侧栏本身就是这个形状 ✓)。工作区名是给眼睛看的 ✓ —— 决定打开哪个会话的永远是会话 id ✓,所以名字过期/写错也照样打开对的会话 ✓(地址栏随后自己纠正成真实工作区 ✓)。读不到工作区行(没有侧栏 / 树里没有)就不猜 ✓,退回 #/session/<id> ✓。
- 作用域由视图决定,不靠猜:主面板是应用级界面(列的是本机插件,不是某个对话),所以它的链接不带会话 id。
- 链接落地即交权:视图一旦变成链接描述的那个界面,链接立刻失去权威——这样你在面板里继续点进去时,地址栏不会被拽回上一层。
- 绝不抛错:官方 selectPanel 对未注册的面板 id 是抛异常的;所有宿主面调用都被容纳,失败只留一条诊断并回落到屏幕上真实的视图。
- 侧栏扫描有预算 ✓:一帧内的多次 DOM 变更合并成一次扫描 ✓;只带文本/普通元素的批次直接跳过 ✓(流式输出不会一帧扫一次 ✓);工作区归属一趟遍历解决 ✓(不是每行走一遍树 ✗);已挂锚的行不再重挂 ✓,锚点被视图丢掉时下一趟自动补回 ✓。
已知限制
- 轮次链接是“位置”,而且现在真能跳 ✓:点某一轮,地址栏记下 #/session/<id>/turn/<n> ✓;粘贴它会打开那个对话、把历史翻页回那一轮、再滚到它 ✓(真机实测:贴 /turn/118 → 窗口变成 118→121、目标在视口 true、最顶可见正是 118 ✓)。用的是官方已有公开契约 ✓:sessions.retainScope(id, source) 拿到会话控制器 ✓ → session.projections.faceOf('turnOutline') 读到那一轮的 seq ✓ → session.loadThrough(seq) 翻页回去 ✓(完事 reference.release() ✓)→ 再按官方视口同款选择器 [data-chat-turn]:not([hidden]) 滚到它 ✓。座位高度/相交都读不到时不算到位 ✓,宁可继续重试也不假报 ✗。
- 右栏 pane 已闭环 ✓:#/session/<id>/pane/<kind> 与 #/panel/<面板>/pane/<kind> ✓(真机验证:贴链接开出对应页签 ✓、地址栏跟着切换 ✓)。页签种类由右栏自己注册 ✓(实测 7 种:guide / subagentchat / changes-review / plan / files / text / terminal ✓)。
- 设置面板已纳入:#/settings ✓、#/settings/<分区> ✓、#/settings/<分区>/<页签> ✓(页签靠标准 role="tab" + aria-selected ✓,分区内任何页签都吃这一套 ✓)。分区没有稳定 id ✗(实测:导航项上只有 aria-current="true" ✓,父链是 nav ✓,右侧内容区一个 data- 都没有 ✗;官方内部的 openSection(id) 也不对外 ✗)→ 所以分区的身份就是它的显示名 ✓:反映读「aria-current="true" 且属于 nav」的那个按钮的标签文字 ✓,驱动按标签点 ✓。含义:换语言或官方改文案后,旧的分区链接会失效 ✗(但你重新点一次,地址栏就会写出新链接 ✓ —— 自洽、不过期 ✓)。裸 #/settings 只要面板开着就算落地 ✓,随后地址栏自动升级为具体分区 ✓。
- 设置页分区的身份只有显示名(上一条的含义,别当成 bug 去找官方要 id ✗):官方那个 openSection(id) 里的 id 不对外 ✗,DOM 上也没有任何 data- ✓ —— 所以链接里写的就是用户读到的那行字 ✓,官方改文案或换语言后旧链接失效是设计如此 ✓。
- 会话内的轮次与行锚点已纳入 ✓:#/session/<id>/turn/<n> ✓(反映 + 翻页 + 滚动 ✓ 全链路已闭环)、#/session/<id>/row/<类>/<作用域>/<id> ✓(反映 + 尽力滚动 ✓,含可证明时的轮次归属 ✓)。轮次跳转用的是官方公开 API ✓,没有等待任何新接缝 ✓(uiChat.scrollToTurn 那条请求已降级为锦上添花 ✓,讨论见 <https://github.com/deepseek-ai/deepseek-harness/discussions/9339> ✓)。
- 技能中心 / SSH 的内部页:需要它们各自发布「当前实体 id + 按 id 打开」的契约(任务看板就是这么做的)。
- 和别的 fragment 写者互斥(例如写 #msg= 的「跳到消息」插件):一个 URL 只有一个 fragment ✓,两个写者只能轮流拥有 ✗。本插件不假装合并 ✓ —— 它认出外来 fragment ✓、绝不覆盖 ✓,并明确说「只能启用一个写者」 ✓(而不是互相静默擦掉对方的链接 ✗)。
- 链接同名不跨机:会话 id 只在同一台机器、同一个 DSH_HOME 下有意义。
开发
手写 JS 直接进 lib/(无构建步骤),npm test 直接跑交付产物(107 条用例,node --test)。改之前请读 AGENTS.md 里的路由与行链接契约。
排障
浏览器 Console 里调用 window.__dshUrlRouter.report() ✓,它会列出:当前地址栏 ✓、本插件认为屏幕在哪个界面 ✓、正在落地的链接与重试次数 ✓、每一层读到了多少个钩子 ✓、右栏 pane 的真实 kind 列表 ✓、它拒绝认领的段位 ✓、以及 compat(与当前 DSH 版本不兼容的层,见下)✓ 和 work(reconcile / 摆放次数,看性能用)✓。它绝不出错、也不写任何东西 ✓。
兼容自检 ✓:官方一改 DOM 契约,插件不会报错,只会静默不再给某一层写链接 ✗。所以渲染期会做五项检查(设置浮层标记、插件管理器钩子、自动化筛选组、会话页签容器、侧栏会话行)✓:屏幕上确实出现了那一层、但本插件要读的钩子没了 → 每个界面只警告一次 ✓,措辞统一为「与当前 DSH 版本不兼容」✓,同时记进 report().compat ✓。它只告警、不改行为 ✓。
DSH Web GUI 的 URL 路由 —— 每个界面都有自己的链接。 点开一段对话,地址栏就变成 #/session/<id>;点开一个面板(插件、任务看板……),它就变成 #/panel/<panelId>;走进插件、组件或任务,地址栏跟着走。把链接粘到另一个标签页,或者右键任意侧栏行,用浏览器自带的「在新标签页中打开 / 复制链接」。
它是 fragment 的唯一写者:路径和查询串(启动时的 ?token=…)从不碰,而且只调用 replaceState。只有浏览器这一半 —— 无依赖、无宿主路由、无遥测。
安装
dsh plugin --profile web add dsh-url-router
restart dsh web, then hard-refresh the browser
已收录进社区插件索引:zhu1090093659/dsh-community-plugins 维护 community.json,它是 DSH Workshop 商店目录和 dsh-market.com manifest 的唯一来源(条目 dsh-url-router,ui/panel)。
路由
| 路由 | 界面 |
| #/session/<id> | 主视图显示的对话 |
| #/panel/<panelId> | 主栏面板 |
| #/panel/schedules/filter/<all\|active\|inactive> | 自动化列表的状态筛选(默认的 all 不写入) |
| #/panel/schedules/task/<id> | 某个自动化任务的详情(规则标签页) |
| #/panel/schedules/task/<id>/records | 该任务的记录标签页(默认的 rule 不写入) |
| #/settings//provider/<provider id> | Models 中编辑器已打开的服务商卡片(用配置里的 id,不是显示名) |
| #/session/<child id>/subagent-of/<parent title> | 子代理会话,标明它是谁的子代理(父级只是装饰,无标题时回退到它的 id;打开的是子会话) |
| #/panel/plugins/<package> | 已安装插件的页面 |
| #/panel/plugins/<item> | 内置插件的页面(shell、agent-loop、subagent、web-search) |
| #/panel/plugins/<package>/<component> | 该插件页面里的某个组件页 |
| #/panel/task-board/task/<taskId> | 任务板上某个任务的详情 |
| #/panel/task-board/new | 任务板的新建任务表单 |
遇到不认识的类型就原样保留,只给一条诊断信息(一个片段只有一个写入方,所以外来形状会被点名,而不是悄悄忽略)。面板内页是面板自己的词汇:插件管理器发布 data-plugin-detail / data-plugin-item-detail / data-plugin-row-detail,任务板发布 data-dsh-taskboard-open-task / data-dsh-taskboard-new-task。
每一行都是真正的链接
会话行和两个插件列表分组都带一个透明的整行锚点:右键弹出原生菜单,中键 / Cmd 点击打开原生新标签页,普通左键点击原地跳转,不新增历史记录。
桌面端地址栏
Windows 桌面窗口在页面内绘制自己的标题栏:preload 标记 并发布 --dsh-windows-titlebar-height,它的菜单是页面里一个固定的 shadow-DOM 元素([data-windows-menu])。这条区域属于页面空间,而桌面窗口没有自己的地址栏——所以这个插件在那里放了一个:
- 只在 html[data-windows-titlebar] 存在时绘制(纯 Web 应用里什么都不画)。
- macOS 桌面版没有页面内的条带可借用,于是地址栏变成一个浮动胶囊:钉在原生标题栏正下方、窗口右上角,380×30,圆角、模糊、带阴影。识别依据是 shell 的 标记(或 Mac 的 user agent),加上当前窗口就是应用本身——user agent 里有 Electron 或使用 dsh-app: 协议——所以浏览器里的 Web 应用永远不会画它。它落在 shell 在框架上方预留的 48px 内(--dsh-frame-top-clearance),避开红绿灯按钮。两种形态共用一套代码路径;Windows 标记存在时优先。
- 放在 shell 自带菜单之后、窗口按钮之前,高度由 --dsh-windows-titlebar-height 控制,并加上 -webkit-app-region: no-drag,保证它始终可点击。
- 接受任意 #/… 路由、裸会话 id,或整条链接(只取其中的 fragment);按 Enter 写入 hash,浏览器触发 hashchange,链接就沿着粘贴链接完全相同的路径落地。
- 它还会回显:本插件每次写入地址栏,都会同步到输入框,所以框里始终显示屏幕上当前的内容。按 Escape 恢复;不指向任何路由的文本会被拒绝。
设置:地址栏的两个偏好
在插件管理器里找到本插件的行,点它的配置控件(或直接打开 #/panel/plugins/dsh-url-router/dsh-url-router)——那个页面就是本插件的设置。两个偏好都保存在本机(localStorage),改动即刻生效,无需重启:
| 偏好 | 默认值 | 含义 |
| 首次点击选中整条链接 | 开 | 像浏览器的地址栏:第一次点击选中框里已有的全部内容,输入即替换旧链接;框已聚焦后再点一次则放置光标。关闭后就是普通文本框。 |
| 记住的链接数 | 8 | 下拉列表列出多少条链接(地址栏里当前显示的屏幕不计入——那是你所在的位置,离开后它会回到列表)。下限是 0(不记忆,也没有最近列表),没有上限。 |
最近列表的行为和浏览器一样:聚焦地址栏就展开,输入即收窄,按 Escape 关闭。条目来自两处——本插件命名过的屏幕(它写入地址栏的每个视图)和粘贴进地址栏的链接(任何它能打开的链接,无论是否落地都会记住)。
左键打开,右键复制。 右键会吞掉浏览器菜单,把完整 URL 放进剪贴板——路径、启动查询(?token=…)和 fragment——这样就能在新标签页或另一台机器的窗口里打开。被复制的那一行会短暂显示「已复制 ✓」,地址栏闪出「已复制链接」;列表保持展开,光标位置不变。
- 身份是屏幕,不是位置:指向 #/session/<id>/turn/3/row/… 的链接会归并到它所属的会话,所以一个会话不会占满列表;再次看到同一屏幕时,它移到最前,而不是重复添加。
- 当前显示的屏幕不会出现在列表里(那不是可以回去的地方)。
- 计数就是下拉列表列出的条数:磁盘上会为当前显示的屏幕多留一条,所以 8 真的显示 8 条链接(不是 7 条)。调低计数会立即裁剪;设为 0 会清空列表并停止记忆。
- 会话条目在侧边栏有标题时显示侧边栏里的会话标题;其他界面显示其类别和链接本身。
- 页面还有一个清除按钮。
- 粘贴的链接永远不会替你按下开关。 插件行的启用开关紧挨着它的配置控件,两者都是 ,所以驱动只点击那些不是 role="switch" 的控件:打不开的组件页会带着一条诊断信息过期,而不是悄悄把插件禁用。
它遵守的规则
- 只改片段。 路径和查询串从不重写。
- 只留一个写入方。 不要在旁边再跑另一个片段写入方(dsh-session-url)。
- 只用 replaceState,所以面板永远不会塞满后退栈。
- 作用域是声明出来的,不是猜出来的。 面板属于应用级,不带会话 id。
- 链接在落地之前一直有效,落地之后就把地址栏交还出去。
- 从不抛异常。 被拒绝的导航用一条诊断信息兜住。
限制
仍未覆盖:技能中心 / SSH 内页,它们需要像任务板那样,各自有一套「发布当前 id + 接受打开请求」的约定。会话链接只在同一台机器、同一个 DSH_HOME 下才有意义。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
DDDMUC/dsh-url-router
DSH 地址栏路由插件Web 与 Windows 桌面版——…
相关插件 · 对话 / 记忆
上下文中枢oceanbase/powercontext
上下文跟着工作走 —— 跨会话、跨智能体、跨人。
★ 1,487已汉化DSH
73
智能体记忆库plastic-labs/honcho
Honcho 是记忆基础设施,用来构建有状态的智能体。这些智能体能理解不断变化的人、智能体、群组、项目和想法。
★ 7,894已汉化DSH
71.7
长程智能体控制面loopx-project/loopx
给 Agent 一个目标,让工作持续向前。
★ 6,358已汉化DSH
71.3
智能体上下文数据库volcengine/OpenViking
给 AI 智能体用的上下文数据库
★ 41,379已汉化DSH
71.3
长效机器人团队Fei2411/DS-Bot
DS Bot 是一个基于 DeepSeek Harness简称 dsh的 bot 插件,插件将 dsh 改造为 bot…
★ 5,084已汉化DSH
71.1
可携带记忆层EverMind-AI/EverOS
为什么选择 EverOS
★ 13,778已汉化DSH
71.1
这是你的仓库?认领条目