dsh-quote-comment 0.1.0 → 0.1.1

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/README.md CHANGED
@@ -26,6 +26,7 @@ chip 上只显示一行摘要(悬停看全文),发送时由本插件的 co
26
26
  - **chip 只带 `source` 名字,序列化靠插件自己注册的属主**:`ctx.get("inputTriggers").registerSource({ trigger: "#", name: "quote-comment", candidates: () => [], codec: { clipboardText, serialize } })`,提交消息时 inputTriggers 按名字找到本插件、调用 `codec.serialize(ref)` 把 `ref`(原始选中文本)展开成引用块。**没有这个属主,发送会被 `no serializer for reference source "quote-comment"` 挡住**,所以注册失败时(服务缺失/名字被占)自动退回纯文本路径。
27
27
  - 兜底写输入框走官方 `inputActions`(ui-conversation 经 `uiSession` 服务以 `props.inputActions` 暴露):`insertText(text, captureInsertion())`。输入框是 Lexical 编辑器,`document.execCommand("insertText")` 对它不可靠,所以再兜底用合成 `paste` 事件。
28
28
  - 会话正文判定用官方 DOM 锚点:`[data-chat-flow]` / `[data-chat-flow-key]` / `[data-chat-anchor-key]` / `[data-conversation-scroll]`,并排除 `[data-composer-seat]`(输入区)与插件自己的 `[data-quote-comment-root]`。
29
+ - **插入后光标必须经 Lexical 复位**:只做裸 DOM `focus()` 会把光标丢到 contenteditable 的开头——官方注释原文 "a bare DOM focus on the contenteditable would land the caret at the start instead"(`@deepseek-ai/dsh-client-ui-conversation/lib/client.js:13815-13823`),于是光标停在 chip 之前。插件照官方两步法复位:`rootElement.focus({ preventScroll: true })` → `rootElement.__lexicalEditor.focus()`(Lexical 把 editor 实例挂在根元素上,见同 bundle `:10026`),让模型里的选区(插入后 = chip 之后)重新刷回 DOM。
29
30
 
30
31
  ## 安装到 desktop profile
31
32
 
@@ -73,9 +74,9 @@ New-Item -ItemType Junction -Path "$profile\node_modules\dsh-quote-comment" -Tar
73
74
  & "C:\Users\wangj\.dsh\dsh-runtimes\dsh-primary-runtime\dependencies\node\bin\node.exe" test\smoke.mjs
74
75
  ```
75
76
 
76
- `test/smoke.mjs` 用迷你 DOM + 迷你 React 在 Node 里驱动 `lib/client.js`,覆盖 49 项断言:模块契约、选区浮出按钮、定位、**官方引用 chip 通道(属主注册、reference 载荷、codec 序列化、摘要截断)**、无 chip 服务时回退 `inputActions.insertText`、多行引用格式、输入区选中不触发、`paste` 兜底、剪贴板兜底。
77
+ `test/smoke.mjs` 用迷你 DOM + 迷你 React 在 Node 里驱动 `lib/client.js`,覆盖 51 项断言:模块契约、选区浮出按钮、定位、**官方引用 chip 通道(属主注册、reference 载荷、codec 序列化、摘要截断)**、无 chip 服务时回退 `inputActions.insertText`、多行引用格式、输入区选中不触发、`paste` 兜底、剪贴板兜底、**插入后经 Lexical 复位光标(无 `__lexicalEditor` 时退化为裸 focus)**。
77
78
 
78
- `test/install-check.mjs` 另做 16 项安装自检(profile 登记、加载器清单契约、bundle 形态、宿主半身)。
79
+ `test/install-check.mjs` 另做 17 项安装自检(profile 登记、加载器清单契约、bundle 形态、宿主半身)。
79
80
 
80
81
  ## 重启后验收(30 秒)
81
82
 
@@ -101,3 +102,8 @@ document.querySelector('[data-composer-chip="quote-comment"]') !== null // true
101
102
  - 引用块用 Markdown `> `,与模型交流时语义明确,也不会触发输入框的 `/` 命令菜单。
102
103
  - 插件注册的属主触发字符是 `#` 且不提供补全候选:输入 `#` 不会弹出额外菜单项。若日后与别的插件撞名(`(trigger,name)` 唯一),插件会自动改用纯文本路径而不会报错。
103
104
  - 若 DSH 后续改了 `shell.overlay` 槽位名、`inputActions` 方法名、`slash/input-insert-reference` 事件名或输入框锚点,需要同步更新 `lib/client.js` 顶部的选择器/常量与 `resolveInputActions()`。
105
+
106
+ ## 更新记录
107
+
108
+ - **0.1.1** — 修复「点添加评论后光标停在 chip 之前」:插入后按官方两步法经 Lexical 复位选区(`rootElement.focus()` → `rootElement.__lexicalEditor.focus()`),`test/smoke.mjs` 增加两条回归断言 + 一条无 Lexical 实例时的退化断言。
109
+ - **0.1.0** — 首个版本:会话正文选中 → 浮出「添加评论」→ 经官方引用通道插入原子 chip(注册 `#quote-comment` 引用属主负责提交时序列化),四级插入兜底(chip → `inputActions.insertText` → 合成 `paste` → 剪贴板)。
package/lib/client.js CHANGED
@@ -164,7 +164,16 @@ function composerText() {
164
164
  return host.textContent || "";
165
165
  }
166
166
 
167
- /** 把焦点交回输入框(insertText 已把光标落在插入文本之后)。 */
167
+ /**
168
+ * 把焦点交回输入框,并让光标停在最后一次插入之后。
169
+ *
170
+ * 只做裸 DOM focus 会把光标丢到 contenteditable 的开头 —— 官方注释原文:
171
+ * "a bare DOM focus on the contenteditable would land the caret at the start instead"
172
+ * (`@deepseek-ai/dsh-client-ui-conversation/lib/client.js:13815-13823` 的 `SessionInputShell.focus()`),
173
+ * 这正是「chip 前出现光标」的原因。官方做法是两步:先 focus 根元素,再让 Lexical
174
+ * 自己 `focus()` 把模型里的选区(插入后 = chip 之后)重新刷到 DOM;Lexical 把 editor
175
+ * 实例挂在根元素上 `__lexicalEditor`(同 bundle `:10026`)。
176
+ */
168
177
  function focusComposer() {
169
178
  var host = composerHost();
170
179
  if (host === null || typeof host.focus !== "function") return;
@@ -177,6 +186,14 @@ function focusComposer() {
177
186
  /* 忽略 */
178
187
  }
179
188
  }
189
+ var editor = host.__lexicalEditor;
190
+ if (editor && typeof editor.focus === "function") {
191
+ try {
192
+ editor.focus();
193
+ } catch (error) {
194
+ /* 忽略:裸 focus 已经做过,最坏情况是光标回到最前面 */
195
+ }
196
+ }
180
197
  }
181
198
 
182
199
  function installStyle() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-quote-comment",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "选中会话内容即浮出「添加评论」按钮,点击把选中文本作为引用插入聊天输入框。",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",