dsh-closet-tracker:把本地衣物願望清單掛進 Harness 側邊欄

前言

DSH 的理念是「一切皆插件」。當你要給自己的 Harness 加一個自己用得上的能力時,常見做法是寫一個面板,字段自己定義、接口自己拼、樣式自己抄。這個插件走的是另一條路:它先有一個獨立的本地 Web 應用管着真實數據,再讓 Harness 面板只做「讀同一份數據 + 同一份操作」。下面介紹的是 ramanasai 維護的 dsh-closet-tracker。

這是什麼

一個倉庫出兩種形態:app/ 是一個零依賴的 Bun Web 應用,負責抓取商品鏈接、存數據、出統計;倉庫根目錄本身是一個 DSH 插件包,在 Harness 左側邊欄放一個衣架圖標,在主列渲染完整的願望清單面板,讀的是同一個 app/data/items.json。

它解決的問題是:兩邊的數據保持同一份,你在 Web 應用里加的條目會立刻出現在 Harness 面板裏,反之亦然。插件在 SkillHub 社區目錄中歸在「客戶端」分類。

核心功能

下面這些能力都來自 README:

  • 讀同一個數據源,兩邊共用 app/data/items.json
  • 粘貼鏈接即可加單品:應用抓取名稱、圖片、價格、店鋪、品牌、分類,條目立刻進網格
  • 統計:願望清單總值、仍需購買件數、已購數量、上次檢查以來的降價
  • 篩選、搜索、排序:狀態頁籤(All / Wishlist / Bought)、分類篩選、自由文本搜索、按最新 / 價格 / 名稱 / 降價幅度排序
  • 單品操作:立即查價、願望清單與已購互切、兩步確認刪除
  • Sync all:重新抓取所有在跟蹤的鏈接並報告降價
  • 原生外觀:只用主題 token,明暗跟隨 Harness;空狀態和離線狀態會說明該怎麼辦;本地應用掛掉時每 12 秒靜默重試

安裝與啓用

安裝分兩步:先把 Web 應用跑起來,再裝插件包。Web 應用不需要 bun install:

cd app
bun run start          # http://localhost:3003
open http://localhost:3003

插件包需要 DeepSeek Harness(面向 0.2.1-rc.5 構建)且已有 profile。官方給出的安裝方式是先把倉庫 clone 下來,再把 clone 的絕對路徑作爲 target 傳給 plugin_manager install_bundle——倉庫根目錄就是插件包本身:

git clone https://github.com/ramanasai/dsh-closet-tracker.git
plugin_manager install_bundle target=/absolute/path/to/dsh-closet-tracker

也可以在 Harness 的 Plugin Manager UI 裏選「從本地目錄安裝 bundle」,填同一個路徑。

另一個不 clone 的方式:從 Releases 下載 dsh-closet-tracker-1.0.0.tgz,直接把 tarball 路徑當 target:

plugin_manager install_bundle target=/absolute/path/to/dsh-closet-tracker-1.0.0.tgz

裝完後邊欄出現標着 Closet Tracker 的衣架圖標。插件只負責界面,數據要應用跑着才顯示;如果安裝前 Harness 頁面已經開着,裝完重新加載一次。

配置

上游地址寫在 cordis.patch.yml,隨 bundle 的 patch 插入 profile:

- insert:
    - id: closet-tracker
      name: dsh-closet-tracker
      config:
        # The local app. localhost reaches IPv4 or IPv6 loopback listeners.
        baseUrl: http://localhost:3003

端口換了的話,應用側用 PORT=4000 bun run start 啓動,再讓 baseUrl 對上。默認的 3003 來自應用自身(process.env.PORT || 3003)。

內部結構

插件分兩半,中間隔着一條代理。index.js 是 Host 端,client.js 是 Client 端。

應用是一個不發 CORS 頭的本地進程,Harness 的插件指引又不允許用 iframe 包頁面,所以 Host 端註冊了一個同源代理路由,Client 端以 /closet-api/api/... 調用。代理的行爲比較剋制:

  • 只轉發 /closet-api/api/*,其餘路徑不代理
  • 保留方法、請求體、上游狀態碼和 content-type
  • 上游只收到 host、content-type、accept;Harness 會話 cookie 和 Authorization 都不轉發
  • 走 Harness Connection 的瀏覽器認證,Connection 服務不可用時 fail closed,返回 401
  • 上游地址由 config.baseUrl 固定,請求路徑改不動它;上游超時 45 秒;應用不可達時回結構化的 502 JSON

Client 端用 Harness module table 裏的 React 渲染,只用 --dsw-alias-* 主題 token,可見文案都走 Harness locale 服務註冊。註冊點一共三個:sidebar.panellist(id: closet-tracker,order: 30,衣架圖標)、main(key: closet-tracker → 願望清單面板)、Host 路由前綴 /closet-api。

典型用法

裝好之後,日常就是三條路。

1、看到喜歡的商品,把鏈接粘進 Web 應用,應用抓取後把條目寫入 items.json;Harness 面板刷新即可看到新條目。

2、在面板裏用狀態頁籤切換 All / Wishlist / Bought,用分類篩選和搜索定位,按價格或降價幅度排序。單品操作裏可以現在查價(立即請求應用抓一次)、互切願望清單與已購、兩步確認刪除。

3、想整體看看降了多少,點 Sync all,應用重新抓取每個在跟蹤的鏈接並回報降價。

測試部分用 Node 自帶的 test runner,不需要 Bun 也不需要真實應用——測試會自己起一個樁上游:

npm test                          # node --test: proxy forwarding, allowlist, gate, header hygiene
node --check index.js client.js   # syntax
cd app && bun run start           # run the app itself

適用場景與注意

適合兩類人:一是想要 Harness 裏一個隱私可控的購物清單面板、且願意自己跑一個本地應用的開發者;二是想研究 DSH 插件裏 Host / Client 兩半怎麼配合、代理還要守哪些邊界的人——test/proxy.test.mjs 覆蓋了轉發白名單、認證門、請求頭衛生,可以當參考。

幾點要注意。插件以當前 DSH 進程的權限運行,所以安裝前先讀一遍 index.js、client.js 和 cordis.patch.yml,以及它的許可證;許可證是 MIT,倉庫裏另有一份打包在 app/public/vendor/ 的 jsPDF,同樣由其作者以 MIT 授權。應用的 app/data/ 是個人數據目錄,已被 gitignore。Web 應用不依賴任何框架,跑在任意瀏覽器裏也能用,不裝插件不影響它本身。README 明確說 Amazon 和 Ajio 的鏈接抓取效果差(兩者都擋爬蟲),條目仍會加入,需要用應用的編輯對話框手動補全。

常見故障和處理:

  • 面板提示 “Closet Tracker is not reachable at http://localhost:3003”:先跑 cd app && bun run start;面板自身每 12 秒會重試,也可以點 Try again
  • 裝完邊欄圖標不顯示:重新加載一次 Harness 頁面,讓新的 client 模塊生成生效
  • 面板顯示的是別的應用的數據:確認 cordis.patch.yml 裏的 baseUrl 與應用端口一致
  • 端口占用:cd app && make stop 會清掉佔用該 PORT(默認 3003)的監聽進程;用別的端口啓動時要同步改 baseUrl。注意 make stop 是按端口殺的,確認是你要殺的東西,可以用 lsof -nP -iTCP:3003 -sTCP:LISTEN 查一下

結尾

這個插件的價值在於分工清楚:應用管數據和抓取,插件管 Harness 裏的呈現,中間用一條帶認證和白名單的同源代理打通。兩邊數據是同一份,改一處就行。目錄頁與源碼在下面。

  • SkillHub 目錄頁:https://www.skillhub.cn/plugins/ramanasai/dsh-closet-tracker
  • GitHub:https://github.com/ramanasai/dsh-closet-tracker
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜