# dsh-wikilink
> **English README**:[README.md](README.md)
DeepSeek Harness Web GUI 的 Obsidian 风格 `[[双链]]` 引用插件。在输入框输入 `[[`,笔记标题选择器即时浮出:边输入边模糊搜索工作区笔记——支持**跳字匹配**(「曼食」找到「曼谷街头美食文化观察」)和**空格分词**(「曼谷 美食」找到「曼谷街头美食文化观察 / 曼谷笔记:美食 / 曼谷朱拉隆功夜市美食探索」)。回车附加,发送消息时把引用笔记的完整内容交给模型。
```
输入框: 总结 [[曼谷 美. ← 选择器浮在未闭合 token 上方
┌────────────────────────────────────────────────────────┐
│ 📄 曼谷街头美食文化观察:鱼鳔老太太摊位的夜间消费场景 │
│ 📄 曼谷笔记:美食 │
│ 📄 曼谷朱拉隆功夜市美食探索:KINNKUNG海鲜馆的惊喜体验 │
└────────────────────────────────────────────────────────┘
草稿: 总结 [[曼谷笔记:美食]] ← 可读的纯文本 token
模型: …内容… ← 发送时注入
```
输入 `[[查询词` 选择器即在双括号处弹出,回车后整体替换为 `[[标题]]`、光标落在 `]]` 之后(Obsidian 式交互)。正文里的单个 `[` 不会误触发。
## 无需 harness 补丁
早期版本需要对已安装的 `@deepseek-ai` 客户端 bundle 打补丁(harness 输入触发管线只识别 `/` 和 `@`)。v0.2 起选择器完全自绘:插件自己监听草稿、在公开的 `conversation.input.overlay` 插槽渲染浮层菜单、通过公开输入动作写回闭合的 `[[标题]]`。**零补丁,无需重打——安装、重启、即用。**
## 安装
> **兼容性**:v0.2.1+ 需要 **dsh ≥ 0.1.2-rc.1**。dsh 0.1.2-rc.1 移除了 `@deepseek-ai/dsh-settings` 的 `settingsNamespace()` 工厂,本插件自 v0.2.1 起以纯字符串字面量注册 `wikilink` 命名空间(旧版 dsh 仍可运行——字符串本就是底层存储格式)。
```sh
dsh plugin --profile web add https://github.com/zhaoscsc/dsh-wikilink/archive/refs/heads/main.tar.gz
```
重启 web 服务以加载 host 半部分与新的 client bundle。启用开关在 **设置 → 双链引用**。
## 配置
Host 侧可调参数在 profile 的插件行:
```yaml
- id: dsh-wikilink
config:
maxIndexedFiles: 100000 # 每个工作区索引条目数上限(大 vault 必须调大)
maxFileBytes: 262144 # 单个附加笔记字节上限;超限文件拒绝附加,绝不截断
ignoreDirs: ['.git', 'node_modules'] # 遍历时跳过的目录名
```
索引按会话缓存 30 秒;输入框上方有**索引状态条**:索引中(「正在索引工作区文件…」)→ 完成(「已索引 N 条笔记」)→ 失败(显示原因)。
## 对模型的影响
| 方面 | 效果 |
| --- | --- |
| Token 开销 | 每个引用笔记把完整内容(不超过 `maxFileBytes`)加入请求 |
| 工具调用 | 无 —— 内容已在提示词中,模型无需再调用工具读取 |
| 消息格式 | 笔记序列化为 `…内容…`,以来源 `wikilink-mention` 的用户消息注入 |
| 解析规则 | `[[目录/标题]]` 按路径精确解析;`[[标题]]` 仅当标题唯一时解析;不唯一或找不到 → 保持纯文本 |
## 匹配算法
四层阶梯(标题优先,路径兜底):连续子串 > 跳字子序列 > 路径连续子串 > 路径子序列。空格分词后各词必须全部命中(AND)。查询与标题均做 NFC 规范化。
真实效果示例(旅行笔记 vault):
| 查询 | 结果 |
| --- | --- |
| `[[曼谷 美食]]` | 曼谷街头美食文化观察:鱼鳔老太太摊位的夜间消费场景 · 曼谷笔记:美食 · 曼谷朱拉隆功夜市美食探索 |
| `[[曼食]]`(跳字) | 曼谷**街**头美**食**文化观察(跨越中间字符匹配) |
| `[[鱼鳔]]` | 曼谷街头美食文化观察:鱼鳔老太太摊位的夜间消费场景 |
## 已知限制
- 选择器在草稿中**最后一个未闭合**的 `[[`/`【【` 处触发(查询词一直延伸到草稿末尾)——公开输入状态不含光标信息,光标不在末尾时不触发
- 自绘菜单的样式、键盘与点击关闭由插件自管,与 `/`、`@` 管线菜单独立演进
- 工作区索引按会话缓存 30 秒;此后新建的文件需等下一次菜单打开刷新
- 文件名为 `.md` 的笔记会被跳过(空标题会破坏 wire schema 校验)
- **⚠️ 输入法提醒**:部分输入法(搜狗/微信/百度/系统拼音等)的**符号自动补全**(智能标点/括号自动配对)会在敲 `[` 或 `【` 时自动补出右括号(`[` → `[]`、`【` → `【】`),导致草稿里形不成连续的 `[[` / `【【`,选择器不弹出。**请在输入法设置里关闭「符号自动补全」**(不同输入法叫法:智能标点 / 括号自动配对 / 符号联想)。
## 开发
```sh
node build.mjs # esbuild 已 vendor 在 ./node_modules;zod 内联进 client bundle
```
架构(自绘选择器,零补丁)、构建循环见 [DEV.md](DEV.md)。
## 更新记录
- **v0.2.1** — 适配 dsh 0.1.2-rc.1:`@deepseek-ai/dsh-settings` 移除了 `settingsNamespace()` 工厂,插件改为以纯字符串字面量注册 `wikilink` 命名空间。
- **v0.2.0** — 零补丁自绘选择器(无需 harness 补丁);模糊/跳字匹配;全角 `【【` 触发支持。
## License
MIT