@wenaixi/dsh-prompt-history 2.0.2 → 2.1.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,18 @@
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [2.1.0] - 2026-10-06
8
+
9
+ ### 变更
10
+
11
+ - **复刻 Claude Code 的上下键历史与双击 Esc 语义**:↑/↓ 从 bash 前缀搜索改为顺序浏览(↑ 从最新一条逐条回退、到底不环绕;↑ 回填光标签行首、↓/恢复草稿光标行尾;多行输入只在光标处于首/末行时才接管方向键,行号按 Lexical 的 `<br>` 结构计算)。双击 Esc 改为草稿非空时第一次提示、第二次存入历史后清空输入框(空草稿仍是打开历史列表)。
12
+ - **去掉设置保存按钮,改动自动保存**:配置卡不再使用官方 `SettingsForm` 外壳与 staged 草稿,开关、单选与「恢复默认」点击即写入宿主;失败时显示提示并回落到宿主真值。删除 `save/saving/conflict/draftHint` 文案键。
13
+ - **README 精简为双语文档**:主 README 改为英文,新增 `README.zh.md` 中文版;移除 `README.en.md` / `README.es.md` / `README.pt.md` 并同步 `package.json` 的 `files` 清单。
14
+
15
+ ### 修复
16
+
17
+ - **Lexical 多行输入的首/末行判定**:Lexical 的换行是 `<br>` 而非 `\n`,旧实现按换行符判断会把多行草稿误判成单行,导致光标停在第二行按 ↑ 也直接进历史。改为按「host 开头到光标锚点的 `<br>` 数」计算行号;空输入框的占位 `<br>` 不计为第二行。
18
+
7
19
  ## [2.0.2] - 2026-10-06
8
20
 
9
21
  ### 修复
@@ -231,7 +243,8 @@
231
243
 
232
244
  - 选中即复制(任意选中方式)。
233
245
 
234
- [Unreleased]: https://github.com/Wenaixi/dsh-prompt-history/compare/v2.0.2...HEAD
246
+ [Unreleased]: https://github.com/Wenaixi/dsh-prompt-history/compare/v2.1.0...HEAD
247
+ [2.1.0]: https://github.com/Wenaixi/dsh-prompt-history/compare/v2.0.2...v2.1.0
235
248
  [2.0.2]: https://github.com/Wenaixi/dsh-prompt-history/compare/v2.0.1...v2.0.2
236
249
  [2.0.1]: https://github.com/Wenaixi/dsh-prompt-history/compare/v2.0.0...v2.0.1
237
250
  [2.0.0]: https://github.com/Wenaixi/dsh-prompt-history/compare/v1.2.15...v2.0.0
package/README.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  # ⌨️ @wenaixi/dsh-prompt-history
4
4
 
5
- **DSH Web 输入框的「类 Linux shell」提示词历史 + 终端式复制粘贴插件。**
5
+ **Terminal-style input for the DeepSeek Harness Web GUI composer — Claude Code-style prompt history, copy & quote, and right-click paste.**
6
6
 
7
- *像在终端里一样按 ↑ —— 历史、引用、粘贴,一个插件搞定。*
7
+ *Press ↑ like it's a terminal — history, quoting and pasting in one plugin.*
8
8
 
9
9
  [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
10
10
  [![DSH plugin](https://img.shields.io/badge/dsh-plugin-✅-green)](https://github.com/topics/dsh-plugin)
@@ -12,90 +12,91 @@
12
12
  [![npm version](https://img.shields.io/npm/v/@wenaixi/dsh-prompt-history)](https://www.npmjs.com/package/@wenaixi/dsh-prompt-history)
13
13
  [![npm downloads](https://img.shields.io/npm/dm/@wenaixi/dsh-prompt-history)](https://www.npmjs.com/package/@wenaixi/dsh-prompt-history)
14
14
 
15
- [English](README.en.md) · **简体中文** · [Español](README.es.md) · [Português](README.pt.md)
15
+ **English** · [简体中文](README.zh.md)
16
16
 
17
17
  </div>
18
18
 
19
19
  ---
20
20
 
21
- ## 兼容性
21
+ ## Compatibility
22
22
 
23
- | 表面 | 状态 |
23
+ | Surface | Status |
24
24
  |---|---|
25
- | DSH 版本 | 目标为 **0.2.0-rc.2**;客户端配置卡片使用 `plugins.bundle.config` 与 Host `Config` schema,UI 走官方 `SettingsForm` 体系 |
26
- | 平台 | Web GUI(客户端插件;设置由 DSH Host 配置持久化;跨会话历史存浏览器本地) |
25
+ | DSH versions | Targets **0.2.0-rc.2**; the configuration card uses `plugins.bundle.config` with the Host `Config` schema and a self-drawn shell (write-on-change, no Save button) |
26
+ | Platform | Web GUI only (client plugin; settings are persisted by the DSH Host, cross-session history stays in browser local storage) |
27
27
  | Node | `>=20` |
28
- | 模型 | 任意(不发起模型请求 —— 纯 UI 行为) |
29
- | 界面语言 | 中文 / English(跟随 DSH 应用语言,设置页可切换) |
28
+ | Model | Any (no model requests — pure UI behavior) |
29
+ | UI language | 中文 / English (follows the DSH app locale) |
30
30
 
31
- ## 你能得到什么
31
+ ## What you get
32
32
 
33
- `@wenaixi/dsh-prompt-history` 把终端的输入历史搬进 DeepSeek Harness Web 输入框:
33
+ `@wenaixi/dsh-prompt-history` puts a terminal's input history into the DeepSeek Harness Web GUI composer:
34
34
 
35
- 1. **类 shell 的方向键召回** — 空输入时 **↑** 召回上一条发送过的消息(最新在前);**输入前缀后按 ↑** 跳到最近一条以该前缀开头的消息(bash 的 `history-search-backward` 行为),继续按 ↑ 往前翻匹配;**↓** 向后翻(含前缀匹配的前向),翻到底时**恢复你翻历史之前正在输入的那一行**(readline 的 pending-line 行为)。
36
- 2. **编辑即退出** — 浏览历史时一旦动手编辑,自动回到当前行,不再继续翻。
37
- 3. **Ctrl+R 历史列表** — 一键调出全部历史提问的浮层列表(最新在前,重复提问只保留最新一次)。焦点留在输入框:继续打字即按「包含」实时过滤并高亮命中词,**↑↓** 移动高亮且不改动草稿,Home/End 跳首尾,**Enter 或 Tab** 把高亮那条写进草稿,**Esc** 关闭并把草稿还原成打开前那一行。底部实时显示「命中数 / 总条数」。
38
- 4. **双击 Esc 打开同一个列表**(设置里可关)— 输入框为空时 800 毫秒内连按两次 Esc 即可打开;第一次 Esc 仍然照常关闭工具栏等浮层(不吞按键),任何其他按键会取消这次待定。设置项三选:**只用 Ctrl+R** / **只用双击 Esc** / **两者都要**(默认)。
39
- 5. **复制 + 引用(两种模式,设置里切换)** — 页面里任何非空选区——输入框、聊天消息、代码块等——按所选模式处理:
40
- - **工具栏**(默认):选区上方出现「复制」「引用」按钮——复制点击才写剪贴板(不刷屏 Win+V);**引用**把选中文本的**完整内容**以简约的 `>` 引用块插入输入框(标准 markdown 引用,发送时渲染为引用块)。
41
- - **选中即自动复制**:终端风格,选中直接写系统剪贴板。
42
- 6. **鼠标右键直接粘贴** — 在输入框上右键即粘贴剪贴板内容(和 Linux 终端一致,不弹菜单);粘贴走与 Ctrl+V 完全一致的管线(图片与引用 chip 行为一致),execCommand 路径被限制时自动回退到 Clipboard API 手动插入。
43
- 7. **跨会话历史记忆**(设置里可开关,默认关)— 开启后 ↑/↓ 历史在会话间保持,存于浏览器本地(上限 200 条),刷新/切换会话不丢失。
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
+ 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).
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
+ - **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
+ - **Auto** (terminal-style): copies the selection straight to the system clipboard on select.
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.
44
44
 
45
- 纯 UI 行为:不产生会话事件、不改变 agent 循环、不发起模型请求。召回/引用的文本只会进入输入框草稿,只有**你**按 Enter 才会到达模型。
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
 
47
- ## 快速开始
47
+ ## Quick start
48
48
 
49
49
  ```sh
50
- # 1. 把插件装进你的 profile
50
+ # 1. install the bundle into your profile
51
51
  dsh plugin --profile web add @wenaixi/dsh-prompt-history
52
52
 
53
- # 2. 刷新页面即可使用(无需重启服务)
53
+ # 2. refresh the page — no service restart needed
54
54
  ```
55
55
 
56
- ## 安装与卸载
56
+ ## Install & uninstall
57
57
 
58
- - **npm 渠道**(已发布版本):`dsh plugin --profile web add @wenaixi/dsh-prompt-history`
59
- - **源码渠道**(本地开发,最新 `main`):`dsh plugin --profile web add "github:Wenaixi/dsh-prompt-history#main"`(源码检出需先 `pnpm run build` —— 未构建的 bundle 会拒绝启动)
60
- - **卸载**:`dsh plugin --profile web remove @wenaixi/dsh-prompt-history`
58
+ - **npm channel** (published releases): `dsh plugin --profile web add @wenaixi/dsh-prompt-history`
59
+ - **git channel** (local dev, latest `main`): `dsh plugin --profile web add "github:Wenaixi/dsh-prompt-history#main"` (a source checkout must be built first — `pnpm run build`; an unbuilt bundle refuses to boot)
60
+ - **uninstall**: `dsh plugin --profile web remove @wenaixi/dsh-prompt-history`
61
61
 
62
- ## 配置
62
+ ## Configuration
63
63
 
64
- 打开 **插件 → `@wenaixi/dsh-prompt-history` → 配置**(由 DSH 宿主配置持久化到 `cordis.patch.yml`;旧版浏览器设置会在首次打开时自动迁移)。配置卡是官方 `SettingsForm`:改动只进草稿,点「保存」才一次写入宿主:
64
+ Open **Plugins → `@wenaixi/dsh-prompt-history` → configuration** (persisted by the DSH Host into `cordis.patch.yml`; legacy browser settings migrate on first open). Changes save immediately — there is no Save button: every toggle, option pick, or "Restore defaults" click writes the Host at once.
65
65
 
66
- | 选项 | 默认 | 说明 |
66
+ | Option | Default | Meaning |
67
67
  |---|---|---|
68
- | 选中文本后 | `弹出工具栏` | `什么都不做` / `弹出工具栏`(点击才写剪贴板)/ `选中即复制`(终端风格) |
69
- | 打开历史列表 | `两者都要` | `只用 Ctrl+R` / `只用双击 Esc` / `两者都要` |
70
- | 上下键历史 | 开 | 关闭后 ↑/↓、Ctrl+R 与双击 Esc 全部交还宿主 |
71
- | 跨会话记忆 | 关 | ↑/↓ 历史在会话间保持,存浏览器本地,上限 200 条 |
72
- | 右键直接粘贴 | 开 | 关闭后右键恢复浏览器原生菜单 |
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) |
72
+ | Right-click paste | On | Off restores the browser's native context menu |
73
73
 
74
- ## 特性
74
+ ## Features
75
75
 
76
- - **历史来自会话自身的消息记录**:直接读取会话快照中的用户消息节点(`user` / `steering`),随消息落地实时追加——与聊天记录严格一致,随会话持久化,刷新页面后依然可用,不需要任何配置或额外存储。
77
- - **连续重复自动合并**,浏览状态跟随会话切换自动重置。
78
- - **界面国际化**:全部文案(设置、工具栏、提示 pill、历史列表)跟随 DSH 应用语言(中文 / English)。
79
- - client bundle 压缩后约 12 KB;依赖全部走官方 `@deepseek-ai/*` peer 依赖。
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.
77
+ - **Consecutive duplicates collapse**; browse state resets on session switch.
78
+ - 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.
80
80
 
81
- ## 已知限制
81
+ ## Known limitations
82
82
 
83
- - **Ctrl+R**:输入框聚焦时 Ctrl+R 打开历史列表,**不再触发浏览器刷新**(想刷新先点一下输入框外面)。
84
- - 纯文本召回:带图片/命令 chip 的消息不参与;召回内容为纯文本。
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).
84
+ - Plain text only: image-only or chip-bearing messages are not recalled; recalled drafts are plain text.
85
+ - 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.
85
86
 
86
- ## 开发
87
+ ## Development
87
88
 
88
89
  ```sh
89
90
  pnpm install
90
91
  pnpm run typecheck # tsc --noEmit
91
- pnpm run build # tsc(lib/types)+ tsdown(lib/index.js / lib/invariant.js / lib/client.js)
92
+ pnpm run build # tsc (lib/types) + tsdown (lib/index.js / lib/invariant.js / lib/client.js)
92
93
  ```
93
94
 
94
- 浏览器半区(`src/client/`)注册在 `conversation.input.right` 槽位与插件详情页配置卡(`plugins.bundle.config`),构建产物为 DSH `__ModuleLoader__` 闭包格式,外部依赖仅 `react` 与官方 `@deepseek-ai/*` peer 包(其余由浏览器模块表提供)。配置卡走官方 `SettingsForm` 体系(`SettingsCardController` 做 staged 草稿与冲突栅栏)。文案字典在 `src/client/locales.ts`(`zh` 为准、`en` 键位对齐),通过 `ctx.locale.register` 注册。
95
+ The browser half (`src/client/`) registers into the `conversation.input.right` slot and the plugin-detail configuration card (`plugins.bundle.config`); the build emits the DSH `__ModuleLoader__` closure format with `react` and the official `@deepseek-ai/*` peer packages as externals (everything else comes from the browser module table). The card draws its own shell and `SettingsCardController` writes on every change, falling back to the Host value on refusal. Copy dictionaries live in `src/client/locales.ts` (`zh` authoritative, `en` key-parity) and register via `ctx.locale.register`.
95
96
 
96
- ## 原理
97
+ ## How it works
97
98
 
98
- 插件是一个不可见的 composer 槽位条目:挂一个 document 捕获期 keydown 监听,仅在目标为 composer 输入框、无修饰键、非输入法组合、菜单未打开、会话非忙碌时接管 ↑/↓,通过 `inputActions.setDraft` 写入历史文本。历史列表由会话快照的 `user`/`steering` 节点按 seq 去重追加,浏览位置(index + 待恢复的当前行)保存在组件 ref 中。
99
+ The plugin is an invisible composer slot entry that mounts a capture-phase `keydown` listener on the document. It takes over Up only when the caret is on the first line (Down only on the last line), the target is the composer editor, no modifiers are held, no IME composition is active, no suggestion menu is open, and the session is not busy — then writes the recalled text through `inputActions.setDraft`. The browse position is an "entries seen" counter (`browseRef.step`) plus a copy of the line typed before browsing began, mirroring Claude Code's `upOrHistoryUp` / `downOrHistoryDown` ("move the caret first"). The history list is fed from the snapshot's `user`/`steering` nodes (deduped by seq). Multi-line row numbers are computed from Lexical's `<br>` structure.
99
100
 
100
101
  ## License
101
102
 
package/README.zh.md ADDED
@@ -0,0 +1,103 @@
1
+ <div align="center">
2
+
3
+ # ⌨️ @wenaixi/dsh-prompt-history
4
+
5
+ **DSH Web 输入框的「Claude Code 式」提示词历史 + 终端式复制粘贴插件。**
6
+
7
+ *像在终端里一样按 ↑ —— 历史、引用、粘贴,一个插件搞定。*
8
+
9
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
10
+ [![DSH plugin](https://img.shields.io/badge/dsh-plugin-✅-green)](https://github.com/topics/dsh-plugin)
11
+ [![Node](https://img.shields.io/badge/node-%3E%3D20-brightgreen.svg)](#)
12
+ [![npm version](https://img.shields.io/npm/v/@wenaixi/dsh-prompt-history)](https://www.npmjs.com/package/@wenaixi/dsh-prompt-history)
13
+ [![npm downloads](https://img.shields.io/npm/dm/@wenaixi/dsh-prompt-history)](https://www.npmjs.com/package/@wenaixi/dsh-prompt-history)
14
+
15
+ [English](README.md) · **简体中文**
16
+
17
+ </div>
18
+
19
+ ---
20
+
21
+ ## 兼容性
22
+
23
+ | 表面 | 状态 |
24
+ |---|---|
25
+ | DSH 版本 | 目标为 **0.2.0-rc.2**;客户端配置卡片使用 `plugins.bundle.config` 与 Host `Config` schema,UI 自绘外壳(改动即写,无保存按钮) |
26
+ | 平台 | Web GUI(客户端插件;设置由 DSH Host 配置持久化;跨会话历史存浏览器本地) |
27
+ | Node | `>=20` |
28
+ | 模型 | 任意(不发起模型请求 —— 纯 UI 行为) |
29
+ | 界面语言 | 中文 / English(跟随 DSH 应用语言) |
30
+
31
+ ## 你能得到什么
32
+
33
+ `@wenaixi/dsh-prompt-history` 把终端的输入历史搬进 DeepSeek Harness Web 输入框:
34
+
35
+ 1. **Claude Code 式方向键召回** — 光标在输入框**第一行**时按 **↑** 从最新一条提问开始**逐条往回**(每条光标停在行首);一直翻到最旧再按 ↑ 不会环绕回最新。**↓** 往更新方向走(回填时光标停在行尾),翻到底**恢复你翻历史之前正在输入的那一行**(空输入则恢复空行)。多行草稿中,光标在第一行/最后一行之外的普通上下移行不受影响。
36
+ 2. **编辑即退出** — 浏览历史时一旦动手编辑,自动回到当前行,不再继续翻。
37
+ 3. **Ctrl+R 历史列表** — 一键调出全部历史提问的浮层列表(最新在前,重复提问只保留最新一次)。焦点留在输入框:继续打字即按「包含」实时过滤并高亮命中词,**↑↓** 移动高亮且不改动草稿,Home/End 跳首尾,**Enter 或 Tab** 把高亮那条写进草稿,**Esc** 关闭并把草稿还原成打开前那一行。底部实时显示「命中数 / 总条数」。
38
+ 4. **双击 Esc**(设置里可关)— 语义与 Claude Code 一致:草稿**非空**时第一次 Esc 提示「再按一次 Esc 清空输入」并照常透传,800 毫秒内第二次把草稿**存入历史后清空输入框**(清掉的内容随后可用 ↑ 召回);草稿**为空**时连按两次 Esc 打开历史列表。设置项三选:**只用 Ctrl+R** / **只用双击 Esc** / **两者都要**(默认)。
39
+ 5. **复制 + 引用(两种模式,设置里切换)** — 页面里任何非空选区——输入框、聊天消息、代码块等——按所选模式处理:
40
+ - **工具栏**(默认):选区上方出现「复制」「引用」按钮——复制点击才写剪贴板(不刷屏 Win+V);**引用**把选中文本的**完整内容**以简约的 `>` 引用块插入输入框(标准 markdown 引用,发送时渲染为引用块)。
41
+ - **选中即自动复制**:终端风格,选中直接写系统剪贴板。
42
+ 6. **鼠标右键直接粘贴** — 在输入框上右键即粘贴剪贴板内容(和 Linux 终端一致,不弹菜单);粘贴走与 Ctrl+V 完全一致的管线(图片与引用 chip 行为一致),execCommand 路径被限制时自动回退到 Clipboard API 手动插入。
43
+ 7. **跨会话历史记忆**(设置里可开关,默认关)— 开启后 ↑/↓ 历史在会话间保持,存于浏览器本地(上限 200 条),刷新/切换会话不丢失。
44
+
45
+ 纯 UI 行为:不产生会话事件、不改变 agent 循环、不发起模型请求。召回/引用的文本只会进入输入框草稿,只有**你**按 Enter 才会到达模型。
46
+
47
+ ## 快速开始
48
+
49
+ ```sh
50
+ # 1. 把插件装进你的 profile
51
+ dsh plugin --profile web add @wenaixi/dsh-prompt-history
52
+
53
+ # 2. 刷新页面即可使用(无需重启服务)
54
+ ```
55
+
56
+ ## 安装与卸载
57
+
58
+ - **npm 渠道**(已发布版本):`dsh plugin --profile web add @wenaixi/dsh-prompt-history`
59
+ - **源码渠道**(本地开发,最新 `main`):`dsh plugin --profile web add "github:Wenaixi/dsh-prompt-history#main"`(源码检出需先 `pnpm run build` —— 未构建的 bundle 会拒绝启动)
60
+ - **卸载**:`dsh plugin --profile web remove @wenaixi/dsh-prompt-history`
61
+
62
+ ## 配置
63
+
64
+ 打开 **插件 → `@wenaixi/dsh-prompt-history` → 配置**(由 DSH 宿主配置持久化到 `cordis.patch.yml`;旧版浏览器设置会在首次打开时自动迁移)。改动即时保存,不需要保存按钮——每次开关、切换单选或点「恢复默认」都立即写入宿主:
65
+
66
+ | 选项 | 默认 | 说明 |
67
+ |---|---|---|
68
+ | 选中文本后 | `弹出工具栏` | `什么都不做` / `弹出工具栏`(点击才写剪贴板)/ `选中即复制`(终端风格) |
69
+ | 打开历史列表 | `两者都要` | `只用 Ctrl+R` / `只用双击 Esc` / `两者都要` |
70
+ | 上下键历史 | 开 | 关闭后 ↑/↓、Ctrl+R 与双击 Esc 全部交还宿主 |
71
+ | 跨会话记忆 | 关 | ↑/↓ 历史在会话间保持,存浏览器本地,上限 200 条 |
72
+ | 右键直接粘贴 | 开 | 关闭后右键恢复浏览器原生菜单 |
73
+
74
+ ## 特性
75
+
76
+ - **历史来自会话自身的消息记录**:直接读取会话快照中的用户消息节点(`user` / `steering`),随消息落地实时追加——与聊天记录严格一致,随会话持久化,刷新页面后依然可用,不需要任何配置或额外存储。开启「跨会话记忆」后改从浏览器 localStorage(上限 200 条)播种并在每次追加时全环去重。
77
+ - **连续重复自动合并**,浏览状态跟随会话切换自动重置。
78
+ - **界面国际化**:全部文案(设置、工具栏、提示 pill、历史列表)跟随 DSH 应用语言(中文 / English)。
79
+ - client bundle 压缩后约 13 KB;依赖全部走官方 `@deepseek-ai/*` peer 依赖。
80
+
81
+ ## 已知限制
82
+
83
+ - **Ctrl+R**:输入框聚焦时 Ctrl+R 打开历史列表,**不再触发浏览器刷新**(想刷新先点一下输入框外面)。
84
+ - 纯文本召回:带图片/命令 chip 的消息不参与;召回内容为纯文本。
85
+ - 多行判定按逻辑行(Lexical 以 `<br>` 换行):超长单行**视觉折行**后按 ↑ 会直接进入历史而非上移一行。
86
+
87
+ ## 开发
88
+
89
+ ```sh
90
+ pnpm install
91
+ pnpm run typecheck # tsc --noEmit
92
+ pnpm run build # tsc(lib/types)+ tsdown(lib/index.js / lib/invariant.js / lib/client.js)
93
+ ```
94
+
95
+ 浏览器半区(`src/client/`)注册在 `conversation.input.right` 槽位与插件详情页配置卡(`plugins.bundle.config`),构建产物为 DSH `__ModuleLoader__` 闭包格式,外部依赖仅 `react` 与官方 `@deepseek-ai/*` peer 包(其余由浏览器模块表提供)。配置卡自绘外壳,`SettingsCardController` 做「操作即写」:每次改动直接写宿主,失败回落宿主真值。文案字典在 `src/client/locales.ts`(`zh` 为准、`en` 键位对齐),通过 `ctx.locale.register` 注册。
96
+
97
+ ## 原理
98
+
99
+ 插件是一个不可见的 composer 槽位条目:挂一个 document 捕获期 keydown 监听,仅在目标为 composer 输入框、无修饰键、非输入法组合、菜单未打开、会话非忙碌时接管 ↑/↓,通过 `inputActions.setDraft` 写入历史文本。浏览位置用「已浏览条数」(`browseRef.step`)表示,配合「开始浏览前那一行」的草稿副本;↑ 只在光标位于第一行时接管,↓ 只在最后一行时接管(对齐 Claude Code `upOrHistoryUp` / `downOrHistoryDown` 的「先移光标」)。历史列表由会话快照的 `user`/`steering` 节点按 seq 去重追加。多行行号按 Lexical 的 `<br>` 结构计算。
100
+
101
+ ## License
102
+
103
+ [MIT](LICENSE)