@kirkchinese/dsh-citeciter 0.4.1 → 0.4.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/README.md +9 -9
- package/README.zh.md +9 -9
- package/lib/client.js +6 -6
- package/lib/index.js +50 -3
- package/lib/types/client/conversation-dom.d.ts +3 -3
- package/package.json +16 -15
package/README.md
CHANGED
|
@@ -25,17 +25,17 @@ Investigate any line in a DSH response—without stopping the Agent or changing
|
|
|
25
25
|
4. Continue asking questions there, or reopen an earlier Topic from CiteCiter's Topic rail.
|
|
26
26
|
5. Change the Topic model, reasoning effort, title, archive state, or panel width without changing the source Session.
|
|
27
27
|
|
|
28
|
-
## Install v0.4.
|
|
28
|
+
## Install v0.4.2
|
|
29
29
|
|
|
30
|
-
CiteCiter 0.4.
|
|
30
|
+
CiteCiter 0.4.2 requires Node.js `^22.19.0 || >=24.0.0` and DSH `>=0.1.1-rc.1 <0.1.1-rc.3`.
|
|
31
31
|
|
|
32
32
|
For DSH Web:
|
|
33
33
|
|
|
34
34
|
```sh
|
|
35
|
-
dsh plugin --profile web add @kirkchinese/dsh-citeciter@0.4.
|
|
35
|
+
dsh plugin --profile web add @kirkchinese/dsh-citeciter@0.4.2
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
Restart DSH Web and refresh the page. Packaged Desktop adaptation is deferred; CiteCiter 0.4.
|
|
38
|
+
Restart DSH Web and refresh the page. Packaged Desktop adaptation is deferred; CiteCiter 0.4.2 does not provide a supported Desktop installation path.
|
|
39
39
|
|
|
40
40
|
## Context modes
|
|
41
41
|
|
|
@@ -47,7 +47,7 @@ Exact Fork is an advanced mode for a source turn that has already ended. `exact-
|
|
|
47
47
|
|
|
48
48
|
| Host | CiteCiter version | Status |
|
|
49
49
|
|---|---|---|
|
|
50
|
-
| DSH Web `0.1.1-rc.2` | `0.4.
|
|
50
|
+
| DSH Web `0.1.1-rc.2` | `0.4.2` | Linux package, regression tests, and real-browser selection checks passed; real-provider acceptance was not run |
|
|
51
51
|
| [DSH Desktop 2.0.2](https://github.com/anywhere-labs/deepseek-harness-desktop) with bundled DSH `0.1.1-rc.2` | Future target | Adaptation and native acceptance are deferred; no packaged-Desktop compatibility claim |
|
|
52
52
|
| [dataelement DSH Desktop](https://github.com/dataelement/dsh-desktop) development shell with DSH `0.1.1-rc.1` | `0.4.0` only | Historical conditional Linux source-shell evidence |
|
|
53
53
|
| DSH Web `0.1.0-rc.7` | `0.3.2` | Previous stable line |
|
|
@@ -57,14 +57,14 @@ The demo uses a deterministic fixture to show the workflow; it is not real-provi
|
|
|
57
57
|
|
|
58
58
|
## Upgrade from an earlier version
|
|
59
59
|
|
|
60
|
-
To install or upgrade v0.4.
|
|
60
|
+
To install or upgrade v0.4.2 in Web:
|
|
61
61
|
|
|
62
62
|
```sh
|
|
63
|
-
dsh plugin --profile web add @kirkchinese/dsh-citeciter@0.4.
|
|
63
|
+
dsh plugin --profile web add @kirkchinese/dsh-citeciter@0.4.2
|
|
64
64
|
dsh plugin --profile web list --depth 0
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
-
Packaged Desktop adaptation is deferred and is not part of the supported 0.4.
|
|
67
|
+
Packaged Desktop adaptation is deferred and is not part of the supported 0.4.2 upgrade path.
|
|
68
68
|
|
|
69
69
|
Upgrading from v0.3 does not migrate or rewrite existing Topics, settings, or source Sessions. Users remaining on DSH `0.1.0-rc.7` should keep CiteCiter 0.3.2.
|
|
70
70
|
|
|
@@ -77,7 +77,7 @@ Upgrading from v0.3 does not migrate or rewrite existing Topics, settings, or so
|
|
|
77
77
|
- Read Frog translated selections are a best-effort compatibility path on DSH rc.1/rc.2 and activate only when its complete private marker set is present; ordinary DSH selection does not depend on Read Frog.
|
|
78
78
|
- DSH does not yet expose a public additive right-dock contribution point. CiteCiter therefore uses a reversible private AppFrame grid adapter whenever the panel and conversation fit; it preserves the layout's details preference but temporarily hides that column while the investigation panel is open, and it must be retested for every supported DSH release.
|
|
79
79
|
- Topics are Host-durable. When Desktop restarts on a different loopback port, CiteCiter falls back to the most recently updated Topic because browser local storage is origin-scoped; configure a fixed Desktop port to restore the exact last-viewed Topic.
|
|
80
|
-
- CiteCiter 0.4.
|
|
80
|
+
- CiteCiter 0.4.2 makes no packaged-Desktop compatibility claim; native Windows and macOS adaptation continues separately.
|
|
81
81
|
- There is currently no TUI interaction adapter.
|
|
82
82
|
- DSH is prerelease software; later DSH API versions may require a CiteCiter update.
|
|
83
83
|
|
package/README.zh.md
CHANGED
|
@@ -25,17 +25,17 @@
|
|
|
25
25
|
4. 在 Topic 中继续追问,或从 CiteCiter 的 Topic 栏恢复旧讨论。
|
|
26
26
|
5. 独立调整模型、思考强度、标题、归档状态和面板宽度,不改变来源 Session。
|
|
27
27
|
|
|
28
|
-
## 安装 v0.4.
|
|
28
|
+
## 安装 v0.4.2
|
|
29
29
|
|
|
30
|
-
CiteCiter 0.4.
|
|
30
|
+
CiteCiter 0.4.2 需要 Node.js `^22.19.0 || >=24.0.0` 与 DSH `>=0.1.1-rc.1 <0.1.1-rc.3`。
|
|
31
31
|
|
|
32
32
|
DSH Web 使用:
|
|
33
33
|
|
|
34
34
|
```sh
|
|
35
|
-
dsh plugin --profile web add @kirkchinese/dsh-citeciter@0.4.
|
|
35
|
+
dsh plugin --profile web add @kirkchinese/dsh-citeciter@0.4.2
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
安装后重启 DSH Web 并刷新页面。正式 Desktop 适配已经暂缓;CiteCiter 0.4.
|
|
38
|
+
安装后重启 DSH Web 并刷新页面。正式 Desktop 适配已经暂缓;CiteCiter 0.4.2 不提供受支持的 Desktop 安装路径。
|
|
39
39
|
|
|
40
40
|
## 上下文模式
|
|
41
41
|
|
|
@@ -47,7 +47,7 @@ Exact Fork 是面向已结束来源轮次的高级模式。`exact-when-available
|
|
|
47
47
|
|
|
48
48
|
| 宿主 | CiteCiter 版本 | 状态 |
|
|
49
49
|
|---|---|---|
|
|
50
|
-
| DSH Web `0.1.1-rc.2` | `0.4.
|
|
50
|
+
| DSH Web `0.1.1-rc.2` | `0.4.2` | Linux 包、回归测试与真实浏览器选区检查通过;真实提供方验收未运行 |
|
|
51
51
|
| [DSH Desktop 2.0.2](https://github.com/anywhere-labs/deepseek-harness-desktop)(内置 DSH `0.1.1-rc.2`) | 后续目标 | 适配与原生验收暂缓;不声明正式 Desktop 安装包兼容性 |
|
|
52
52
|
| [dataelement DSH Desktop](https://github.com/dataelement/dsh-desktop) 源码开发壳(内置 DSH `0.1.1-rc.1`) | 仅 `0.4.0` | 历史上的有条件 Linux 源码壳证据 |
|
|
53
53
|
| DSH Web `0.1.0-rc.7` | `0.3.2` | 旧版稳定线 |
|
|
@@ -57,14 +57,14 @@ Exact Fork 是面向已结束来源轮次的高级模式。`exact-when-available
|
|
|
57
57
|
|
|
58
58
|
## 从旧版本升级
|
|
59
59
|
|
|
60
|
-
在 Web 安装或升级 v0.4.
|
|
60
|
+
在 Web 安装或升级 v0.4.2:
|
|
61
61
|
|
|
62
62
|
```sh
|
|
63
|
-
dsh plugin --profile web add @kirkchinese/dsh-citeciter@0.4.
|
|
63
|
+
dsh plugin --profile web add @kirkchinese/dsh-citeciter@0.4.2
|
|
64
64
|
dsh plugin --profile web list --depth 0
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
-
正式 Desktop 适配已经暂缓,不属于 0.4.
|
|
67
|
+
正式 Desktop 适配已经暂缓,不属于 0.4.2 的受支持升级路径。
|
|
68
68
|
|
|
69
69
|
从 v0.3 升级不会迁移或重写现有 Topic、设置或来源 Session。仍在 DSH `0.1.0-rc.7` 上运行的用户应继续使用 CiteCiter 0.3.2。
|
|
70
70
|
|
|
@@ -77,7 +77,7 @@ dsh plugin --profile web list --depth 0
|
|
|
77
77
|
- Read Frog 翻译选区是 DSH rc.1/rc.2 上的 best-effort 兼容路径,仅在其完整私有标记同时存在时启用;普通 DSH 选区不依赖 Read Frog。
|
|
78
78
|
- DSH 尚未提供公开的增量右侧 dock 布局扩展点。CiteCiter 因此在面板与主对话能够同时容纳时使用可逆的私有 AppFrame grid 适配器;它保留布局的 details 偏好,但在调查面板打开期间临时隐藏该列,并且每个受支持的 DSH 版本都必须重新验证。
|
|
79
79
|
- Topic 由 Host 持久保存。Desktop 重启到不同 loopback 端口时,浏览器 localStorage 会因 origin 改变而失去精确指针,CiteCiter 将回退到最近更新的 Topic;需要精确恢复“上次查看”时应配置固定 Desktop 端口。
|
|
80
|
-
- CiteCiter 0.4.
|
|
80
|
+
- CiteCiter 0.4.2 不声明正式 Desktop 安装包兼容性;Windows 与 macOS 原生适配将另行继续。
|
|
81
81
|
- 当前没有 TUI 交互适配器。
|
|
82
82
|
- DSH 仍处于预发布阶段,后续 API 版本可能要求同步更新 CiteCiter。
|
|
83
83
|
|
package/lib/client.js
CHANGED
|
@@ -5449,13 +5449,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
5449
5449
|
return null;
|
|
5450
5450
|
}
|
|
5451
5451
|
/**
|
|
5452
|
-
* Determine whether a node is
|
|
5452
|
+
* Determine whether a node is projected reasoning or translation rather than committed answer text.
|
|
5453
5453
|
*
|
|
5454
5454
|
* @param node - rendered node to classify.
|
|
5455
|
-
* @returns whether
|
|
5455
|
+
* @returns whether the node must stay out of committed answer text.
|
|
5456
5456
|
*/
|
|
5457
|
-
function
|
|
5458
|
-
return node.nodeType === Node.ELEMENT_NODE && node.matches(READ_FROG_TRANSLATION_SELECTOR);
|
|
5457
|
+
function isNonAnswerContent(node) {
|
|
5458
|
+
return node.nodeType === Node.ELEMENT_NODE && node.matches(`${DSH_REASONING_SELECTOR}, ${READ_FROG_TRANSLATION_SELECTOR}`);
|
|
5459
5459
|
}
|
|
5460
5460
|
/**
|
|
5461
5461
|
* Resolve a selection wholly inside one Read Frog translation to its source paragraph.
|
|
@@ -6939,7 +6939,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6939
6939
|
let targetStart;
|
|
6940
6940
|
let targetEnd;
|
|
6941
6941
|
const visit = (node) => {
|
|
6942
|
-
if (
|
|
6942
|
+
if (isNonAnswerContent(node)) return;
|
|
6943
6943
|
if (node === target) targetStart = text.length;
|
|
6944
6944
|
if (node.nodeType === Node.TEXT_NODE) text += node.textContent ?? "";
|
|
6945
6945
|
else for (const child of node.childNodes) visit(child);
|
|
@@ -6956,7 +6956,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
6956
6956
|
let text = "";
|
|
6957
6957
|
let found = false;
|
|
6958
6958
|
const visit = (node) => {
|
|
6959
|
-
if (found ||
|
|
6959
|
+
if (found || isNonAnswerContent(node)) return;
|
|
6960
6960
|
if (node === boundary) {
|
|
6961
6961
|
if (node.nodeType === Node.TEXT_NODE) text += (node.textContent ?? "").slice(0, offset);
|
|
6962
6962
|
else for (let index = 0; index < offset; index++) {
|
package/lib/index.js
CHANGED
|
@@ -14369,7 +14369,8 @@ function compactMapped(units) {
|
|
|
14369
14369
|
});
|
|
14370
14370
|
else compact[compact.length - 1] = {
|
|
14371
14371
|
...previous,
|
|
14372
|
-
endOffset: unit.endOffset
|
|
14372
|
+
endOffset: unit.endOffset,
|
|
14373
|
+
...previous.synthetic === true || unit.synthetic === true ? { synthetic: true } : {}
|
|
14373
14374
|
};
|
|
14374
14375
|
}
|
|
14375
14376
|
return compact;
|
|
@@ -14384,7 +14385,8 @@ function joinMapped(parts, separator) {
|
|
|
14384
14385
|
for (const text of separator) joined.push({
|
|
14385
14386
|
text,
|
|
14386
14387
|
startOffset: before,
|
|
14387
|
-
endOffset: after
|
|
14388
|
+
endOffset: after,
|
|
14389
|
+
synthetic: true
|
|
14388
14390
|
});
|
|
14389
14391
|
}
|
|
14390
14392
|
joined.push(...part);
|
|
@@ -14442,6 +14444,47 @@ function candidatesFromProjection(markdown, projection, needle) {
|
|
|
14442
14444
|
}
|
|
14443
14445
|
return candidates;
|
|
14444
14446
|
}
|
|
14447
|
+
function candidatesIgnoringSyntheticWhitespace(markdown, projection, needle) {
|
|
14448
|
+
const rendered = visibleText(projection);
|
|
14449
|
+
const visibleOffsets = [0];
|
|
14450
|
+
for (const unit of projection) visibleOffsets.push(visibleOffsets.at(-1) + unit.text.length);
|
|
14451
|
+
const candidates = [];
|
|
14452
|
+
const seen = /* @__PURE__ */ new Set();
|
|
14453
|
+
for (let start = 0; start < projection.length; start++) {
|
|
14454
|
+
const first = projection[start];
|
|
14455
|
+
if (first.synthetic === true) continue;
|
|
14456
|
+
let unitIndex = start;
|
|
14457
|
+
let needleOffset = 0;
|
|
14458
|
+
let lastIndex = -1;
|
|
14459
|
+
while (needleOffset < needle.length && unitIndex < projection.length) {
|
|
14460
|
+
const unit = projection[unitIndex];
|
|
14461
|
+
if (unit.synthetic === true) {
|
|
14462
|
+
while (projection[unitIndex]?.synthetic === true) unitIndex++;
|
|
14463
|
+
needleOffset += /^\s+/u.exec(needle.slice(needleOffset))?.[0].length ?? 0;
|
|
14464
|
+
continue;
|
|
14465
|
+
}
|
|
14466
|
+
if (!needle.startsWith(unit.text, needleOffset)) break;
|
|
14467
|
+
needleOffset += unit.text.length;
|
|
14468
|
+
lastIndex = unitIndex;
|
|
14469
|
+
unitIndex++;
|
|
14470
|
+
}
|
|
14471
|
+
if (needleOffset !== needle.length || lastIndex < start) continue;
|
|
14472
|
+
const last = projection[lastIndex];
|
|
14473
|
+
const key = `${first.startOffset}:${last.endOffset}`;
|
|
14474
|
+
if (seen.has(key)) continue;
|
|
14475
|
+
seen.add(key);
|
|
14476
|
+
const visibleStart = visibleOffsets[start];
|
|
14477
|
+
const visibleEnd = visibleOffsets[lastIndex + 1];
|
|
14478
|
+
candidates.push({
|
|
14479
|
+
startOffset: first.startOffset,
|
|
14480
|
+
endOffset: last.endOffset,
|
|
14481
|
+
sourceText: markdown.slice(first.startOffset, last.endOffset),
|
|
14482
|
+
displayPrefix: rendered.slice(Math.max(0, visibleStart - 240), visibleStart),
|
|
14483
|
+
displaySuffix: rendered.slice(visibleEnd, visibleEnd + 240)
|
|
14484
|
+
});
|
|
14485
|
+
}
|
|
14486
|
+
return candidates;
|
|
14487
|
+
}
|
|
14445
14488
|
/**
|
|
14446
14489
|
* Locate every GFM source range that renders as one browser-visible selection.
|
|
14447
14490
|
*
|
|
@@ -14458,7 +14501,11 @@ function markdownSourceCandidates(markdown, displayText) {
|
|
|
14458
14501
|
if (needle === "") return [];
|
|
14459
14502
|
const exact = candidatesFromProjection(markdown, projection, needle);
|
|
14460
14503
|
if (exact.length > 0) return exact;
|
|
14461
|
-
|
|
14504
|
+
const compactProjection = compactMapped(projection);
|
|
14505
|
+
const compactNeedle = needle.replace(/\s+/gu, " ");
|
|
14506
|
+
const compact = candidatesFromProjection(markdown, compactProjection, compactNeedle);
|
|
14507
|
+
if (compact.length > 0) return compact;
|
|
14508
|
+
return candidatesIgnoringSyntheticWhitespace(markdown, compactProjection, compactNeedle);
|
|
14462
14509
|
}
|
|
14463
14510
|
//#endregion
|
|
14464
14511
|
//#region lib/types/citation-mapping.js
|
|
@@ -56,12 +56,12 @@ export declare function dshRangeTouchesExcludedContent(range: Range, flow: HTMLE
|
|
|
56
56
|
*/
|
|
57
57
|
export declare function findDshAssistantAnchor(anchorKey: string): HTMLElement | null;
|
|
58
58
|
/**
|
|
59
|
-
* Determine whether a node is
|
|
59
|
+
* Determine whether a node is projected reasoning or translation rather than committed answer text.
|
|
60
60
|
*
|
|
61
61
|
* @param node - rendered node to classify.
|
|
62
|
-
* @returns whether
|
|
62
|
+
* @returns whether the node must stay out of committed answer text.
|
|
63
63
|
*/
|
|
64
|
-
export declare function
|
|
64
|
+
export declare function isNonAnswerContent(node: Node): boolean;
|
|
65
65
|
/**
|
|
66
66
|
* Resolve a selection wholly inside one Read Frog translation to its source paragraph.
|
|
67
67
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kirkchinese/dsh-citeciter",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Verifiable, source-bound, read-only investigations for DeepSeek Harness responses",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"deepseek-harness",
|
|
@@ -80,6 +80,20 @@
|
|
|
80
80
|
"cordis.patch.yml",
|
|
81
81
|
"README.zh.md"
|
|
82
82
|
],
|
|
83
|
+
"scripts": {
|
|
84
|
+
"build": "npm run build:lib && npm run build:bundle",
|
|
85
|
+
"prebuild:lib": "node scripts/clean-types.mjs",
|
|
86
|
+
"build:lib": "tsc -p tsconfig.json",
|
|
87
|
+
"prebuild:bundle": "node scripts/clean-bundle.mjs",
|
|
88
|
+
"build:bundle": "tsdown --env.DSH_BUILD_FACE client",
|
|
89
|
+
"postbuild:bundle": "node scripts/normalize-bundle.mjs",
|
|
90
|
+
"prepack": "npm run build",
|
|
91
|
+
"dev": "npm run build && node dev/watch.mjs",
|
|
92
|
+
"smoke:seed": "node dev/seed-smoke-session.mjs",
|
|
93
|
+
"smoke:hmr": "node dev/hmr-smoke.mjs",
|
|
94
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
95
|
+
"test": "npm run build:lib && node --test tests/*.test.mjs"
|
|
96
|
+
},
|
|
83
97
|
"peerDependencies": {
|
|
84
98
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
85
99
|
"@deepseek-ai/dsh-agent": ">=0.1.1-rc.1 <0.1.1-rc.3",
|
|
@@ -159,18 +173,5 @@
|
|
|
159
173
|
"tsdown": "^0.22.2",
|
|
160
174
|
"typescript": "^6.0.3",
|
|
161
175
|
"zod": "^4.4.3"
|
|
162
|
-
},
|
|
163
|
-
"scripts": {
|
|
164
|
-
"build": "npm run build:lib && npm run build:bundle",
|
|
165
|
-
"prebuild:lib": "node scripts/clean-types.mjs",
|
|
166
|
-
"build:lib": "tsc -p tsconfig.json",
|
|
167
|
-
"prebuild:bundle": "node scripts/clean-bundle.mjs",
|
|
168
|
-
"build:bundle": "tsdown --env.DSH_BUILD_FACE client",
|
|
169
|
-
"postbuild:bundle": "node scripts/normalize-bundle.mjs",
|
|
170
|
-
"dev": "npm run build && node dev/watch.mjs",
|
|
171
|
-
"smoke:seed": "node dev/seed-smoke-session.mjs",
|
|
172
|
-
"smoke:hmr": "node dev/hmr-smoke.mjs",
|
|
173
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
174
|
-
"test": "npm run build:lib && node --test tests/*.test.mjs"
|
|
175
176
|
}
|
|
176
|
-
}
|
|
177
|
+
}
|