dsh-knit
把会话工作区里已有的 Markdown 文档、源码、图片与视频列进 DSH 侧边栏,按与当前对话的相关性排序。默认的词法模式用最近几条消息在本地与标题、摘要、正文做带 IDF 加权的匹配(BM25)—— 不调用模型、没有网络出口,内容不出本机。列表来自工作区扫描,而不是「最近打开记录」,所以重启 DSH 或新开会话都不会变空。排序结果组织成主要 / 辅助 / 相关三层的阅读顺序,每一条都写明可核验的理由(命中了哪个字段、被哪一篇引用),点一行即可就地预览:Markdown 按渲染后的样子显示、相对路径图片真实渲染、源码走宿主自带的语法高亮、视频走 HTTP Range 流式播放。同一份 Con
安装
dsh plugin --profile web add dsh-knit
沙箱测试结果
| 阶段 | 结果 |
|---|---|
| 1 安装 | ✓ |
| 2 列装 | ✓ |
| 3 挂载 | ✓ |
| 4 启动 | — |
四阶段在隔离沙箱里跑:安装(有网)→ 列装 → 挂载 → 启动(后三步断网)。
README
Knit
面向 AI Coding Agent 的任务感知工作区上下文检索与生命周期追踪。
Task-aware workspace context retrieval and lifecycle tracking for AI coding agents.
Knit 接的是当前任务和整个工作区之间那一层:从工作区里找出最相关的文档、源码与媒体,
组织成 主要 / 辅助 / 相关 三层上下文(Context Pack),交给面板、也交给 agent;
再持续追踪这些上下文有没有被读、被读之后有没有变。
找到 → 组织 → 追踪,默认的词法模式三步都在本机用字符串运算完成 —— 不调模型、不联网、零延迟、内容不出本机。
可选的混合模式默认关闭:只有你自己配好 provider 并且手动切到混合检索,才会有出网请求;
那时发出去的是你这句查询原话 + 每篇候选文件的标题与摘要(完整正文、绝对路径都不发)——
⚠️ 这里有两个容易想当然的地方,见下面的「混合模式到底发出去了什么」。
当前任务
│
工作区检索
┌────────────┼────────────┐
▼ ▼ ▼
主要上下文 辅助上下文 相关上下文
└────────────┼────────────┘
▼
Context Pack ──► `knit_docs` 工具(给 agent)
▼
Agent 读取
▼
读取证据 · Context Epoch
▼
工作区发生变化
▼
重新读取 · 生命周期
它不是「更聪明的最近文件列表」,也不是「代码浏览器」。
最近文件记的是「你点开过什么、哪个更新」;Knit 回答的是
当前这个任务,项目里哪些东西最值得先看 —— 以及看过之后,事情变成了什么样。
真机截图(不是原型):同一个工作区,这张停在 「代码」档 —— v0.19 起,源码和 Markdown 一样是一等公民。
每行下面的副行写着它是怎么被命中的(直接命中 classification · changelog / 路径命中 agents · classification),
以及命中段 —— 这次查询在这份文件里最像的是哪一段(命中段 24–38)。
点一行就地展开预览,并且直接停在那一段上:这里是 knit/src/host/passage.js,行号栏 + 语法高亮,
命中的那几行带一条灰底横带;预览头里只有路径和四个动作(复制 / 全屏 / 本地打开 / 关闭)。
头部只放路径、一个计数与两个开关;列表按「相关」还是「最新」排,由左边那一对页签决定 —— 按「相关」时排的就是你正在聊什么。
v0.14 起列表永远单列:最左边独立一列是序号(与标题第一行垂直居中),右边第一行=
Primary 点 + 标题 + 相对时间(时间靠右),摘要再往下;路径只出现在预览头里(目录收敛成一个 …/ 占位,完整相对路径在悬停提示里),列表行不再重复。
序号是跨三档连续的一条(先看 / 辅助 / 背景);「其他相关文档」不在包里、不编号,那一格用一个 · 占位 ——
空着会被读成「漏了一个号」(2026-10-01)。
排序跟着对话走(同一个工作区、新开的一个会话):聊天里先聊过一轮发布清单,顶上几条就是发布清单那一族;
再问一句「Knit 里 BM25 的字段权重是怎么定的?」,列表整个换成 BM25 那一族 ——
分组标题与跨三档连续的序号随之一起出现,每篇下面多一行「为什么」(命中在哪、怎么命中的、命中段是哪一段)。
⚠️ 面板是每 5 秒轮询一次的,重排不是发消息那一瞬间:这一屏里顶上几条是这一轮对话推进之后才整个换掉的
(中间那几十秒被剪掉了)。动图比真实时间快。
扫整个项目文件夹的文档 / 代码 / 图片 / 视频 · 排序跟着对话走 · 默认词法模式下不调模型、不联网
dsh plugin --profile web add dsh-knit
为什么需要它
Agent 一天产出 20 篇文档,你找不到刚才那篇。
这是它最开始要解决的问题:产出速度超过了人翻目录的速度。
DSH 自带的「最近文件」只记你点开过什么;一轮对话结束,前面那几篇就沉下去了。
Knit 换了个问法:不看「谁新」,看「和现在这件事有多相关」。
它扫的是整个工作区(不是这一轮生成的那几篇),按你正在聊的内容排序 ——
重启 DSH、换会话、跨天回来,它都还在。
后来问题往前长了一步:真要动一个功能时,最该先看的往往不是文档,而是那几行源码。
v0.19 起代码进了同一条链路。再往后,「排在前面」也不够用了 ——
排出来的那些,agent 到底读了没有?读完改过没有? v0.15–v0.18 补的就是这一层。
三句话:找到(扫全工作区、按当前任务排序)→ 组织(主要 / 辅助 / 相关三层 + 每条的理由)
→ 追踪(读了没有、读完变了没有)。
「最近文件列表」和「代码浏览器」都不是它
这两个类比各自只说中 Knit 的一个表层形态,说不到它回答的问题。
· 最近文件列表 · 代码浏览器 · Knit
范围 · 你点开过的 · 一棵目录树 · 整个工作区:文档 / 代码 / 图片 / 视频
排序 · 修改时间 · 你自己翻 · 当前任务的相关性(BM25 + IDF,本地算)
输出 · 一条平铺列表 · 你打开的那一个文件 · 主要 / 辅助 / 相关 三层,每条都写明为什么在这里
给谁 · 你 · 你 · 你和 agent —— 同一份 Context Pack,走 knit_docs
之后 · 不管 · 不管 · 读了没有 / 读完变了没有(读取证据 + 生命周期)
三条最要紧的区别:
1. 范围:最近打开列表只记你点开过的文件;Knit 扫整个项目文件夹 ——
重启 DSH、新开会话、跨天回来,它都还在。
2. 排序:它按时间排;Knit 按你正在聊什么排 ——
聊架构,架构文档浮上来;聊 loader 的 bug,plugin-loader.ts 浮上来。
3. 它不止于「找」:找完还要组织(三层 + 可核验的理由)和追踪(哪些真被读了、读完有没有变)。
默认词法模式下不调模型、不联网:全是本地字符串运算,零延迟、零成本、内容不出本机。
可选的混合模式默认关闭,指向本机服务(loopback)时内容不出这台机器。
⚠️ 语义收益仍待真 provider 实测(value-evidence: pending),不承诺召回提升。
混合模式到底发出去了什么
这段是按报文实测写的,不是按设计意图写的 —— 复现命令与逐条断言见
docs/evaluations/hybrid-retrieval.md(审计脚本
tools/semantic-request-audit.mjs 会把每一次请求的 body 录下来再逐条判)。
发出去了(请求体只有 { model, input } 两个字段,input 是一串文本):
# · 内容 · 精确边界
① · 你这句查询原话 · 面板走会话路径时是「最近一条有实质内容的用户消息」,截到 80 字;knit_docs(query=…) 走显式路径时最多 2000 字。每一轮刷新都会重发一次(文档向量有缓存,查询没有)
② · 每篇候选文件的标题 · Markdown 是正文里的第一个 # 标题(没有就用文件名);代码是带扩展名的文件名;图片 / 视频是去掉扩展名的文件名
③ · 每篇候选文件的摘要 · Markdown 的「摘要」是正文首个正文段落的节选(≤ 60 字)——它来自正文;代码的「摘要」是工作区相对目录(如 src/host/);媒体没有摘要
没有发出去:完整正文(审计对工作区里每一篇够长的文件都做了「开头 200 字 + 中段 200 字」两处探针,一处都没出现)、
绝对路径(工作区根 / 家目录 / file:// 一条都没出现)、会话历史、你工作区里没被选中的文件。
⚠️ 两个容易想当然的地方:
①「摘要」不等于「与正文无关的元数据」——Markdown 的摘要是正文的节选,所以会有至多 60 字的正文离开本机;
②图片 / 视频的文件名也会被发出去(它们没有摘要,发的是文件名本身,例如 screenshot-media)。
安装
dsh plugin --profile web add dsh-knit
装完重启 DSH,然后硬刷新浏览器(Cmd + Shift + R)。
怎么打开:
- 会话头部右侧的 Knit 图标按钮(就在右侧栏展开按钮旁边)—— 一键开面板
- 或右侧栏 tab 条上的「+」→「Knit 最近文档」
可选:装了 dsh-better-sidebar 的话,面板也会注册成它的一个 tab;
没装不受影响,两边是各自独立的可选依赖。
升级:命令和首次安装是同一条,装完同样要重启 DSH + 硬刷新。
功能
能力 ·
按当前对话相关性排序(BM25 + IDF)—— 默认纯本地、零模型调用;可选的混合模式默认关闭,见下 · ✅
当前任务上下文:把排序结果拆成 主要 / 辅助 / 相关 三层,每条都写明「为什么在这里」 · ✅
关系证据(v0.21):每行标出 检索 / 关系 / 用户固定;「为什么」展开行级证据(引用 / 导入 / 测试 / 文档,带对方文件与行号,面板最多 3 条、工具最多 2 条)—— 每条都能按行号 grep 回原文,一个字的理由都不是编的 · ✅
固定 / 排除(v0.21):固定进最上方独立区(不编号,三层编号不变);排除在检索之前生效(计数与状态摘要同时变,可恢复);宿主给了存储就活过重启,没给就写明「本会话有效(未持久化)」 · ✅
检索状态摘要(v0.21.x):面板头部一行如实显示 收集 · 排除 · 候选 | BM25 词法检索 · 关系 · 固定 | 入包(组内中点、组间细竖线、没有箭头),换任务 / 换档都跟着变 · ✅
工具栏一行(2026-10-12):相关 / 最新(排序)文档 / 代码 / 媒体(类型)—— 两组之间没有竖线,靠间距分界 | 右侧是搜索框(唯一可伸缩项,常规 180–240px,面板窄了先缩它,其余按钮永不被挤)。检索方式不在这行 —— 它是第三行状态摘要里的可点状态格(BM25 检索 ›,见下一条);四项彼此独立 —— 切排序 / 切类型 / 切检索方式都不动搜索词 · ✅
顶行计数(v0.21.x):只显示阿拉伯数字(9 / 过滤时 3 / 79)—— 量词随类型档变,索性不上屏;悬停提示里仍是完整那句(9 个代码文件) · ✅
给 agent 用的 knit_docs 工具:让模型拿回三层任务上下文(不是一条平铺列表) · ✅
文档生命周期(v0.17):每篇推荐文档现在处于 未读 / 已读 / 读后已更新 / 修改后已重新读取 哪一档,另外给出最近读了哪篇、包外读了哪几篇、上下文最近一次怎么变 · ✅
相关性 / 修改时间双模式一键切换(偏好记在 localStorage) · ✅
扫描会话工作区里的 `.m
…(truncated)
以上内容来自 npm 上的 README,我们只做格式化,不改内容。
版本
npm 上共发布:23,最后更新 2026-10-30