折叠推理过程并内联渲染图表,让回复更易读
31.4/100
综合分
2
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/9/23 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
自动兼容检查有告警:未发布到 npm registry,仅可从源码安装。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add qianshe/dsh-assistant-optimization该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · other
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 43 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意未发布到 npm registry,仅可从源码安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✗npm 包dsh-assistant-optimization(未发布到 npm,仅可源码安装)
✓Node 引擎要求 >=20 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/11 07:01:01
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
读写/删除本地文件读取剪贴板或密钥环境变量发起外部网络请求
查看扫描证据(共 47 处,展示前 36 条)
- 发起网络请求lib/client.js:1625
fetch(KEY_ENDPOINT, { method: "GET" }) - 发起网络请求lib/client.js:1633
fetch(KEY_ENDPOINT, { method: "GET" }) - 发起网络请求lib/client.js:1642
fetch(KEY_ENDPOINT, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ key: k }) }) - 发起网络请求lib/client.js:1655
fetch(KEY_ENDPOINT, { method: "DELETE" }) - 发起网络请求lib/client.js:2215
return fetch(ENDPOINT, { - 发起网络请求lib/client.js:2663
return fetch(RESUME_ENDPOINT, { - 读取本地文件lib/fast-context/tool.js:155
stat = statSync(projectRoot); - 读取本地文件lib/fast-context/key-source.js:42
if (!existsSync(path)) return ""; - 读取本地文件lib/fast-context/key-source.js:45
return readFileSync(path, "utf8").trim().replace(/^["']|["']$/g, ""); - 写入本地文件lib/fast-context/key-source.js:59
mkdirSync(dirname(path), { recursive: true }); - 写入本地文件lib/fast-context/key-source.js:61
writeFileSync(path, `${String(key).trim()}\n`, { encoding: "utf8", mode: 0o600 }); - 读取本地文件lib/fast-context/key-source.js:72
if (!existsSync(path)) return false; - 删除本地文件lib/fast-context/key-source.js:73
rmSync(path, { force: true }); - 读取本地文件lib/fast-context/extract-key.js:112
if (!existsSync(credentialsPath)) { - 读取本地文件lib/fast-context/extract-key.js:123
text = readFileSync(credentialsPath, "utf8"); - 读取本地文件lib/fast-context/extract-key.js:193
if (!existsSync(dbPath)) { - 写入本地文件lib/fast-context/extract-key.js:216
copyFileSync(dbPath, snapshot); - 删除本地文件lib/fast-context/extract-key.js:219
try { rmSync(snapshot, { force: true }); } catch { } - 删除本地文件lib/fast-context/extract-key.js:250
try { rmSync(snapshot, { force: true }); } catch { } - 读取本地文件lib/fast-context/extract-key.js:268
if (!existsSync(source.path)) continue; - 读取本地文件lib/fast-context/executor.js:45
if (existsSync(override)) { - 读取本地文件lib/fast-context/executor.js:54
if (typeof mod.rgPath === "string" && mod.rgPath !== "" && existsSync(mod.rgPath)) { - 读取本地文件lib/fast-context/executor.js:91
if (existsSync(candidate)) return candidate; - 读取本地文件lib/fast-context/executor.js:113
if (typeof mod.rgPath === "string" && mod.rgPath !== "" && existsSync(mod.rgPath)) { - 读取本地文件lib/fast-context/executor.js:224
if (!existsSync(rp)) { - 读取本地文件lib/fast-context/executor.js:288
const stat = statSync(rp); - 读取本地文件lib/fast-context/shared.js:40
entries = readdirSync(dir, { withFileTypes: true }).filter((e) => !e.name.startsWith(".")); - 读取本地文件lib/fast-context/shared.js:111
let entries = readdirSync(projectRoot).sort(); - 读取本地文件lib/fast-context/cache.js:66
entries = readdirSync(dir, { withFileTypes: true }); - 读取本地文件lib/fast-context/cache.js:78
const st = statSync(full); - 读取密钥环境变量lib/fast-context/windsurf.js:113
const key = process.env.WINDSURF_API_KEY; - 发起网络请求lib/fast-context/windsurf.js:214
const doFetch = () => fetch(url, { - 发起网络请求lib/fast-context/windsurf.js:276
const doFetch = () => fetch(url, { - 读取本地文件lib/fast-context/content-embed.js:97
content = readFileSync(fullPath, "utf-8"); - 读取本地文件lib/fast-context/path-safety.js:31
const canonicalRoot = existsSync(lexicalRoot) ? realpathSync(lexicalRoot) : lexicalRoot; - 读取本地文件lib/fast-context/path-safety.js:59
if (existsSync(lexicalTarget)) {
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 折叠推理内容
- 内联渲染图表
DSH 插件:把渲染出错的思考/推理内容折叠成可收起区块,并内联渲染 mermaid 图表。
README
由 DeepSeek 最新模型翻译生成dsh-assistant-optimization
一个面向 DSH web profile 的插件:让模型输出更好读,让你的 prompt 更好写。
功能
八项能力,开箱即用。官方渲染从不被替换——插件遮蔽 DSH 组件后把渲染委托回去,所以 Markdown、工具卡片、图片、表格的行为与原版完全一致。
| | 能力 | 做什么 |
| 💭 | 推理折叠 | 把误渲染进正文的推理过程折叠进原生 "Think" 区块 |
| 📊 | Mermaid 图表 | 把 mermaid 代码块渲染成可交互 SVG(缩放 / 拖拽 / 触摸) |
| ✎ | 工具调用分组 | 连续工具调用收成一行「# bash · N 个工具」;中间夹思考行不打断分组——跨思考行合并,折叠态思考行随组收起、展开态与成员同款缩进 |
| ✨ | Prompt 增强 | 一键把粗糙草稿改写成更清晰的指令 |
| ▶ | 断点续发 | 手动中断或会话出错后,发送键变为播放键——悬停显示提示,单击从断点续跑,使用当前选中的模型。输入文字或开始新一轮对话会立即恢复正常发送键。 |
| 📁 | 回合过程折叠 | 回合结束后,过程内容(思考、工具调用、中间正文)自动收起为一行「已完成 · 时长」,总结回复保持展开;运行中不折叠。
展开完整文档(README 剩余 1 节)
dsh-assistant-optimization 一个面向 DSH web profile 的插件:让模型输出更好读,让你的 prompt 更好写。 功能 八项能力,开箱即用。官方渲染从不被替换——插件遮蔽 DSH 组件后把渲染委托回去,所以 Markdown、工具卡片、图片、表格的行为与原版完全一致。 | | 能力 | 做什么 | | 💭 | 推理折叠 | 把误渲染进正文的推理过程折叠进原生 "Think" 区块 | | 📊 | Mermaid 图表 | 把 mermaid 代码块渲染成可交互 SVG(缩放 / 拖拽 / 触摸) | | ✎ | 工具调用分组 | 连续工具调用收成一行「# bash · N 个工具」;中间夹思考行不打断分组——跨思考行合并,折叠态思考行随组收起、展开态与成员同款缩进 | | ✨ | Prompt 增强 | 一键把粗糙草稿改写成更清晰的指令 | | ▶ | 断点续发 | 手动中断或会话出错后,发送键变为播放键——悬停显示提示,单击从断点续跑,使用当前选中的模型。输入文字或开始新一轮对话会立即恢复正常发送键。 | | 📁 | 回合过程折叠 | 回合结束后,过程内容(思考、工具调用、中间正文)自动收起为一行「已完成 · 时长」,总结回复保持展开;运行中不折叠。中断续跑的多段回合归并为一个组,运行中插话随组收起并显示「· N 条插话」;插件接管内置转写模式避免双重折叠 | | 🛰️ | 语义搜索 | context_search:用模糊描述定位代码(Windsurf 驱动) | | 🧹 | 归档会话清理 | 把归档藏起来的会话列出来、按勾选释放磁盘,也能取消归档——一键完成,不用停宿主,不用手改 JSON | 推理折叠 部分模型(走 OpenAI 兼容接口、没有独立 reasoning_content 通道的)会把推理过程直接输出到正文: 用户想要了解 X,我应该先解释 Y…… 这是对你问题的回答…… DSH 会把整段当作一块正文渲染。本插件在可配置的标记处拆开,推理部分折叠进原生 "Think" 区块,正文保持可见。在 设置 → 通用 → Thinking Tag Markers 里管理标记。 Mermaid 图表 mermaid 代码块就地渲染为交互式 SVG。右上角按钮缩放与复位,滚轮缩放,鼠标或触摸拖拽平移。 编辑 Diff 数值(已退役) dsh 0.1.2+ 的官方 Write、Edit 行原生渲染 diff 统计,插件自己的徽标自 v1.8.0 起退役。模块保留以兼容旧版 host,但在当前版本上不再注册任何内容。 Prompt 增强 发送按钮左侧有一个星形按钮,用输入框里当前已选的模型把粗糙草稿改写成更清晰的指令。只发一次普通 chat 请求——不创建会话,不写日志——草稿原地替换,按 Ctrl/Cmd+Z 可撤销。 请求进行中显示旋转进度环与「增强中」,完成后变绿对勾;失败时图标闪红、原因写进 tooltip,且草稿绝不会被清空。tooltip 使用与 DSH 原生按钮统一的 CSS 样式,还会报告上次调用实际收到了多少上下文——改写不理想时这是第一个该看的地方。 断点续发 当会话异常停止——用户点了停止或会话出错——发送按钮变为 ▶ 播放键。悬停时显示与 DSH 原生按钮统一的提示(「断点续发」)。 - 单击续跑:通过宿主路由发送续跑信号,agent 从中断处继续,使用输入框中当前选中的模型。 - 即时恢复:在草稿中输入文字、或 agent 开始运行时,立即恢复正常发送/停止按钮——不会卡在播放图标。 - 判定逻辑:直接读 session.chat.timeline 中最后一轮已关闭 turn 的 turn/end 原因。aborted(用户停止)、error(会话出错)、max-tokens(截断)与 interrupted(dsh-session 崩溃修复合成的终态)触发播放键——与宿主路由的 RESUME_TERMINAL_KINDS 同集;正常完成及其他终态不触发。running 位只有在时间线佐证(存在 open turn)时才拦截:时间线全闭 + running=true 是陈旧位(宿主崩溃残留),此时落到终态判定,让崩溃过的会话能被 ▶ 唤醒,而不是永远卡在「运行中不可操作」。 - 空标记行:续跑标记进入对话流时,插件将空白气泡 + 复制按钮替换为一条低调的「已从中断处继续」提示。 - 实现方式:CSS 叠加——通过 data-dsao-resume 属性隐藏官方按钮 SVG 并注入播放 SVG,不干扰 React 重渲染周期。 回合过程折叠 覆盖官方折叠。 dsh 0.1.2+ 自带回合过程折叠(设置 → 对话显示 → Compact)。本插件现在会接管该设置:这里开启回合折叠时,官方模式被强制为 Normal,只有插件自己的折叠(时长 + 插话计数、断点链合并)生效;这里关闭则交还给官方 Compact。两边任意切换都会重新对齐。 回合运行中不做任何改动——原生的 "Deep diving…" 状态行 + 计时就是"运行中"显示。回合结束(结论落定)的瞬间,该回合的过程内容——思考行、工具调用、中间正文——自动收起为一行折叠头:已完成 · 时长(出错/停止的回合显示已出错/已停止)。运行中插入的插话(steering)随组收起,折叠头会显示「· N 条插话」。保持可见的:你的提问、总结性回复、以及它的操作行(复制等)。点折叠头可展开看全过程,再点收起。展开/收起选择只保存在内存里,刷新页面后默认收起。 折叠计划完全由会话快照计算:轮次分组走 chat.locations,完成判定走 turn/end 原因,总结性回复由官方 turn-tail 节点的 closing 指针定位,时长取自轮次起止时间戳(与原生计时同一数字)。在 设置 → 通用 → Turn Folding 里开关。 语义搜索(context_search) 面向模糊或不清晰搜索的宿主端工具:传一句自然语言描述,即可拿到匹配文件、行范围与代码。内部跑一个 agentic 搜索循环,基于 fast-context 思路、由 Windsurf key 驱动。 key 门控——核心设计。 工具与其一句提示词引导只在能解析到 Windsurf key 时才注册。没有 key 时两者都不注册,模型因此永远不会被告知一个它调不了的工具。 key 按以下顺序解析(取第一个命中):WINDSURF_API_KEY 环境变量 → 手动填写(设置 → 通用 → Windsurf API Key,存 ~/.dsh/dsao-windsurf-key,权限 0600)→ 本地自动读取已登录的 Windsurf/Devin 编辑器 state.vscdb。DSAO_FC_AUTO_KEY=0 关闭自动读取。非官方协议提示见 lib/fast-context/NOTICE.md。 归档会话清理 dsh 0.1.2 里「归档」只是隐藏:归档集合是一个显示过滤器,被归档的会话会同时从分组列表、扁平列表和搜索里消失,而它的会话正文、投影缓存行、工作区记账一分不少地留在 ~/.dsh 下。整个 GUI 没有任何「取消归档」入口,持久层也没有删除 API——官方 README 把它写成「带外维护(out-of-band backend maintenance)」。于是磁盘上出现一片既看不见、也找不回、更没法清的死角。 设置 → 归档会话 —— 设置导航里的独立分区(不塞在通用设置下面:这是一整页操作流程,不是一条偏好开关)—— 会扫描归档名单,逐条给出:标题(取自客户端会话列表)、项目名(完整路径挪到悬停提示里)、大小、最后写入时间。然后可以: - 删除已选 —— 连根拔掉后端为该 id 推导出的会话目录(目录里的全部正文代际 session.jsonl[.zstd] 与 session.vN.jsonl[.zstd],以及其它任何属于该会话的产物;只删 locate() 点名的那一个文件的话,重启后旧代际会重新成为最新正文,会话又从「未分组」里冒出来)、删除投影缓存行、把工作区记账里的该会话摘掉、广播 api-session/removed 让所有已打开的 GUI 立即摘掉侧栏行(不再残留到「未分组」、不再挂着陈旧的「运行中」状态点)、最后清掉归档条目。两步确认:第一次点击让按钮进入待确认态,第二次才真删。不可逆——正文就是那段历史的唯一副本,所以每行同时提供导出链接(复用官方 session.export 路由),可以先拿走 ZIP 再删。 - 取消归档已选 —— 只把 id 写回归档名单之外。文件一字不动,侧栏里立刻回来。这就是官方缺的那个「取消归档」。 - 全选可删 —— 只选中守卫允许的那些。 - 强制模式(开关,仅在宿主暴露 agents 注册表时出现)—— 解锁仍然常驻的归档会话:运行中的先走官方停止键同一个 agent.cancel(排队输入一并丢弃),等它静默(settle)之后才删除。等不到静默的会话直接拒绝(not-settled)而不会在其活写入者下面 unlink——JSONL 后端按批打开正文文件,未静默的 writer 下次 flush 会重建半截文件。当前正在查看的会话在任何模式下都不可勾选。 这里碰不到任何你没归档的会话:候选列表完全由归档名单驱动,未归档的 id 会被拒(not-archived)——force 也越不过这条授权边界,被拒的会话连 cancel 都不会发生。常驻会话必须开强制模式才会出现在候选里,并按宿主的真值源细分为 running(代理正在执行)与 attached(常驻但空闲)——上一版把两者混叫 live-session 一律拦下,正是"空闲常驻被误标运行中、删不掉"的根源。删除的单位是后端自己 locate() 推导出的会话目录 ///,并且是递归清除:JSONL 后端在该目录里按 Session 格式代际各存一份日志,读取时"目录里版本号最大的那份"就是该会话,所以只删当前代际会留下旧代际让会话复活。递归被三道前置校验限定住作用域:路径只能来自 locate()(调用方输入永不参与拼路径)、locate() 给出的文件名仍需匹配 session(.vN)?.jsonl[.zstd]、目录名必须等于该 id(或其路径段编码形式)。任一条不过就报 kept 并保持归档(隐形、可重试,绝不静默摘掉过滤器让会话浮出), 那一层永远不碰,兄弟会话因此不可能被带走。 存储清单的两种历史形态都读:老后端 list() 返回裸 header,新后端返回 SessionPersistenceSnapshot 信封(header 嵌在 .header 里)。只认前者正是本次故障的根因——在当前宿主上每次删除都"找不到目标",于是一个字节都没删、归档条目却被摘掉,重启后会话带着完整的文件重新出现在「未分组」。如今映射不到任何 id 的清单会被整批显式拒绝(扫描报错、删除抛错),绝不再被误读成"这些会话本就没有正文"。 不用停宿主就能做。在 host 外面改 ~/.dsh/storages/workspace.json 是不安全的:JSON 的 single 布局内存权威、每次写整体重写、且无跨进程锁;但在 host 进程内,这些事实是通过各 owner service 自己的串行写链拿到的,内存与磁盘同步移动,workspace 的 follow 流会重发归档集合——已经打开的 GUI 标签页不用刷新就更新。两处需要碰私有字段(归档名单没有公开的可写入口,投影缓存 table 是服务内部句柄):两者都是调用时探测,拿不到就如实降级报告,不猜路径、不崩。 这一页只用宿主自己的 --dsw-alias-* 设计令牌说话——不写死任何颜色,所以浅色/深色主题都跟着外壳走;四种状态全部建模:扫描中的骨架行、明确的空态、可重试的错误横幅、以及"只有零拒绝零失败才用成功语气"的结果条。交互态(hover、focus-visible、disabled、表头 sticky、prefers-reduced-motion)放在一段带 id 的作用域样式里而不是 inline style——因为这些状态 inline 表达不了。规则与理由见 docs/technical-reference.md §11.7。 安装 dsh plugin --profile web add github:qianshe/dsh-assistant-optimization dsh web 打开 http://127.0.0.1:3080 ,插件自动生效。安装、更新、卸载后都需要重启。 | 从本地源码 | dsh plugin --profile web add . | | 更新 | dsh plugin --profile web update dsh-assistant-optimization | | 卸载 | dsh plugin --profile web remove dsh-assistant-optimization | 配置 | 设置项 | 默认值 | 说明 | | Thinking Tag Markers | [""] | 分割推理与正文的标记。支持多个。在 设置 → 通用 编辑。 | | Turn Folding | 开 | 已完成回合的过程自动收起为一行「已完成 · 时长」。在 设置 → 通用 编辑。 | | Windsurf API Key | — | context_search 的凭据。解析顺序见上。无 key 时该工具不注册。 | 要求 - DSH (DeepSeek Harness) web profile - 仅 mermaid 图表需要网络,且只在出现图表时从 CDN 加载 开发 node test/diff-stats.test.mjs node test/ensure-badge.test.mjs node test/context.test.mjs node test/prompt-enhance.test.mjs node test/host-prompt-enhance.test.mjs node test/resume-gate.test.mjs node test/resume-route.test.mjs node test/resume-continuity.test.mjs node test/turn-fold.test.mjs node test/fast-context-gate.test.mjs node test/content-embed.test.mjs node test/turn-fold-sync.test.mjs node scripts/repro-switch-back.cjs node scripts/lib-sync-check.cjs node scripts/build-client.cjs verify node --check lib/client.js 测试从 lib/client.js / lib/index.js 取出真实模块。 lib/client.js 是构建产物:改 src/ 后运行 node scripts/build-client.cjs build 重新生成,不要手改。slot key、优先级、参考提取契约、失败状态码映射与完整文件结构见 docs/technical-reference.md。 许可证 MIT
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
qianshe/dsh-assistant-optimization
折叠推理过程并内联渲染图表,让回复更易读
相关插件 · 其他
模型破甲清洗HunYiSage/dsh-purge
⚔️ DeepSeek Harness 网络安全红队工具dsh-purge
★ 16,993已汉化DeepSeek 客户端
73
女娲蒸馏alchaincyf/nuwa-skill
输入名人名字,提炼其思维模型与决策方式供你调用
★ 37,308已汉化DSH
72
逆向分析桥接Fanqi89/dsh-rea
REA(Reverse Engineer Anything)MCP 桥接,用来把 REA 逆向工具接入 DSH 插件
★ 51已汉化DSH
72
语音女友beiyege-01/dsh-voice-ai-girlfriend
语音 AI 女友Voice AI girlfriend for DeepSeek Harness:Whisper…
★ 888已汉化DSH
71.6
红队越狱测试套件Minglink/dsh-infinite-gen-5
DeepSeek v4.1 flash 逆向工具无限五代 求 Star 收藏 ⭐欢迎大家提交项目的改进
★ 3,759已汉化DSH
71.4
协同办公空间dream-num/univer-workspace
一个让人类与 AI Agent 共同创作、协作和审阅的开源 Office 工作空间。
★ 2,269已汉化DSH
70.8
这是你的仓库?认领条目