前言¶
在 DeepSeek Harness(DSH)裏做倉庫內的輕量 UI,常見做法是單獨寫前端、再掛進宿主,或把邏輯塞進一個大插件裏。倉庫裏如果有多份小腳本、小面板,往往難以在對話視圖裏「一文件一標籤」呈現,也難在改動後仍可控地授權讀、寫和網絡。
下面介紹維護者 AlseFum 的 dsh-pluginlet(GitHub:AlseFum/dsh-pluginlet,社區分類 admin-security)。它把工作區中符合規則的每個 *.pluginlet 文件變成 Conversation View 裏的獨立標籤頁;運行前按內容哈希綁定能力授權,寫入只能通過宿主確認完成。當前 README 標明 experimental, source-only,尚未發佈到 npm,需從倉庫 Git URL 安裝。
這是什麼¶
dsh-pluginlet 是 DSH 的 Web 側插件:掃描工作區內指定目錄下的 *.pluginlet 純 JavaScript 文件,每個文件對應一個標籤(例如 對話 / 軌跡 / hello)。插件隨倉庫攜帶的 pluginlet 會隨檢出一起可用,不依賴按項目再裝 npm 包。
設置不在插件 UI 裏改,而在宿主插件配置(Plugins → Pluginlet,或該 bundle 對應行的 config:)中完成。
核心功能¶
發現與標籤¶
默認只掃描工作區根下的 .dsh/pluginlets/(根目錄散落的 *.pluginlet 不會變成標籤)。可通過 directories 增加搜索路徑;extensions 默認 ['.pluginlet']。
示例佈局:
repo/
.dsh/pluginlets/
app.pluginlet -> 標籤名 "app"
schema.pluginlet -> 標籤名 "schema"
hello.pluginlet -> 標籤名 "hello"
發現上限由 maxEditors(默認 64)與單文件 maxEditorBytes(默認 524288)約束。
pluginlet 編寫約定¶
.pluginlet 爲純 JavaScript:無 JSX、無 import(安裝無構建步驟)。可導出三種形態之一:
- 默認導出函數(迷你 React:
api.h+ hooks) setup(api)返回渲染函數(類 Vue)mount(el, api)命令式掛載
api 提供 h、Fragment、常見 hooks、fs.read / fs.list(包裝讀)、net.fetch(包裝網絡)、write.request(僅發起確認,不自行寫盤)、ui.toast、meta.name / meta.path 等。安裝 Host 半部後會註冊技能 pluginlet-development,正文在 skills/pluginlet-development.md,供智能體寫 pluginlet 前加載。
安全與授權¶
掃描器是策略門,真正邊界是沙箱:pluginlet 在 sandbox="allow-scripts" 的 iframe 中運行,CSP 極嚴;fs / net 僅通過 postMessage 到宿主,再訪問 /api/pluginlet/*,並記入審計。
- 寫入無宿主確認對話框則不可能;幀內只有
write.request。 eval、import/require、裸fetch等由掃描阻斷,不可授予。- 授權按內容哈希與路徑作用域綁定,批准數據存放在
$DSH_HOME/pluginlet/,不進倉庫。 - 批准發生在該 pluginlet 標籤要運行時;對話框可按能力勾選路徑子集。
devMode: true時(工作區可見橫幅)可接受哈希變更而免重新批准,並放寬可授予能力,被阻斷的構造仍被阻斷。
主要配置項(節選):
| key | 默認值 | 含義 |
|---|---|---|
devMode |
false |
變更哈希可不重新批准(仍審計;讀寫網絡仍受控) |
extensions |
['.pluginlet'] |
視爲 pluginlet 的後綴 |
directories |
['.dsh/pluginlets'] |
相對工作區根的搜索目錄 |
allowRead / allowNetwork / allowWrite |
true |
是否允許提供對應能力 |
net |
{ perMinute: 20, perHour: 240, maxBytes: 1048576 } |
每個 pluginlet 的網絡預算 |
宿主 API¶
路由均爲 POST,路徑前綴 /api/pluginlet/,並要求請求頭 x-dsh-plugin: pluginlet。包括 discover、scan、source、state / grant / revoke / log、fs/list、fs/read、net/fetch、write 等(網絡僅限 http(s)、有超時與大小與速率限制)。
安裝與啓用¶
在 profile web 下添加插件(README 原文命令):
dsh plugin --profile web add github:AlseFum/dsh-pluginlet
也可使用完整 Git URL:https://github.com/AlseFum/dsh-pluginlet.git。克隆爲完整包,無需 npm install 或構建。
配置示例(cordis.patch.yml 片段):
- id: pluginlet
config:
devMode: false
allowNetwork: false
或在 Plugins 頁面安裝爲 Pluginlet。修改 Host 半部後需重啓 dsh web;客戶端半部刷新頁面生效。
package.json 中版本爲 0.1.0,許可證 MIT,要求 Node >= 22.0.0。GitHub 星標數以目錄站展示爲準(抓取時爲 0)。
典型用法¶
- 在工作區創建
.dsh/pluginlets/,新增hello.pluginlet。 - 重啓或刷新 DSH Web,在 Conversation View 看到對應標籤。
- 首次運行時在標籤內完成能力批准(按需縮小路徑作用域)。
- 需要寫文件時,在代碼裏調用
write.request(target, text, version),在宿主對話框確認。
最小計數器示例(README 摘錄):
export default function Editor(api) {
const [count, setCount] = api.useState(0)
return api.h('div', { style: { padding: '12px' } },
api.h('button', { onClick: () => setCount(count + 1) }, '+1'),
' ' + count)
}
適用場景與注意¶
適合:需要在同一倉庫內維護多個小型、可審查的沙箱 UI(配置預覽、Schema 編輯、運維小面板等),且希望授權與源碼哈希、路徑作用域強綁定。admin-security 分類與此一致:強調宿主側策略、審計與確認寫。
注意:
- 插件以當前 DSH 進程權限運行;安裝前請閱讀源碼與 MIT 許可證,並理解
devMode與allowNetwork等開關的含義。 - 網絡代理對 DNS 重綁定等仍有殘餘風險,README 明確其爲護欄而非完整出站過濾。
- DSH 社區插件目錄(如 SkillHub 上的條目)爲獨立生態站點,與 DeepSeek / 幻方無官方從屬關係;非 npm 正式發佈階段,升級與變更以 GitHub 倉庫爲準。
結尾¶
dsh-pluginlet 把「一文件一標籤」和哈希綁定的能力授權結合起來,讓倉庫自帶的 .pluginlet 能在對話視圖裏安全試運行。進一步細節見倉庫 README 與 docs/DESIGN.md。
- 目錄頁:https://www.skillhub.cn/plugins/AlseFum/dsh-pluginlet
- GitHub:https://github.com/AlseFum/dsh-pluginlet