dsh-turn-navigator 0.4.3 → 0.4.4
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 +16 -0
- package/CONTRIBUTING.md +10 -0
- package/README.md +8 -2
- package/README.zh.md +8 -2
- package/lib/client.js +18 -1
- package/package.json +2 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.4.4] - 2026-09-22
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **Live disable/reload no longer leaves the OFFICIAL rail hidden.** The plugin hides the built-in rail with a `tn-hide-official` class on `document.body`, but nothing removed that class when the plugin unloaded. dsh 0.1.6-alpha.2 enables the host `hmr` row by default for launcher-provided profiles, so the dsh Plugins page can now disable or reload a bundle **without a restart** — with the stale class the official rail stayed hidden after the plugin was gone, and only a page reload brought it back. The class is now applied inside `ctx.effect(...)` and removed by its dispose hook (`clearModeFromBody`), so unloading restores the built-in default — `src/client/index.ts`, `src/client/mode.ts`.
|
|
8
|
+
|
|
9
|
+
- **The release gate no longer fails on proxied networks.** `release-check.mjs` probed the registry with Node's `fetch`, which ignores npm's `.npmrc` proxy settings — and the proxy variables plus `NODE_USE_ENV_PROXY` are sampled when the process starts (verified on Node 24.18: setting them inside the script changes nothing), so the probe went **direct**. On 2026-09-22 three probe timeouts blocked the 0.4.4 publish with `The operation was aborted due to timeout`, while `npm publish` itself (which does honor `.npmrc`) would have worked. The probe now runs `npm view` — the same registry, proxy and auth as the publish it guards. `post-publish-check.mjs` gets the same treatment for its curl fallbacks (registry probes and the tarball download), preferring npm's configured proxy over an inherited variable so the check actually verifies instead of degrading to "unreachable" — `scripts/release-check.mjs`, `scripts/post-publish-check.mjs`.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- **Two stale `dsh.client.inject` entries removed** — `@deepseek-ai/dsh-client-runtime` and `@deepseek-ai/dsh-client-web-react`. Neither package exists in the current dsh client graph (the former was removed upstream in dsh 0.1.2, per the 0.4.2 entry below) and this plugin's source never imported either one; `inject` names package rows to order against, so listing absent rows was dead weight. The remaining six entries are unchanged.
|
|
14
|
+
|
|
15
|
+
### Tests
|
|
16
|
+
|
|
17
|
+
- **New `scripts/test-client-dispose.mjs`, wired into `pnpm test`.** It loads the real built `lib/client.js` in a minimal DOM + module-loader stub and asserts the observable contract: `apply()` hides the official rail through the body class, and the registered cordis effect's disposer restores it. Verified as a real gate by negative control — replacing the `ctx.effect(...)` wrapper with a bare `applyModeToBody()` makes it fail.
|
|
18
|
+
|
|
3
19
|
## [0.4.3] - 2026-09-06
|
|
4
20
|
|
|
5
21
|
### Changed
|
package/CONTRIBUTING.md
CHANGED
|
@@ -21,6 +21,16 @@ Every release must be done in one pass: code + bilingual README + CHANGELOG + ve
|
|
|
21
21
|
7. `npm publish` (requires 2FA; the agent cannot do this step).
|
|
22
22
|
8. `postpublish` runs `scripts/post-publish-check.mjs` automatically.
|
|
23
23
|
|
|
24
|
+
## The release gates use npm's own transport
|
|
25
|
+
|
|
26
|
+
`release-check.mjs` asks `npm view` whether the version is already published, and
|
|
27
|
+
`post-publish-check.mjs` gives its curl fallbacks npm's configured proxy — both on
|
|
28
|
+
purpose. Node's `fetch` cannot be proxied after startup (the proxy variables and
|
|
29
|
+
`NODE_USE_ENV_PROXY` are sampled at process start) and ignores `.npmrc` entirely, so
|
|
30
|
+
a fetch-based gate goes direct and blocks every release on a network where the
|
|
31
|
+
registry is only reachable through the proxy in `.npmrc` — even though
|
|
32
|
+
`npm publish` itself would work. Keep new registry access on the npm/curl path.
|
|
33
|
+
|
|
24
34
|
## npm publish is manual (2FA)
|
|
25
35
|
|
|
26
36
|
npm accounts with two-factor authentication require an OTP that the agent cannot provide. The agent prepares everything to "one command to publish"; the human runs `npm login` → `npm publish`.
|
package/README.md
CHANGED
|
@@ -40,6 +40,7 @@ The official built-in `TurnNavigator` has **no off-switch** and is always render
|
|
|
40
40
|
| Capability | DSH official rail (0.1.3-alpha.1) | Smoothly TN (v0.4.3) |
|
|
41
41
|
|---|---|---|
|
|
42
42
|
| Turns shown | **Every turn** — host `turnOutline` projection (0.1.3+) | Every persisted turn — **client-side** journal read |
|
|
43
|
+
| Full-history robustness | Depends on the host `turnOutline` projection — **not driven** by browser-synthesized sessions (e.g. `?fixture`), where it falls back to the loaded window | Always full — reads the persisted journal directly, no host projection required (verified full on both real and fixture sessions) |
|
|
43
44
|
| How full history is read | Host-side projection embedded in the snapshot | Client pages the persisted journal (`session/page`); older dsh falls back to `sessions.history` RPC — **zero host changes** |
|
|
44
45
|
| Jump to a turn outside the window | ✅ (0.1.3+ unloaded anchor pages history by seq) | ✅ on-demand window extension + "Locating turn N…" pulse/bubble |
|
|
45
46
|
| Long-session open performance | Reads the projection | **Zero prepend** — plain data, no flow re-render, no stall |
|
|
@@ -55,6 +56,8 @@ The official built-in `TurnNavigator` has **no off-switch** and is always render
|
|
|
55
56
|
|
|
56
57
|
As of dsh 0.1.3 the built-in rail caught up on full-session scope and out-of-window jumps. What still sets Smoothly TN apart: you can **switch it off** (the official rail cannot), the tooltip carries the **timestamp + full summary**, there are **scroll buttons and wave hover**, and it remains an **external, read-only plugin with zero host changes**. And on dsh ≤ 0.1.2 the built-in rail is simpler still (loaded window only), so the gap Smoothly TN closes is even larger there.
|
|
57
58
|
|
|
59
|
+
**Verified on dsh 0.1.3-alpha.1 (2026-09-06, Playwright against the live web UI)**: on a real 42-turn session both rails show all 42 turns (the official one via its host projection, ours via the journal); on a `?fixture` browser-synthesized session the official rail degrades to the loaded window (24/75) while Smoothly TN still shows all 75 — because our full history never depends on the host projection. Jumps, follow-scroll highlight, the mode switch, and the subtractive takeover of the official rail (`display: none` via the stylesheet override) all verified working.
|
|
60
|
+
|
|
58
61
|
## Version map
|
|
59
62
|
|
|
60
63
|
Which Smoothly TN release matches which dsh:
|
|
@@ -65,6 +68,7 @@ Which Smoothly TN release matches which dsh:
|
|
|
65
68
|
| v0.2.x – v0.4.1 | dsh 0.1.2+ | Adapted to the `ui-chat` refactor; full history via the journal `session/page` channel; v0.4.1 fixed true turn numbers and rail-viewport follow |
|
|
66
69
|
| **v0.4.2** | dsh 0.1.2+, incl. **0.1.3-alpha.1** | Comparison/positioning updated against the 0.1.3 official rail (see above) |
|
|
67
70
|
| **v0.4.3** | dsh 0.1.2+, incl. **0.1.3-alpha.1** | This release: brand naming standardized to **Smoothly**(思磨力)/ **Smoothly Turn Nav**(**Smoothly TN**)/ **思磨力轮次胶囊条** — technical IDs (npm package `dsh-turn-navigator`, plugin/slot IDs, locale namespace, CSS prefix, localStorage key) unchanged |
|
|
71
|
+
| **v0.4.4** | dsh 0.1.2+, client contract re-checked against **0.1.6-alpha.2** | This release: the official-rail body class gained a dispose hook (disabling or reloading the bundle live from the dsh Plugins page restores the built-in rail), and two stale `inject` entries are gone |
|
|
68
72
|
|
|
69
73
|
The official-rail comparison in this README targets **dsh 0.1.3-alpha.1**; on older dsh the official rail is simpler, so Smoothly TN's advantage is larger there.
|
|
70
74
|
|
|
@@ -106,14 +110,16 @@ The plugin registers **two additive slots** — **no DSH source code is modified
|
|
|
106
110
|
|
|
107
111
|
## Compatibility
|
|
108
112
|
|
|
109
|
-
- DeepSeek Harness (dsh) with the web client (`dsh web`); developed and verified against dsh 0.1.2+ and
|
|
113
|
+
- DeepSeek Harness (dsh) with the web client (`dsh web`); developed and verified against dsh 0.1.2+ and **verified against dsh 0.1.3-alpha.1** (Playwright re-test, 2026-09-06: full-history rail, jumps, follow highlight, mode switch, and the official-rail stylesheet takeover all passing).
|
|
110
114
|
- Requires the `conversation.session.header.utilities` and `settings.general.item` slot declarations (present in current DSH).
|
|
115
|
+
- Client contract re-checked against **dsh 0.1.6-alpha.2** (2026-09-22): the `conversation.session.header.utilities`, `settings.general.item` and `shell.overlay` slot declarations, the `ui-primitives` exports the rail uses, and the `--dsw-alias-*` tokens it references all still exist. The interactive Playwright re-test was **not** re-run on 0.1.6 (the 2026-09-06 run remains the last interactive verification).
|
|
111
116
|
- Default `Smoothly TN` mode hides the official rail (stylesheet override) and centers our rail in its place; `DSH official` mode shows the built-in rail instead; `Hide all` hides both. Both rails auto-hide below 900px width.
|
|
112
117
|
- Coexists with full-screen plugin pages (e.g. the kanban board): the rail sits below their overlay layer.
|
|
113
118
|
|
|
114
119
|
## Development
|
|
115
120
|
|
|
116
|
-
- `pnpm typecheck`
|
|
121
|
+
- `pnpm typecheck` — TypeScript check (tsdown does not typecheck).
|
|
122
|
+
- `pnpm test` — typecheck plus `scripts/test-client-dispose.mjs`, which loads the built bundle in a DOM stub and asserts the apply/dispose contract of the official-rail body class.
|
|
117
123
|
- `pnpm bundle` — build the module-table client bundle into `lib/`.
|
|
118
124
|
- `scripts/verify-*.mjs` — Playwright acceptance scripts against a live `dsh web` (rail, full-history journal, mode switch, jump, feedback, overlay, sizing, UI).
|
|
119
125
|
- `pnpm release:check` — release gates (version, tag, tree, build, registry).
|
package/README.zh.md
CHANGED
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
| 能力 | DSH 官方胶囊条(0.1.3-alpha.1) | 思磨力轮次胶囊条(v0.4.3) |
|
|
41
41
|
|---|---|---|
|
|
42
42
|
| 显示的轮次 | **全部轮次**——宿主 `turnOutline` 投影(0.1.3+) | 全部持久化轮次——**客户端**读取 journal |
|
|
43
|
+
| 全量历史的健壮性 | 依赖宿主 `turnOutline` 投影——**浏览器合成会话**(如 `?fixture`)不驱动投影,此时退回"仅加载窗口" | 始终全量——直接读持久化日志,无需宿主投影(真实会话与 fixture 会话均已实测全量) |
|
|
43
44
|
| 全会话历史怎么读 | 宿主侧投影内嵌在会话快照里 | 客户端分页读持久化日志(`session/page`);旧版 dsh 退回 `sessions.history` RPC——**零宿主改动** |
|
|
44
45
|
| 跳转窗口外轮次 | ✅(0.1.3+ 未加载锚点按 seq 分页) | ✅ 按需扩展窗口 + "正在定位第 N 轮…"脉冲/气泡 |
|
|
45
46
|
| 长会话打开性能 | 读投影 | **零 prepend**——纯数据、不重渲染会话流、不卡顿 |
|
|
@@ -55,6 +56,8 @@
|
|
|
55
56
|
|
|
56
57
|
dsh 0.1.3 起官方胶囊条已在紧要的全会话范围与窗口外跳转上追平。**思磨力轮次胶囊条仍然独占的**:可以**关掉它**(官方关不掉)、Tooltip 带**时间戳与完整摘要**、**滚动按钮 + 波浪悬停**、以及它始终是**零宿主改动的外部只读插件**。在 dsh ≤ 0.1.2 上官方胶囊条更简单(仅加载窗口),思磨力轮次胶囊条填补的差距更大。
|
|
57
58
|
|
|
59
|
+
**dsh 0.1.3-alpha.1 实测(2026-09-06,Playwright 直连在线 Web UI)**:真实 42 轮会话上两个胶囊条都显示全部 42 轮(官方走宿主投影、我们走 journal);`?fixture` 浏览器合成会话上官方胶囊条退化为"仅加载窗口"(24/75),而思磨力轮次胶囊条仍显示全部 75——因为我们的全量历史从不依赖宿主投影。跳转、滚动跟随高亮、模式开关、以及减法接管官方胶囊条(样式覆盖 `display: none`)均实测通过。
|
|
60
|
+
|
|
58
61
|
## 版本对照
|
|
59
62
|
|
|
60
63
|
我们的版本与 dsh 版本的对应关系:
|
|
@@ -65,6 +68,7 @@ dsh 0.1.3 起官方胶囊条已在紧要的全会话范围与窗口外跳转上
|
|
|
65
68
|
| v0.2.x – v0.4.1 | dsh 0.1.2+ | 适配 `ui-chat` 重构;通过 journal `session/page` 通道读全量历史;v0.4.1 修复真实轮次号与胶囊条视口跟随 |
|
|
66
69
|
| **v0.4.2** | dsh 0.1.2+(含 **0.1.3-alpha.1**) | 对照 dsh 0.1.3 官方胶囊条更新对比与定位(见上文) |
|
|
67
70
|
| **v0.4.3** | dsh 0.1.2+(含 **0.1.3-alpha.1**) | 本版:品牌命名规范化为 **Smoothly**(思磨力)/ **Smoothly Turn Nav**(**Smoothly TN**)/ **思磨力轮次胶囊条**——技术标识符(npm 包名 `dsh-turn-navigator`、插件/slot ID、locale 命名空间、CSS 前缀、localStorage key)不变 |
|
|
71
|
+
| **v0.4.4** | dsh 0.1.2+,客户端契约对照 **0.1.6-alpha.2** 复核 | 本版:官方胶囊条的 body class 补上 dispose(从 dsh 插件页在线停用/重载后会恢复内置胶囊条);清掉两个陈旧 `inject` 条目 |
|
|
68
72
|
|
|
69
73
|
本文 README 的对比对象为 **dsh 0.1.3-alpha.1**;在更旧的 dsh 上官方胶囊条更简单,思磨力轮次胶囊条的优势更大。
|
|
70
74
|
|
|
@@ -106,14 +110,16 @@ dsh web
|
|
|
106
110
|
|
|
107
111
|
## 兼容性
|
|
108
112
|
|
|
109
|
-
- DeepSeek Harness (dsh) Web 客户端(`dsh web`);基于 dsh 0.1.2+
|
|
113
|
+
- DeepSeek Harness (dsh) Web 客户端(`dsh web`);基于 dsh 0.1.2+ 开发与实测,并在 **dsh 0.1.3-alpha.1 上复测通过**(Playwright 直连实测,2026-09-06:全量历史胶囊条、跳转、跟随高亮、模式开关、官方胶囊条样式接管全部通过)。
|
|
110
114
|
- 需要 `conversation.session.header.utilities` 与 `settings.general.item` slot 声明(当前 DSH 已包含)。
|
|
115
|
+
- 客户端契约已对照 **dsh 0.1.6-alpha.2** 复核(2026-09-22):`conversation.session.header.utilities`、`settings.general.item`、`shell.overlay` 的 slot 声明、胶囊条用到的 `ui-primitives` 导出、以及它引用的 `--dsw-alias-*` token 均仍存在。0.1.6 上的 Playwright 交互复测**未重跑**(2026-09-06 那次仍是最近一次交互验证)。
|
|
111
116
|
- 默认 `思磨力轮次胶囊条` 模式以样式覆盖隐藏官方 rail,我们的 rail 居中接管;`DSH 官方` 模式显示内置 rail;`全部隐藏` 两者皆隐。900px 以下都自动隐藏。
|
|
112
117
|
- 与全屏插件页面(如看板)共存:胶囊条层级位于全屏 overlay 之下。
|
|
113
118
|
|
|
114
119
|
## 开发
|
|
115
120
|
|
|
116
|
-
- `pnpm typecheck`
|
|
121
|
+
- `pnpm typecheck` — TypeScript 检查(tsdown 只转译不检查)。
|
|
122
|
+
- `pnpm test` — 类型检查 + `scripts/test-client-dispose.mjs`:在 DOM 桩里加载构建产物,断言官方胶囊条 body class 的 apply/dispose 契约。
|
|
117
123
|
- `pnpm bundle` — 构建模块表 client bundle 到 `lib/`。
|
|
118
124
|
- `scripts/verify-*.mjs` — 针对真实 `dsh web` 的 Playwright 验收脚本(rail、全量历史 journal、模式开关、跳转、反馈、overlay、尺寸、UI)。
|
|
119
125
|
- `pnpm release:check` — 发布门禁(版本、tag、工作树、构建、registry)。
|
package/lib/client.js
CHANGED
|
@@ -371,6 +371,20 @@ window.__ModuleLoader__.load({
|
|
|
371
371
|
if (typeof document === "undefined") return;
|
|
372
372
|
document.body.classList.toggle("tn-hide-official", current !== "official");
|
|
373
373
|
}
|
|
374
|
+
/**
|
|
375
|
+
* Drop the `tn-hide-official` body class — the plugin's dispose hook.
|
|
376
|
+
*
|
|
377
|
+
* dsh 0.1.6+ enables the host `hmr` row by default for launcher-provided
|
|
378
|
+
* profiles, so this plugin can be disabled or reloaded LIVE (the dsh Plugins
|
|
379
|
+
* page toggles bundles without a restart). Without this teardown the class
|
|
380
|
+
* outlives the plugin and keeps hiding the OFFICIAL rail, and only a page
|
|
381
|
+
* reload brings it back. Removing the class is the correct "unloaded" state:
|
|
382
|
+
* the official rail is the built-in default whenever this plugin is not applied.
|
|
383
|
+
*/
|
|
384
|
+
function clearModeFromBody() {
|
|
385
|
+
if (typeof document === "undefined") return;
|
|
386
|
+
document.body.classList.remove("tn-hide-official");
|
|
387
|
+
}
|
|
374
388
|
//#endregion
|
|
375
389
|
//#region src/client/TurnNavRail.tsx
|
|
376
390
|
/**
|
|
@@ -1262,7 +1276,10 @@ body.tn-hide-official [data-conversation-scroll] nav {
|
|
|
1262
1276
|
}), "dsh-turn-navigator: copy dictionaries");
|
|
1263
1277
|
const t = ctx.locale.bind(NS);
|
|
1264
1278
|
const api = ctx.get("connection")?.api;
|
|
1265
|
-
|
|
1279
|
+
ctx.effect(() => {
|
|
1280
|
+
applyModeToBody();
|
|
1281
|
+
return clearModeFromBody;
|
|
1282
|
+
}, "dsh-turn-navigator: official-rail body class");
|
|
1266
1283
|
let journal;
|
|
1267
1284
|
let sessionAccess;
|
|
1268
1285
|
const resolveHandles = () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-turn-navigator",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"description": "Smoothly Turn Nav (Smoothly TN): full-history piano-key turn rail for DeepSeek Harness (dsh) web conversations — see every turn at a glance, hover to preview, click to jump anywhere, and replace the official (non-disableable) turn rail.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -32,11 +32,9 @@
|
|
|
32
32
|
"inject": [
|
|
33
33
|
"@deepseek-ai/dsh-client-connection",
|
|
34
34
|
"@deepseek-ai/dsh-client-locale",
|
|
35
|
-
"@deepseek-ai/dsh-client-runtime",
|
|
36
35
|
"@deepseek-ai/dsh-client-ui-conversation",
|
|
37
36
|
"@deepseek-ai/dsh-client-ui-layout",
|
|
38
37
|
"@deepseek-ai/dsh-client-ui-slots",
|
|
39
|
-
"@deepseek-ai/dsh-client-web-react",
|
|
40
38
|
"@deepseek-ai/dsh-api-remotes"
|
|
41
39
|
],
|
|
42
40
|
"platform": "web"
|
|
@@ -46,7 +44,7 @@
|
|
|
46
44
|
"bundle": "tsdown --config ./tsdown.config.ts",
|
|
47
45
|
"prepare": "tsdown --config ./tsdown.config.ts",
|
|
48
46
|
"typecheck": "tsc --noEmit",
|
|
49
|
-
"test": "tsc --noEmit",
|
|
47
|
+
"test": "tsc --noEmit && node scripts/test-client-dispose.mjs",
|
|
50
48
|
"release:check": "node scripts/release-check.mjs",
|
|
51
49
|
"prepack": "node scripts/release-check.mjs",
|
|
52
50
|
"prepublishOnly": "node scripts/release-check.mjs && tsdown --config ./tsdown.config.ts",
|