@wenaixi/dsh-prompt-history 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,20 @@
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [2.2.0] - 2026-10-06
8
+
9
+ ### 变更
10
+
11
+ - **移除 Ctrl+R 手势**:历史列表入口仅剩「输入框为空时双击 Esc」;Ctrl+R 交还浏览器(恢复原生刷新)。删除 `historyGesture` 字段与相关文案。**已有用户升级需在 `cordis.patch.yml` 里删除 `historyGesture` 行**(同 tocVisible 先例,否则配置写入会被宿主以未知键拒绝)。
12
+ - **双击 Esc 独立开关(默认开)**:新增 `doubleEsc`。开:非空草稿双击清空并存入历史、空草稿双击开历史列表;关:Esc 完全交还宿主。
13
+ - **历史面板对齐 Claude Code**:行首相对时间(`relativeTime`,默认开,条目带源事件时间戳);过滤支持包含 + 字符子序列模糊(`fuzzyMatch`,默认开,复刻 `isSubsequence`,exact 在前 fuzzy 在后);高亮两端夹取不环绕(复刻 FuzzyPicker `clamp`);宽窗口(≥1000px)右侧显示选中条目完整内容预览;列表最新在顶。
14
+ - **历史条数上限可调**:新增 `maxHistoryItems`(默认 100,档位 50/100/200/500/1000),历史环与列表统一按此裁剪。
15
+
16
+ ### 修复
17
+
18
+ - 历史条目从纯字符串改为 `{ text, time }`:跨会话 localStorage 环保留时间戳,旧纯字符串条目兼容显示为无相对时间。
19
+ - 相对时间格式化为 `5m / 3h / 2d` 短格式(Claude Code `formatRelativeTimeAgo` 近似)。
20
+
7
21
  ## [2.1.0] - 2026-10-06
8
22
 
9
23
  ### 变更
@@ -243,7 +257,8 @@
243
257
 
244
258
  - 选中即复制(任意选中方式)。
245
259
 
246
- [Unreleased]: https://github.com/Wenaixi/dsh-prompt-history/compare/v2.1.0...HEAD
260
+ [Unreleased]: https://github.com/Wenaixi/dsh-prompt-history/compare/v2.2.0...HEAD
261
+ [2.2.0]: https://github.com/Wenaixi/dsh-prompt-history/compare/v2.1.0...v2.2.0
247
262
  [2.1.0]: https://github.com/Wenaixi/dsh-prompt-history/compare/v2.0.2...v2.1.0
248
263
  [2.0.2]: https://github.com/Wenaixi/dsh-prompt-history/compare/v2.0.1...v2.0.2
249
264
  [2.0.1]: https://github.com/Wenaixi/dsh-prompt-history/compare/v2.0.0...v2.0.1
package/README.md CHANGED
@@ -34,13 +34,13 @@
34
34
 
35
35
  1. **Claude Code-style arrow recall** — with the caret on the **first line** of the draft, **Up** walks back through prompts one by one from the most recent (caret parks at the start of each recalled line); at the oldest entry Up does nothing (no wrap-around). **Down** walks forward (recalled lines park the caret at the end) and, at the bottom edge, **restores the line you were typing before browsing began** (an empty draft restores an empty line). In multi-line drafts, Up/Down still move the caret normally unless it is on the first/last line.
36
36
  2. **Edit exits browsing** — editing the draft while browsing drops back to the live line.
37
- 3. **Ctrl+R history list** — one key opens the full prompt-history overlay (newest first, duplicates keep only their latest occurrence). Focus stays in the input: typing filters by substring with live highlighting, **↑↓** move the highlight without touching the draft, Home/End jump to the edges, **Enter or Tab** fills the highlighted entry, **Esc** closes and restores the draft from before opening. The footer shows "matches / total" live.
38
- 4. **Double Escape** (toggleable in Settings) — matches Claude Code semantics: with a **non-empty** draft the first Escape hints "Esc again to clear" and passes through, the second within 800 ms **saves the draft to history and clears the input** (the cleared text is then recallable with Up); with an **empty** draft a double Escape opens the history list. Three-way choice: **Ctrl+R only** / **Double Escape only** / **Both** (default).
37
+ 3. **History list via double Escape** — with an empty draft, pressing **Escape twice within 800 ms** opens the full prompt-history overlay (newest first, duplicates keep only their latest occurrence). Focus stays in the input: typing filters live with substring plus optional fuzzy subsequence matching (default on), **↑↓** move the highlight without touching the draft (clamped at the edges, no wrap), Home/End jump to the edges, **Enter or Tab** fills the highlighted entry, **Esc** closes and restores the draft from before opening. Each row shows a relative timestamp when the setting is on; on wide windows (≥1000px) the selected entry previews in full on the right. The footer shows "matches / total" live.
38
+ 4. **Double Escape** (toggleable in Settings, default on) — matches Claude Code semantics: with a **non-empty** draft the first Escape hints "Esc again to clear" and passes through, the second within 800 ms **saves the draft to history and clears the input** (the cleared text is then recallable with Up); with an **empty** draft a double Escape opens the history list. Turning the toggle off hands every Escape back to the Host.
39
39
  5. **Copy + quote (two modes, in Settings)** — any non-empty selection in the page — the composer input, chat messages, code blocks — is handled per the chosen mode:
40
40
  - **Toolbar** (default): Copy / Quote buttons appear above the selection — copy writes the clipboard only on click (no Win+V flooding); **Quote** inserts the FULL selected text as a clean `>`-prefixed markdown blockquote into the composer (rendered as a blockquote when sent).
41
41
  - **Auto** (terminal-style): copies the selection straight to the system clipboard on select.
42
42
  6. **Right-click pastes directly** — a right-click on the composer pastes the clipboard — no context menu, like a Linux terminal. Paste runs the same pipeline as Ctrl+V (images and reference chips behave identically), with a Clipboard API fallback when the execCommand path is blocked.
43
- 7. **Cross-session history** (Settings toggle, default off) — keeps Up/Down history across sessions, stored in browser localStorage (cap 200), survives reloads and session switches.
43
+ 7. **Cross-session history** (Settings toggle, default off) — keeps Up/Down history across sessions, stored in browser localStorage (capped by the max-history setting), survives reloads and session switches.
44
44
 
45
45
  Pure UI behavior: no session events, no agent-loop changes, no model requests. Recalled or quoted text only enters the ordinary composer draft — it reaches the model only if *you* press Enter.
46
46
 
@@ -66,21 +66,24 @@ Open **Plugins → `@wenaixi/dsh-prompt-history` → configuration** (persisted
66
66
  | Option | Default | Meaning |
67
67
  |---|---|---|
68
68
  | After selecting text | `Show a toolbar` | `Nothing` / `Show a toolbar` (writes the clipboard only on click) / `Copy immediately` (terminal-style) |
69
- | Open history list | `Both` | `Ctrl+R only` / `Double Escape only` / `Both` |
70
- | Up/Down history | On | Off hands ↑/↓, Ctrl+R and double Escape back to the Host |
71
- | Cross-session memory | Off | Up/Down history persists across sessions in browser local storage (cap 200) |
69
+ | Up/Down history | On | Off hands every history behavior back to the Host |
70
+ | Double Escape | On | Off hands every Escape back to the Host (no clear, no history list) |
71
+ | Max history entries | `100` | How many prompts Up/Down and the history list remember (50 / 100 / 200 / 500 / 1000) |
72
+ | Relative time | On | Show "5m / 3h / 2d" at the start of each history-list row |
73
+ | Fuzzy match | On | History-list filtering also matches character subsequences (e.g. "dpl" finds "deploy now") |
74
+ | Cross-session memory | Off | Up/Down history persists across sessions in browser local storage (capped by max history) |
72
75
  | Right-click paste | On | Off restores the browser's native context menu |
73
76
 
74
77
  ## Features
75
78
 
76
- - **History comes from the session's own message log**: reads the conversation snapshot's user nodes (`user` / `steering`) and appends as they land — strictly consistent with the transcript, persisted with the session, survives page reloads, and needs no configuration or extra storage. With "Cross-session memory" on it seeds from browser localStorage (cap 200) and dedupes against the whole ring on every append.
79
+ - **History comes from the session's own message log**: reads the conversation snapshot's user nodes (`user` / `steering`) and appends as they land — strictly consistent with the transcript, persisted with the session, survives page reloads, and needs no configuration or extra storage. With "Cross-session memory" on it seeds from browser localStorage (capped by the max-history setting) and dedupes against the whole ring on every append.
77
80
  - **Consecutive duplicates collapse**; browse state resets on session switch.
78
81
  - Fully localized (中文 / English): settings, toolbar, feedback pills, history list all follow the DSH app locale.
79
- - The client bundle is ~13 KB gzipped and depends only on the official `@deepseek-ai/*` peer packages.
82
+ - The client bundle is ~14 KB gzipped and depends only on the official `@deepseek-ai/*` peer packages.
80
83
 
81
84
  ## Known limitations
82
85
 
83
- - **Ctrl+R**: while the composer is focused, Ctrl+R opens the history list — it no longer reloads the page (click outside the input first to reload).
86
+ - **Ctrl+R is not bound** — the browser keeps its native refresh; the history list opens via double Escape (or the Up/Down recall for one entry at a time).
84
87
  - Plain text only: image-only or chip-bearing messages are not recalled; recalled drafts are plain text.
85
88
  - Multi-line detection works on logical lines (Lexical line-breaks are `<br>`): pressing Up on a visually wrapped single line enters history instead of moving the caret up one visual row.
86
89
 
package/README.zh.md CHANGED
@@ -34,8 +34,8 @@
34
34
 
35
35
  1. **Claude Code 式方向键召回** — 光标在输入框**第一行**时按 **↑** 从最新一条提问开始**逐条往回**(每条光标停在行首);一直翻到最旧再按 ↑ 不会环绕回最新。**↓** 往更新方向走(回填时光标停在行尾),翻到底**恢复你翻历史之前正在输入的那一行**(空输入则恢复空行)。多行草稿中,光标在第一行/最后一行之外的普通上下移行不受影响。
36
36
  2. **编辑即退出** — 浏览历史时一旦动手编辑,自动回到当前行,不再继续翻。
37
- 3. **Ctrl+R 历史列表** — 一键调出全部历史提问的浮层列表(最新在前,重复提问只保留最新一次)。焦点留在输入框:继续打字即按「包含」实时过滤并高亮命中词,**↑↓** 移动高亮且不改动草稿,Home/End 跳首尾,**Enter 或 Tab** 把高亮那条写进草稿,**Esc** 关闭并把草稿还原成打开前那一行。底部实时显示「命中数 / 总条数」。
38
- 4. **双击 Esc**(设置里可关)— 语义与 Claude Code 一致:草稿**非空**时第一次 Esc 提示「再按一次 Esc 清空输入」并照常透传,800 毫秒内第二次把草稿**存入历史后清空输入框**(清掉的内容随后可用 ↑ 召回);草稿**为空**时连按两次 Esc 打开历史列表。设置项三选:**只用 Ctrl+R** / **只用双击 Esc** / **两者都要**(默认)。
37
+ 3. **双击 Esc 打开历史列表** — 输入框为空时 800 毫秒内连按两次 Esc 调出全部历史提问的浮层列表(最新在前,重复提问只保留最新一次)。焦点留在输入框:继续打字即按「包含」+ 可选「子序列模糊」实时过滤并高亮命中词,**↑↓** 移动高亮(两端夹取不环绕)且不改动草稿,Home/End 跳首尾,**Enter 或 Tab** 把高亮那条写进草稿,**Esc** 关闭并把草稿还原成打开前那一行。每行开头显示相对时间(可关);宽窗口(≥1000px)时右侧显示选中条目的完整内容预览。底部实时显示「命中数 / 总条数」。
38
+ 4. **双击 Esc**(设置里可关,默认开)— 语义与 Claude Code 一致:草稿**非空**时第一次 Esc 提示「再按一次 Esc 清空输入」并照常透传,800 毫秒内第二次把草稿**存入历史后清空输入框**(清掉的内容随后可用 ↑ 召回);草稿**为空**时连按两次 Esc 打开历史列表。关闭后 Esc 完全交还宿主。
39
39
  5. **复制 + 引用(两种模式,设置里切换)** — 页面里任何非空选区——输入框、聊天消息、代码块等——按所选模式处理:
40
40
  - **工具栏**(默认):选区上方出现「复制」「引用」按钮——复制点击才写剪贴板(不刷屏 Win+V);**引用**把选中文本的**完整内容**以简约的 `>` 引用块插入输入框(标准 markdown 引用,发送时渲染为引用块)。
41
41
  - **选中即自动复制**:终端风格,选中直接写系统剪贴板。
@@ -66,21 +66,24 @@ dsh plugin --profile web add @wenaixi/dsh-prompt-history
66
66
  | 选项 | 默认 | 说明 |
67
67
  |---|---|---|
68
68
  | 选中文本后 | `弹出工具栏` | `什么都不做` / `弹出工具栏`(点击才写剪贴板)/ `选中即复制`(终端风格) |
69
- | 打开历史列表 | `两者都要` | `只用 Ctrl+R` / `只用双击 Esc` / `两者都要` |
70
- | 上下键历史 | 开 | 关闭后 ↑/↓、Ctrl+R 与双击 Esc 全部交还宿主 |
71
- | 跨会话记忆 | 关 | ↑/↓ 历史在会话间保持,存浏览器本地,上限 200 条 |
69
+ | 上下键历史 | 开 | 关闭后全部历史行为交还宿主 |
70
+ | 双击 Esc | 开 | 关闭后 Esc 完全交还宿主(不清空也不开列表) |
71
+ | 历史条数上限 | `100` | ↑/↓ 与历史列表最多记住多少条(50 / 100 / 200 / 500 / 1000) |
72
+ | 显示相对时间 | 开 | 历史列表每行开头显示「5 分钟前 / 3 小时前」这类相对时间 |
73
+ | 模糊匹配 | 开 | 历史列表过滤时还允许字符子序列模糊匹配(例如搜「dpl」也能找到「deploy now」) |
74
+ | 跨会话记忆 | 关 | ↑/↓ 历史在会话间保持,存浏览器本地(受「条数上限」约束) |
72
75
  | 右键直接粘贴 | 开 | 关闭后右键恢复浏览器原生菜单 |
73
76
 
74
77
  ## 特性
75
78
 
76
- - **历史来自会话自身的消息记录**:直接读取会话快照中的用户消息节点(`user` / `steering`),随消息落地实时追加——与聊天记录严格一致,随会话持久化,刷新页面后依然可用,不需要任何配置或额外存储。开启「跨会话记忆」后改从浏览器 localStorage(上限 200 条)播种并在每次追加时全环去重。
79
+ - **历史来自会话自身的消息记录**:直接读取会话快照中的用户消息节点(`user` / `steering`),随消息落地实时追加——与聊天记录严格一致,随会话持久化,刷新页面后依然可用,不需要任何配置或额外存储。开启「跨会话记忆」后改从浏览器 localStorage 播种并在每次追加时全环去重。
77
80
  - **连续重复自动合并**,浏览状态跟随会话切换自动重置。
78
81
  - **界面国际化**:全部文案(设置、工具栏、提示 pill、历史列表)跟随 DSH 应用语言(中文 / English)。
79
- - client bundle 压缩后约 13 KB;依赖全部走官方 `@deepseek-ai/*` peer 依赖。
82
+ - client bundle 压缩后约 14 KB;依赖全部走官方 `@deepseek-ai/*` peer 依赖。
80
83
 
81
84
  ## 已知限制
82
85
 
83
- - **Ctrl+R**:输入框聚焦时 Ctrl+R 打开历史列表,**不再触发浏览器刷新**(想刷新先点一下输入框外面)。
86
+ - **Ctrl+R 不再绑定**:浏览器保留原生刷新;历史列表通过双击 Esc 打开(单条回顾仍可用 ↑/↓)。
84
87
  - 纯文本召回:带图片/命令 chip 的消息不参与;召回内容为纯文本。
85
88
  - 多行判定按逻辑行(Lexical 以 `<br>` 换行):超长单行**视觉折行**后按 ↑ 会直接进入历史而非上移一行。
86
89
 
@@ -96,7 +99,7 @@ pnpm run build # tsc(lib/types)+ tsdown(lib/index.js / lib/invariant
96
99
 
97
100
  ## 原理
98
101
 
99
- 插件是一个不可见的 composer 槽位条目:挂一个 document 捕获期 keydown 监听,仅在目标为 composer 输入框、无修饰键、非输入法组合、菜单未打开、会话非忙碌时接管 ↑/↓,通过 `inputActions.setDraft` 写入历史文本。浏览位置用「已浏览条数」(`browseRef.step`)表示,配合「开始浏览前那一行」的草稿副本;↑ 只在光标位于第一行时接管,↓ 只在最后一行时接管(对齐 Claude Code `upOrHistoryUp` / `downOrHistoryDown` 的「先移光标」)。历史列表由会话快照的 `user`/`steering` 节点按 seq 去重追加。多行行号按 Lexical 的 `<br>` 结构计算。
102
+ 插件是一个不可见的 composer 槽位条目:挂一个 document 捕获期 keydown 监听,仅在目标为 composer 输入框、无修饰键、非输入法组合、菜单未打开、会话非忙碌时接管 ↑/↓,通过 `inputActions.setDraft` 写入历史文本。浏览位置用「已浏览条数」(`browseRef.step`)表示,配合「开始浏览前那一行」的草稿副本;↑ 只在光标位于第一行时接管,↓ 只在最后一行时接管(对齐 Claude Code `upOrHistoryUp` / `downOrHistoryDown` 的「先移光标」)。历史列表由会话快照的 `user`/`steering` 节点按 seq 去重追加,条目带源事件时间戳用于相对时间显示;过滤支持包含 + 子序列模糊(Claude Code `isSubsequence`)。多行行号按 Lexical 的 `<br>` 结构计算。
100
103
 
101
104
  ## License
102
105
 
package/cordis.patch.yml CHANGED
@@ -13,5 +13,8 @@
13
13
  copyMode: toolbar
14
14
  rightClickPaste: true
15
15
  historyEnabled: true
16
- historyGesture: both
16
+ doubleEsc: true
17
+ maxHistoryItems: 100
18
+ relativeTime: true
19
+ fuzzyMatch: true
17
20
  globalHistory: false