左侧栏一个入口,中央一块面板。既直接操作得到大脑(原 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/天;登录通道实测宽得多。自动同步有增量模式, 连续两页没有变化就提前收工,不会把配额烧在读旧笔记上。
笔记(离线,完全不联网)
[[另一篇笔记]] / [[目标|显示文字]] 是可点的,点了直接跳到那篇笔记;
![[图片.png]] 会就地显示图片(按文件名在本文附件里找).bak)、新建(YYYY-MM-DD-标题.md)、删除进 .trash/_<note_id>_audio 这种机器后缀@path,直接粘到对话里让 DSH 读云端(联网,直接操作得到大脑)
recall,按意思找,不是本地那个子串搜索).md× 删标签、创建分享链接(可排除音频)音频
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同步(自动或手动)
导入(旧的一次性 OAuth 全量导入,仅在没有 API Key 时作为兜底出现)
设置
$DSH_HOME/dsh-getnote/vault)这是整个插件最容易毁数据的地方,规则写死如下——一律偏向保住用户的东西:
| 情况 | 行为 |
|---|---|
| 本地没有这篇 | 新建 |
| 本地有、且没改过 | 覆盖成云端最新(不留 .bak,那份内容就是我们自己上轮写的) |
| 本地改过、云端没改 | 保留本地,只更新记账 |
| 两边都改 | 本地版另存 .conflicts/,正文写云端版,备份失败就整篇不覆盖 |
本地已有 note_id 但同步引擎没见过它 |
判定为你手写的,原样保留并标记 adopted;以后云端再改也只往 .conflicts/ 另存 |
| 云端删了、本地改过 | 保留本地,只在面板标「云端已删除」,不替你做主 |
写入前会先解析出真实的绝对路径(resolveInside 返回的是对象,不是字符串——这里踩过坑,
把它当字符串用会让每一篇都判成「本地不存在」从而无条件覆盖)。
三栏是从深到浅的同一条蓝,越往里越亮,眼睛自然从「我在哪」滑到「我读什么」:
| 栏 | 配色 | 内容 |
|---|---|---|
| 左 | 深蓝 #0a2a52 → #071d3b |
目录树、标签云,浅色文字 |
| 中 | 浅蓝 #c5daf3 → #b6cfee |
笔记列表,深蓝文字 |
| 右 | 近白蓝 #f7fbff |
阅读区 / 编辑区,深灰蓝正文 |
实现方式不是给每个元素改颜色,而是在各栏容器上局部重定义 --dsw-alias-* 主题变量:
自定义属性沿 DOM 继承,栏内所有用 token 的字色、底色、边框色自动跟着变。以后调色只改
一组变量,不会漏掉某个还在用旧 token 的角落。云端/同步/设置三个整页复用右栏那套浅色。
扫描与列表会跳过 .conflicts、.trash、asset 这些内部目录:前两个是不该被当成笔记的
副本与回收站,asset 里的 _transcript.md 虽然也是 markdown,但它是录音的转写附件,
混进列表会让人点「笔记」却打开转写。
从索引源安装(推荐)
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 项,全部离线运行,不需要网络也不需要真实凭证。
MIT