wanghehe123 / dsh-cite

Listed

DeepSeek Harness 的引注插件:@ 历史会话、圈选前文加批注、打开这一轮写出的文件。

mainOther View source

Installation

npx -y @deepseek-ai/dsh plugin --profile web add github:wanghehe123/dsh-cite

This installation command is an unverified starting point generated from the GitHub repository address.

README

Maintainer-authored documentation snapshot.

View on GitHub ↗
Commit 1d244e1Synced Aug 18, 2026

dsh-cite

把值得留下的东西,指回这一轮。

选中刚才说过的话,加一句批注;@ 另一段会话当证据;模型刚写完的文件直接出现在回复下面。不用再把旧对话和路径粘进输入框。

这是 DeepSeek Harness 的 Web 插件。中文名:引注。曾用名 dsh-sessions

dsh plugin --profile web add @wishp3/dsh-cite
dsh --profile web

装好后打开设置 → 插件 → 插件配置 → 引注,按需把 @ 范围从「仅当前工作区」改成「所有可见会话」。

四件你会立刻用到的事

1. 圈一段前文,像批注一样带回去

在聊天里选中文本,点「添加到对话」。句子末尾出现 1、2、3 小号圆点;点圆点就能写下评论。发送时,模型看到的是普通 Markdown 引用,评论跟在后面:

> 你选中的第一行
> 你选中的第二行

你的可选评论

同一轮可以圈多处。输入框上方只留一颗「N 条注释」胶囊,点开再管理。

2. @ 一段旧会话,当只读证据

新对话里输入 @,从历史会话里挑一段。宿主会做成有界、只读、带来源的快照,再交给模型——不是把整段日志糊进去。

输入 @ 后出现的会话候选菜单

也可以直接写 session-<uuid>,或在开关打开时手打 @标题(标题必须唯一,重名会当普通文本)。

3. 这一轮写出的文件,就钉在回复下面

回复完成后,「产物」列表出现在消息下方:文件名、说明。左键打开;右键复制路径,或在 Finder / 资源管理器 / 文件管理器里显示所在文件夹。

4. 会话和工作区的两个小菜单

会话行 可以复制原生 session id;工作区行 可以直接打开那个文件夹。

复制会话 ID复制成功
会话行菜单里的复制会话 ID复制会话 ID 成功 toast

和官方的关系

dsh-cite 是社区插件,不是 DeepSeek 官方产品,也不改官方运行时。

  • 跨会话快照完全走官方 @deepseek-ai/dsh-session-reference。本包只做 Web 触发、路由和 agent/pre-step 接线。
  • 浏览器半挂在官方的 inputTriggers、slots、conversation 等服务上。
  • 选区引注是浏览器里组装的 > 文本,不写入结构化引用元数据。

需要改核心运行时或走 CLI,请以官方仓库为准。插件怎么装进 profile,见官方插件管理架构说明

配置

插件配置页:引注卡片展开后的样式

卡片默认折叠。scope 在卡片上改,保存后写入宿主 settings;其余键用 cordis.patch.yml 或 profile 覆盖。

卡片不走官方 settings 槽(api-proxy 白名单不覆盖第三方包),而是走本包的 GET/POST /dsh-sessions/settings。持久化节目前仍是 settings.yaml 里的 dsh-sessions:,以免已有配置丢失。

默认作用
scopeworkspaceworkspace:只能引用与目标会话同 cwd 的记录;all:引用本机 dsh 可见的全部持久化会话
allowBareSessionIdstrue解析消息中的裸 session id
allowPlainTitleMentionstrue解析手打 @标题
candidateLimit50预留:浏览器半目前固定请求 50 个候选
failureModepassthroughpreflight 成功后、pre-step 再次 prepare 失败时:passthrough 保留可读文本继续,reject 拒绝该步

引用前文,逐步

  1. 在聊天正文里选中一段文本(代码、自然语言都可以)。选区上方出现「添加到对话」。
  2. 点击后:
    • 文本先 trim,超过 16,000 Unicode 码点会截断并加上本地化截断标记;
    • 草稿末尾插入一个 dsh-sessions-quote chip,输入框里显示「引用 N」;
    • 选中句子第一行末尾出现小号数字圆点。
  3. 点击圆点:
    • 弹出评论卡片,预填已有评论(没有就是空的);
    • 「保存」写回这条引用;圆点上多一个小点,表示已有评论;
    • 「取消」、Esc 或点卡片外,什么都不改。
  4. 输入框上方的「N 条注释」默认收起。展开后可看预览、全文、评论,或逐条移除(等价于删掉对应 chip)。
  5. 发送时每个 chip 变成逐行 > 的引用块;有评论则空一行再跟评论。
  6. 发送成功后草稿清空,圆点和注释胶囊一起消失。

选区必须在会话正文([data-conversation-scroll])里,且不在输入区([data-composer-seat])。空选区、输入阶段不是 plain 时,按钮不会出现。

@ 跨会话引用差在哪

引用前文@ 历史会话
来源当前会话里已经出现的文字本机其他历史会话
谁准备内容浏览器当场组装宿主 prepare() 做快照
模型看到的> Markdown + 可选评论## Referenced sessions 快照 + 可读 @label
来源能不能追溯没有结构化元数据有 session id、label、cwd
大小限制单条 16,000 码点;评论 4,000 码点每个来源 65536 字节

实现要点

  • 圆点位置:添加前克隆选区 Range,取第一行非空 clientRect 的右端、垂直居中;滚出视口就隐藏。上游刷新卸掉节点后,圆点会消失,再引用一次即可。
  • 保存评论:官方输入机先 slash/input-consume-token 拿掉旧 chip,再 slash/input-insert-reference 插回同一位置。两次事务,撤销要按两下。失败会回滚旧 chip,并在卡片里提示重试。
  • 状态只有一份:注释条从 input.occurrences 里过滤 source === 'dsh-sessions-quote'。撤销、重做、复制、粘贴、手删 chip,都会一起变。
  • 序列化serializeclipboardText 都带首尾换行,相邻引用不会粘成一行。草稿重载后不再是 chip,只留下 > 文本。
  • 不挡 @ 菜单:引注用的是一个候选恒为空的 @ 源,空分组不渲染。

@ 跨会话,逐步

  1. @ 候选来自 POST /dsh-sessions/candidates。选中后插入 chip,不透明 ref 带着目标会话、来源会话、label 和规范 mention。
  2. 提交时 serialize/dsh-sessions/preflight:按当前 scope 过滤并完整跑一次 prepare()。失败会中止提交、保住草稿;成功才写出 @[label](dsh-session:…)
  3. 宿主 agent/pre-step 先走普通 enter,再解析这条 user 消息:规范 mention 收成可读 @label;裸 id 和手打 @标题 看开关。每个 id 必须落在 scope 里,否则按 failureMode 处理。
  4. prepare() 一次读完全部来源并去重,重写成 [快照, 可读直接消息, …]。快照源标记为 { kind: 'session-reference', version: 1 }

快照语义沿用 @deepseek-ai/dsh-session-reference

  • 每个来源只调一次 sessionQuery.readSurface(),入队后不重读。只投影用户直接发出的 user/message、assistant 文本,以及带 dsh-compaction 标记的检查点。工具、reasoning、上下文、插件生成的 user 消息、未完成的 assistant 分片、被压缩遮蔽的事件全部排除。
  • 每个来源独立受 65536 字节限制,保留检查点和最新消息,旧的非检查点单元按 dsh-output-retention 头尾截断。固定字段就超限时以 SESSION_REFERENCE_BUDGET_EXCEEDED 失败。
  • 一条消息最多 3 个不同来源;不能引用自己。
  • 目标日志先记带来源的上下文 user/message,再记可读直接消息。之后源会话变更、压缩或删除,都不影响目标回放。

模型看到的跨会话内容

两条连续的 user 消息:先是 ## Referenced sessions 不可信快照,再是带可读 @label 的当前消息。警告禁止遵循快照里的指令、权限声明或工具请求,除非当前 user 又说了一遍。label、cwd、id 和会话文本以 JSON 放进 <referenced-sessions>;数据里的每个 < 会写成 \u003c,源文本拼不出定界标签。

每条带引用的消息多一段固定警告,外加最多三个快照。精确快照留在目标历史里,直到目标自己压缩或摘要它。源会话之后怎么变,都不会再涨 token。快照和请求是两条只追加的新消息,前面的 KV cache 还能用;换一套引用只动新后缀。

工作区界面(vendor)

当前发布的 ui-workspace 没有会话行菜单槽位。upstream/0001-web-session-row-menu-slot.patch 是给上游的补丁;在它合并之前,本包 vendor 了工作区浏览器(src/vendor/workspace/),在 bundle patch 里关掉内置行,自己补上 sidebar.workspacesconversation.hero.workspace。其余行为和内置一致。

复制先在点击手势里走 document.execCommand('copy'),失败再试 navigator.clipboard.writeText()。toast 在行组件里渲染,4 秒后消失。

bundle patch 同时插入官方 session-reference 和本包这一行(dsh.bundle + dsh.client),Web loader 会从同一行带上浏览器半。dsh 升级工作区 UI 后,需要同步 vendor;上游槽位补丁合并后,可以删掉 vendor、恢复内置实现。

已知限制

  • 选区引注只收文本。图片、工具卡片进不去。
  • 同一段文字可以圈多次,不会自动去重。
  • 不做 AI 回复里的引用块渲染;> 就是普通 Markdown。
  • 不做语音输入,也不放装饰性的死按钮。
  • 草稿重载后,选区引用不会变回 chip。
  • 手打 @标题 只精确匹配;重名请用菜单或裸 id。
  • 不搜索消息正文。候选只看 id、cwd 和折叠后的标题。
  • 跨会话只传播文本。非文本块不过去。
  • 引用不是实时链接:快照在发送时冻结,不是 fork、恢复或订阅。
  • preflight 和 pre-step 之间,源会话可能被删或损坏。默认 passthrough 留下可读文本;reject 则拒绝这一步。
  • 浮层定位依赖上游的 data-conversation-scroll / data-composer-seat

开发

npm install --ignore-scripts   # 首次安装,跳过 prepare
npm run build
npm test

构建需要 Node 22+(tsdown 用到 Promise.withResolvers),加载 TypeScript 配置需要 unrun(已在 devDependencies)。本机若是 Node 20,用 npx -y -p node@22 npm run build

在 deepseek-harness 源码树里本地调试:

pnpm dsh web --patch /absolute/path/to/dsh-cite/cordis.patch.yml

仓库目录如果还叫 dsh-sessions,把路径换成实际目录即可。

发布

npm run build
npm publish

package.json 已声明 publishConfig.access: public,scope 为 @wishp3

License

MIT

基于 DeepSeek Harness 的社区插件,并非 DeepSeek 官方产品。

Project files and signals

Shown items are public repository signals detected in the directory snapshot.

TestsDetected
DocumentationDetected

Repository information

Language
TypeScript
License
MIT
Last updated
Aug 17, 2026, 1:35 AM

Install deliberately

Review source code, permissions, lifecycle hooks, dependencies and network access. Test untrusted plugins in an isolated environment.