dsh-rewind-plugin 0.14.0-beta.1 → 0.14.0-beta.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.en.md +7 -3
- package/README.md +7 -3
- package/assets/icon.svg +14 -10
- package/assets/screenshots/add-plugin.png +0 -0
- package/docs/compat/audit.md +88 -120
- package/lib/client.js +43 -13
- package/lib/index.js +3 -0
- package/lib/types/client/popover.d.ts +6 -1
- package/lib/types/client/portals.d.ts +14 -0
- package/package.json +51 -51
package/README.en.md
CHANGED
|
@@ -16,7 +16,7 @@ A deliberately focused plugin with one job: **rewind to any user message, no mat
|
|
|
16
16
|
|
|
17
17
|
## Preview
|
|
18
18
|
|
|
19
|
-
Every user message carries a **↶ rewind** button in its action row. Clicking it opens a mode-selection popover — "**rewind conversation only**" or "**rewind conversation and code**", the latter showing the file-change list for confirmation first. You can also rewind conveniently via the **`/rewind`
|
|
19
|
+
Every user message carries a **↶ rewind** button in its action row. Clicking it opens a mode-selection popover — "**rewind conversation only**" or "**rewind conversation and code**", the latter showing the file-change list for confirmation first. You can also pick and rewind conveniently via the **`/rewind` and `/undo` commands**.
|
|
20
20
|
|
|
21
21
|
<table>
|
|
22
22
|
<tr>
|
|
@@ -29,7 +29,7 @@ Every user message carries a **↶ rewind** button in its action row. Clicking i
|
|
|
29
29
|
</tr>
|
|
30
30
|
</table>
|
|
31
31
|
|
|
32
|
-
## Install
|
|
32
|
+
## Install
|
|
33
33
|
|
|
34
34
|
Check your local DSH version, then find the matching plugin version in
|
|
35
35
|
[Releases](https://github.com/SiriLee/dsh-rewind/releases).
|
|
@@ -42,12 +42,16 @@ dsh plugin --profile web add dsh-rewind-plugin@<version>
|
|
|
42
42
|
|
|
43
43
|
**Graphical interface**: the **Plugins** page in the sidebar → **Add plugin** → enter `dsh-rewind-plugin@<version>` → install → restart DSH and refresh the browser.
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
<img src="assets/screenshots/add-plugin.png" width="600" alt="Add plugin dialog: enter dsh-rewind-plugin@version in the field"><br>
|
|
46
|
+
<sub>The screenshot is an example only — use the version that matches your DSH version.</sub>
|
|
46
47
|
|
|
47
48
|
**Updating**: the command line overwrites the installed version directly; the
|
|
48
49
|
graphical interface rejects a re-install, so uninstall the old version first,
|
|
49
50
|
then install the new one.
|
|
50
51
|
|
|
52
|
+
> [!WARNING]
|
|
53
|
+
> The npm name `dsh-rewind` belongs to another author's package — install with `dsh-rewind-plugin`.
|
|
54
|
+
|
|
51
55
|
## Usage
|
|
52
56
|
|
|
53
57
|
1. Find the user message you want to rewind to in the conversation, or type `/rewind` (or its alias `/undo`) to open the candidate picker.
|
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ DeepSeek Harness 插件:**一键就地回退对话到任意更早的用户消
|
|
|
16
16
|
|
|
17
17
|
## 效果预览
|
|
18
18
|
|
|
19
|
-
每条用户消息的操作行都有一个 **↶ 回退** 按钮。点击后弹出模式选择浮层——「**仅回退对话**」或「**回退对话和代码**」,后者会先展示文件变更清单再确认。还可以通过 **`/rewind`
|
|
19
|
+
每条用户消息的操作行都有一个 **↶ 回退** 按钮。点击后弹出模式选择浮层——「**仅回退对话**」或「**回退对话和代码**」,后者会先展示文件变更清单再确认。还可以通过 **`/rewind` 和 `/undo` 命令**便捷地选择和回退。
|
|
20
20
|
|
|
21
21
|
<table>
|
|
22
22
|
<tr>
|
|
@@ -29,7 +29,7 @@ DeepSeek Harness 插件:**一键就地回退对话到任意更早的用户消
|
|
|
29
29
|
</tr>
|
|
30
30
|
</table>
|
|
31
31
|
|
|
32
|
-
##
|
|
32
|
+
## 安装
|
|
33
33
|
|
|
34
34
|
确认本机 DSH 版本后,在 [Release](https://github.com/SiriLee/dsh-rewind/releases) 找到适配的插件版本。
|
|
35
35
|
|
|
@@ -41,10 +41,14 @@ dsh plugin --profile web add dsh-rewind-plugin@<版本>
|
|
|
41
41
|
|
|
42
42
|
**图形界面**:侧栏「插件」页 →「添加插件」→ 填 `dsh-rewind-plugin@<版本>` → 安装 → 重启 DSH 并刷新浏览器。
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
<img src="assets/screenshots/add-plugin.png" width="600" alt="「添加插件」弹窗:在输入框填入 dsh-rewind-plugin@版本号"><br>
|
|
45
|
+
<sub>图片仅为示例,请以实际适配版本号为准。</sub>
|
|
45
46
|
|
|
46
47
|
**更新**:命令行可直接覆盖安装;图形界面会拒绝重复安装,需先卸载旧版本,再装新版本。
|
|
47
48
|
|
|
49
|
+
> [!WARNING]
|
|
50
|
+
> npm 上的 `dsh-rewind` 属于其他作者,请用 `dsh-rewind-plugin` 安装。
|
|
51
|
+
|
|
48
52
|
## 使用
|
|
49
53
|
|
|
50
54
|
1. 在对话中找到要回退的那条用户消息,或输入 `/rewind`(或其别名 `/undo`)打开候选列表选择。
|
package/assets/icon.svg
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
<svg width="
|
|
1
|
+
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
2
|
<!-- Layout follows the terminal card glyph (packages/client/ui-sidebar-terminal):
|
|
3
|
-
a rounded tile inset from the canvas
|
|
4
|
-
|
|
3
|
+
a rounded tile inset from the canvas with a white round-capped prompt. The
|
|
4
|
+
fill follows the Subagent plugin artwork
|
|
5
5
|
(packages/client/ui-primitives/src/plugin-artwork.tsx), whose blue square
|
|
6
6
|
carries the same vertical light-to-dark gradient: #69B9FF at the top,
|
|
7
7
|
#324DE2 at the bottom.
|
|
@@ -10,13 +10,17 @@
|
|
|
10
10
|
(1.75,1.75)-(14.25,12.75) on that grid, so the translate lands its centre
|
|
11
11
|
on the tile centre (18,18), and the ink spans 62.5% of the tile width —
|
|
12
12
|
the terminal glyph's own ratio.
|
|
13
|
-
The
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
<
|
|
13
|
+
The canvas stays 36x36, the size the harness and the official artwork use,
|
|
14
|
+
so the consumer's `size` attribute keeps the authority over display size;
|
|
15
|
+
the inner group shrinks the finished drawing to 26/28 of the canvas around
|
|
16
|
+
its centre — one uniform scale over coordinates that are already correct,
|
|
17
|
+
so the tile, its radius, the mark and the stroke ratio stay in proportion. -->
|
|
18
|
+
<g transform="translate(18 18) scale(0.9286) translate(-18 -18)">
|
|
19
|
+
<rect x="4" y="4" width="28" height="28" rx="8" fill="url(#rewind_blue)" />
|
|
20
|
+
<g transform="translate(6.8 7.85) scale(1.4)" stroke="#FFFFFF" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
|
|
21
|
+
<path d="M6.5 2.5 2.5 6.5l4 4" />
|
|
22
|
+
<path d="M2.5 6.5h7a4 4 0 0 1 4 4v1.5" />
|
|
23
|
+
</g>
|
|
20
24
|
</g>
|
|
21
25
|
<defs>
|
|
22
26
|
<linearGradient id="rewind_blue" x1="18" y1="4" x2="18" y2="32" gradientUnits="userSpaceOnUse">
|
|
Binary file
|
package/docs/compat/audit.md
CHANGED
|
@@ -1,31 +1,24 @@
|
|
|
1
1
|
# Compatibility audit (compat-audit)
|
|
2
2
|
|
|
3
3
|
> Method: **the tests are the audit**. The probes in `tests/compat-invariants.test.ts`,
|
|
4
|
-
> `tests/compat-interop.test.ts`, `tests/compat-gaps.test.ts
|
|
4
|
+
> `tests/compat-interop.test.ts`, `tests/compat-gaps.test.ts`,
|
|
5
|
+
> `tests/compat-tool-updates.test.ts` and
|
|
5
6
|
> `scripts/verify-host.mjs` drive the plugin's real execution paths through the DSH
|
|
6
7
|
> subsystems' **real consumer paths** (real `@deepseek-ai/*` packages) and assert
|
|
7
8
|
> compatibility invariants. A probe failure is a finding; it enters the
|
|
8
9
|
> fix/pin/record loop.
|
|
9
10
|
>
|
|
10
|
-
> Targeted version: npm `@deepseek-ai/*@0.1.7-rc.
|
|
11
|
+
> Targeted version: npm `@deepseek-ai/*@0.1.7-rc.2`, declared by the peers as `^0.1.7-rc.2`.
|
|
11
12
|
> Source reference: the upstream [github.com/deepseek-ai/deepseek-harness](https://github.com/deepseek-ai/deepseek-harness).
|
|
12
13
|
>
|
|
13
|
-
> Version alignment:
|
|
14
|
-
>
|
|
15
|
-
>
|
|
16
|
-
>
|
|
17
|
-
>
|
|
18
|
-
>
|
|
19
|
-
>
|
|
20
|
-
>
|
|
21
|
-
> sources, tool-role results, `developer/message`) and replaced the settings
|
|
22
|
-
> namespace registry with each entry's volatile `Config`, so the peer floor and
|
|
23
|
-
> both plugin seams moved with them. Signal: `npm view @deepseek-ai/dsh dist-tags`;
|
|
24
|
-
> flow: `scripts/check-dsh-version.mjs` (it reads the `latest` dist-tag only; a
|
|
25
|
-
> prerelease published under another tag is a manual pre-release check).
|
|
26
|
-
>
|
|
27
|
-
> The plugin targets a single DSH version line; compatibility with earlier
|
|
28
|
-
> lines is not kept.
|
|
14
|
+
> Version alignment: one peer tuple per DSH line, declaring only what was verified — the
|
|
15
|
+
> model, the update steps, and the `check-dsh-version.mjs` signal live in
|
|
16
|
+
> `docs/release/release.md`. The floor moved when a release changed interfaces inside the
|
|
17
|
+
> tuple: `0.1.6-alpha.2` removed the client session-ownership and queue-mirror APIs, and
|
|
18
|
+
> `0.1.7-alpha.1` moved the session writer to format v4 (producer-owned message sources,
|
|
19
|
+
> tool-role results, `developer/message`) and replaced the settings namespace registry with
|
|
20
|
+
> each entry's volatile `Config`, so the peer floor and both plugin seams moved with them.
|
|
21
|
+
> The plugin targets a single DSH version line; compatibility with earlier lines is not kept.
|
|
29
22
|
|
|
30
23
|
### Single channel
|
|
31
24
|
|
|
@@ -53,29 +46,25 @@ legacy branch).
|
|
|
53
46
|
| I6 tool pipeline | before-snapshot capture/commit/restore is correct (existing `snapshot.test.ts` + `verify-host` 4–8) for the tracked tools `write` / `edit` — `str_replace_editor` is an optional DSH package that stopped being a default tool in DSH 0.1.3, so it is not tracked; cancellation timing never hangs | `verify-host` 4–9 |
|
|
54
47
|
| I7 client ordering | A log carrying tool turns and rewind markers (a single `user/message` replace) satisfies the client builder ordering | `compat-interop` I7 |
|
|
55
48
|
| I8 runtime safety | `rewind`/`compact` combinations never leave a dangling step/turn frame | `verify-host` 13 |
|
|
49
|
+
| I9 tool-update projection | rc.2 folds mid-conversation tool additions from the whole log while a rewind cuts only the surface: after a withdrawal no `tool-addition`/`tool-removal` block reaches the provider and the current declarations stay complete | `compat-tool-updates` I9 |
|
|
56
50
|
|
|
57
51
|
## Verified-compatible surfaces (probes pass)
|
|
58
52
|
|
|
59
|
-
- **token-meter replay** (the `user/message` marker + multiple rewinds + interleaved real turns + compact stacking).
|
|
60
53
|
- **compaction transactions**: `toolPairingBalancedBefore/After` stays balanced after a marker cut; the real `/compact` command (`command-compact` + `compaction-basic`, stub summarizer) can land `compaction/start…end` on top of a rewind marker and stay replayable; `/compact` is a legal no-op on a small surface.
|
|
61
|
-
- **
|
|
54
|
+
- **tool-update history (`0.1.7-rc.2`)**: `Session.toolHistory()` folds the full append-only log, so a withdrawn `tool-addition` stays recorded after a rewind; `projectToolUpdates` drops every update whose message left the request and falls back to the complete current declarations. Pin: `tests/compat-tool-updates.test.ts` (on-surface projection, then the post-rewind fallback).
|
|
62
55
|
- **session-stats**: the `user/message` marker adds no step (the step count stays at the real turns' steps), no phantom turn.
|
|
63
56
|
- **session-title / goal fold**: a marker does not disturb `foldSessionTitle` / `foldGoal`.
|
|
64
|
-
- **client ordering**: turn-tail ordering + `step/start` uniqueness hold for tool turns + marker logs.
|
|
65
|
-
- **rewind across a compact checkpoint**: `RewindError('not-on-surface')` refuses cleanly, no crash.
|
|
66
57
|
- **plan-mode**: the marker is a turn-less `user/message` (no phantom turn); a rewind never touches the log-only `plan/mode` state (plan mode stays active; the user leaves it with `/plan off`) and the log stays replayable (`compat-invariants` I1/I3 marker + `plan/mode` probe, `verify-host`).
|
|
67
58
|
- **agent-loop cancellation**: `finally` guarantees step/turn closure; the rewind force-stop path leaves no dangling frame.
|
|
68
|
-
- **settings
|
|
59
|
+
- **settings card (`0.1.7-alpha.1`)**: the card declares `configForms` as a module-level inject (the web profile always composes `ui-settings`), stages through the harness's own `SettingsFormModel` + `SettingsForm`, and registers into `plugins.bundle.config` keyed by the bundle package name; it reads that shared per-entry form's snapshot and writes through its revision-fenced `mutate`, disposing the model's subscription with the fiber. The host half declares the bundle's page policy (`configure({ auto: false }, ctx.fiber)` inside a `ctx.inject(['settings'])` child, per the dsh-settings README), opting the entry out of a client-built schema page. Pins: `verify:host` (`the bundle declares its own config page`), `tests/client-settings-card.test.ts` (staged plan, refusal, subscription release), `tests/client-lifecycle.test.ts`.
|
|
69
60
|
- **client session ownership (`0.1.6-alpha.2`)**: `SessionListState.current` / `currentAddress` are gone; main-view ownership is read from the row's `retainedBy.mainView` label — what `ui-workspace` retains the open session with. Pin: `tests/client-refill.test.ts`.
|
|
70
61
|
- **client pending input (`0.1.6-alpha.2`)**: `SessionSnapshot.queue` and the host `queue-mirror` are gone; pending steering rows come from the session's own `inbox` projection, and only USER-sourced `next-step` rows are retractable (the removed mapping was `source.kind === 'user' ? 'steering' : 'context'`). Pins: `tests/pending.test.ts`, `tests/client-retract.test.ts`.
|
|
71
62
|
- **client settings slot (`0.1.6-alpha.2`)**: `settings.plugin.item` is gone; the configuration form registers into `plugins.bundle.config`, keyed by the bundle package name. Pin: `tests/client-contract.test.ts`.
|
|
72
|
-
- **client settings form (`0.1.7-alpha.1`)**: the same release retired the `settingsScope` bind (namespace registry) in favour of the shared per-entry form; the card now reads that form's snapshot and stages edits through `mutate`. Pin: `tests/client-settings-card.test.ts` (staged plan, refusal, and the fiber releasing the model's subscription), `tests/client-lifecycle.test.ts`.
|
|
73
|
-
|
|
74
63
|
- **`agent/created` lifecycle guard**: the session-format reconcile runs on the alpha line's `agent/created` (fire-and-forget); pin: `verify-host` 4e dispatches it.
|
|
75
64
|
- **marker vs `/compact`**: the checkpoint shape is unchanged on this line — a `user/message` replace (`surfaceOp {replace, startSeq, endSeq}` + `sourceEventSeqs`); `assistant/message` still cannot carry `sourceEventSeqs`.
|
|
76
65
|
- **`image/offload` projection**: the alpha line's first `SessionMessageProjection` changes derived content without touching surface node membership; candidate listing and target resolution tolerate it. Pin: `tests/image-offload-projection.test.ts`.
|
|
77
66
|
- **session-cwd**: the fs tools no longer canonicalize a parent-traversing cwd, so `src/session-cwd.ts` returns `header.cwd` verbatim. Pin: `tests/session-cwd.test.ts`.
|
|
78
|
-
- **startup admission (`0.1.7-rc.1`)**: the
|
|
67
|
+
- **startup admission (`0.1.7-rc.1`)**: the gate reads the manifest's own `@deepseek-ai/dsh-*` peers and requires each to satisfy the runtime with `includePrerelease`; it runs for a profile bundle and again for every row its patch inserts, and a denial skips the bundle or disables the row. This plugin's declarations all satisfy `0.1.7-rc.2`, so it is admitted with no exemption — a skipped bundle on a later line is a peer mismatch, not a load failure.
|
|
79
68
|
|
|
80
69
|
## Known behavior boundaries (deterministic differences, non-crash, documented)
|
|
81
70
|
|
|
@@ -89,107 +78,88 @@ legacy branch).
|
|
|
89
78
|
- **Attachment files left after a message is shadowed**: attachment storage is not cleaned with the surface (`dsh-attachment-local` not installed, not automatically verified).
|
|
90
79
|
- **Rewind leaves plan mode untouched**: `/plan text` is two independent actions (enter plan mode + steer the message). Rewinding the message undoes only the message — the log-only `plan/mode` state stays active, and the user leaves plan mode with `/plan off`, which still commits after a rewind (the marker creates no open turn). Pin: `verify-host` plan checks (`plan rewind leaves plan mode active`, `/plan off after rewind turns plan mode off`), `tests/hidden.test.ts` `messageTextAt`.
|
|
91
80
|
- **Bundle card metadata is declared by the plugin, not by the manager (`0.1.7-alpha.1`)**: the manager still titles a bundle with `shortName(pkg.name)` and its raw `package.json` description when nothing else is declared, but it now reads plugin-owned resources first — `locale/<lang>.json` (`meta.title`/`meta.description`) through the package exports map, and an `icon` file relative to the manifest. This plugin declares both, so its card shows an icon and copy that follows the active language; only the fallback description remains mixed-language. Pin: `tests/package-layout.test.ts` (icon path/media/size and both dictionaries).
|
|
92
|
-
|
|
93
|
-
- **Synchronous Session history reads are deprecated** on this line (`snapshotEvents` / `eventAt` / `ownEvents`): existing calls may remain, new calls are prohibited. The plugin keeps its existing reads (turn anchor + candidate listing); the migration path is a `ctx.sessionProjections` projection unit or the async paged history read this line has not shipped yet — not a plugin-side index. Not migrated in this release.
|
|
81
|
+
- **Synchronous Session history reads are deprecated** on this line (`snapshotEvents` / `eventAt` / `ownEvents`): existing calls may remain, new calls are prohibited. The plugin keeps its existing reads (turn anchor + candidate listing); the migration path is a `ctx.sessionProjections` projection unit or the async paged history read this line has not shipped yet — not a plugin-side index.
|
|
94
82
|
|
|
95
83
|
## Upstream (harness) issues and the plugin's no-compensation stance
|
|
96
84
|
|
|
97
|
-
The plugin treats these as harness-side defects it does not compensate for. Each entry records
|
|
85
|
+
The plugin treats these as harness-side defects it does not compensate for. Each entry records
|
|
86
|
+
the harness issue, its current status, and the plugin's stance, so a future maintainer does not
|
|
87
|
+
"fix the wrong direction."
|
|
98
88
|
|
|
99
89
|
### RU-I18N (resolved on the 0.1.7 line): host command copy follows the user's language
|
|
100
90
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
(`readHostLocale` in `src/index.ts` calls `settings.describe({ redactSecrets: true })`, the route
|
|
117
|
-
the settings UI and the client's own locale runtime take): at mount, which is what the
|
|
118
|
-
once-registered command descriptions carry, and again before each command renders, so the output
|
|
119
|
-
follows a language switch without a remount (the descriptors keep the mount-time language until
|
|
120
|
-
the plugin remounts). The read is best-effort: a missing method, a missing entry, or a
|
|
121
|
-
throwing read stays on the neutral English default.
|
|
122
|
-
- **Client-side command-description i18n is still first-party-only**: DSH localizes host command
|
|
123
|
-
descriptions through the client `locale` binding (`ui-commands`), but the description keys come
|
|
124
|
-
from a **closed allowlist** (`HOST_FACES`: compact, export, feedback, goal,
|
|
125
|
-
permission, plan). A command outside that set — every third-party plugin — is passed through
|
|
126
|
-
verbatim, never translated (`builtinRowFace` only rewrites a description that equals the
|
|
127
|
-
first-party English copy), and no host command *output* is localized by the harness for anyone.
|
|
128
|
-
This plugin's host dictionary is what carries both, in the language read above.
|
|
129
|
-
|
|
130
|
-
### R-OPENSTEP (rewind part resolved): an unclosed `step` in the log breaks token-meter replay; the rewind no longer compounds it
|
|
131
|
-
|
|
132
|
-
> **Root cause (harness-side)**: an unclosed step left by a crash makes token-meter replay
|
|
133
|
-
> reject any later step activity. DSH `0.1.1-rc.2` now auto-closes crash-left step/turn/tool
|
|
134
|
-
> boundaries at load via `interruptedTurnClosers` (`dsh-session`, consumed by
|
|
135
|
-
> `packages/core/agent-loop/src/index.ts:907`) — **the crash path is fixed**.
|
|
91
|
+
> **Status**: the `locale` settings section is gone — the locale host half only calls
|
|
92
|
+
> `settings.configure({ auto: false })`, and the preference lives in the `locale` entry's own
|
|
93
|
+
> Config. The plugin reads that value through the settings service's descriptor read
|
|
94
|
+
> (`readHostLocale` in `src/index.ts` calls `settings.describe({ redactSecrets: true })`, the
|
|
95
|
+
> route the settings UI and the client's own locale runtime take) at mount — which is what the
|
|
96
|
+
> once-registered command descriptions carry — and again before each command renders, so the
|
|
97
|
+
> output follows a language switch without a remount. The read is best-effort: a missing
|
|
98
|
+
> method, a missing entry, or a throwing read stays on the neutral English default.
|
|
99
|
+
>
|
|
100
|
+
> **Client-side command-description i18n is still first-party-only**: DSH localizes host
|
|
101
|
+
> command descriptions through the client `locale` binding (`ui-commands`), but the
|
|
102
|
+
> description keys come from a **closed allowlist** (`HOST_FACES`: compact, export, feedback,
|
|
103
|
+
> goal, permission, plan). A command outside that set — every third-party plugin — is passed
|
|
104
|
+
> through verbatim, and no host command *output* is localized by the harness for anyone. This
|
|
105
|
+
> plugin's host dictionary is what carries both, in the language read above.
|
|
136
106
|
>
|
|
137
|
-
> **Plugin
|
|
138
|
-
>
|
|
139
|
-
>
|
|
140
|
-
>
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
-
|
|
163
|
-
|
|
164
|
-
- **rewind's role (resolved)**: the v2 `user/message` rewind marker appends no `step/start`, so a rewind no longer introduces the first trip-wire and the R-OPENSTEP rewind amplifier is closed. The harness-side root cause (an unclosed step after a crash, tripped by continuing the conversation) remains.
|
|
107
|
+
> **Plugin stance**: no compensation; the seam is the descriptor read above. The wrong direction
|
|
108
|
+
> is the earlier one — reading `settings.get('locale').preference` once inside an
|
|
109
|
+
> `ctx.inject(['settings'])` callback and assuming cordis ordered the locale section before it
|
|
110
|
+
> (it does not; the descriptors were baked in the English default, defect #28).
|
|
111
|
+
|
|
112
|
+
### R-OPENSTEP (rewind part resolved): an unclosed `step` in the log breaks token-meter replay
|
|
113
|
+
|
|
114
|
+
> **Situation**: once a step is left unclosed, replay rejects any later step activity, so
|
|
115
|
+
> manual `/compact` fails permanently and automatic compaction silently stays disabled (the
|
|
116
|
+
> `agent/pre-step` hook catches and warns). The conversation itself is unaffected — only
|
|
117
|
+
> compaction-basic measures tree-wide. DSH now auto-closes crash-left step/turn/tool
|
|
118
|
+
> boundaries at load (`interruptedTurnClosers`, consumed by
|
|
119
|
+
> `packages/core/agent-loop/src/index.ts:907`), so **the crash path is fixed**. The tree has
|
|
120
|
+
> exactly one `append('step/start')` producer, `agent-loop/src/agent.ts:303`; an unclosed step
|
|
121
|
+
> otherwise comes from a third-party plugin appending `step/start` through the public
|
|
122
|
+
> `Session.append`, or from a hand-edited log. After a crash resume, `turn()` opens a new turn
|
|
123
|
+
> (`agent.ts:277-283`) without closing the leftover step, so continuing the conversation trips
|
|
124
|
+
> the same check — a rewind is **not** the only trigger.
|
|
125
|
+
>
|
|
126
|
+
> **Rewind's part**: the marker is a `user/message` and appends no `step/start`, so a rewind
|
|
127
|
+
> no longer introduces the first trip-wire and the R-OPENSTEP rewind amplifier is closed.
|
|
128
|
+
>
|
|
129
|
+
> **Plugin stance**: no guard. A `hasOpenStep` + `planRewind` pre-refusal was implemented and
|
|
130
|
+
> misjudged on **real session logs** (normal rewinds refused, GUI verification broken), so it
|
|
131
|
+
> was reverted — do not re-attempt a plugin-side pre-refusal. The fix direction is upstream
|
|
132
|
+
> (token-meter recovery for unclosed steps), and the residual risk is accepted: that log is
|
|
133
|
+
> already abnormal.
|
|
165
134
|
|
|
166
135
|
### R-PROMPTCARD (resolved on the 0.1.7 line): the repeated `System prompt` card is filtered out of chat
|
|
167
136
|
|
|
168
|
-
> **
|
|
169
|
-
>
|
|
170
|
-
>
|
|
171
|
-
>
|
|
172
|
-
>
|
|
173
|
-
> card repeats. Triggers beyond rewind: `/compact`, restart/resume, projections, explicit
|
|
174
|
-
> `startsSeries`.
|
|
175
|
-
>
|
|
176
|
-
> **Upstream decision (deliberate, twice)**: `6ad01cbd8d` suppressed the repeat on `resume` (note
|
|
177
|
-
> `2026-09-03-resume-headers-do-not-repeat-system-prompts.md`, rejecting the card as a "lifecycle
|
|
178
|
-
> marker" that "incorrectly implies another prompt injection"); three days later `77b6b10c21`
|
|
179
|
-
> restored it — a resume/series header starts a visible request series. Locked by the `ui-chat` test
|
|
180
|
-
> `repeats an unchanged system prompt after a surface rewrite…`.
|
|
137
|
+
> **Status**: `isVisibleChatNode`
|
|
138
|
+
> (`packages/client/ui-chat/src/client/contract/chat-visibility.ts`) drops `system-prompt`
|
|
139
|
+
> nodes — and the `permission` command — from the visible chat rows before the row is built,
|
|
140
|
+
> so a rewind on this line adds no prompt row at all; the durable events and the trajectory
|
|
141
|
+
> inspection keep them. #22, #31 and README known issue #4 no longer reproduce.
|
|
181
142
|
>
|
|
182
|
-
> **
|
|
183
|
-
>
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
>
|
|
188
|
-
>
|
|
143
|
+
> **Plugin stance**: still no compensation. The DOM row-hiding seam (`hiddenSeqsOf`) covers
|
|
144
|
+
> withdrawn messages, where hiding is essential, not cosmetic.
|
|
145
|
+
|
|
146
|
+
### R-PANELKEYS: the panel keyboard stays the plugin's own
|
|
147
|
+
|
|
148
|
+
> **Situation**: on Web, Escape, Tab, the four arrows, and Enter without Alt are
|
|
149
|
+
> platform-reserved — inline in the shortcuts `bindingIssue` list, with no exported form — so
|
|
150
|
+
> neither a plugin nor a user may bind them and there is nothing to read and follow. `Menu`
|
|
151
|
+
> is the dropdown primitive, while the harness's command-option panel (`ui-commands`'
|
|
152
|
+
> popupSelect) renders `MenuSurface` plus its own controller with `role="listbox"`/
|
|
153
|
+
> `role="option"`. `ui-commands`' `settle()` also calls `focusComposer()` unconditionally
|
|
154
|
+
> after `await onSelect(...)`; its only early return requires replacing the popup binding,
|
|
155
|
+
> which needs the internal `segment` that business code cannot reach.
|
|
189
156
|
>
|
|
190
|
-
> **
|
|
191
|
-
>
|
|
192
|
-
>
|
|
157
|
+
> **Decision**: the mode-selection and retract panels keep their own capture-phase
|
|
158
|
+
> Escape/↑/↓ handling — focus-independent, the shape the official command panel uses — and
|
|
159
|
+
> keep `role="dialog"`. The plugin neither renders `Menu` nor compensates the composer focus
|
|
160
|
+
> restore. Capture ownership is pinned by `tests/client-popover.test.ts`; the ghost-row walk
|
|
161
|
+
> exclusion is **not** pinned, and on the typed `/rewind` path Enter still needs a row to hold
|
|
162
|
+
> focus after the shell's focus restore.
|
|
193
163
|
|
|
194
164
|
## Uncovered boundaries (need an additional e2e layer; non-blocking)
|
|
195
165
|
|
|
@@ -216,8 +186,6 @@ new turn at `phase.turn + 1` (`agent.ts:277-283`) **without closing the leftover
|
|
|
216
186
|
| client ordering | — | — | ✓ | — | — | — | ✓ | — |
|
|
217
187
|
| plan-mode | ✓ | — | ✓ | — | — | — | — | ✓ (static) |
|
|
218
188
|
|
|
219
|
-
✓ = probe passes; — = not applicable.
|
|
220
|
-
above
|
|
221
|
-
|
|
222
|
-
`compat-gaps.test.ts` (G1 surface classification via `foldSurface` and G2 projection checkpoint
|
|
223
|
-
both pass).
|
|
189
|
+
✓ = probe passes; — = not applicable. Statuses and stances for the named findings live in the
|
|
190
|
+
sections above; G1 (surface classification via `foldSurface`), G2 (projection checkpoint) and
|
|
191
|
+
G3 (the confirmed-non-defect usage anchor on token-meter) all pass in `compat-gaps.test.ts`.
|
package/lib/client.js
CHANGED
|
@@ -430,6 +430,11 @@ var STYLE = `
|
|
|
430
430
|
// src/client/popover.ts
|
|
431
431
|
var popoverEl = null;
|
|
432
432
|
var disposeOutside = null;
|
|
433
|
+
var liveSessionId = null;
|
|
434
|
+
var composerFocuser = null;
|
|
435
|
+
function registerComposerFocuser(focus) {
|
|
436
|
+
composerFocuser = focus;
|
|
437
|
+
}
|
|
433
438
|
function closePopover() {
|
|
434
439
|
if (popoverEl !== null) {
|
|
435
440
|
popoverEl.remove();
|
|
@@ -439,6 +444,14 @@ function closePopover() {
|
|
|
439
444
|
disposeOutside();
|
|
440
445
|
disposeOutside = null;
|
|
441
446
|
}
|
|
447
|
+
const sessionId = liveSessionId;
|
|
448
|
+
liveSessionId = null;
|
|
449
|
+
if (sessionId !== null) {
|
|
450
|
+
try {
|
|
451
|
+
composerFocuser?.(sessionId);
|
|
452
|
+
} catch {
|
|
453
|
+
}
|
|
454
|
+
}
|
|
442
455
|
}
|
|
443
456
|
function formatTarget(t, seq, time, preview) {
|
|
444
457
|
const d = new Date(time);
|
|
@@ -689,6 +702,7 @@ function openRetractPopover(opts) {
|
|
|
689
702
|
}
|
|
690
703
|
function openPopover(opts) {
|
|
691
704
|
closePopover();
|
|
705
|
+
liveSessionId = opts.session.sessionId;
|
|
692
706
|
if (opts.retract !== void 0) {
|
|
693
707
|
openRetractPopover(opts);
|
|
694
708
|
return;
|
|
@@ -854,6 +868,10 @@ function writeComposer(text, facade) {
|
|
|
854
868
|
if (facade !== void 0) {
|
|
855
869
|
try {
|
|
856
870
|
facade.setDraft(text);
|
|
871
|
+
try {
|
|
872
|
+
facade.focus?.();
|
|
873
|
+
} catch {
|
|
874
|
+
}
|
|
857
875
|
return true;
|
|
858
876
|
} catch {
|
|
859
877
|
}
|
|
@@ -973,6 +991,7 @@ function hideWithdrawnSeats(chat, seats, hiddenSeqs, hidden) {
|
|
|
973
991
|
delete seat.dataset.dshRewindHidden;
|
|
974
992
|
hidden.delete(seat);
|
|
975
993
|
}
|
|
994
|
+
if (seat.dataset.chatNodeKey === void 0) continue;
|
|
976
995
|
const shell = seat.parentElement?.closest(GROUP_SHELL_SELECTOR);
|
|
977
996
|
if (shell === null || shell === void 0) continue;
|
|
978
997
|
shells.set(shell, (shells.get(shell) ?? true) && withdrawn);
|
|
@@ -1233,9 +1252,9 @@ function createRewindBridge(deps) {
|
|
|
1233
1252
|
}
|
|
1234
1253
|
|
|
1235
1254
|
// src/client/build-info.ts
|
|
1236
|
-
var PLUGIN_VERSION = true ? "0.14.0-beta.
|
|
1255
|
+
var PLUGIN_VERSION = true ? "0.14.0-beta.2" : "dev";
|
|
1237
1256
|
var PLUGIN_PACKAGE = "dsh-rewind-plugin";
|
|
1238
|
-
var BUILD_HASH = true ? "
|
|
1257
|
+
var BUILD_HASH = true ? "1afddb1d" : "dev";
|
|
1239
1258
|
|
|
1240
1259
|
// src/client/locales.ts
|
|
1241
1260
|
var zh = {
|
|
@@ -1438,24 +1457,35 @@ function apply(ctx) {
|
|
|
1438
1457
|
return void 0;
|
|
1439
1458
|
}
|
|
1440
1459
|
};
|
|
1460
|
+
const composerFacade = (sessionId) => {
|
|
1461
|
+
const conversation = ctx.get("conversation");
|
|
1462
|
+
const input = conversation?.input;
|
|
1463
|
+
const scope = ctx.sessions.scope?.(sessionId);
|
|
1464
|
+
if (input === void 0 || scope === void 0) return void 0;
|
|
1465
|
+
return {
|
|
1466
|
+
setDraft: (draft) => {
|
|
1467
|
+
input.for(scope).setDraft(draft);
|
|
1468
|
+
},
|
|
1469
|
+
focus: () => {
|
|
1470
|
+
input.for(scope).focus();
|
|
1471
|
+
}
|
|
1472
|
+
};
|
|
1473
|
+
};
|
|
1441
1474
|
const setComposerText = (sessionId, text) => {
|
|
1442
1475
|
try {
|
|
1443
|
-
|
|
1444
|
-
const input = conversation?.input;
|
|
1445
|
-
const scope = ctx.sessions.scope?.(sessionId);
|
|
1446
|
-
const facade = input !== void 0 && scope !== void 0;
|
|
1447
|
-
const ok = writeComposer(
|
|
1448
|
-
text,
|
|
1449
|
-
facade ? { setDraft: (draft) => {
|
|
1450
|
-
input.for(scope).setDraft(draft);
|
|
1451
|
-
} } : void 0
|
|
1452
|
-
);
|
|
1453
|
-
return ok;
|
|
1476
|
+
return writeComposer(text, composerFacade(sessionId));
|
|
1454
1477
|
} catch (error) {
|
|
1455
1478
|
rewindLog.warn("refill", "composer write threw", error);
|
|
1456
1479
|
return false;
|
|
1457
1480
|
}
|
|
1458
1481
|
};
|
|
1482
|
+
registerComposerFocuser((sessionId) => {
|
|
1483
|
+
try {
|
|
1484
|
+
composerFacade(sessionId)?.focus();
|
|
1485
|
+
} catch (error) {
|
|
1486
|
+
rewindLog.warn("refill", "composer focus threw", error);
|
|
1487
|
+
}
|
|
1488
|
+
});
|
|
1459
1489
|
const watchChat = (sessionId, cb) => resolveChatWatch(
|
|
1460
1490
|
(id) => {
|
|
1461
1491
|
try {
|
package/lib/index.js
CHANGED
|
@@ -2766,6 +2766,9 @@ function apply(ctx, config) {
|
|
|
2766
2766
|
ctx.effect(() => () => {
|
|
2767
2767
|
lifecycle.abort();
|
|
2768
2768
|
}, "dsh-rewind lifecycle abort");
|
|
2769
|
+
ctx.inject(["settings"], (child) => {
|
|
2770
|
+
child.effect(() => child.settings.configure({ auto: false }, ctx.fiber), "dsh-rewind page policy");
|
|
2771
|
+
});
|
|
2769
2772
|
const dshHome = config?.dshHome;
|
|
2770
2773
|
const store = new SnapshotStore(config?.snapshotDir, { dedup: config?.dedup, dshHome });
|
|
2771
2774
|
const configKey = cleanupConfigKey(rewindConfigKey(ctx));
|
|
@@ -54,7 +54,12 @@ export interface PopoverOptions {
|
|
|
54
54
|
*/
|
|
55
55
|
readonly onRewind?: (mode: 'chat' | 'both') => void;
|
|
56
56
|
}
|
|
57
|
-
/**
|
|
57
|
+
/**
|
|
58
|
+
* Register the composer focus channel (called once by the client plugin).
|
|
59
|
+
* @param focus - returns the keyboard to one session's composer, caret included.
|
|
60
|
+
*/
|
|
61
|
+
export declare function registerComposerFocuser(focus: (sessionId: string) => void): void;
|
|
62
|
+
/** Close the current popover, if any, handing the keyboard back to its composer. */
|
|
58
63
|
export declare function closePopover(): void;
|
|
59
64
|
/**
|
|
60
65
|
* Seqs of the command nodes currently matching `match`. Sample BEFORE issuing
|
|
@@ -124,6 +124,12 @@ export interface SlotsLike {
|
|
|
124
124
|
*/
|
|
125
125
|
interface ComposerDraftWriter {
|
|
126
126
|
setDraft(text: string): void;
|
|
127
|
+
/**
|
|
128
|
+
* Return the keyboard to the composer with the caret it last held (the
|
|
129
|
+
* facade's own `focus`). Optional so the DOM fallback and older faces still
|
|
130
|
+
* restore the text.
|
|
131
|
+
*/
|
|
132
|
+
focus?(): void;
|
|
127
133
|
}
|
|
128
134
|
/**
|
|
129
135
|
* Fill the dsh composer with `text` through the `contenteditable`
|
|
@@ -206,6 +212,14 @@ export declare function actionsContainerOf(row: HTMLElement | undefined): HTMLEl
|
|
|
206
212
|
* that member is genuinely on the surface, in which case the shell stays; a
|
|
207
213
|
* shell the batch carries no member of is left alone.
|
|
208
214
|
*
|
|
215
|
+
* A MEMBER is a real chat node seat — `ChatNodeSeat` is the one shape that
|
|
216
|
+
* writes `data-chat-node-key` beside the anchor key. An anchor-only descendant
|
|
217
|
+
* (the tool call tree's own `call:<callId>` row, or a third-party anchor) is
|
|
218
|
+
* nested decoration: it resolves to no chat node, so it does NOT vote on the
|
|
219
|
+
* shell's emptiness. Counting such a row as "still live" is what left a fully
|
|
220
|
+
* withdrawn "command executed" tool group on screen as an empty expandable row
|
|
221
|
+
* after every member below it had been hidden.
|
|
222
|
+
*
|
|
209
223
|
* Cost stays O(seats) per refresh: the caller queries the batch once, and each
|
|
210
224
|
* shell decision reuses the member outcomes already computed here — no second
|
|
211
225
|
* document scan, and no per-shell subtree walk.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-rewind-plugin",
|
|
3
|
-
"version": "0.14.0-beta.
|
|
3
|
+
"version": "0.14.0-beta.2",
|
|
4
4
|
"description": "In-window conversation rewind with workspace file restore · 同窗口内对话回退并可还原工作区文件",
|
|
5
5
|
"icon": "./assets/icon.svg",
|
|
6
6
|
"keywords": [
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"patch": "./cordis.patch.yml"
|
|
54
54
|
},
|
|
55
55
|
"engines": {
|
|
56
|
-
"dsh": ">=0.1.7-rc.
|
|
56
|
+
"dsh": ">=0.1.7-rc.2"
|
|
57
57
|
},
|
|
58
58
|
"client": {
|
|
59
59
|
"inject": [
|
|
@@ -78,20 +78,20 @@
|
|
|
78
78
|
},
|
|
79
79
|
"peerDependencies": {
|
|
80
80
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
81
|
-
"@deepseek-ai/dsh-client-locale": "^0.1.7-rc.
|
|
82
|
-
"@deepseek-ai/dsh-client-ui-commands": "^0.1.7-rc.
|
|
83
|
-
"@deepseek-ai/dsh-client-ui-plugin-manager": "^0.1.7-rc.
|
|
84
|
-
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.7-rc.
|
|
85
|
-
"@deepseek-ai/dsh-client-ui-settings": "^0.1.7-rc.
|
|
86
|
-
"@deepseek-ai/dsh-client-ui-slots": "^0.1.7-rc.
|
|
87
|
-
"@deepseek-ai/dsh-commands": "^0.1.7-rc.
|
|
88
|
-
"@deepseek-ai/dsh-fs": "^0.1.7-rc.
|
|
89
|
-
"@deepseek-ai/dsh-home-paths": "^0.1.7-rc.
|
|
90
|
-
"@deepseek-ai/dsh-llm": "^0.1.7-rc.
|
|
91
|
-
"@deepseek-ai/dsh-sandbox": "^0.1.7-rc.
|
|
92
|
-
"@deepseek-ai/dsh-session": "^0.1.7-rc.
|
|
93
|
-
"@deepseek-ai/dsh-settings": "^0.1.7-rc.
|
|
94
|
-
"@deepseek-ai/dsh-tools": "^0.1.7-rc.
|
|
81
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.7-rc.2",
|
|
82
|
+
"@deepseek-ai/dsh-client-ui-commands": "^0.1.7-rc.2",
|
|
83
|
+
"@deepseek-ai/dsh-client-ui-plugin-manager": "^0.1.7-rc.2",
|
|
84
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.7-rc.2",
|
|
85
|
+
"@deepseek-ai/dsh-client-ui-settings": "^0.1.7-rc.2",
|
|
86
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.7-rc.2",
|
|
87
|
+
"@deepseek-ai/dsh-commands": "^0.1.7-rc.2",
|
|
88
|
+
"@deepseek-ai/dsh-fs": "^0.1.7-rc.2",
|
|
89
|
+
"@deepseek-ai/dsh-home-paths": "^0.1.7-rc.2",
|
|
90
|
+
"@deepseek-ai/dsh-llm": "^0.1.7-rc.2",
|
|
91
|
+
"@deepseek-ai/dsh-sandbox": "^0.1.7-rc.2",
|
|
92
|
+
"@deepseek-ai/dsh-session": "^0.1.7-rc.2",
|
|
93
|
+
"@deepseek-ai/dsh-settings": "^0.1.7-rc.2",
|
|
94
|
+
"@deepseek-ai/dsh-tools": "^0.1.7-rc.2",
|
|
95
95
|
"@deepseek-ai/schemastery": "^3.18.1"
|
|
96
96
|
},
|
|
97
97
|
"peerDependenciesMeta": {
|
|
@@ -147,41 +147,41 @@
|
|
|
147
147
|
"devDependencies": {
|
|
148
148
|
"@deepseek-ai/cordis": "4.0.3",
|
|
149
149
|
"@deepseek-ai/cosmokit": "1.8.4",
|
|
150
|
-
"@deepseek-ai/dsh-agent": "0.1.7-rc.
|
|
151
|
-
"@deepseek-ai/dsh-api-session-controller": "0.1.7-rc.
|
|
152
|
-
"@deepseek-ai/dsh-attachment": "0.1.7-rc.
|
|
153
|
-
"@deepseek-ai/dsh-client-connection": "0.1.7-rc.
|
|
154
|
-
"@deepseek-ai/dsh-client-locale": "0.1.7-rc.
|
|
155
|
-
"@deepseek-ai/dsh-client-store": "0.1.7-rc.
|
|
156
|
-
"@deepseek-ai/dsh-client-ui-commands": "0.1.7-rc.
|
|
157
|
-
"@deepseek-ai/dsh-client-ui-conversation": "0.1.7-rc.
|
|
158
|
-
"@deepseek-ai/dsh-client-ui-input-trigger": "0.1.7-rc.
|
|
159
|
-
"@deepseek-ai/dsh-client-ui-plugin-manager": "0.1.7-rc.
|
|
160
|
-
"@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.
|
|
161
|
-
"@deepseek-ai/dsh-client-ui-session": "0.1.7-rc.
|
|
162
|
-
"@deepseek-ai/dsh-client-ui-settings": "0.1.7-rc.
|
|
163
|
-
"@deepseek-ai/dsh-client-ui-slots": "0.1.7-rc.
|
|
164
|
-
"@deepseek-ai/dsh-command-compact": "0.1.7-rc.
|
|
165
|
-
"@deepseek-ai/dsh-commands": "0.1.7-rc.
|
|
166
|
-
"@deepseek-ai/dsh-compaction": "0.1.7-rc.
|
|
167
|
-
"@deepseek-ai/dsh-compaction-basic": "0.1.7-rc.
|
|
168
|
-
"@deepseek-ai/dsh-compaction-image-offload": "0.1.7-rc.
|
|
169
|
-
"@deepseek-ai/dsh-fs": "0.1.7-rc.
|
|
170
|
-
"@deepseek-ai/dsh-goal": "0.1.7-rc.
|
|
171
|
-
"@deepseek-ai/dsh-home-paths": "0.1.7-rc.
|
|
172
|
-
"@deepseek-ai/dsh-llm": "0.1.7-rc.
|
|
173
|
-
"@deepseek-ai/dsh-plan-mode": "0.1.7-rc.
|
|
174
|
-
"@deepseek-ai/dsh-sandbox": "0.1.7-rc.
|
|
175
|
-
"@deepseek-ai/dsh-scope": "0.1.7-rc.
|
|
176
|
-
"@deepseek-ai/dsh-session": "0.1.7-rc.
|
|
177
|
-
"@deepseek-ai/dsh-session-projection": "0.1.7-rc.
|
|
178
|
-
"@deepseek-ai/dsh-session-stats": "0.1.7-rc.
|
|
179
|
-
"@deepseek-ai/dsh-session-title": "0.1.7-rc.
|
|
180
|
-
"@deepseek-ai/dsh-settings": "0.1.7-rc.
|
|
181
|
-
"@deepseek-ai/dsh-token-meter": "0.1.7-rc.
|
|
182
|
-
"@deepseek-ai/dsh-tools": "0.1.7-rc.
|
|
183
|
-
"@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.
|
|
184
|
-
"@deepseek-ai/dsh-user-questions": "0.1.7-rc.
|
|
150
|
+
"@deepseek-ai/dsh-agent": "0.1.7-rc.2",
|
|
151
|
+
"@deepseek-ai/dsh-api-session-controller": "0.1.7-rc.2",
|
|
152
|
+
"@deepseek-ai/dsh-attachment": "0.1.7-rc.2",
|
|
153
|
+
"@deepseek-ai/dsh-client-connection": "0.1.7-rc.2",
|
|
154
|
+
"@deepseek-ai/dsh-client-locale": "0.1.7-rc.2",
|
|
155
|
+
"@deepseek-ai/dsh-client-store": "0.1.7-rc.2",
|
|
156
|
+
"@deepseek-ai/dsh-client-ui-commands": "0.1.7-rc.2",
|
|
157
|
+
"@deepseek-ai/dsh-client-ui-conversation": "0.1.7-rc.2",
|
|
158
|
+
"@deepseek-ai/dsh-client-ui-input-trigger": "0.1.7-rc.2",
|
|
159
|
+
"@deepseek-ai/dsh-client-ui-plugin-manager": "0.1.7-rc.2",
|
|
160
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.1.7-rc.2",
|
|
161
|
+
"@deepseek-ai/dsh-client-ui-session": "0.1.7-rc.2",
|
|
162
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.1.7-rc.2",
|
|
163
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.7-rc.2",
|
|
164
|
+
"@deepseek-ai/dsh-command-compact": "0.1.7-rc.2",
|
|
165
|
+
"@deepseek-ai/dsh-commands": "0.1.7-rc.2",
|
|
166
|
+
"@deepseek-ai/dsh-compaction": "0.1.7-rc.2",
|
|
167
|
+
"@deepseek-ai/dsh-compaction-basic": "0.1.7-rc.2",
|
|
168
|
+
"@deepseek-ai/dsh-compaction-image-offload": "0.1.7-rc.2",
|
|
169
|
+
"@deepseek-ai/dsh-fs": "0.1.7-rc.2",
|
|
170
|
+
"@deepseek-ai/dsh-goal": "0.1.7-rc.2",
|
|
171
|
+
"@deepseek-ai/dsh-home-paths": "0.1.7-rc.2",
|
|
172
|
+
"@deepseek-ai/dsh-llm": "0.1.7-rc.2",
|
|
173
|
+
"@deepseek-ai/dsh-plan-mode": "0.1.7-rc.2",
|
|
174
|
+
"@deepseek-ai/dsh-sandbox": "0.1.7-rc.2",
|
|
175
|
+
"@deepseek-ai/dsh-scope": "0.1.7-rc.2",
|
|
176
|
+
"@deepseek-ai/dsh-session": "0.1.7-rc.2",
|
|
177
|
+
"@deepseek-ai/dsh-session-projection": "0.1.7-rc.2",
|
|
178
|
+
"@deepseek-ai/dsh-session-stats": "0.1.7-rc.2",
|
|
179
|
+
"@deepseek-ai/dsh-session-title": "0.1.7-rc.2",
|
|
180
|
+
"@deepseek-ai/dsh-settings": "0.1.7-rc.2",
|
|
181
|
+
"@deepseek-ai/dsh-token-meter": "0.1.7-rc.2",
|
|
182
|
+
"@deepseek-ai/dsh-tools": "0.1.7-rc.2",
|
|
183
|
+
"@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2",
|
|
184
|
+
"@deepseek-ai/dsh-user-questions": "0.1.7-rc.2",
|
|
185
185
|
"@deepseek-ai/schemastery": "3.18.3",
|
|
186
186
|
"@types/node": "^24.0.0",
|
|
187
187
|
"@types/react": "^18.3.31",
|