dsh-doc-assistant
Verifieddsh-doc-assistant · v0.1.19 · MIT · Web UI
企业文档助手 (Enterprise Document Assistant) — a DSH plugin that turns the harness into a document workbench: project-scoped document library, an e-reader style three-column page (tree | document | AI chat), selection-to-ask, and AI rewrite shown as tracked-cha
Install
dsh plugin add dsh-doc-assistant Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Published to npm without a public repository. Inspect the package contents before installing.
Tags
Creators
Readme
dsh-doc-assistant(企业文档助手)
把 DSH 变成一个文档工作台:按项目组织企业文档,在阅读器里边读边和 AI 交流; 选中文字后引用到对话输入区,输入问题或个性化修改要求;也可以让 AI 润色、扩写或直接翻译, 改动以修订模式高亮呈现,逐条接受 / 撤回,不需要的修订卡片可以删除。
这是 需求基线 的实现。
它解决什么
传统做法是"复制一段 → 切到对话框 → 粘贴 → 提问 → 切回去对照"。文档一长,上下文就散了。 本插件把阅读器和对话放在同一屏:选区就是上下文,修订就是结果,接受才落盘。
三条设计原则:
- AI 永远不直接改文件。 改写只生成"修订"这种插件内部数据;只有用户点「接受」才写回磁盘。 这让"反悔"成为一等公民,而不是靠备份文件兜底。
- 锚点是地基。 所有格式先转成统一的
DocIR,每个文本片段都带源文件字符偏移。 引用和改写共用同一套定位,生成修订前核对选区原文与文件中的位置。 - 除 PDF 与图片外,全部格式支持修订闭环。 靠两级修订模型实现,不是给每种格式写一套功能。
架构
┌─ 宿主半(Node,跑在 DSH 进程里)─────────────────────────────┐
│ config.js 插件配置($DSH_HOME/doc-assistant/config.json,600)│
│ projects.js 项目注册表 + resolve() 唯一路径安全闸门 │
│ tree.js 目录列举 / 文件名搜索 / docCount │
│ revisions.js 修订持久化 + 落盘前快照 │
│ routes.js HTTP 路由(同源守卫 + accept 流水线) │
│ docir.js 格式判定 + 解析成 DocIR(含真实源偏移) │
│ writers/ 按格式插拔的落盘层 │
│ revise.js AI 改写通道(subagent / ctx.llm.stream) │
│ chat.js 插件自有对话(ctx.llm.stream,零会话足迹) │
│ covers.js 两级智能封面(启发式 + AI 增强,可失败降级) │
│ upload.js 文档上传(原子写 + 重名避让 + 格式校验) │
│ tools.js doc_* 模型侧工具 │
└───────────────────────────┬──────────────────────────────────┘
│ fetch /doc-assistant/*
┌───────────────────────────┴──────────────────────────────────┐
│ 客户端半(浏览器,由 dev/build-client.mjs 从 src/client 生成)│
│ ./dom DOM 工具与图标 │
│ ./api HTTP 封装 + 语义化 API.* │
│ ./styles 样式(全部 --dsw-* 令牌,明暗自动跟随) │
│ ./revisions 词级 diff / 修订卡片 / 选中工具条 │
│ ./shelf 书架总览:分架书卡 + 封面渲染 + 上传入口 │
│ ./reader main 'doc-assistant' —— 顶栏 + 书架/阅读器切换 │
│ ./library SettingsWindow:齿轮打开的独立设置窗口 │
│ ./boot 装配(只注册 sidebar.panellist + main) │
└───────────────────────────────────────────────────────────────┘
挂在哪些插槽上
| 插槽 | id / key | 作用 |
|---|---|---|
main |
doc-assistant |
⭐ 整个文档工作台:左「项目 + 文档树 + 大纲」/ 中正文 / 右 AI 对话 |
sidebar.panellist |
doc-assistant |
侧边栏图标「企业文档助手」,点击进入上面这个页面 |
只有这两个。 本插件不注册任何 conversation.* 插槽 —— 文档功能全部归属插件自己的页面,
右侧对话也是插件自有的(走本包的 /chat/* 路由),而不是 DSH 的会话。
为什么不挂在
conversation.view? v1.x 曾把阅读器做成对话里的一个视图,靠它拿 DSH 的会话能力(inputActions/useConversation)。 但那会把文档功能塞进对话,且conversation.view由conversation.session声明 —— 用户切到别的主面板时它会被卸载,文档树只能挂在阅读器里自保。 v2.0 按需求改为插件自有页面 + 自有对话,两个问题一起消失。
main面板拿不到会话绑定怎么办? 官方明确main只有保留的conversationkey 才绑定会话。 所以对话不走 DSH 会话,而是走插件自己的宿主通道 —— 用ctx.llm.stream()直连模型, 零会话足迹,文档问答不会污染用户的任何对话历史。详见CONTRACT.md §13。
为什么对话要自带,而不是复用 DSH 会话
客户端 sessions 服务确实暴露了 SessionBinding.session.prompt(),理论上能从 main 面板驱动真会话。
但渲染会话流要自己消费 eventSource 并重建 tool-call / 流式 / 审批等全部 Chat 节点 ——
那等于重写一遍 client-ui-chat。而需求要的是文档问答,不是通用 agent 会话。
所以分工是:
| 能力 | 通道 | 理由 |
|---|---|---|
| 文档问答(右栏对话) | ctx.llm.stream() 直连 |
快、省、零会话足迹 |
| 润色改写(修订) | 一次性 subagent(有 agent 时)+ LLM 兜底 | 要 schema 级结构化保证,且可审计 |
两条通道都已在真机验证通过。
两级修订模型
「除 PDF 外都要修订」如果按格式各做一套,就是 4 套独立功能。拆成两层:
统一层(所有可写格式共用)
Revision 数据模型 · 三种呈现粒度 · 修订卡片
接受 / 撤回 / 批量 / 撤销 · 持久化 · 并发保护 · 多轮迭代
│ 只有「接受」时才调用
落盘层(Writer,按格式插拔)
TextRangeWriter → md / txt / html / code
DocxWriter → OOXML,写 w:ins / w:del(M2)
XlsxWriter → openpyxl 单元格(M2)
PptxWriter → python-pptx run(M2)
新增一种格式 = 实现一个 Writer(约 100~200 行),UI 与数据模型完全复用。
格式支持
| 格式 | 预览 | 选中提问 | 选中改写 | 修订 | 落盘 | 修订粒度 |
|---|---|---|---|---|---|---|
.md .txt .html 代码 |
✅ | ✅ | ✅ | ✅ | ✅ | 行内词级 diff |
.docx |
✅ | ✅ | ✅ | ✅ | ✅ OOXML 原生修订 | 行内词级 diff |
.xlsx .csv |
✅ | ✅ | ✅ | ✅ | ✅ openpyxl | 单元格级 |
.pptx |
✅ | ✅ | ✅ | ✅ | ✅ python-pptx | 形状段落级 |
.pdf |
✅ | ✅ | ❌ | ❌ | ❌ 只读 | — |
| 图片 | ✅ | ❌ | ❌ | ❌ | ❌ | — |
PDF 按需求决策为只读;图片没有文本层,物理上不存在"可改写的对象"。 M1 已交付前四行中的文本类,Office 三件套在 M2。
安装
书架标题栏与自动构建(0.1.19)
- 文档预览左栏的“项目”改为“书架”。书架总览移除独立标题行,书架数、文档数和刷新按钮统一放在顶部标题栏。
- 从项目目录执行
npm publish会通过prepublishOnly自动运行npm run build。发布前仍需更新版本号。
通用排版保护与并行生成(0.1.18)
- 不同选区可以同时润色、扩写;每个任务独立保留选区原文、位置、模型及处理状态,完成顺序不影响结果。生成期间不会写入文档,接受时按文档逐次写入。
- 一条修订接受后,其他未改动选区沿插件自己的写入记录调整位置,再精确核对完整原文。相同选区的候选、交叠修改或无法追溯的外部保存不自动合并,避免覆盖文字。
- Word 按实际结构保护排版,不依赖文件名或报告内容。普通正文保留字体、分栏、表格边界并随文字流动;固定行距、固定行高等约束会在写回时处理。固定位置框中的长内容须通过渲染检查,可能发生重叠或无法验证时,保留待处理卡片和原文档。
- 检测到可能重叠、裁切或无法确认安全排版时,先提示并保留待处理修订。用户可以点击“仍然接受并写入”,写入后卡片持续提醒从标题栏打开 Office 手动调整排版,保存后自动刷新预览。确认仅针对当前文档和这份修订;不创建编辑副本,也不迁移修订。
整段修订、PPT 跳页与旧 Word(0.1.16)
- Word 跨段选区先核对全部来源,按顺序拼成完整原文,一次提交给模型,生成一份完整修订。不再逐片段调用、逐片段跳过“无变化”;只在整个结果与整个原文相同时显示无变化。模型选择提供第二份扩写时,每一份都是完整选区的完整候选。
- 接受时整体替换该选区,不按生成结果的字数拆回段落;保留选区外的前后文字、圆点、相邻单元格及未选段落。保留原物理段落身份和原生修订记录,预览忽略本次合并产生的已删除空段;撤回恢复完整原文件。引用后的自然语言修改也支持完整跨段选区。
- 当前只支持连续的正文或同一表格单元格内的跨段选区。跨未选中的正文、单元格或图片/链接/复杂域的合并写回会明确拒绝,避免丢内容。同一选区的候选不能批量同时接受。
- PPT 底部页号可以直接输入,按 Enter 或点“跳转”;只接受 1 至总页数的整数,Esc 恢复当前页号。上下页同步页号,重新进入插件恢复阅读页,文件刷新后页数缩小时自动限制到有效页。
- 支持旧
.doc:导入时通过 DSH 的 Office 引擎转换成.docx并保存可修订副本,同名文件自动避让;外部原始.doc保留。已有书架目录中的.doc可阅读、选中引用及对话,点击“转换并编辑”创建并打开可修订的 DOCX 副本;旧 DOC 二进制文件不直接写回。转换失败显示原因且回滚本次导入,缺少 Office 引擎时提示安装组件。
图片文档与选区修复(0.1.15)
- 发送及接受按钮使用 DSH 的主按钮背景、前景和悬停颜色,明暗主题切换即刻生效。
- 图片型 PPTX 封面和页面优先读取完整原图,不再为首页转换整册;复杂页面仍走版式转换。封面加载时先显示标题占位,文档保存后封面缓存自动更新。
- Windows 接入系统 WinRT OCR;缺少中文识别组件时显示安装提示。macOS 使用系统 Vision,无需 Xcode/Swift 编译环境。复杂幻灯片将原生文字与图片 OCR 合并,保留真实文字位置。
- 图片型 PPTX、PDF 的文档提问逐页收集 OCR/原生文字;所选模型在 DSH 中标明支持图片且附件服务可用时,通过 DSH 图片附件读取未识别页面,并把相关页原图附到提问中。图片识别、问答和修订使用所选模型,不自动换模型。
- 对话先显示问题,再显示「正在读取图片页 x / 总页数」动画。逐页记录缓存按文档内容及模型区分;文件变化后重新读取。一次最多读取 160 页;无法识别的页面和预算省略的内容明确告诉模型,避免把局部内容当成全文。
- 「东方证券」这类按视觉行拆成 Word 段落的双栏报告,可精确匹配圆点后的正文与重复片段;跨段改写保留完整选区作上下文,圆点仅保留、不单独扩写。仍逐段核对原文及版本,拒绝猜测写回位置。
- 选区末尾未包含句末标点时,润色、扩写和引用修改不额外补句末标点;保存修订前再检查尾部,避免接受后与选区外的句号重复。
阅读与修订交互(0.1.16)
顶栏使用 DSH 的
data-window-drag标记,参与宿主拖拽区域刷新;标题、文档名、格式徽章和中间空白区域明确设为拖拽区,按钮保持可点击。修复预览滚动后顶栏空白处无法拖拽:正文及对话区域不再继承原生
no-drag,避免已经滚出视口的页面与控件覆盖顶栏的拖拽区域。标题及空白块单独参与宿主的区域刷新。Word 和有原生文字的 PDF 版式支持从空白处拖出矩形选框。框内选中的字会高亮,松手后可引用、复制或进行可用的文字操作;Word 的每个选区都核对源文字和位置,不连续的范围分别处理。 普通拖选移到行外时不会缩回起始行;跨页拖选到上下边缘会自动滚动,完成拖选后的迟到滚动事件不会清掉菜单。拖选期间按 Esc 可以取消。
「清空输入」右侧的模型选择统一用于文档对话、引用修改、润色、扩写、翻译及重新生成;默认跟随 DSH,也可从已配置模型中选择并记住。一次请求及重试保持同一模型;重新生成使用当前选择,失败后的「重试」保留原请求的选择。所选模型不可用时明确提示重新选择,不转用默认模型。
npm 作者字段为
stone086,通过当前 npm 登录用户确认。引用对话明确将总结、概括和提炼要点作为回答;只有要求修改原文时才生成修订。完整回答放入 JSON 的
reply,换行与引号需正确转义。 模型在 JSON 前后附加说明或代码围栏时,可提取唯一的完整决策对象;不会猜测缺失的修改文字或将普通文字当作修订。 格式不完整、空回复或输出截断时自动重试一次,截断时增加输出预算。重试使用同一份问题、引用和位置,不重复保存问题或修订;两次失败后保留问题并提示重新发送。权限、版本变化、配额和取消请求不触发格式重试。 对话记录增加诊断字段completion,仅记录尝试次数、错误类别、结束状态与输出长度,便于排查;不额外保存失败的原始输出。AI 回复右下角显示复制图标与具体时间,悬停时间可查看完整日期。复制整条回复,成功后显示「已复制」;剪贴板权限不可用时尝试本地复制方式。当前 DSH 没有供插件调用的回复朗读接口,未显示朗读按钮。
修订卡片可以点击顶部箭头折叠和展开;折叠后显示结果摘要与状态。切换标签、刷新或重新进入插件时保留折叠状态。
去掉 Word 页面上「选中文字即可引用、润色、扩写或翻译;接受修订后写回 Word。」的说明及其占用的空白行。
文档标题右侧增加「用 Office 编辑」图标,打开书架内的原文件,可以手动修改。DSH 随附的 LibreOffice Kit 只有转换与预览能力,没有桌面编辑窗口;因此调用本机已安装的 Microsoft Office、完整版 LibreOffice、WPS 或 ONLYOFFICE。未找到编辑器时显示安装指引。 保存同一个原文件后,插件确认文件变化稳定,再自动重新读取正文、版式预览和修订;保留对话草稿与卡片折叠状态。检查间隔约 1.5 秒,实际刷新还需等待解析和预览转换。 在 AI 生成或写回期间暂缓刷新,完成后继续检测。文档变化后,旧 Word 修订不能按旧位置接受;另存为其他文件时需将新文件导入书架。
设置中的「改写」更名为「润色和扩写风格」。文风同时用于润色和扩写。
扩写支持「按增加比例」和「按目标字数」。默认增加约 100%,完整结果约为原文的 2 倍;例如增加 200% 表示结果约为原文的 3 倍。 目标字数表示扩写后全文长度,需大于原文,可设 50–8000 字;增加比例可设 10%–500%。 文风不再限制扩写幅度,即使选「简洁精炼」也会充分展开已有要点。自然语言中明确提出的字数或扩写程度优先于默认设置。
文档页合并为单行顶栏,文档名只显示一次,保留返回书架、面板折叠、新建书架和设置。
标签栏最右侧按当前标签显示「清空对话」或「接受全部」,与标签在同一排。
选区菜单「提问」改为「引用」。引用后可输入个性化修改要求,由模型判断是回答问题还是生成修订。 生成修订后对话中提供「查看修订」入口;接受后才写回文件。可继续对话调整上一份草稿。 生成前和生成完成后都核对引用原文与文档版本;不一致时提示重新引用。普通咨询和翻译不生成修订,无变化时直接说明。
在文档空白处右键选择「刷新文档」,重新读取正文、版式预览和修订记录;选中文字的右键菜单仍提供选区操作。
修订卡片增加「删除」,待处理、已撤回、已接受的卡片都可删除,刷新后保持隐藏。 删除已接受的卡片会保留已写入文档的修改;需要还原文件时,先使用「撤回」。
文档对话支持 Markdown 标题、粗体、列表、引用、代码块、链接和表格。
「引用」先把选区放入输入区,保留已写的问题,用户编辑后点击「发送」。 可以单独移除引用。「翻译」直接发送,保留输入框里尚未发送的问题;移除「解释」「重写」。
润色、扩写和翻译使用 DSH 对话原版鲸鱼尾巴动画资源,并显示处理状态;减少动态效果或强制颜色模式下显示静态尾巴。
点击「重新生成」后立即移除当前卡片,再显示生成动画。旧卡片刷新后仍保持删除;删除失败时恢复卡片,生成失败时可使用保存的原文与位置重试。
请求提交时保存独立的原文、文档版本和选区位置。等待期间点击空白处、取消高亮或选择其他文字不会改变请求;切换文档后迟到的结果不会混入新文档。
润色和扩写卡片只显示词级差异和操作按钮。未接受时显示「接受」,接受后显示「撤回」;接受按钮悬停时保持清晰的文字对比度。
润色、扩写结果与原文一致时,直接显示「内容无变化」,不创建修订卡片。两份结果中若只有一份有变化,只保留有变化的那一份。
扩写通常生成一份,由模型判断是否存在另一种有实质差异的扩写方向。只有有必要时才生成第二份。同一句话的待选扩写左右并排,供用户选择。
修订栏默认与文档对话同宽。只有存在两份可比较的待选结果时才自动加宽,并可拖动边界调整;接受或删除其中一份后自动恢复原有宽度,历史卡片改为纵向排列。
切换到其他插件再回来,恢复当前文档、阅读位置、右侧标签和修订栏宽度。
选中文字后即使浮动菜单消失,右键仍可重新打开同一组选区操作。
点击发送后立即显示问题和引文,再显示「思考中」;失败时保留问题和引用供重新编辑。
更新安装包后请完全退出 DSH 再重新打开,macOS 使用 ⌘Q;仅关闭窗口可能仍在运行旧版。
可在插件设置 → 关于确认运行版本为 0.1.19。
Word 选区完整性(0.1.5)
Word 版式拖选使用 PDF 的真实字形宽度和逐字符位置,替代按字体类型估算宽度的透明文字层选区。 高亮、引用与生成修订共用同一份精确原文,保留句尾;表格拖选限制在起始单元格,避免带上相邻格的内容。 表格中的多段内容分别保存 Word 段落及段内位置,重复文字也能写入选中的单元格。 生成前核对选区原文和文档版本,生成期间或接受前文档已变化时拒绝写入。 旧版尚未接受的 Word 修订可能已有漏字选区,升级后需重新选中完整文字生成修订;已接受修订仍可撤回。
Word 版式选句改写(0.1.4)
Word 版式视图优先使用转换后 PDF 的真实文字层,仅没有文字层的页面使用 OCR。
版式显示修改后的当前正文,转换时使用临时副本排除已删除的旧文字;源 Word 文件仍保留原生修订记录。
升级后旧的 Word 预览和封面缓存会自动失效,连续改写不会再被旧修订文字干扰。
Word、PPT、PDF 只显示版式,Excel 保留「版式 / 文本」切换。
Word 移除「原文」入口,润色、扩写始终留在版式;无法定位时在当前页面提示重新选择。
版式文字结合全文阅读顺序及相邻行的精确上下文对回 .docx 正文,区分重复句子,
容许空格、换行及不可见换行符差异,保留逐字符位置。自动编号映射到正文后面的文字,
不会把编号一起替换。跨段选区按段生成修订。文字层不完整且没有足够上下文时仍拒绝猜测位置。
Word 修订保留段落及段内选区位置,同一段中重复文字可准确修改选中的一处。 写回前再次核对该位置的原文;位置失效会拒绝写入。同段批量修订从后往前应用, 避免先写入的文字长度变化影响后面的选区。内置 LibreOffice Kit 用于转换和版式预览, 插件本身通过 OOXML 写回 Word,不能据此视为完整的嵌入式 Word 编辑器。
新机器与预览组件(0.1.1)
插件优先复用 DSH 随附的 LibreOffice Kit 和 Python,不把大型引擎打进插件安装包。
运行路径从当前 DSH 进程、应用安装位置和当前用户的 DSH_HOME / ~/.dsh 自动查找,
支持移动应用、不同用户名,以及 Windows 的 Node/Python 可执行文件布局。
推荐安装或更新官方完整 DSH 桌面版,然后完全退出并重启。 独立安装 LibreOffice 桌面软件不会自动接入这个插件。 若版式预览组件缺失,Word/Excel 的预览页和 PPT 错误提示会提供「查看安装指引」; 设置 → 关于也提供同一入口。已导入的文件会保留,无需重新导入。
命令行或第三方 DSH 若没有携带引擎,可按安装指引使用 npm 将
@deepseek-ai/[email protected](包括 optional 引擎包)安装到
$DSH_HOME/doc-assistant/preview-runtime,安装后重启 DSH,插件会自动查找它。
需要 Node.js ≥ 22.19。引擎的下载大小取决于系统,可能需要数百 MB。
Office 正文提取和修订写回还依赖 DSH 自带 Python 及文档库。
自定义环境仍可通过 DSH_DOC_LIBREOFFICE_CLI、DSH_DOC_NODE、DSH_DOC_PYTHON
指定组件路径。导入时会显示旋转动画、当前文件、文件序号和处理阶段,
封面准备期间提示持续显示;成功、部分成功或失败后会在书架显示结果。
源码安装
插件源码在本仓库,通过软链进入 DSH profile:
PROFILE=~/.dsh/profiles/desktop
ln -sfn /Users/stone/Desktop/ceshi/dsh-doc-assistant "$PROFILE/node_modules/dsh-doc-assistant"
然后在 $PROFILE/cordis.patch.yml 的 - insert: 列表里加一行:
- id: dsh-doc-assistant
name: "dsh-doc-assistant"
这一行做两件事:应用宿主半(注册 doc_* 工具 + /doc-assistant 路由),
并让 dsh-client-modules 扫描到本包,把 lib/client.js 送到 Web GUI。
改动源码后自动热重载,把源码目录加进 HMR watch root:
- id: hmr
disabled: false
config:
root:
- /Users/stone/Desktop/ceshi/dsh-doc-assistant
新增 client 插件不是 HMR 能就地替换的改动 —— 装好后必须刷新一次 Web GUI。 之后改宿主半会热重载;改客户端半要重跑
node dev/build-client.mjs再刷新页面 (除非pnpm run dev:web在跑)。
卸载
PROFILE=~/.dsh/profiles/desktop
rm "$PROFILE/node_modules/dsh-doc-assistant"
# 再从 cordis.patch.yml 删掉对应行与 hmr root
使用
入口:侧边栏「企业文档助手」图标 —— 打开的是书架。
书架(总览)
每个项目是一个独立的架:架头显示项目名与文档数,下面是横向排列的书卡。
封面优先用文档自己的首页(阅读类软件的做法):
| 格式 | 封面 |
|---|---|
| 图片 | 图片本身 |
| 第 1 页 | |
| Word / PPT / Excel | 转 PDF 后取第 1 页 |
| Markdown / 文本 / 代码 | 自动生成(渐变 + 书脊 + 标题排版) |
书卡形状跟随文档自身宽高比 —— 16:9 的幻灯片是横版卡、A4 文档是竖版卡, 所以 PPT 首页不会被裁掉标题,混排起来像真书架。
- 点书 → 进入阅读器;顶栏出现「← 返回书架」
- + 新建书架 → 顶栏右上角,新建一个书架(用系统目录选择器挑根目录)
- 架内 + 添加文档 → 从本机选文件,复制进该书架(重名自动避让成
报告 (2).md) - 右上角 ⚙ → 打开设置窗口
- 封面全自动:上传后自动生成,打开书架时按需渲染;有缓存后是毫秒级
阅读器
左栏是 项目 → 大纲 → 文件目录(阅读时大纲排在最前)/ 中正文 / 右对话,三栏一屏。 两侧各有一个收起/展开按钮(样式与 DSH 自身一致)。
桌面版可拖动单行顶栏的标题及空白处来移动整个 DSH 窗口。 拖拽区至少 44px 高,Mac 侧栏折叠时为窗口控件留出空间;返回、设置等按钮仍正常响应点击。
引用与对话:正文里选中文字 → 浮出工具条 →「引用」把选中内容作为引文 放到右侧输入区 → 输入问题或修改要求 → 点击「发送」。发送后先显示问题和引文,再显示「思考中」。 模型区分咨询与修改要求:咨询直接回答,修改生成待接受的修订,可点击「查看修订」。 可继续对话调整上一份草稿;移除引用或清空输入会停止沿用旧的引用位置。 回答支持 Markdown 排版。对话是每份文档各自的历史,切换文档时自动切换,改写文档后历史仍在。 「翻译」直接将选区送到文档对话,立即显示引文与问题,再显示翻译中的动画。
选区工具条按阅读区与可视窗口的边界定位。靠近边缘时自动移回区域内,窄窗口按需换行,高度不足时可在菜单内滚动。
保留选区时,右键也能打开同一菜单。
改:选中文字点「润色」或「扩写」→ 右栏「修订」标签出现词级差异卡片 (删去文字红底删除线、增加文字绿底下划线)→ 未接受时点击「接受」,写入后点击「撤回」还原。 也可以批量接受互不冲突的修订;同一句话存在多份扩写时需选择其中一份。 卡片上的「删除」只清理卡片;删除已接受的卡片不会撤销文档中的修改。 点击卡片顶部箭头可折叠结果,展开后恢复差异与操作按钮。
标题旁的编辑图标可用本机 Office 打开当前文件。手动修改并保存原文件后自动刷新预览;没有桌面编辑器时,按页面安装指引安装后再点击图标。
普通咨询直接回答;带原文引用的修改要求可生成修订,仍需点击「接受」才写回。
设置窗口
右上角齿轮打开的独立窗口(可拖动标题栏,Esc / 点遮罩 / 关闭按钮三种关法), 左侧分区导航:
| 分区 | 内容 |
|---|---|
| 项目 | 项目 CRUD、多根目录(路径 / 标签 / 只读开关) |
| 封面 | 是否自动生成、送给模型的文档长度、「重建封面缓存」 |
| 对话 | 历史上限、随文档附带的正文长度、携带轮数 |
| 改写 | 风格预设、上下文长度、快照保留数 |
| 关于 | 版本与数据目录 |
「重建封面缓存」是维护动作(清掉缓存让它们自动重生成),不是"手动生成封面"—— 封面本来就是全自动的。
数据存放
| 路径 | 内容 | 权限 |
|---|---|---|
$DSH_HOME/doc-assistant/config.json |
插件设置 | 600 |
$DSH_HOME/doc-assistant/projects.json |
项目注册表 | 600 |
$DSH_HOME/doc-assistant/revisions/<projectId>/<docHash>.json |
未处理与历史修订 | 600 |
$DSH_HOME/doc-assistant/history/<projectId>/<时间戳>-<文件名> |
每次落盘前的原文件快照 | 600 |
$DSH_HOME 默认 ~/.dsh。
开发
node dev/build-client.mjs # 从 src/client/*.js 生成 lib/client.js(必须跑!)
node dev/build-client.mjs --check # CI 用:产物是否最新
node dev/harness.mjs # 宿主半测试
node --test dev/review-regression.mjs # 并发写回 / 整组撤回 / 上传占位回归
node dev/render-test.mjs # 客户端半测试
npm run test:ui # 选区菜单边界 / 缩放 / 交互回归及客户端端到端检查
node dev/spike-client-view.mjs # M0 门禁:conversation.view 注册契约
客户端半为什么需要构建
DSH 的客户端模块系统每个包只服务一个浏览器产物,而客户端半只能 require() 平台种子表
(React 等),拿不到任何 npm 包。所以本包把客户端源码拆成 src/client/*.js(一人一档,不冲突),
由 dev/build-client.mjs 拼成单个 lazy-CJS bundle,并加一个七行的模块注册表,
让这些文件之间还能 require('./dom') 互相引用。
零依赖、零转译、无 JSX。 构建脚本会校验每个文件的 __define('<id>', ...) 声明与文件名一致,
并用 vm.Script 做语法解析——这两道关卡拦住的是"构建成功但产物是坏的"那类事故。
加一个客户端模块
- 新建
src/client/<序号>-<名字>.js - 第一条语句写
__define('./<名字>', (module, exports, require) => { - 只
require('react')与./开头的本包模块 - 重跑
node dev/build-client.mjs
关键约束(踩了就崩)
| 约束 | 说明 |
|---|---|
host.call() 不可用 |
那是动态包(cordis_run)专用。文件型插件一律 fetch('/doc-assistant/...') |
styles.insert() 不可用 |
同上。用 document.createElement('style') |
不能 require npm 包 |
只能用平台种子表 + 本包模块 |
宿主半不能 import '@deepseek-ai/*' |
插件被软链进 profile,裸标识符解析不到 |
| 文档写回必须先备份 | accept 流水线:校验 hash → 备份 → apply → verify → 原子写 |
文档
| 文件 | 内容 |
|---|---|
CONTRACT.md |
接口冻结文档:IPC 路由、数据形状、模块边界、集成裁决 |
docs/SLOT-CATALOG.md |
从 DSH 应用包抽出的 90 个插槽完整目录(ownerProps / standardProps / 注册示例 / 源码路径) |
已知限制与后续
- M1 范围:文本类格式(
.md/.txt/.html/代码)的完整闭环 + 项目管理 + 对话 - M2 计划:
.docx(OOXML 原生w:ins/w:del)、.xlsx、.pptx三种 Writer;PDF 只读预览;书签与高亮 - M3 计划:全文检索、审计日志、文档状态流转、团队共享
- 同一物理文件的
accept/restore/reject已按 canonical 路径串行;批量接受共用一次快照,单条撤回会拒绝并要求整组还原 - 模型工具
doc_apply_revision与面板共用写回逻辑、文件锁、只读及版本检查;旧记录缺少写后指纹时拒绝自动撤销,以免覆盖后续编辑 - 上传使用硬链接原子发布;不支持硬链接的文件系统会拒绝上传,请选择支持的目录
- 图片 OCR 旁注、跨文档引用均未实现
许可
MIT。