dsh-quote-annotate-pro 0.2.0 → 0.2.2

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
@@ -2,6 +2,19 @@
2
2
 
3
3
  本项目的所有重要变更都记在这里。版本号遵循 [SemVer](https://semver.org/lang/zh-CN/)。
4
4
 
5
+ ## 0.2.2 — 引用界面改为紧凑式
6
+
7
+ - **输入框上方的引用块**:不再显示 `引用#N · 第N轮 · 角色` 这类标签,改为**只显示原文片段**(单行、超出省略);点一下即跳回原文并高亮,且**不再弹出"已跳转"提示**、取消常驻导航条 —— 输入区更干净
8
+ - 输入框内的 chip 标签简化为 `引用1` / `引用2`(唯一、简短)
9
+ - **定位能力不变**:锚点仍写入 `localStorage`(按会话,≤60 条),多轮对话里仍可精确跳回;发送的引用块仍以 `【引用 · 第N轮 · 角色】` 开头(模型侧定位不受影响)
10
+ - 引用块不提供删除按钮:要撤掉引用,请在输入框用 Backspace 删除对应 chip
11
+
12
+ ## 0.2.1 — 文档与自动发版
13
+
14
+ - README / README.en:新增 npm 版本、CI、License 徽章;安装章节补上 `dsh plugin add dsh-quote-annotate-pro`(npm)与 `github:` 两种方式
15
+ - 新增 `.github/workflows/release.yml`:推 `v*` 标签即由 **npm Trusted Publishing(OIDC)** 自动发布,仓库不存任何 token,并生成 provenance 签名
16
+ - `lib/client.js` 相对 0.2.0 **无变化**(本次发版只为验证 OIDC 发布链路并把文档同步到 npm)
17
+
5
18
  ## 0.2.0 — 首个公开发布
6
19
 
7
20
  Fork 自 [`dsh-quote-annotate`](https://github.com/wangwei-wade/dsh-quote-annotate) v0.1.1(MIT),
package/README.en.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # dsh-quote-annotate-pro
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/dsh-quote-annotate-pro?color=2ea44f&label=npm)](https://www.npmjs.com/package/dsh-quote-annotate-pro)
4
+ [![ci](https://github.com/zhao-guang-ai/dsh-quote-annotate-pro/actions/workflows/ci.yml/badge.svg)](https://github.com/zhao-guang-ai/dsh-quote-annotate-pro/actions/workflows/ci.yml)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
6
+
3
7
  **Select → annotate → quote, inside a DSH conversation.** The selected text enters the composer as an anchored quote reference; on send it serializes into a structured quote block, and a quote bar under the composer jumps back to the exact source message and highlights it. The model sees `【引用 · 第N轮 · DSH 回复】` — which turn, whose message — so it no longer has to guess what "that part above" means.
4
8
 
5
9
  > An enhanced fork of [`dsh-quote-annotate`](https://github.com/wangwei-wade/dsh-quote-annotate) (MIT, by wangwei-wade).
@@ -12,8 +16,8 @@
12
16
  | Capability | Detail |
13
17
  | --- | --- |
14
18
  | Select & annotate | Select text in the transcript → a bubble appears above the selection → write a comment (optional) → `Enter` |
15
- | Quote chip | An atomic `引用#1 · 第3轮 · DSH 回复` chip lands in the composer; it expands to the full quote block on send |
16
- | **Quote bar** | A persistent bar under the composer (`引用 ❝ …`): click to jump back to the source and highlight it, hover to preview |
19
+ | Quote chip | An atomic `引用1` chip (short label) lands in the composer; it expands to the full quote block on send |
20
+ | **Quote block** | While a quote is in the composer, a compact block above it shows the **quoted text snippet** (single line, ellipsised). Click it to jump back to the source and highlight it — no visible "jump" affordance, so the composer stays clean |
17
21
  | **Turn-accurate context** | The quote block starts with `【引用 · 第3轮 · 你的消息】` followed by `> quoted text`, so the model knows exactly which turn and whose message |
18
22
  | Turn-level quoting | Every finished turn gets `引用提问` / `引用回答` buttons that quote the whole question or answer |
19
23
  | Anchors survive reload | The `ref → anchor` map is persisted in `localStorage` (per session, 60 entries max), so quotes still jump after a page refresh |
@@ -21,6 +25,9 @@
21
25
  ## Install
22
26
 
23
27
  ```sh
28
+ # from npm (recommended)
29
+ dsh plugin --profile <profile> add dsh-quote-annotate-pro
30
+
24
31
  # from GitHub
25
32
  dsh plugin --profile <profile> add github:zhao-guang-ai/dsh-quote-annotate-pro
26
33
 
@@ -73,6 +80,22 @@ npm run diag # local diagnostics sink (http://127.0.0.1:47821)
73
80
 
74
81
  `lib/client.js` is a hand-written bundle (no build step) — edit and save; the client HMR reloads it. See [README.md](./README.md) (Chinese) for the diagnostics channel and known limitations.
75
82
 
83
+ ## Releasing (maintainers)
84
+
85
+ Releases go through **npm Trusted Publishing (OIDC)** — no token is stored in the repository and no one-time code is needed:
86
+
87
+ 1. Bump `version` in `package.json` and note the change in `CHANGELOG.md`
88
+ 2. Commit, tag and push:
89
+
90
+ ```sh
91
+ git tag -a v0.2.2 -m "v0.2.2"
92
+ git push origin main --follow-tags
93
+ ```
94
+
95
+ 3. [`release.yml`](.github/workflows/release.yml) then checks the tag against the version, runs the syntax/manifest checks, and publishes with `--provenance` (SLSA attestation). An already-published version is skipped, so the workflow is safe to re-run.
96
+
97
+ Trusted Publisher configured on npm: `zhao-guang-ai` / `dsh-quote-annotate-pro` / workflow `release.yml` / environment `npm`.
98
+
76
99
  ## License
77
100
 
78
101
  MIT — see [LICENSE](./LICENSE). Upstream: [`wangwei-wade/dsh-quote-annotate`](https://github.com/wangwei-wade/dsh-quote-annotate) (MIT, © 2026 wangwei-wade).
package/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # dsh-quote-annotate-pro
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/dsh-quote-annotate-pro?color=2ea44f&label=npm)](https://www.npmjs.com/package/dsh-quote-annotate-pro)
4
+ [![ci](https://github.com/zhao-guang-ai/dsh-quote-annotate-pro/actions/workflows/ci.yml/badge.svg)](https://github.com/zhao-guang-ai/dsh-quote-annotate-pro/actions/workflows/ci.yml)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
6
+
3
7
  **在 DSH 会话里划词 → 批注 → 引用**:选中的文字变成带锚点的引用进入输入框,发送时序列化为结构化引用块;输入框下方常驻一条**引用导航条**,点一下就能跳回原文并高亮。多轮对话里,模型看到的是 `【引用 · 第N轮 · 你的消息】`,不再需要猜"你说的是哪一处"。
4
8
 
5
9
  > 这是 [`dsh-quote-annotate`](https://github.com/wangwei-wade/dsh-quote-annotate)(MIT,作者 wangwei-wade)的增强 fork。
@@ -12,11 +16,11 @@
12
16
  | 能力 | 说明 |
13
17
  |---|---|
14
18
  | 划词批注 | 会话里选中任意文字 → 选区上方浮出气泡(预览 + 「批注」)→ 编辑框里写评语(可留空)→ `Enter` 插入 |
15
- | 引用 chip | 输入框里出现 `引用#1 · 第5轮 · DSH 回复` 的原子 chip;发送时展开为完整引用块 |
16
- | **引用导航条** | 输入框下方常驻 `引用 ❝ 引用#1 …`,**点击跳回原文并高亮**,悬停预览原文 |
19
+ | 引用 chip | 输入框里出现 `引用1` 的原子 chip(短标签);发送时展开为完整引用块 |
20
+ | **引用块(输入框上方)** | 有引用时在输入框上方显示**原文片段**(单行、超出省略);**点一下即跳回原文并高亮** —— 不做任何可见的"跳转"提示,保持输入区干净 |
17
21
  | **模型侧精确定位** | 引用块首行是 `【引用 · 第5轮 · 你的消息】`,后接 `> 原文`,让模型明确知道**哪一轮、谁说的** |
18
22
  | 回合级引用 | 每条已完成回合尾部有「引用提问 / 引用回答」,整段引用该轮 |
19
- | 锚点持久化 | `ref → 锚点` 映射写入 `localStorage`(按会话,最多 60 条),**刷新页面后引用条仍能跳回原文** |
23
+ | 锚点持久化 | `ref → 锚点` 映射写入 `localStorage`(按会话,最多 60 条),**刷新页面后引用块仍能跳回原文** |
20
24
  | 中英自适应 | 按钮文案跟随界面语言(沿用上游) |
21
25
 
22
26
  ## 与上游的差异
@@ -46,13 +50,19 @@
46
50
 
47
51
  6. **引用块带轮次/角色** —— 上游只发 `> 原文`。→ 首行加 `【引用 · 第N轮 · 角色】`(轮次取自 `data-chat-turn`,角色取自 `data-chat-flow-kind`)。
48
52
 
49
- 7. **引用导航条 + 锚点持久化** —— 本版本输入框 chip **没有 `data-*` 属性**(只有 CSS 类),上游"点 chip 跳转"不可能成立。
50
- → 改为读官方输入状态 `occurrences`(`source === 'quote-ref'`)渲染导航条;`ref → 锚点` 落 `localStorage`,刷新后仍可跳。
51
- (输入框 chip 本体也支持点击跳转:按 `title` = label 反查 ref,不依赖 CSS 类顺序。)
53
+ 7. **输入框上方的引用块 + 锚点持久化** —— 本版本输入框 chip **没有 `data-*` 属性**(只有 CSS 类),上游"点 chip 跳转"不可能成立。
54
+ → 改为读官方输入状态 `occurrences`(`source === 'quote-ref'`)渲染引用块,只显示**原文片段**(不显示标签/轮次,保持简洁);
55
+ `ref → 锚点` 落 `localStorage`,刷新后仍可跳。(输入框 chip 本体也支持点击跳转:按 `title` = label 反查 ref,不依赖 CSS 类顺序。)
52
56
 
53
57
  ## 安装
54
58
 
55
59
  ```sh
60
+ # 从 npm 安装(推荐,一步到位)
61
+ dsh plugin --profile <profile> add dsh-quote-annotate-pro
62
+
63
+ # 或直接从 GitHub 安装
64
+ dsh plugin --profile <profile> add github:zhao-guang-ai/dsh-quote-annotate-pro
65
+
56
66
  # 本地开发:
57
67
  # <本仓库绝对路径> 为克隆后的目录;link 安装后改文件即刻热更,无需重启
58
68
  dsh plugin --profile <profile> add <本仓库绝对路径>
@@ -73,7 +83,8 @@ dsh plugin --profile <profile> add <本仓库绝对路径>
73
83
  emit('slash/input-insert-reference', { reference, span }) ← 官方会话事件,会话作用域
74
84
  │ 输入机 mint 一条 occurrence(source='quote-ref' / ref / label)
75
85
  ▼
76
- 输入框 chip(官方 Lexical 装饰节点)
86
+ 输入框 chip(官方 Lexical 装饰节点,标签 `引用N`)
87
+ │ 同时:输入框上方出现「引用块」(显示原文片段,点一下可跳回)
77
88
  │ 发送
78
89
  ▼
79
90
  本插件 codec.serialize(ref) → 完整引用块
@@ -83,7 +94,7 @@ emit('slash/input-insert-reference', { reference, span }) ← 官方会话
83
94
  ▼
84
95
  模型收到"哪一轮 + 谁说的 + 原文"
85
96
 
86
- 跳回原文:导航条/锚点 → [data-chat-anchor-key] 行 → scrollIntoView + 高亮
97
+ 跳回原文:引用块/锚点 → [data-chat-anchor-key] 行 → scrollIntoView + 高亮(无可见提示)
87
98
  ```
88
99
 
89
100
  用到的官方接口:`slots`(`shell.overlay` / `conversation.chat.turnTail` / `conversation.input.dock`)、
@@ -127,12 +138,41 @@ turnTail:render 回合尾部按钮取文
127
138
 
128
139
  不需要时把 `DIAG_ENABLED` 改成 `false` 即可(`console.log('[quote-pro]', …)` 会保留)。
129
140
 
141
+ ## 发版(维护者)
142
+
143
+ 发布走 **npm Trusted Publishing(OIDC)**,仓库里不保存任何 token,也不需要动态验证码:
144
+
145
+ 1. 改 `package.json` 的 `version`,并在 `CHANGELOG.md` 记录变更
146
+ 2. 提交、打标签、推送:
147
+
148
+ ```sh
149
+ git tag -a v0.2.2 -m "v0.2.2"
150
+ git push origin main --follow-tags
151
+ ```
152
+
153
+ 3. GitHub Actions 的 [`release.yml`](.github/workflows/release.yml) 自动执行:
154
+ 校验 tag 与版本一致 → 语法与清单自检 → `npm publish --provenance`(带 SLSA 签名)
155
+ 4. 该版本已存在时自动跳过,工作流可安全重跑
156
+
157
+ 已在 npm 包设置页配置的 Trusted Publisher:
158
+
159
+ | 字段 | 值 |
160
+ |---|---|
161
+ | Organization or user | `zhao-guang-ai` |
162
+ | Repository | `dsh-quote-annotate-pro` |
163
+ | Workflow filename | `release.yml` |
164
+ | Environment name | `npm` |
165
+
166
+ > 注:npm 现在对"绕过 2FA 的 token 直接发布"逐步收紧(账号变更已限制,直接发布 2027-01 起限制),
167
+ > 因此本仓库从一开始就只走 OIDC —— 这是官方推荐方向,也避免了 token 泄漏风险。
168
+
130
169
  ## 已知限制
131
170
 
132
171
  - **输入框 chip 本体跳转依赖 `title`**:本版本 chip 无 `data-*` 属性,是按渲染出的 `title`(= 插入时写入的 label)反查 ref;
133
- label 相同的多条引用只会命中最早的一条(导航条则始终精确)。
172
+ chip 标签为 `引用1`、`引用2` 这样的短标签(唯一),因此不再有歧义;上方引用块则始终精确。
134
173
  - **跳转要求原文行在当前页面**:目标消息未加载(历史未翻到)时只能给出提示,不做自动翻页加载。
135
- - **导航条在会话切换后重建**:锚点按会话存储;切到别的会话不会串。
174
+ - **引用块在会话切换后重建**:锚点按会话存储;切到别的会话不会串。
175
+ - **引用块不提供"删除"按钮**:要撤掉引用,请在输入框里用 Backspace 删除对应 chip(官方输入的既有行为)。
136
176
  - **回合尾部按钮在有交付文件的回合也会显示**:上游会隐藏、让位给官方「已生成文件」chips。
137
177
  - **评语以纯文本追加在 chip 之后**:编辑 chip 文本请用 Backspace 删除。
138
178
 
package/lib/client.js CHANGED
@@ -397,8 +397,8 @@ window.__ModuleLoader__.load({
397
397
  notifyTimer = setTimeout(() => toastStore.hide(), 2600)
398
398
  } catch (e) { /* ignore */ }
399
399
  }
400
- /** 跳到某个锚点行并高亮它。 */
401
- function jumpToAnchorKey(anchorKey, pos) {
400
+ /** 跳到某个锚点行并高亮它。opts.silent=true 时不弹成功提示(高亮本身就是反馈)。 */
401
+ function jumpToAnchorKey(anchorKey, pos, opts) {
402
402
  if (!anchorKey) return false
403
403
  let row = null
404
404
  for (const r of document.querySelectorAll('[data-chat-anchor-key]')) {
@@ -412,12 +412,12 @@ window.__ModuleLoader__.load({
412
412
  row.scrollIntoView({ block: 'center', behavior: 'smooth' })
413
413
  row.classList.add('dshq-flash')
414
414
  setTimeout(() => row.classList.remove('dshq-flash'), 1600)
415
- notify('已跳转到原文 ✓', pos, true)
415
+ if (!(opts && opts.silent)) notify('已跳转到原文 ✓', pos, true)
416
416
  report('jump:ok', { anchorKey })
417
417
  return true
418
418
  }
419
419
  /** 按 ref 跳回原文:优先用锚点键,退化到按引用正文反查。 */
420
- function jumpToRef(ref, pos) {
420
+ function jumpToRef(ref, pos, opts) {
421
421
  const info = refTargets.get(ref)
422
422
  if (!info) {
423
423
  notify('跳转失败:找不到该引用(可能已发送或已删除)', pos, false)
@@ -442,7 +442,7 @@ window.__ModuleLoader__.load({
442
442
  notify('跳转失败:没有定位键(选中时未识别到消息行)', pos, false)
443
443
  return false
444
444
  }
445
- return jumpToAnchorKey(anchorKey, pos)
445
+ return jumpToAnchorKey(anchorKey, pos, opts)
446
446
  }
447
447
 
448
448
  /**
@@ -760,8 +760,8 @@ window.__ModuleLoader__.load({
760
760
  const base = (st.draft || '').replace(/[\s\u00A0]+$/, '')
761
761
  const commentTail = c === '' ? '' : '\n\n' + c
762
762
  const ref = 'q' + REF_RUN + (++refSeq)
763
- const anchorLabel = anchorLabelOf(item)
764
- const chipLabel = '引用#' + refSeq + (anchorLabel === '' ? '' : ' · ' + anchorLabel)
763
+ // 输入框里的 chip 文案只要短、可区分即可(轮次/角色写在发送后的引用块里,不在输入框展示)
764
+ const chipLabel = '引用' + refSeq
765
765
  refTargets.set(ref, { sessionId, anchorKey: item.anchorKey || null, body: quoteBody, label: chipLabel })
766
766
  refCodecs.set(ref, { body: quoteBody, clipboardText: quoteBody })
767
767
  saveRef(sessionId, ref, { anchorKey: item.anchorKey || null, body: quoteBody, label: chipLabel })
@@ -794,7 +794,7 @@ window.__ModuleLoader__.load({
794
794
  report('insert:chip', { ref, anchorKey: item.anchorKey || null, header, chars: item.text.length })
795
795
  setStatus({
796
796
  ok: true,
797
- text: '已插入引用 chip ✓(' + (item.anchorKey ? '点击 chip 可跳回原文' : '未定位到消息行,点击可能无法跳转') + ')',
797
+ text: '已插入引用 ✓' + (item.anchorKey ? '(输入框上方的引用块可点回原文)' : '(未定位到消息行,可能无法跳回)'),
798
798
  })
799
799
  editorStore.close()
800
800
  return
@@ -869,42 +869,39 @@ window.__ModuleLoader__.load({
869
869
  }
870
870
 
871
871
  // ============ 样式(主题令牌自适应明暗) ============
872
- // ============ 组件六:输入框下方的引用导航条 ============
872
+ // ============ 组件六:输入框上方的引用块(紧凑样式;点击可跳回原文,但不显式提示) ============
873
873
  // 本版本输入框里的引用 chip 没有 data 属性(只有 CSS 类),DOM 无法反查 occurrence;
874
- // 因此导航条直接读官方输入状态的 occurrences(source === 'quote-ref')来渲染,
875
- // 点击即可跳回原文 —— 这是「多轮对话里精准定位」的可靠入口。
876
- const QuoteDockChip = ({ item }) => {
874
+ // 因此这里直接读官方输入状态的 occurrences(source === 'quote-ref')来渲染。
875
+ // 展示的是**原文片段本身**(不再显示「引用#N · 第N轮 · 角色」这类标签),保持输入区干净;
876
+ // 定位能力保留:点一下就跳回原文并高亮,只是不做任何可见的"跳转"提示。
877
+ const SNIPPET_MAX = 90
878
+ const snippetOf = (body) => {
879
+ const raw = String(body || '')
880
+ .split('\n')
881
+ .filter((line) => line.trim() !== '' && !/^【引用/.test(line.trim()))
882
+ .map((line) => line.replace(/^>\s?/, ''))
883
+ .join(' ')
884
+ .replace(/\s+/g, ' ')
885
+ .trim()
886
+ return raw.length > SNIPPET_MAX ? raw.slice(0, SNIPPET_MAX) + '…' : raw
887
+ }
888
+
889
+ const QuoteBlock = ({ item }) => {
877
890
  const onJump = (e) => {
878
891
  try {
879
892
  const r = e.currentTarget.getBoundingClientRect()
880
893
  report('dock:click', { ref: String(item.ref), anchorKey: item.anchorKey || null })
881
- jumpToRef(item.ref, { left: r.left + 16, top: r.top })
882
- } catch (err) { /* ignore */ }
883
- }
884
- const onOver = (e) => {
885
- try {
886
- const info = refTargets.get(item.ref)
887
- if (!info || !info.body) return
888
- const r = e.currentTarget.getBoundingClientRect()
889
- tooltipStore.show({
890
- text: String(info.body).replace(/^> ?/gm, '').trim(),
891
- label: info.label || '引用',
892
- rect: { left: r.left, top: r.top, right: r.right, bottom: r.bottom },
893
- })
894
+ jumpToRef(item.ref, { left: r.left + 16, top: r.top }, { silent: true })
894
895
  } catch (err) { /* ignore */ }
895
896
  }
896
- const onOut = () => { try { tooltipStore.hide() } catch (err) { /* ignore */ } }
897
- return React.createElement('button', {
898
- type: 'button',
899
- className: 'dshq-dock-chip',
897
+ return React.createElement('div', {
898
+ className: 'dshq-quote-block',
900
899
  onClick: onJump,
901
- onMouseEnter: onOver,
902
- onMouseLeave: onOut,
903
- title: '点击跳回原文,悬停查看原文',
904
- },
905
- React.createElement('span', { className: 'dshq-dock-chip-icon' }, '❝'),
906
- React.createElement('span', { className: 'dshq-dock-chip-label' }, item.label || ('引用#' + item.ref)),
907
- )
900
+ onKeyDown: (e) => { if (e.key === 'Enter' || e.key === ' ') onJump(e) },
901
+ role: 'button',
902
+ tabIndex: 0,
903
+ title: '点击跳回原文',
904
+ }, React.createElement('span', { className: 'dshq-quote-block-text' }, item.snippet || '引用'))
908
905
  }
909
906
 
910
907
  const QuoteDock = (props) => {
@@ -930,7 +927,11 @@ window.__ModuleLoader__.load({
930
927
  for (const occ of occurrences) {
931
928
  if (!occ || occ.source !== 'quote-ref') continue
932
929
  const info = refTargets.get(occ.ref)
933
- next.push({ ref: occ.ref, label: (info && info.label) || occ.label || ('引用#' + occ.ref), anchorKey: (info && info.anchorKey) || null })
930
+ next.push({
931
+ ref: occ.ref,
932
+ anchorKey: (info && info.anchorKey) || null,
933
+ snippet: snippetOf(info && info.body),
934
+ })
934
935
  }
935
936
  setRows(next)
936
937
  if (next.length > 0) report('dock:rows', { count: next.length })
@@ -949,8 +950,8 @@ window.__ModuleLoader__.load({
949
950
  }
950
951
  }, [sessionId])
951
952
  if (!sessionId || rows.length === 0) return null
952
- const children = [React.createElement('span', { className: 'dshq-dock-title', key: '__t' }, '引用')]
953
- for (const row of rows) children.push(React.createElement(QuoteDockChip, { key: row.ref, item: row }))
953
+ const children = []
954
+ for (const row of rows) children.push(React.createElement(QuoteBlock, { key: row.ref, item: row }))
954
955
  return React.createElement('div', { className: 'dshq-dock' }, children)
955
956
  }
956
957
 
@@ -985,13 +986,11 @@ window.__ModuleLoader__.load({
985
986
  /* 根因:textarea(透明文字、absolute、inset:0)渲染在 backdrop 之后,整层盖住 chip。
986
987
  给 chip 提升 z-index 使其浮到 textarea 之上,点击才能落到 chip 上。 */
987
988
  [data-occurrence]{pointer-events:auto;cursor:pointer;position:relative;z-index:1}
988
- /* 引用导航条:输入框下方,点击跳回原文 */
989
- .dshq-dock{display:flex;align-items:center;gap:6px;flex-wrap:wrap;padding:2px 6px;font-size:11px;color:var(--dsw-alias-label-secondary)}
990
- .dshq-dock-title{opacity:.65;user-select:none}
991
- .dshq-dock-chip{appearance:none;display:inline-flex;align-items:center;gap:4px;max-width:280px;padding:2px 9px;border-radius:999px;border:1px solid var(--dsw-alias-border-l1);background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);font:inherit;font-size:11px;line-height:18px;cursor:pointer}
992
- .dshq-dock-chip:hover{border-color:var(--dsw-alias-brand-primary);color:var(--dsw-alias-brand-primary)}
993
- .dshq-dock-chip-icon{opacity:.55}
994
- .dshq-dock-chip-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
989
+ /* 引用块:输入框上方,紧凑单行(点一下跳回原文,但不显示任何"跳转"提示) */
990
+ .dshq-dock{display:flex;flex-direction:column;gap:4px;padding:0 2px;min-width:0}
991
+ .dshq-quote-block{display:flex;align-items:center;min-width:0;max-width:100%;box-sizing:border-box;padding:5px 10px;border-radius:8px;background:var(--dsw-alias-bg-layer-2);background:color-mix(in oklab,var(--dsw-alias-brand-primary) 8%,var(--dsw-alias-bg-layer-1));color:var(--dsw-alias-label-secondary);font-size:12px;line-height:18px;cursor:pointer;transition:background .12s ease,color .12s ease}
992
+ .dshq-quote-block:hover{color:var(--dsw-alias-label-primary)}
993
+ .dshq-quote-block-text{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
995
994
  `
996
995
 
997
996
  // ============ 插件主体 ============
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dsh-quote-annotate-pro",
3
- "version": "0.2.0",
4
- "description": "选区引用与锚点批注(增强 fork):划词 → 批注 → 带精确锚点的引用 chip,点击跳回原文;提交时把轮次/角色/位置写入引用块,让模型精确知道你指的是哪一处。",
3
+ "version": "0.2.2",
4
+ "description": "选区引用与锚点批注(增强 fork):划词 → 批注 → 带精确锚点的引用;输入框上方只显示原文片段,点一下跳回原文;发送时把轮次/角色写入引用块,让模型精确知道你指的是哪一处。",
5
5
  "keywords": ["dsh", "dsh-plugin", "deepseek-harness", "quote", "annotate", "selection", "reference", "anchor"],
6
6
  "license": "MIT",
7
7
  "type": "module",