前言¶
DSH 的 Web 側欄裏,會話行自帶置頂:hover 出現按鈕,點一下釘到最前,置頂後不再 hover 時行尾留一枚灰色實心圖釘。工作區(文件夾)行沒有這個入口,只能靠拖拽排序;而且新建工作區會被宿主前插到列表最前,已經手工排好的次序很容易被打亂。
本文介紹的插件 dsh-workspace-pin 就是把「會話置頂」那套圖釘原樣補到工作區行上,視覺與交互直接複用官方實現,不改 dsh 自身任何文件。插件由 Richard 維護,分類爲客戶端插件,倉庫版本 0.3.0,許可證 MIT。
這是什麼¶
一句話定位:給 DSH Web 側欄的工作區(文件夾)行補一個與會話置頂同款的圖釘按鈕,點擊即把該工作區釘到列表最前,置頂集合由宿主持久化,跨瀏覽器和清緩存都不丟。
它解決的問題有兩個:一是工作區行沒有置頂入口,二是工作區順序僅靠拖拽維護,容易被新建工作區搶佔頂部位置。
核心功能¶
下面介紹的能力均可在 README 中核對。
- hover 任一工作區行時,行尾出現圖釘按鈕,位置在官方「…」和「+」旁邊,最右;點擊釘到列表最前,再點一次取消置頂。取消不會把工作區挪回原位。
- 置頂按鈕複用官方按鈕類名(
Rows.module.css的*_iconButton)、同一套 16×16 尺寸、--dsw-radius-xs圓角、label-tertiary靜止色 / hoverlabel-primary、無 hover 背景,圖標用官方 14pxIconPinOutline/IconPinFill。 - 懸浮提示用官方
Tooltip,參數side: bottom、align: end、delayMs: 500、portal: true。 - 置頂後無 hover 時,行尾出現與官方
*_pinIndicator同度量、同配色的灰色實心圖釘,行一 hover 就讓位給懸浮按鈕。 - 置頂集合存在宿主半邊,跨瀏覽器、無痕窗口、清站點數據、換設備都不丟。
- 頁面加載、工作區列表變化、頁面重新可見時,已置頂工作區會被重新排到最前,新建工作區被宿主前插時置頂項仍回到頂部。
- 不改 dsh 源碼,不 fork dsh,卸載即恢復原生側欄。
唯一的實現差異:官方靜止標記用 margin-left: 6px(會話行 gap: 0),插件把 margin-left 取 0,由工作區行自身的 gap: 6px 承擔同樣間距。
安裝¶
插件沒有提供 dsh plugin add 形式的命令,安裝由倉庫自帶的腳本完成。安裝腳本只動三處:把插件包複製到 profile 的 plugins 目錄、在 node_modules 裏建 junction / 軟鏈、把 cordis.patch.yml 裏的 insert 塊追加進 profile 的 cordis.patch.yml;前兩處會先備份到 ~/.dsh-backup-<時間戳>/。
Windows(PowerShell):
git clone https://github.com/Richard2091/dsh-workspace-pin.git
cd dsh-workspace-pin
pwsh -File .\install.ps1
只有 Windows PowerShell 5.1 時可改用:
powershell -ExecutionPolicy Bypass -File .\install.ps1
macOS / Linux:
git clone https://github.com/Richard2091/dsh-workspace-pin.git
cd dsh-workspace-pin
sh install.sh
安裝後刷新瀏覽器裏的 DSH Web 頁面即生效,profile 配置與插件文件由宿主 HMR 重組;如果宿主沒有熱加載新文件,重啓一次 dsh web 即可。
驗證與使用¶
安裝後在控制台執行下面兩條檢查:
window.__dshWorkspacePinVersion
window.__dshWorkspacePinStorageMode
前者期望 "0.3.0",後者爲 "host" 表示已連上宿主狀態;若爲 "cache",說明只加載了瀏覽器半邊或宿主未熱加載,此時退回 localStorage 緩存模式,不跨瀏覽器。
日常使用:
1、hover 任一工作區行,行尾出現圖釘按鈕;
2、點一下置頂,該工作區釘到列表最前;再點一下取消;
3、所有連到同一臺 DSH 的瀏覽器和設備看到的是同一份置頂集合。
數據位置與重置¶
工作區置頂集合 <DSH_HOME>/storages/dsh-workspace-pin/state.json
工作區顯示順序 宿主 workspace registry(workspace.json 的 global.workspaceIds)
瀏覽器 localStorage 僅作本地緩存/舊數據遷移源,鍵 dsh.workspace-pin.v1
默認路徑下置頂集合位於 ~/.dsh/storages/dsh-workspace-pin/state.json。重置置頂:刪掉 state.json 後刷新頁面,或向狀態路由發送 {"op":"set","pinned":[]}。
也可以用條目 config 的 stateFile 把狀態文件指到別的位置:
- insert:
- id: workspace-pin
name: 'dsh-workspace-pin'
config:
stateFile: 'D:\dsh-data\workspace-pin.json'
實現原理¶
宿主半邊(lib/index.js)用官方 ctx.webServer.register() 註冊一條精確路由 GET|POST /plugins/dsh-workspace-pin/state,請求准入複用官方 ctx.connection.requestRejection()(Host/Origin 圍欄加瀏覽器會話鑑權),未認證請求返回 401、跨源寫請求返回 403。狀態文件寫入走「臨時文件 + rename」原子替換;pin / unpin 是增量操作,由宿主串行化讀改寫,多瀏覽器併發置頂不會互相覆蓋;set 僅用於舊數據遷移。宿主半邊不新增任何依賴,只用 Node 內置模塊。
瀏覽器半邊(lib/client.js)首幀先用 localStorage 緩存把圖釘畫出來,隨後 GET 宿主狀態對齊,宿主纔是數據源。點擊時本地立即生效(樂觀更新),再 POST {op:"pin"|"unpin"},用宿主返回的權威集合校正 UI;失敗只告警並退回本地緩存模式,不影響已生效的操作。頁面重新可見時再向宿主對齊一次。按鈕通過平臺模塊表用官方 React、Tooltip、IconPinFill、IconPinOutline 渲染;官方 UI 原語不可用時退回等價兜底樣式與原生 title。舊版本升級時,若宿主爲空而本機 localStorage 有舊置頂集合,會一次性 set 遷移到宿主。
兼容性與已知限制¶
在 DSH 0.2.1-rc.2(Web GUI)上實測,依賴官方工作區行 DOM、ctx.workspaces.insertBefore 客戶端服務、ctx.webServer / ctx.connection 宿主服務,以及平臺模塊表裏的 react / react-dom/client / @deepseek-ai/dsh-client-ui-primitives。dsh 大版本升級後如果官方行結構、類名、模塊表或宿主服務變化,插件需要跟着適配。
需要留意的幾點:
- 插件依賴官方工作區行的 DOM 結構(
[data-row-key^="workspace:"]、行尾 actions 容器)和Rows.module.css的類名度量,官方調整時插件需要同步更新。 - 頁面加載時把已置頂工作區排到最前,這是一次真實的順序寫入,不是純視覺排序。
- 宿主狀態文件與宿主 workspace registry 是兩份獨立數據,不要在
dsh web運行時手改,會被內存狀態覆蓋;備份遷移時整目錄拷貝即可。 - 以後在 profile 裏跑
pnpm install會清掉安裝腳本建的軟鏈,重跑一次安裝腳本即可,腳本是冪等的。 - 註銷後
storages/dsh-workspace-pin/state.json不會被自動刪除,需要的話手動刪掉。
適用場景與注意¶
適合用 DSH Web 側欄管理多個工作區、希望常用工作區穩定排在頂部的人。插件以當前 dsh web 進程的權限運行,會讀寫 profile 的 plugins、node_modules、cordis.patch.yml 以及宿主 storage 目錄,安裝前建議先閱讀倉庫源碼與 MIT 許可證,確認與現有 profile 不衝突。
卸載¶
pwsh -File .\uninstall.ps1 # Windows
sh uninstall.sh # macOS / Linux
或手動刪掉三處:cordis.patch.yml 裏的安裝塊、node_modules 裏的軟鏈、plugins 裏的插件目錄,然後刷新頁面。已寫入宿主的工作區順序會保留;置頂集合文件需要手動刪除。
小結¶
dsh-workspace-pin 做了一件很窄的事:把官方會話置頂的圖釘交互原封不動搬到工作區行上,並把置頂數據交給宿主持久化。它不改 dsh 源碼,有自己的卸載腳本和三個點的說明文檔,代價是依賴官方行結構的當前形態。對多工作區用戶來說,這比反覆拖拽排序省事。
目錄頁:https://www.skillhub.cn/plugins/Richard2091/dsh-workspace-pin
GitHub:https://github.com/Richard2091/dsh-workspace-pin