跳过主要内容
P

dsh-composer-history

perrylink/dsh-composer-history

Web 作曲器终端风格输入历史:边缘优先的方向键召回并精确还原草稿与光标、浏览器本地持久化历史、Ctrl+R 反向搜索,以及滑动上下文感知;0.5.0 再加智能输入层——跨会话片段库(/save、/load)、带变量的提示词模板、复用洞察与压缩摘要高亮。

安装

dsh plugin --profile web add github:perrylink/dsh-composer-history

README

dsh-composer-history 横幅:在作曲器首行按 ↑ 召回历史;右侧是历史栈(session / persisted / workspace / [compacted])、暂存 {draft, caret} 与 Ctrl+R 搜索覆盖层

dsh-composer-history

像终端一样按 ↑ 找回历史——你打到一半的草稿一个字都不会丢。

DeepSeek Harness Web GUI 作曲器的输入历史层:边缘优先的方向键召回、浏览器本地持久化、Ctrl+R 反向搜索、片段与模板库,全部只落在普通草稿里。

安装 · 配置 · FAQ · 简体中文 · English · Español · Português · हिन्दी

License DSH npm CI Node

Stars npm downloads dshfind OpenSSF Scorecard DSH Market Gitee

dsh plugin --profile <name> add dsh-composer-history

社区插件,与 DeepSeek 官方无关。唯一仓库:https://github.com/PerryLink/dsh-composer-history(Gitee 为镜像)。

它是什么

它把终端的输入历史搬进 DeepSeek Harness 的 Web 作曲器:光标在首行时按 ↑ 召回上一条你发过的消息,光标不在首行时 ↑/↓ 照常移动光标,绝不抢键。

第一次召回会暂存 {draft, caret},回到底部或按 Esc 时两者精确还原——你打到一半的草稿不会被清空。历史存在浏览器本地,刷新页面、切换会话都还在;Ctrl+R 打开反向搜索,历史、片段、模板一起搜。harness 自动压缩上下文时,检查点摘要以 [compacted] … 条目加入召回与搜索,并弹出一条可一键填入 /compact 的短暂通知。

纯 UI 行为:不产生会话事件、不改 agent-loop、不发模型请求。召回的文本只进入普通作曲器草稿;只有你按下 Enter,它才会到模型。

DraftRecall 状态机:IDLE ⇄ BROWSING 共用 phase=plain 门控;首行 ↑ 暂存 {draft, caret} 并填入最新条目,末行 ↓ 或 Esc 还原;Ctrl+R 是绕过状态的并行搜索通道;所有效果只走 setDraft,数据落在四个 localStorage 键

三步上手

  1. 安装(三选一):

    # git 通道(最新 main;等价于 git+https://github.com/PerryLink/dsh-composer-history.git)
    dsh plugin --profile web add github:PerryLink/dsh-composer-history
    # npm 通道(已发布版本)
    dsh plugin --profile web add dsh-composer-history
    # tarball 通道:本仓库 pnpm pack 后
    dsh plugin --profile web add ./dsh-composer-history-<version>.tgz
    

    npm 包自带构建产物;源码 checkout 须先 pnpm run build——客户端包检查会拒绝未构建的 bundle 启动。

  2. 最小配置(默认即可用;bundle patch 只插入一行,其余取 Config 默认值):

    - insert:
        - id: composer-history
          name: dsh-composer-history
    
  3. 验证已生效:

    dsh --profile web --dump-config | grep -A3 'id: composer-history'
    

    输出里应能看到 id: composer-history 与 name: dsh-composer-history。重启后在 Web GUI 把光标放到作曲器首行按 ↑,最新一条用户消息会填入草稿。

卸载:dsh plugin --profile web remove dsh-composer-history(或从 profile patch 删掉该行)。

从 DSH Desktop 市场安装

所有 PerryLink 插件均可在 DSH Desktop 内置市场中浏览:市场 → 来源 → 添加来源 → 粘贴 https://perrylink-dsh-catalog.perrylink.workers.dev/catalog-source.json → 选中。安装仍需通过市场的 npm 身份校验与你的确认。

核心能力

dsh-composer-history 只做一件事:让作曲器记住你发过什么,并在你需要时原样还回来。

  1. 边缘优先的方向键召回——裸 ↑/↓ 先移动光标;只有当光标位于首行/末行时才触发历史召回。首次召回暂存 {draft, caret},回到最新一条(或按 Esc)时两者精确还原——从不被清空。
  2. 持久化历史——每条已发送消息追加到有界的浏览器本地存储,所以召回能活过页面刷新,并跨会话可用。
  3. 反向搜索——Ctrl+R(可配置)在合并的历史、片段与模板上打开查询覆盖层。
  4. 智能输入层——/save//load 片段、带 {{workspace}}/{{session}}/{{draft}} 变量的提示词模板,以及浏览器本地的复用洞察。
  5. 感知滑动上下文——压缩摘要以 [compacted] … 条目加入召回与搜索,每次压缩弹出带一键 /compact 填入的短暂通知。
  6. 版本化 JSON 备份——历史、片段、模板、洞察四个库导出/导入为一份带 schema 版本的文档;导出可下载或复制,导入可选文件或粘贴。

纯 UI 行为:不产生会话事件、不改 agent-loop、不发模型请求。召回的文本只进入普通作曲器草稿;只有你按下 Enter 才会到模型。

keydown ──interceptor──▶ setDraft ──▶ draft ──Enter──▶ model
                            ▲                              │
                            └──── localStorage ◀───────────┘
                                  dsh.composer-history.v1 · snippets.v1
                                  templates.v1 · insights.v1

命令与工具面

表面类型说明
ArrowUpkeybinding边缘优先的 ↑/↓ 召回——暂存 {draft, caret},回到底部或按 Esc 时两者精确还原
Ctrl+Rkeybinding在合并的历史、片段与模板上打开反向搜索覆盖层
/savecommand把当前草稿存为带名称与标签的片段
/loadcommand在光标处插入已保存的片段
templatesUI历史、片段、模板、洞察四个库的版本化 JSON 备份导出/导入(仅显式点击触发)
composer-historysettings form该 profile 条目自身的活 Config 表单——把解析后的配置(cordis.yml 基线与 profile 覆盖)带进浏览器半边

按键行为

按键状态行为
↑IDLE,光标在首行暂存 {draft, caret},填入最新条目,光标到末尾(无历史 → 放行)
↑BROWSING,光标在首行走向更早条目;在最旧一条按住不动(拦截,无任何变更)
↑光标不在首行完全放行(浏览器移动光标)
↓IDLE始终放行(普通光标移动)
↓BROWSING,光标在末行走向更新条目;到最新一条 → 还原 savedDraft + savedCaret → IDLE
↓光标不在末行完全放行
EscBROWSING(restoreOnEscape: true)还原 savedDraft + savedCaret → IDLE,拦截
Esc其他情况放行(菜单/弹窗的 Escape 语义不受影响)
Ctrl+↑/↓enableCtrlAlias: true与裸方向键一致
searchKeys chord作曲器聚焦、plain 阶段、无菜单/选区/IME打开反向搜索;浏览结束,当前显示的文本成为草稿
Shift/Alt/Meta+方向键、IME、选区任意始终放行

upKey/downKey/escapeKey/searchKeys 可以重命名上表按键;修饰键策略(以及搜索组合键的精确修饰键匹配)不变。搜索覆盖层内:↑/↓ 移动匹配选择(选中行自动滚入可见区域)、Enter 填充、Esc 取消、点击选中、点击面板外取消;匹配到的子串在每行中高亮显示。

示例

以下为插件真实入口;安装后调用一个即可。

详细示例——命令 /save,输入:

/save ship-check --tag=release,ops

输出:

snippet saved: ship-check

Observed from plugins/dsh-composer-history/README.md §Smart input layer (lines 199-205); code at src/client/index.ts:314-327

失败分支——输入:

/load nope

输出:

no snippet named nope (open Ctrl+R search to browse snippets)

Observed from plugins/dsh-composer-history/src/client/index.ts:330-333; plugins/dsh-composer-history/src/client/notice.ts:62-65

简短示例:/load · /compact

反向搜索

  • 打开:作曲器聚焦且输入处于 plain 阶段时按下 searchKeys 组合键(此时 Ctrl+R 也会拦截浏览器的页面刷新——按键只在作曲器内被消费)。
  • 过滤:对合并历史(当前会话 + 持久化 + 工作区条目)做子串匹配;是否区分大小写由 searchCaseSensitive 决定;匹配到的子串在每行中高亮。
  • 选中:Enter 填充草稿并把光标移到末尾——与普通召回同一条 setDraft 写路径。召回文本只有在你随后按 Enter 时才会到达模型。
  • 取消:Esc 或点击面板外;草稿不被触碰。

智能输入层

在终端式历史之上,三套浏览器本地库把作曲器变成可复用的输入面。下面的所有内容都存于 localStorage(键 dsh.composer-history.snippets.v1、.templates.v1、.insights.v1),绝不触碰网络,每个开关都是 Config 字段。

片段(跨会话命令库)

/save ship-check --tag=release,ops
check the build, run the smoke suite, tag the release        ← 草稿其余部分就是片段
/save ship-check                                             → "snippet saved: ship-check"
/load ship-check                                             → 片段填入作曲器
Ctrl+R → 搜索面板在历史旁列出片段(绿色徽标 = 名称)
  • /save <名字> 消费这次 Enter,把草稿(去掉命令那一行)以 kebab-case 名称(可带标签)存下,并清空作曲器。没有可保存的内容 → 弹出错误通知,命令绝不发送。
  • /load <名字> 在光标处插入片段(整段替换、光标到末尾)并计一次使用。
  • 作用域:带工作区 cwd 保存的片段是工作区作用域;不带的是全局。maxSnippets 限定库大小;同名保存会替换。
  • 插件从不发送:每次填入都落在普通草稿里,Enter 永远属于你。

带变量的提示词模板

模板是带 {{variable}} 占位符的存储提示词文本。搜索面板以紫色徽标列出;选中一条会从实时会话填充变量并插入结果。内置变量:{{workspace}}(会话的 cwd)、{{session}}(会话 id)、{{draft}}(当前草稿)。引用未知变量的模板会响亮失败并列出缺失项——半填充的提示词比报错更糟。

整个库——历史、片段、模板与洞察——通过面板的 Export JSON / Import file 动作导出/导入为一份版本化 JSON 文档,详见下面的「备份导出与导入」。这是显式的用户操作;插件从不自行写文件。

复用洞察

每条新提交的用户消息(以及每次片段加载)都会以精确文本为键写入一条浏览器本地使用记录。当你输入时,一旦草稿匹配到至少在 insightMinUses(默认 2)个会话里用过的提示词,作曲器下方的小提示就会显示 used M× in N sessions · 在 N 个会话里用过 M 次。用 enableInsights 开关;统计只包含去重后的文本与计数器。

压缩摘要高亮

Ctrl+R 给 [compacted] … 摘要加琥珀色徽标(历史不加徽标),片段绿色、模板紫色——面板的来源一眼可见。用 enableCompactionHighlight 开关。

备份导出与导入

四个浏览器本地库统一导出/导入为一份带版本号的 JSON 文档。面板的 Export JSON / Copy JSON / Import file / Paste JSON 操作完全在浏览器内完成:导出时下载或复制到剪贴板,导入时选文件或粘贴文本——不会上传任何内容,不涉及宿主 RPC 或网络调用。

文档结构

{
  "schemaVersion": 1,
  "exportedAt": 1735689600000,
  "data": {
    "history": ["…"],
    "snippets": [{ "name": "…", "text": "…", "tags": [], "scope": "global", "createdAt": 0, "updatedAt": 0, "useCount": 0, "lastUsedAt": 0 }],
    "templates": [{ "name": "…", "text": "…", "description": "", "updatedAt": 0 }],
    "insights": [{ "text": "…", "sessions": [], "uses": 0, "lastUsedAt": 0 }]
  }
}

合并与冲突策略

  • 历史条目是纯字符串,按精确文本去重;重复或空白条目被跳过,绝不覆盖。
  • 片段与模板按 name 为键;洞察按精确 text 为键。同键冲突时最新时间戳胜出(片段/模板看 updatedAt,洞察看 lastUsedAt);更旧或等时间戳的导入被跳过,新键追加。
  • 导入遵守 maxPersisted 与 maxSnippets;模板与洞察止于固定协议上限(各 500)。
  • 结果通知会报告写入多少条、跳过多少条(更旧/重复)。

模式版本

schemaVersion 从 1 开始。导入按版本逐步迁移(一次一个版本),未来格式可就地升级旧文档。schemaVersion 高于当前构建理解的文档以错误拒绝——绝不静默丢弃或部分合并;过旧无法迁移的版本同样拒绝。

滑动上下文

harness 核心给每个 dsh 会话提供滑动上下文窗口——与 Claude Code 和 Codex 同款的工作流:当会话接近模型的上下文上限(或提供方回报溢出)时,harness 会自动压缩——更早的轮次被总结为留在会话记录中的 compaction 检查点标记,模型只保留摘要加上最近的尾部,会话继续;/compact 可随时手动触发同样的压缩,标记在记录中渲染为可展开的「上下文已压缩」行。

dsh-composer-history 把作曲器接入这个工作流,让上下文窗口滑动时你的输入历史一条不丢:

  • 召回跨压缩留存——被遮蔽的轮次仍留在 Chat 视图发布的已结算会话里,↑ 依旧能走过检查点前后你发送过的每一条消息。
  • 摘要加入历史——每个检查点的摘要文本以 [compacted] … 条目进入 ↑ 召回和 Ctrl+R 搜索(开关:includeCompactionSummaries),模型不再逐字看到的上下文仍然一键可达。
  • 压缩通知——页面打开期间有检查点落地时,底部弹出短暂通知(Claude Code 的「自动压缩会话…」时刻),附摘要片段和一键填入 /compact 按钮(showCompactionNotice、compactCommandText);填入只进普通草稿,只有你按 Enter 才发送。
  • 搜索计数——Ctrl+R 面板新增实时的 N entries / N matches 状态行,长条目限两行显示。

压缩本身(阈值、摘要模型、/compact)由 harness 核心的 compaction 插件负责——本插件只观察 Chat 视图的会话投影(uiConversation.binding(id).target('chat').legacy.nodes)已经发布的检查点标记,因此不需要任何 agent-loop 或模型请求改动。

配置

所有可调项都是 Schemastery Config 字段(可从 cordis.yml 与该条目的设置表单修改;profile patch 即持久化文档)。按 id 的覆盖会替换整行——重新列出你需要的每个键。非法枚举值会响亮地中止整个 dsh 启动,设置表单的编辑也会在持久化前由宿主拒绝非法值。

最常用的键:

键默认值含义
recallWithDraft'save'召回模式(save / gate):save 在召回前暂存非空草稿;gate 仅空草稿才召回(Claude/Codex 式门控)
restoreOnEscapetrueEsc 结束浏览时还原暂存的草稿
edgeMode'logical'边缘判定模式(logical / visual):按 \n 行,或按测量出的折行
maxHistory500召回条目上限(保留最新);0 = 不限
historyScope'session'历史范围(session / workspace):workspace 把其他已列表会话的用户消息排在当前会话之前
enableSearchtrue启用 Ctrl+R 反向搜索覆盖层
maxSnippets200最大存储片段数;0 = 不限
完整配置表(25 个键)
键默认值含义
recallWithDraft'save'召回模式(save / gate):save 在召回前暂存非空草稿;gate 仅空草稿才召回(Claude/Codex 式门控)
restoreOnEscapetrueEsc 结束浏览时还原暂存的草稿
edgeMode'logical'边缘判定模式(logical / visual):按 \n 行,或按测量出的折行
enableCtrlAliastrue让 Ctrl+↑/↓ 与裸方向键行为一致
restoreCarettrue回到底部 / Esc 时同时还原暂存的光标
upKey'ArrowUp'向上召回的 KeyboardEvent.key;'' 表示禁用
downKey'ArrowDown'走向更新 / 还原的 KeyboardEvent.key;'' 表示禁用
escapeKey'Escape'退出浏览的 KeyboardEvent.key;'' 表示禁用
maxHistory500召回条目上限(保留最新);0 = 不限
includeKinds['user']允许进入历史的会话节点 kind(加入 'steering' 以包含 steer 消息)
historyScope'session'历史范围(session / workspace):workspace 把其他已列表会话的用户消息排在当前会话之前
persistHistorytrue把已发送消息追加到浏览器本地存储
maxPersisted200持久化条目上限;0 = 不限
enableSearchtrue启用 Ctrl+R 反向搜索覆盖层
searchKeys['Ctrl+R']打开搜索的组合键规格(修饰键 Ctrl/Alt/Meta/Shift + 键名);非法规格会使浏览器 fiber 响亮失败
searchCaseSensitivefalse搜索匹配是否区分字母大小写
includeCompactionSummariestrue把 [compacted] … 检查点摘要纳入召回与搜索
showCompactionNoticetrue压缩检查点落地时显示短暂通知
compactCommandText'/compact'通知中「Compact now」按钮填入作曲器的斜杠命令;'' 隐藏该按钮
enableSnippetstrue启用片段库(/save、/load、搜索面板选取)
maxSnippets200最大存储片段数;0 = 不限
enableTemplatestrue启用提示词模板库(插入时填充变量)
enableInsightstrue启用复用洞察提示(本地使用统计)
insightMinUses2复用提示显示前的最少使用次数
enableCompactionHighlighttrue在搜索面板中给 [compacted] … 摘要加醒目徽标

profile patch 覆盖示例:

- insert:
    - id: composer-history
      name: dsh-composer-history
      config:
        recallWithDraft: gate
        maxHistory: 1000
        historyScope: workspace

FAQ

数据到底存在哪?会被上传吗?

四份浏览器本地 localStorage 键:dsh.composer-history.v1(已发送消息历史)、dsh.composer-history.snippets.v1(片段文本 + 标签 + 使用计数)、dsh.composer-history.templates.v1(模板文本)、dsh.composer-history.insights.v1(去重提示词文本 + 每会话使用计数)。全部有界、仅同源可读、绝不上传;损坏载荷静默重置。唯一出浏览器的路径是你显式点击的备份导出(下载文件或复制到剪贴板)。

宿主换掉作曲器 DOM 会怎样?会静默失效吗?

会——这正是「已知限制」第一条。拦截锚定的是宿主私有 DOM:[data-input-scroll] 内的 contenteditable div[data-composer-input](顺带兼容 0.1.1-rc.2 及以前的 textarea 作曲器)。这不是公开 API(上游提案 C3 记载插件只能猜测宿主 DOM),所以未来宿主 DOM 变化可能让拦截静默失效。compat 工作流的 jsdom 冒烟针对打包产物重新断言这个面,把回归挡在发布前。

会和其他插件抢键、抢槽位吗?

不会。插件只在 plain 输入阶段、作曲器聚焦时拦截;斜杠菜单、命令弹窗、IME 组合、文本选区与修饰键组合一律放行,Enter 从不拦截。Ctrl+R 只在作曲器内被消费,不是全局快捷键。它不提供任何服务键、不注册 HTTP 路由、不改全局对象,也不产生会话事件。逐条论证见「与其他 DSH 插件的互操作性」。

性能开销多大?

纯前端 DOM/JS:无网络、无模型调用,日常召回只是一次 setDraft。默认 edgeMode: 'logical' 按 \n 判边,零测量;visual 模式用隐藏 mirror 测量真实折行,每次边缘检查做 O(行数·log n) 的二分,并按草稿与宽度 memoize。

按 ↑ 召回之后会不会误发消息?

不会。召回、片段加载、模板填充与 /compact 填入都只走普通 setDraft;Enter 从不被拦截,也没有任何路径会替你发送。召回的历史文本只有在你按下 Enter 后才会离开浏览器。

安全边界

  • 仅 UI,从不执行强制。 插件只编辑作曲器草稿;沙箱、审批与会话系统仍是执行权威,绝不接管或绕过任何命令或工具。
  • 内容不出浏览器。 历史、片段、模板与洞察都活在 localStorage 里;什么都不上传,也不发模型请求或网络调用。版本化备份只在显式点击时写入本地下载或剪贴板。
  • 响亮失败。 非法枚举值中止整个 dsh 启动;非法搜索组合键使浏览器 fiber 失败——错误配置绝不静默降级。
  • 处处有界。 maxHistory、maxPersisted、maxSnippets 限定保留条目;损坏或外来的载荷静默重置。
  • 放行路径零副作用。 插件仅在 plain 输入阶段拦截,对斜杠菜单、命令弹窗、IME 组合、文本选区与修饰键组合一律放行。

权限与数据

  • 权限:插件在其 workshop manifest 中声明 browser:local-storage——仅此而已。无网络、无子进程、无会话事件。
  • 数据:四个浏览器本地 localStorage 键(历史、片段、模板、洞察),规则见上方 FAQ 第一条;全部有界、仅同源可读、绝不上传,损坏载荷静默重置。
  • 模型可见 ⟺ 你按 Enter:召回文本、片段加载、模板填充、/compact 填入都只进普通作曲器草稿。在你按下 Enter 之前,任何内容都不会到达模型。

已知限制

  • 作曲器 DOM 面。 拦截锚定宿主私有 DOM:[data-input-scroll] 内的 contenteditable div[data-composer-input](0.1.2-alpha.5 / 0.1.2-rc.1 及以后的宿主);[data-input-scroll] 内的旧式 textarea 作曲器(0.1.1-rc.2 及以前)保持匹配。该形状并非公开 API(上游提案 C3 记载插件只能猜测宿主 DOM),未来宿主 DOM 变化可能让拦截静默失效——compat 工作流的 jsdom 冒烟针对打包产物重新断言该面。
  • 逻辑行 vs 视觉行。 默认 logical 按 \n 判定(一条自动折行的长消息算一行);visual 通过复制 contenteditable 表面计算盒的隐藏 mirror(每次边缘检查 O(行数·log n) 二分,按草稿/宽度 memoize)测量真实折行。mirror 测量需要真实布局引擎——纯 span 数学已单测覆盖;Lexical 作曲器上测得的 span 保持尽力而为(默认仍为 logical)。
  • 持久化历史按浏览器隔离。 存储位于某一 origin 的 localStorage,不在浏览器或机器间同步。损坏载荷静默重置。
  • 撤销栈包含召回事务。 每次填充/还原都是输入机撤销日志里的一条 setDraft 事务;Ctrl+Z 会一步步退回召回。精确化需要上游暴露 edit-range。
  • 召回 /xxx 条目后按 Enter 走正常的命令 claim/adjudication 路径(符合预期,且 Enter 从不被拦截)。
  • 菜单/弹窗与非 plain 阶段永远优先;提交发送与会话切换都会重置为 IDLE。
  • 引用 chip(U+FFFC 占位符)随召回/还原的草稿文本一起保留。
  • historyScope: 'workspace' 读取其他已列表会话的 Chat 目标;本页面尚未激活过 Chat 视图的会话暂时没有贡献。
  • 搜索覆盖层是纯 DOM(无 React 依赖);最多渲染 maxHistory 条匹配。
  • 压缩感知是观察性的。 安装前(或会话切换前)已落地的检查点绝不触发通知;摘要事件落在已加载窗口之外的检查点不产生 [compacted] … 条目(summary: null)。
  • 通知的「Compact now」按钮只把配置的命令文本填入草稿——发送仍由你的 Enter 决定。
  • 片段、模板与洞察是浏览器本地的。 名称用 kebab-case(1..64 字符);标签上限 8 × 32 字符。模板变量从实时会话解析;{{draft}} 是选取时刻的草稿。

与其他 DSH 插件的互操作性

浏览器半只吃已发布的客户端包(dsh-client-ui-conversation、dsh-client-ui-input-trigger、dsh-client-ui-settings)与 cordis Context,因此在插件层面没有可争抢的资源:

  • 无会话事件、无 agent-loop 改动。 插件只观察 Chat 视图已发布的会话投影(uiConversation.binding(id).target('chat').legacy.nodes),不 append 会话事件,也不发模型请求。
  • 无服务键。 host 半的 inject 为空数组、不 provide 任何服务键,因此不存在服务键冲突。
  • 无 HTTP 路由。 不注册任何 webServer 前缀。
  • 无全局改写。 不改原型、不改写 process.env、不替换全局 fetch dispatcher。
  • 设置面自持。 自 0.1.7-alpha.1 起不再注册 composer-history 命名空间,改用自己的活 Config 条目(profile 行 id 即表单名);不读写其他插件的设置小节。
  • 拦截最小化。 只在 plain 输入阶段、作曲器聚焦时拦截;菜单/弹窗、IME、选区与修饰键组合永远优先;Enter 从不被拦截。

唯一的耦合点是宿主私有 DOM(div[data-composer-input]),已记录在「已知限制」第一条;compat 工作流用 jsdom 冒烟针对打包产物重新断言该面,把这类漂移挡在发布前。

兼容性

维度状态
宿主DeepSeek Harness dsh-v0.2.1-rc.2(2026-10-18 验证):engines.dsh >=0.2.1-0 <0.3.0;P0 兼容路径已有回归测试。
Node^22.19.0 || >=24.9.0
平台仅 Web GUI(客户端插件;浏览器本地存储;无网络、无原生代码)
模型任意(不发模型请求——纯 UI 行为)

浏览器半边基于已发布的客户端包(dsh-client-ui-conversation、dsh-client-ui-input-trigger、dsh-client-ui-settings)与 cordis Context;它不再依赖已移除的 dsh-client-runtime 包,因此客户端接口面同样对齐 0.1.2-rc.1 宿主。

拦截锚定 Web 作曲器的 DOM:[data-input-scroll] 内的 contenteditable 表面 div[data-composer-input](自 0.1.2-alpha.5 / 0.1.2-rc.1 起随附的 Lexical 作曲器),同时保留对 [data-input-scroll] 内旧式 textarea 作曲器(0.1.1-rc.2 及以前宿主线)的匹配;其余 textarea 一律穿过。compat 工作流的 jsdom web 行为冒烟针对打包产物断言该身份/文本/光标面。

0.1.2-rc.1(2026-09-04 已适配):会话信封保留 ignorable 字段但仅用于存量日志读取兼容——Session.append 仍无法盖章,门控行为不变。已于 2026-09-06 对照 dsh-v0.1.7-alpha.1 master checkout 核验(全部门禁链 + profile 试装冒烟)。

0.1.5-rc.1(2026-09-10 已适配):依赖钉号移至已发布的 0.1.5-rc.1 线;无接缝变更影响本插件行为。

0.1.5-rc.2(2026-09-11 已适配):依赖钉号移至已发布的 0.1.5-rc.2 线;无接缝变更影响本插件行为。

0.1.7-alpha.1(2026-09-22 已适配):设置接缝在两个半边都被替换。宿主半边不再通过已移除的 ctx.settings.register(ns, schema, { base }) 注册 composer-history 命名空间——该线上插件的持久设置面就是它自己的活 Config:每个可调项声明为 .volatile(),profile 条目 id(composer-history,即 bundle patch 的行 id)就是表单名,apply 认领生成表单的呈现策略(ctx.settings.configure({ auto: true }, ctx.fiber),由 effect 持有以便 reload 干净重注册)。浏览器半边改经 ctx.configForms.get('composer-history') 读取同一条目,取代已移除的 ctx.settingsScope.bind({ namespace });快照/订阅形状未变,因此每次提交的变更仍会重装接线。可编辑面是保留而非新增:旧命名空间暴露过的字段全部 volatile,没有任何新字段变成可编辑。既有的 settings.yaml 中名为 composer-history 的小节由宿主自身迁移进同 id 的 profile 条目。

生态与质量

开发

pnpm install           # node ^22.19 || >=24.9
pnpm run build         # tsc build + tsdown bundle (lib/)
pnpm run typecheck     # tsc --noEmit (src + tests)
pnpm test              # vitest run
pnpm run test:watch    # vitest watch
pnpm run test:coverage # vitest run --coverage
pnpm run check:readmes # 五语 README 一致性门禁
pnpm run verify:pack   # 发布文件齐全 + 被 package.json files[] 覆盖

配图由 scripts/gen-readme-assets.py 程序化生成(Pillow 画 hero,手写 SVG 画结构图),可重复执行:python scripts/gen-readme-assets.py 写出 docs/assets/dsh-composer-history-hero-{zh,en}-{light,dark}.webp 与 docs/assets/dsh-composer-history-flow-v5-{light,dark}.svg(hero 按语言本地化,结构图只有命令 token,五语共用)。

Topics:deepseek-harness · dsh · dsh-plugin · web-gui · input-history · keyboard-shortcuts · compaction · sliding-context · typescript

家族与致谢

本项目是 PerryLink 维护的 DeepSeek Harness 插件家族成员(全部 Apache-2.0)。如果这个插件帮到了你,给个 star——它不解锁任何功能,但会让下一个人更容易找到它。

  • @gengwg —— volatile 启动配置处理(#11)。
  • @yujethrozheng-crypto —— 0.2.1-rc.2 上的作曲器历史还原(#12);rc.2 启动修复随 0.8.15 发布。
  • @PerryLink —— 创建者与维护者:边缘优先的方向键召回、持久化历史、反向搜索、滑动上下文感知、片段库、提示词模板、复用洞察,以及 dsh.bundle / dshWorkshop manifest。
展开全部插件
插件状态
dsh-aqua-input-check
dsh-archive-check
dsh-auto-review
dsh-autotier🧊 已冻结 — 见仓库 README
dsh-bid-ca-precheck
dsh-bid-qual-check
dsh-cert-mcp🧊 已冻结 — 见仓库 README
dsh-checkpoint-rewind
dsh-click
dsh-composer-history
dsh-contract-stance
dsh-customs-doc-check
dsh-data-quality🧊 已冻结 — 见仓库 README
dsh-demurrage-ledger
dsh-doublecheck
dsh-drill-script-check
dsh-eia-guide-check
dsh-emergency-plan
dsh-essay-rubric-check
dsh-evidence-check
dsh-export-ctl-check
dsh-fast
dsh-fmea-table-check
dsh-forecast-penalty
dsh-fund-research
dsh-github
dsh-gongwen-flow-check
dsh-gongwen-word-check
dsh-guard-plan-qc
dsh-hazchem-check
dsh-hazplan-check
dsh-hidden-risk-map
dsh-hs-classify
dsh-icd-rule-check
dsh-industry-research
dsh-lawcite-adapter
dsh-laya
dsh-lc-doc-check
dsh-learning-gap-check
dsh-library
dsh-local-ai
dsh-lsp-actions
dsh-mask
dsh-mcp-panel
dsh-medrec-qc
dsh-memento🧊 已冻结 — 见仓库 README
dsh-nsfc-form-check
dsh-nurse-record-check
dsh-observe
dsh-origin-rvc-check
dsh-ota-review-check
dsh-output-styles
dsh-paper-doc-adapter
dsh-permission-rules
dsh-permit-report-check
dsh-pipeline-check
dsh-pleading-draft
dsh-plugin-doctor🚫 已退役(仓库已归档)
dsh-plugin-guide
dsh-plugin-kit🚫 已退役(仓库已归档)
dsh-plugin-upgrade🚫 已退役(仓库已归档)
dsh-policy-brief-draft
dsh-power-loss-split
dsh-power-ticket-check
dsh-ppap-check
dsh-protest-deadline
dsh-railway-window
dsh-repair-order-qc
dsh-research-report
dsh-review-reply-check
dsh-rulefile-check
dsh-safety-brief-check
dsh-score🧊 已冻结 — 见仓库 README
dsh-session-sync
dsh-site-log-check
dsh-skill-pack-security
dsh-soe-decision-check
dsh-soilwater-check
dsh-sop-sync-check
dsh-spc-gbt-adapter
dsh-talk
dsh-tender-extract
dsh-tender-matrix
dsh-test-drive
dsh-ticktick🚫 已退役(仓库已归档)
dsh-translate
dsh-warranty-calc
dsh-budget🧊 已冻结 — 见仓库 README
dsh-claude-move🧊 已冻结 — 见仓库 README
dsh-defend🧊 已冻结 — 见仓库 README
dsh-draw🧊 已冻结 — 见仓库 README
dsh-reach🧊 已冻结 — 见仓库 README
dsh-background-agents🚫 已退役(仓库已归档)
dsh-session-pin🚫 已退役(仓库已归档)
dsh-team-rooms🚫 已退役(仓库已归档)

License

LICENSE(Apache License 2.0)© 2026 dsh-composer-history contributors

Apache-2.0 · 社区插件,与 DeepSeek 无关。

相关插件