dsh-getnote — 把「得到大脑」接进 DeepSeek Harness
左侧栏一个入口,中央一块面板。既直接操作得到大脑(原 Get笔记 / biji.com)的云端内容(看、改、删、打标签、语义召回、生成分享链接),
也把一切镜像成本地 Markdown 文件(离线可读、可搜索、可以用 @路径 喂给对话)。
自动同步默认需要你亲手开一次,开了之后就不用再管:只要 DSH 开着,它自己按时拉新笔记。
本地优先:笔记是磁盘上的纯 Markdown,会员到期之后,已经同步下来的内容照常能读能写能搜。 云端的 OAuth 登录和 API Key 都是可选增强。
两条通道,用哪条取决于你有什么
| 通道 | 你需要做的事 | 说明 |
|---|---|---|
| 登录得到大脑(OAuth) | 在「同步」页点一次「登录得到大脑」,浏览器授权 | 一次授权,之后自动续期。推荐,不用去控制台 |
| API Key(官方 Open API) | 去 openapi.biji.com 控制台建个人应用,拿 API Key + Client ID,填进「设置 → 云端接入」 | 长期凭证,不依赖浏览器 |
面板会自动挑:配了 Key 就优先用 Key,Key 被服务端拒绝(401 / 未授权)就静默回落到登录通道,
并在设置页用黄色横幅告诉你「Key 被拒了,现在走的是登录通道」——不会让你看到「已接入」却满屏报错。
换 Key 或清凭证会重置这个判断,重新试。
配额:官方 Open API 读 1000/天、写 200/天;登录通道实测宽得多。自动同步有增量模式, 连续两页没有变化就提前收工,不会把配额烧在读旧笔记上。
功能
笔记(离线,完全不联网)
- 目录树(按知识库/主题分)、标签云、全文搜索
- Markdown 阅读:标题、列表、任务列表、表格、引用、代码围栏、链接
- Obsidian 双链:正文里的
[[另一篇笔记]]/[[目标|显示文字]]是可点的,点了直接跳到那篇笔记;![[图片.png]]会就地显示图片(按文件名在本文附件里找) - 编辑保存(原文件留
.bak)、新建(YYYY-MM-DD-标题.md)、删除进.trash/ - 回收站页签:删除的笔记能看见、能一键恢复(撞名时自动改名,绝不覆盖)、能永久清空
- 图片附件直接显示,不用切到文件管理器;播放器标题会自动去掉
_<note_id>_audio这种机器后缀 - 「复制引用」把绝对路径复制成
@path,直接粘到对话里让 DSH 读
云端(联网,直接操作得到大脑)
- 笔记列表 + 分页加载
- 语义搜索(官方
recall,按意思找,不是本地那个子串搜索) - 打开一篇笔记看详情,录音笔记带原始音频播放器
- 改标题 / 改正文,保存即回写云端,并顺手刷新本地那份
.md - 按知识库筛选(顶上一排知识库 chip),新建云端笔记(可指定知识库)
- 加标签 / 点标签上的
×删标签、创建分享链接(可排除音频) - 把本地改动推回云端:以前只能「云端 → 本地」单向,本地改完没法送回去; 现在详情页有一个推送按钮(会二次确认,推的是正文与标题)
音频
- 录音笔记的音频地址在
attachments[type=audio].url(一个会过期的签名 URL), 所以播放器不直连 CDN,而是走/getnote/audio?url=代理:签名不暴露给浏览器、 支持Range请求(能拖进度条)、白名单限制域名(防止这个端点变成开放代理) - 本地库里的录音也能直接播:笔记同目录
asset/下形如<标题>_<note_id>_audio.mp3的附件,会显示成「本地录音」播放器,走/getnote/asset?path=读磁盘(同样支持 Range)。认领靠note_id,所以 本地标题和云端标题不一样也能对上 - 进度条是自绘的(不是原生
<input type=range>):整条轨道都是可点区域, 点哪跳哪,按住拖动跟随,松手才真正 seek - 逐字稿按「时间戳 + 说话人 + 内容」分条排版,中文长文自动折行,不是塞进等宽代码块
同步(自动或手动)
- 自动同步:开关 + 间隔(5 分钟 ~ 12 小时)。DSH 启动 20 秒后第一次跑,之后每分钟查一次 「到点没有」,到点才真的发请求。失败静默(原因留在面板里),不刷错误提示
- 手动「立即同步」= 增量;「全量扫描」额外能发现云端已删除的笔记(慢、费配额,所以不自动)
- 增量同步遇到连续两页没变化就停,不全量扫
- 结果分列显示:拉取 / 保留本地 / 保留本地(接管)/ 冲突 / 移入回收站 / 失败
导入(旧的一次性 OAuth 全量导入,仅在没有 API Key 时作为兜底出现)
设置
- 笔记库目录可指定任意路径(默认
$DSH_HOME/dsh-getnote/vault) - 空库时扫描常见位置并建议(不擅自切换)已有的归档目录
- 云端凭证状态、打码后的 Key、凭证文件路径
同步怎么决定「该不该动你的文件」
这是整个插件最容易毁数据的地方,规则写死如下——一律偏向保住用户的东西:
| 情况 | 行为 |
|---|---|
| 本地没有这篇 | 新建 |
| 本地有、且没改过 | 覆盖成云端最新(不留 .bak,那份内容就是我们自己上轮写的) |
| 本地改过、云端没改 | 保留本地,只更新记账 |
| 两边都改 | 本地版另存 .conflicts/,正文写云端版,备份失败就整篇不覆盖 |
本地已有 note_id 但同步引擎没见过它 |
判定为你手写的,原样保留并标记 adopted;以后云端再改也只往 .conflicts/ 另存 |
| 云端删了、本地改过 | 保留本地,只在面板标「云端已删除」,不替你做主 |
写入前会先解析出真实的绝对路径(resolveInside 返回的是对象,不是字符串——这里踩过坑,
把它当字符串用会让每一篇都判成「本地不存在」从而无条件覆盖)。
界面
三栏是从深到浅的同一条蓝,越往里越亮,眼睛自然从「我在哪」滑到「我读什么」:
| 栏 | 配色 | 内容 |
|---|---|---|
| 左 | 深蓝 #0a2a52 → #071d3b |
目录树、标签云,浅色文字 |
| 中 | 浅蓝 #c5daf3 → #b6cfee |
笔记列表,深蓝文字 |
| 右 | 近白蓝 #f7fbff |
阅读区 / 编辑区,深灰蓝正文 |
实现方式不是给每个元素改颜色,而是在各栏容器上局部重定义 --dsw-alias-* 主题变量:
自定义属性沿 DOM 继承,栏内所有用 token 的字色、底色、边框色自动跟着变。以后调色只改
一组变量,不会漏掉某个还在用旧 token 的角落。云端/同步/设置三个整页复用右栏那套浅色。
扫描与列表会跳过 .conflicts、.trash、asset 这些内部目录:前两个是不该被当成笔记的
副本与回收站,asset 里的 _transcript.md 虽然也是 markdown,但它是录音的转写附件,
混进列表会让人点「笔记」却打开转写。
安装
从索引源安装(推荐)
- 打开 DSH 的插件页,切到发现标签(若没有,先在插件设置里打开「自定义插件索引」)
- 添加索引源,填这个地址:
https://magicbaobaoli.github.io/dsh-getnote/index.json - 找到「得到大脑」,点安装
从 GitHub 直接装
dsh plugin --profile <你的 profile> add github:magicbaobaoli/dsh-getnote
本地开发
plugin_manager action:install_bundle target:"<绝对路径>/dsh-getnote"
装完重启 DSH,左侧栏出现大脑图标。
数据在哪
| 内容 | 位置 |
|---|---|
| 笔记 | 设置里的 vaultRoot,默认 $DSH_HOME/dsh-getnote/vault |
| 设置 | $DSH_HOME/dsh-getnote.json |
| 云端凭证(API Key) | $DSH_HOME/dsh-getnote/cloud.json(0600) |
| 登录令牌(OAuth) | $DSH_HOME/dsh-getnote/auth.json(0600,仅 host 可读) |
| 同步记账 | $DSH_HOME/dsh-getnote/state.json(每篇的路径与指纹) |
| 冲突备份 | <库根>/.conflicts/ |
| 回收站 | <库根>/.trash/ |
DSH_HOME 默认是 ~/.dsh。
结构
lib/index.js host 入口:/getnote/* 路由、双通道选择、自动同步定时器
lib/vault.js 文件层:扫描、frontmatter、读写、搜索、回收站、附件认领
lib/settings.js 设置、云端凭证、同步记账的持久化(原子写)
lib/openapi.js 官方 Open API 客户端 + 字段归一化(normalizeNote / extractAudio)
lib/mcp-cloud.js 把登录通道包成与 openapi.js 相同的接口(含音频字段桥接)
lib/biji.js OAuth(PKCE)与 MCP JSON-RPC 客户端
lib/cloud-sync.js 同步引擎:四分支决策、指纹、Markdown 渲染、推送
lib/sync.js 旧的一次性全量导入
lib/client.js 浏览器产物:sidebar.panellist 入口 + main 面板(五个页签)
test/ 四套离线测试,不联网
测试
node test/vault.test.mjs # 52 项:文件层、frontmatter、附件认领、回收站
node test/sync.test.mjs # 66 项:同步引擎(重点验「什么情况下不该动用户文件」)
node test/host.test.mjs # 99 项:/getnote/* 路由、凭证、白名单、SSRF 防护、Range、回收站
node test/client.test.mjs # 161 项:UI 结构、Markdown 渲染、播放器、逐字稿、双链、图片、回收站
四套共 378 项,全部离线运行,不需要网络也不需要真实凭证。
边界
- 云端写入只动你自己的笔记。不做企业代授权场景的适配。
- 录音卡(GetSeed 硬件)的专用接口是 fail-closed 的,普通个人账号调用会 403;这类笔记 走通用笔记接口照样能读能播。
- 录音类笔记的 ASR 原文原样保留,不做改写。
- 同步是「云端 → 本地」的镜像 + 面板里的显式「推送」。没有自动的双向同步: 本地文件被外部手改成什么样,插件不会猜你的意图替你回写云端。
- API Key 那条通道用的是得到大脑官方 Open API,该接口仅对会员开放; 会员到期后登录通道可能失效,但已经同步到本地的 Markdown 永远能读。
许可
MIT
No comments yet. Be the first to write one.