前言¶
在 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