前言¶
在 DSH 裏做個人主頁,常見做法是寫一個固定頁面,或者把 Markdown 筆記當成首頁。前者要自己寫前端和抓取邏輯,改一個源就要動一次代碼;後者只能呈現已經整理好的內容,沒法把外部信息源按卡片擺進去。
下面介紹的 dsh-sooyo 走的是另一種思路:插件在側欄加一個「sooyo daily」,頁面是一塊 bento 網格,每格是一個 Widget,每個 Widget 可以掛不同的信息源。維護者是 CaiZongyuan,許可證 MIT,GitHub 倉庫 CaiZongyuan/dsh-sooyo 當前 0 星,屬於客戶端類插件。
它要解決的問題是:日常要盯的幾個信息源(AI新聞、論文、Product Hunt、YouTube 頻道)和本地的任務、筆記、習慣,分散在各處,打開 DSH 時看不到「今天要做什麼、有什麼值得讀、項目走到哪了」。
一句話定位¶
sooyo daily 是一個可組合、本地優先的個人空間:Board 裝着 Widget,Widget 是用戶擺上去的一個實例,Source 只負責供內容。
模型只有這一句,其它都是它的展開。
核心設計¶
這個插件把界面拆成三層,避免「一個源對應一張固定卡片」的耦合:
| 層 | 職責 |
|---|---|
| Board | 頁面分段,總覽、工作、生活、閱讀四個開箱即用,也可以自己建 |
| Widget | 用戶擺上去的一個實例;同一個 Widget Type 可以放好幾份,各自選來源、呈現和尺寸 |
| Source | 只供 Item,外加「建議」一個默認呈現;不聲明卡片 |
Size 用 S / M / L / Wide 表示四種信息層級,不是把一張卡拉伸。每種 Widget 只聲明它真正支持的尺寸。
訂閱 Widget 一個類型包五種呈現:圖文、榜單、論文、產品、視頻。加一個源不寫客戶端代碼。
卡片流(Deck)一次一條,可拖動:右滑稍後讀、左滑跳過,論文卡可以翻面看摘要,S 尺寸自動輪播,方向鍵也能用。
關注詞命中標題、摘要、一句話總結或推薦理由的條目會帶標記,開啓「關注優先」排序後排到前面。
Widget 庫¶
| Widget | 尺寸 | 說明 |
|---|---|---|
| 任務 | S / M / L | 今天要做的事,直接勾選完成;可以只看一個 Project |
| 訂閱 | S / M / L / Wide | 一個或多個來源的最新內容,可選五種呈現與卡片流 |
| 快速記錄 | M / Wide | 一行記下想法,回車進收件箱;#note 開頭存爲 Note |
| 書籤 | S / M / Wide | 常去的網站一鍵直達 |
| 項目 | S / M / L | 按任務完成度算進度,不連外部服務 |
| 稍後讀 | S / M / L | 存下來、晚點再讀的文章 |
| Agent 收件箱 | S / M / L | 後臺審閱給出的建議,逐條批准或拒絕 |
| 習慣 | S / M | 每天打卡,看連續天數 |
| 專注計時 | S / M | 番茄鍾,可關聯一個任務,倒計時由宿主保存 |
| 日程 / 天氣 / 簡報 / 嵌入 | — | 需要一個數據源,尚未接上;標爲「即將推出」,不顯示假數據 |
內置信息源¶
| 源 | 默認呈現 | 封面來源 | 頻率 |
|---|---|---|---|
| AIHOT 精選 | 圖文 + 評分與推薦理由 | 原文頁 og:image |
10 分鐘 |
| AIHOT 熱榜 | 榜單(多源熱點 Top 10) | 無(編號即視覺) | 30 分鐘 |
| HuggingFace 論文 | 論文真實封面 + 一句話總結 + 關鍵詞 + 贊數/評論 | HuggingFace CDN 或論文配圖 | 6 小時 |
| Product Hunt 今日 | 字母徽標 + 一句話 | 產品頁 og:image |
3 小時 |
| YouTube · Dwarkesh Patel | 完整節目 16:9,Shorts 豎屏貨架 | YouTube 縮略圖 | 3 小時 |
AIHOT 和 Product Hunt 的接口本身不帶圖片,插件會去條目鏈接的頁面讀 og:image(也喫 twitter:image 和 JSON-LD)。每個頁面只讀一次,只讀前 160KB 就斷開,結果永久緩存;讀不到圖的頁面會被記下來,不反覆請求。
安裝與啓用¶
前置條件:DeepSeek Harness >=0.2.0-rc.1,Node.js >=20。插件自身版本 0.2.0,純 JavaScript,package.json 裏沒有 dependencies,沒有打包步驟。
從 GitHub 直接裝(Web profile):
dsh plugin --profile web add github:CaiZongyuan/dsh-sooyo
桌面端可以在「設置 → 插件」裏安裝;本地開發時也可以用插件管理器指向本目錄。
裝好之後重啓一次 DSH。宿主插件是按 specifier 緩存的,改動要新進程才生效。重啓並刷新頁面後,側欄就會出現「sooyo daily」。
配置¶
配置寫在 cordis.patch.yml 的 config 下:
config:
mode: selected # AIHOT:selected 爲編輯精選,all 爲全部公開動態
sources: [] # 留空表示全部啓用;只啓用列出的源 id
refreshMinutes: null # 覆蓋所有源的抓取節奏
thumbnailBatch: 6 # 每輪補封面的頁面上限,最大 20
sync:
role: standalone
tokens: []
context: true
| 字段 | 默認 | 說明 |
|---|---|---|
mode |
selected |
AIHOT 取 selected(編輯精選)還是 all(全部公開動態) |
sources |
全部 | 只啓用列出的源 id |
refreshMinutes |
— | 覆蓋所有源的抓取節奏 |
thumbnailBatch |
6 |
每輪補封面的頁面上限(最大 20) |
sync.role |
standalone |
standalone / hub / client |
sync.tokens / sync.token |
環境變量 | Hub 的設備令牌 / Client 的令牌,只存 Host 側 |
sync.allowLoopbackOnly |
true |
Hub 是否只接受本機連接 |
sync.context |
true |
是否在真人對話時注入 Sooyo Context |
不寫 sync 就是 standalone,老配置不用改。
多設備同步¶
三種角色:
| 角色 | 誰持有數據 | 抓取信源 | 適合 |
|---|---|---|---|
standalone(默認) |
本機 | 本機 | 單機使用 |
hub |
本機 | 本機 | 常駐服務器,對外提供受令牌保護的同步 API |
client |
Hub | 不抓 | 筆記本、手機等其它設備 |
Hub 側配置:
sync:
role: hub
tokens:
- { token: '至少-16-字符的隨機串', device: macbook, access: write }
Client 側配置:
sync:
role: client
endpoint: https://sooyo.example.com
# 令牌建議走環境變量 SOOYO_SYNC_TOKEN
Client 缺 endpoint 或缺令牌時會明確報錯,不會悄悄起一個空的本地庫。切換到 client 之前先備份,切換本身不刪除任何本地數據。
備份與遷移走 HTTP 接口:
GET /sooyo/export # 導出 JSON(不含抓取到的條目)
POST /sooyo/import # 不帶 apply:dry-run,逐表列新建/相同/衝突/拒絕
POST /sooyo/import { apply: true } # 真正寫入;衝突仍然不覆蓋
POST /sooyo/import { overwrite: true, apply: true } # 顯式覆蓋
導入永不刪除、永不覆蓋未確認的記錄,中斷後重跑不會產生重複實體。
Agent 工具¶
插件註冊了若干工具,讀與寫分開:
| 工具 | 讀/寫 | 用途 |
|---|---|---|
sooyo_context_get |
只讀 | 今日/未完成/收件箱/最近筆記/待批建議的實時摘要 |
sooyo_task_list |
只讀 | 按列表、完成狀態、Project 過濾任務 |
sooyo_task_create |
寫入 | 建任務(可帶 Origin) |
sooyo_task_update |
寫入 | 改任務,必須帶 revision;被別的設備改過會返回 conflict |
sooyo_note_capture |
寫入 | 記筆記,來源標記爲 agent |
sooyo_inbox_list |
只讀 | 看待審批的建議 |
sooyo_proposal_create |
寫入建議 | 寫一條待批准的建議,不直接改數據 |
sooyo_review_run |
只讀+游標 | 後臺審閱的確定性入口:先免費掃描,再 ack 看過的條目 |
保存 Todo 不調用任何模型。sooyo_action 這種能傳任意命令名的通用工具是故意不做的。
後臺審閱¶
只在 Hub 上跑一條 DSH Schedule,時間取自 GET /sooyo/review/schedule 的 spec。第一步是 sooyo_review_run 的確定性掃描:沒有新增或改動過的事項時提示模型立刻結束這一輪,不產出任何內容。
建議不會直接改數據,而是進 Agent 收件箱等人工批准。同步 API 拒絕批准操作,所以模型無法批准自己寫的建議。審批後按條執行,失敗的標爲 failed,不假裝成功。
加一個源¶
源只供 Item,建議一個默認呈現,佈局和尺寸由用戶決定:
{
id: 'my-source',
label: '我的源',
cadenceMinutes: 180,
suggests: { pres: '圖文' },
async load(signal, previous) {
// 返回 { items: [{ nativeId, title, url, publishedAt, summary, score, category, origin }], etag }
},
}
想關掉某個源,編輯本包的 SOURCES 註冊表把對應項注掉即可,這是唯一的信息源擴展點。
出網與安全¶
插件自帶出網層:每源獨立節奏、條件請求(ETag/304)、全局併發上限、失敗按 1/2/4… 分鐘遞增重試,一個源壞掉不影響其它源。
抓到的第三方文本一律視爲資料,不作爲指令執行;每條內容都帶來源與原文鏈接。AIHOT 明確允許個人非商業使用,插件保留 attribution 與原文鏈接;請同時遵守各站點的 robots 與使用條款。
適用場景與注意¶
適合已經在用 DSH、想要一個常駐側欄的個人主頁,並且能接受把任務、筆記、稍後讀、習慣也放進插件裏統一管理的用戶。東西都是個人數據,落在 DSH 存儲域上,Board、佈局、任務、Note、稍後讀、關注詞、習慣、番茄鍾都持久化。
前提是插件運行在當前 DSH 進程的權限範圍內,能讀到本機的配置和存儲,也能按配置聯網抓取信源。安裝前應當打開源碼過一遍,包括 cordis.patch.yml、SOURCES 註冊表和自帶的工具註冊邏輯;許可證是 MIT,倉庫公開,但社區目錄是獨立站點,與 DeepSeek / 幻方沒有官方從屬關係,它也不是官方應用商店。
倉庫 0 星、0 fork,屬於早期個人項目,接口和 Widget 形態後續都可能調整。當前版本 0.2.0 要求 DSH >=0.2.0-rc.1。
小結¶
dsh-sooyo 做的事不復雜:把 Board/Widget/Source 三層拆開,讓信息源只生產 Item,讓卡片形態和佈局變成用戶數據而不是代碼。零依賴、零構建,裝完重啓就能用;需要多設備時再切 hub/client 角色。
目錄頁:https://www.skillhub.cn/plugins/CaiZongyuan/dsh-sooyo
倉庫:https://github.com/CaiZongyuan/dsh-sooyo