dsh-rewind-plugin 0.13.0-alpha.1 → 0.13.0-alpha.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/CONTRIBUTING.md +1 -1
- package/SECURITY.md +1 -1
- package/docs/README.md +1 -1
- package/docs/architecture.md +3 -3
- package/docs/compat/audit.md +18 -12
- package/docs/compat/diagnostics.md +1 -0
- package/docs/compat/diagnostics.zh.md +1 -0
- package/docs/contract/client-contract.md +1 -1
- package/docs/contract/client-contract.zh.md +1 -1
- package/docs/format.md +2 -2
- package/docs/harness-reference.md +6 -3
- package/docs/release/release.md +9 -9
- package/docs/release/release.zh.md +10 -10
- package/docs/rewind-fix.md +1 -1
- package/docs/rewind-fix.zh.md +1 -1
- package/lib/client.js +315 -346
- package/lib/index.js +47 -13
- package/lib/types/client/build-info.d.ts +6 -0
- package/lib/types/client/candidates.d.ts +0 -2
- package/lib/types/client/hidden.d.ts +6 -7
- package/lib/types/client/locales.d.ts +6 -14
- package/lib/types/client/pending.d.ts +57 -15
- package/lib/types/client/popover.d.ts +1 -1
- package/lib/types/client/portals.d.ts +37 -27
- package/lib/types/client/settings-card.d.ts +177 -48
- package/lib/types/client/styles.d.ts +1 -1
- package/lib/types/index.d.ts +1 -1
- package/lib/types/locales.d.ts +1 -1
- package/lib/types/rewind.d.ts +1 -1
- package/lib/types/snapshot-cleanup.d.ts +6 -4
- package/lib/types/snapshot.d.ts +1 -8
- package/package.json +54 -47
package/CONTRIBUTING.md
CHANGED
|
@@ -8,7 +8,7 @@ first), and the docs live under `docs/` with an index in `docs/README.md`.
|
|
|
8
8
|
|
|
9
9
|
- **Focused on purpose** — one thing: in-window rewind to any earlier user
|
|
10
10
|
message, never forking a session.
|
|
11
|
-
- **Security first** — session logs are append-only; file restores
|
|
11
|
+
- **Security first** — session logs are append-only; file restores draw only from
|
|
12
12
|
the plugin's own backup directory. See `SECURITY.md`.
|
|
13
13
|
- **Minimal** — avoid over-abstraction; keep the plugin light and maintainable.
|
|
14
14
|
|
package/SECURITY.md
CHANGED
|
@@ -90,7 +90,7 @@ transcript.
|
|
|
90
90
|
|
|
91
91
|
## Filesystem containment
|
|
92
92
|
|
|
93
|
-
- **Store root**: `<
|
|
93
|
+
- **Store root**: `<dsh home>/rewind-snapshots/` by default (resolved via
|
|
94
94
|
`resolveDshHome`, so `~/.dsh/...` when `DSH_HOME` is unset); the `snapshotDir`
|
|
95
95
|
config, then `DSH_REWIND_SNAPSHOT_DIR` env, override it. Deleting it only
|
|
96
96
|
removes file backups and the store rebuilds from scratch.
|
package/docs/README.md
CHANGED
|
@@ -12,7 +12,7 @@ index/navigation entry point.
|
|
|
12
12
|
| `format.md` | Durable on-disk format spec (checkpoint entries + restore journals) | maintainers |
|
|
13
13
|
| `harness-reference.md` | DeepSeek Harness interface reference + plugin source layout | maintainers |
|
|
14
14
|
| `snapshot-auto-cleanup.md` | Global snapshot auto-cleanup policy and command (`.zh` mirror) | users / maintainers |
|
|
15
|
-
| `rewind-fix.md` |
|
|
15
|
+
| `rewind-fix.md` | Historical guide for the removed `/dsh-rewind-fix` (`.zh` mirror) | users / maintainers |
|
|
16
16
|
| `contract/client-contract.md` | Rewind visibility contract for third-party DOM plugins (`.zh` mirror) | integrators |
|
|
17
17
|
| `compat/audit.md` | Compatibility audit: verified surfaces, recorded findings, probe matrix | maintainers |
|
|
18
18
|
| `compat/tracking-boundary.md` | Which files a rewind restores: the tracking boundary (`.zh` mirror) | users / maintainers |
|
package/docs/architecture.md
CHANGED
|
@@ -134,13 +134,13 @@ pruneStale cross-session auto-cleanup (default off): whole
|
|
|
134
134
|
|
|
135
135
|
## Compatibility strategy
|
|
136
136
|
|
|
137
|
-
- **Peer ranges as one tuple per DSH line** (`^0.1.
|
|
137
|
+
- **Peer ranges as one tuple per DSH line** (`^0.1.6-alpha.2`): npm's prerelease
|
|
138
138
|
rules require the peer range to share the host's `[major, minor, patch]`
|
|
139
139
|
tuple, so a new DSH tuple replaces the peer tuple (the single-line model);
|
|
140
140
|
`scripts/check-dsh-version.mjs` flags when a new tuple arrives. See
|
|
141
141
|
`docs/release/release.md`.
|
|
142
|
-
- **Test-driven investigation**: `tests/compat-invariants.ts` /
|
|
143
|
-
`compat-interop` / `compat-gaps` probe harness behavior and pin findings in
|
|
142
|
+
- **Test-driven investigation**: `tests/compat-invariants.test.ts` /
|
|
143
|
+
`compat-interop.test.ts` / `compat-gaps.test.ts` probe harness behavior and pin findings in
|
|
144
144
|
`docs/compat/audit.md`; `scripts/verify-host.mjs` runs a real end-to-end
|
|
145
145
|
rewind + `/compact` chain (the full check suite).
|
|
146
146
|
- **Stable machine channels for third parties**: `dsh-rewind-plugin/client`
|
package/docs/compat/audit.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
> compatibility invariants. A probe failure is a finding; it enters the
|
|
8
8
|
> fix/pin/record loop.
|
|
9
9
|
>
|
|
10
|
-
> Targeted version: npm `@deepseek-ai/*@0.1.6-alpha.
|
|
10
|
+
> Targeted version: npm `@deepseek-ai/*@0.1.6-alpha.2` (the range the peers and `dsh.engines.dsh` declare).
|
|
11
11
|
> Source reference: the upstream [github.com/deepseek-ai/deepseek-harness](https://github.com/deepseek-ai/deepseek-harness).
|
|
12
12
|
>
|
|
13
13
|
> Version alignment: `peerDependencies` use one tuple per DSH line
|
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
> share the range comparator's `[major, minor, patch]` tuple, so a new DSH tuple
|
|
16
16
|
> replaces the peer tuple (single-line model). The range is conservative — it
|
|
17
17
|
> declares only what was verified, so a release already inside it changes
|
|
18
|
-
> nothing
|
|
18
|
+
> nothing — unless it changes interfaces inside the tuple: `0.1.6-alpha.2`
|
|
19
|
+
> removed the client session-ownership and queue-mirror APIs, so the peer floor
|
|
20
|
+
> moved to it. Signal: `npm view @deepseek-ai/dsh dist-tags`;
|
|
19
21
|
> flow: `scripts/check-dsh-version.mjs` (it reads the `latest` dist-tag only; a
|
|
20
22
|
> prerelease published under another tag is a manual pre-release check).
|
|
21
23
|
>
|
|
@@ -45,9 +47,9 @@ legacy branch).
|
|
|
45
47
|
| I3 step/turn structure | Client turn-tail ordering, unique `step/start` (real turns), no ghost turns; the `user/message` rewind marker adds no step frame | `compat-invariants` I3, `helpers.assertTurnTailOrdering` |
|
|
46
48
|
| I4 fold-service safety | stats / title / goal / projection fold a marker-bearing log without throwing, with predictable values | `compat-invariants` I4 |
|
|
47
49
|
| I5 compact interop | A tool-call orphaned by a cancelled turn is pair-balanced once shadowed by a rewind; a rewind across a compaction checkpoint is explicitly refused; a rewind-then-compact transaction stays legal | `compat-interop` I5, `verify-host` 12/14 |
|
|
48
|
-
| 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–
|
|
50
|
+
| 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 |
|
|
49
51
|
| I7 client ordering | A log carrying tool turns and rewind markers (a single `user/message` replace) satisfies the client builder ordering | `compat-interop` I7 |
|
|
50
|
-
| I8 runtime safety | `rewind`/`compact` combinations never leave a dangling step/turn frame | `verify-host`
|
|
52
|
+
| I8 runtime safety | `rewind`/`compact` combinations never leave a dangling step/turn frame | `verify-host` 13 |
|
|
51
53
|
|
|
52
54
|
## Verified-compatible surfaces (probes pass)
|
|
53
55
|
|
|
@@ -61,6 +63,9 @@ legacy branch).
|
|
|
61
63
|
- **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`).
|
|
62
64
|
- **agent-loop cancellation**: `finally` guarantees step/turn closure; the rewind force-stop path leaves no dangling frame.
|
|
63
65
|
- **settings-card registration**: the Snapshot cleanup card must be registered through a **nested** `ctx.inject(['settingsScope'], …)` — naming `settingsScope` in the module-level inject would keep the whole client plugin unmounted on a host without that service (card and rewind button would disappear). It reads `getSnapshot().value` + `set`, never the `mutate` write API.
|
|
66
|
+
- **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`.
|
|
67
|
+
- **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`.
|
|
68
|
+
- **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`.
|
|
64
69
|
|
|
65
70
|
- **`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.
|
|
66
71
|
- **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`.
|
|
@@ -78,6 +83,7 @@ legacy branch).
|
|
|
78
83
|
- **Files written but uncommitted in a cancelled turn**: a `both` rewind cannot restore them (tool side-effect timing; same as Claude Code).
|
|
79
84
|
- **Attachment files left after a message is shadowed**: attachment storage is not cleaned with the surface (`dsh-attachment-local` not installed, not automatically verified).
|
|
80
85
|
- **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`.
|
|
86
|
+
- **Bundle card metadata is not localizable (`0.1.6-alpha.2`)**: the manager titles a bundle with `shortName(pkg.name)` (`dsh-rewind-plugin` → `rewind-plugin`) and shows the raw `package.json` description; only its private `BUILTIN_COPY` (three official bundles) is translated, and `DshManifest` carries no title/description field. Its rows section renders for every bundle, official included. Only the description is the plugin's to set; nothing is compensated.
|
|
81
87
|
|
|
82
88
|
- **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.
|
|
83
89
|
|
|
@@ -108,13 +114,13 @@ The plugin treats these as harness-side defects it does not compensate for. Each
|
|
|
108
114
|
command descriptions). The plugin's `t()` design is retained; localized host output is treated
|
|
109
115
|
as an upstream capability to be restored when the harness provides it. (This is still not a
|
|
110
116
|
plugin deviation: the client localizes only the six first-party descriptions in
|
|
111
|
-
`
|
|
117
|
+
`HOST_FACES` — compact, export, feedback, goal, permission, plan — while every
|
|
112
118
|
third-party description, this plugin's included, passes through verbatim.)
|
|
113
119
|
- **Client-side command-description i18n is first-party-only**: DSH also localizes host command
|
|
114
120
|
descriptions through the client `locale` binding (`ui-commands`), but the description keys come
|
|
115
|
-
from a **closed allowlist** (`
|
|
121
|
+
from a **closed allowlist** (`HOST_FACES`: compact, export, feedback, goal,
|
|
116
122
|
permission, plan). A command outside that set — every third-party plugin — is passed through
|
|
117
|
-
verbatim, never translated (`
|
|
123
|
+
verbatim, never translated (`builtinRowFace` only rewrites a description that equals the
|
|
118
124
|
first-party English copy). So the plugin's own `/rewind` command description can never ride this
|
|
119
125
|
channel either; it is authored in the host's tongue (English by default), same as the host
|
|
120
126
|
runtime copy above.
|
|
@@ -124,7 +130,7 @@ The plugin treats these as harness-side defects it does not compensate for. Each
|
|
|
124
130
|
> **Root cause (harness-side)**: an unclosed step left by a crash makes token-meter replay
|
|
125
131
|
> reject any later step activity. DSH `0.1.1-rc.2` now auto-closes crash-left step/turn/tool
|
|
126
132
|
> boundaries at load via `interruptedTurnClosers` (`dsh-session`, consumed by
|
|
127
|
-
> `
|
|
133
|
+
> `packages/core/agent-loop/src/index.ts:907`) — **the crash path is fixed**.
|
|
128
134
|
>
|
|
129
135
|
> **Plugin guard (attempted and reverted)**: a `hasOpenStep` + `planRewind` pre-refusal was
|
|
130
136
|
> implemented (`open-step`) but misjudged on **real session logs** (normal rewinds refused, GUI
|
|
@@ -135,19 +141,19 @@ The plugin treats these as harness-side defects it does not compensate for. Each
|
|
|
135
141
|
|
|
136
142
|
#### Concrete `step/start` trigger paths (source-confirmed)
|
|
137
143
|
|
|
138
|
-
The tree has exactly **one** `append('step/start')` producer: `packages/core/agent-loop/src/agent.ts:
|
|
144
|
+
The tree has exactly **one** `append('step/start')` producer: `packages/core/agent-loop/src/agent.ts:303`
|
|
139
145
|
(no other producer inside the official packages; `session/end-seed` etc. only truncate torn writes,
|
|
140
146
|
not logically-unclosed steps).
|
|
141
147
|
|
|
142
148
|
| # | Trigger path | Plausibility | Basis |
|
|
143
149
|
|---|---|---|---|
|
|
144
|
-
| P1 | **Abnormal process termination**: `step/start` is batched to disk (write-behind, `maxDelayMs` per batch) → the step is mid-execution (LLM stream/tool, seconds to minutes) → SIGKILL / OOM-kill / power loss / WSL hard-close → `step/end` (in `finally`, only runs while the process is alive) is never persisted | **Most realistic** | `agent.ts:
|
|
150
|
+
| P1 | **Abnormal process termination**: `step/start` is batched to disk (write-behind, `maxDelayMs` per batch) → the step is mid-execution (LLM stream/tool, seconds to minutes) → SIGKILL / OOM-kill / power loss / WSL hard-close → `step/end` (in `finally`, only runs while the process is alive) is never persisted | **Most realistic** | `agent.ts:313` finally; write-behind batching; torn-write fix truncates only a half-written line |
|
|
145
151
|
| P2 | **Third-party plugin bug**: only the official agent-loop produces one, but external plugins may `session.append('step/start', …)` and never close it | possible | public `Session.append` |
|
|
146
152
|
| P3 | **Manual session-file editing**: edit `~/.dsh/…/session.jsonl[.zstd]` (zstd needs decompress/recompress; plaintext config edits directly) | possible but laborious | `persistence-jsonl/format.ts` (`JsonlCompression = 'zstd' \| 'none'`) |
|
|
147
|
-
| P4 | **append itself failing**: `append('step/end')` in `finally` throws (payload is plain numbers, nearly impossible) | theoretical | `agent.ts:
|
|
153
|
+
| P4 | **append itself failing**: `append('step/end')` in `finally` throws (payload is plain numbers, nearly impossible) | theoretical | `agent.ts:313` |
|
|
148
154
|
|
|
149
155
|
**Amplifier (rewind is not the only trigger)**: after a crash resume, agent-loop `turn()` opens a
|
|
150
|
-
new turn at `phase.turn + 1` (`agent.ts:
|
|
156
|
+
new turn at `phase.turn + 1` (`agent.ts:277-283`) **without closing the leftover step** — so
|
|
151
157
|
"continue the conversation" (a new `step/start`) trips the same token-meter check. Scope:
|
|
152
158
|
|
|
153
159
|
- **The conversation itself is unaffected** (the request path does not call `tokenMeter.measure`; only compaction-basic does tree-wide).
|
|
@@ -35,6 +35,7 @@ console filter:
|
|
|
35
35
|
| `refill` | The composer refill after a rewind (command/wait/refill throws, a rejected or unmatched command, an outcome that never settles) |
|
|
36
36
|
| `preview` | The `/rewind preview` impact probe behind the mode popover (command rejected/unmatched/threw, an outcome that never settles) |
|
|
37
37
|
| `portals` | Per-message button mount issues (e.g. no session binding) |
|
|
38
|
+
| `retract` | The pending-steering retract path (the remove lost the race, or the remove threw) |
|
|
38
39
|
| `settings` | The snapshot-cleanup settings card |
|
|
39
40
|
| `hiding` | **Reserved** — no active alert at present. If a future row-hiding diagnostic is added, it belongs in this region. |
|
|
40
41
|
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
| `refill` | 回退后的输入框回填(命令/等待/回填抛出异常、命令被拒绝或未匹配、等待的结果始终未落定) |
|
|
26
26
|
| `preview` | 模式气泡背后的 `/rewind preview` 影响探测(命令被拒绝/未匹配/抛出异常、等待的结果始终未落定) |
|
|
27
27
|
| `portals` | 每条消息按钮的挂载问题(如无会话绑定) |
|
|
28
|
+
| `retract` | 插话撤回路径(remove 竞争失败,或 remove 抛错) |
|
|
28
29
|
| `settings` | 快照清理设置卡片 |
|
|
29
30
|
| `hiding` | **保留区**——当前无活跃告警。若未来新增行隐藏诊断,应归属此区域。 |
|
|
30
31
|
|
|
@@ -21,7 +21,7 @@ the plugin itself uses (it never reads the DOM or host copy):
|
|
|
21
21
|
```ts
|
|
22
22
|
import { hiddenSeqsOf, type HiddenChat } from 'dsh-rewind-plugin/client'
|
|
23
23
|
|
|
24
|
-
const chat = uiConversation.binding(sessionId).target('chat')?.getSnapshot() // the
|
|
24
|
+
const chat = uiConversation.binding(sessionId).target('chat')?.getSnapshot() // the `uiConversation` "chat" view
|
|
25
25
|
const hidden = hiddenSeqsOf(chat as HiddenChat) // Set<number> of anchor seqs
|
|
26
26
|
```
|
|
27
27
|
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
```ts
|
|
21
21
|
import { hiddenSeqsOf, type HiddenChat } from 'dsh-rewind-plugin/client'
|
|
22
22
|
|
|
23
|
-
const chat = uiConversation.binding(sessionId).target('chat')?.getSnapshot() //
|
|
23
|
+
const chat = uiConversation.binding(sessionId).target('chat')?.getSnapshot() // `uiConversation` 的 "chat" 视图
|
|
24
24
|
const hidden = hiddenSeqsOf(chat as HiddenChat) // 被隐藏的 anchor seq 集合
|
|
25
25
|
```
|
|
26
26
|
|
package/docs/format.md
CHANGED
|
@@ -7,7 +7,7 @@ and this spec disagree, the code wins and this spec is a bug.
|
|
|
7
7
|
|
|
8
8
|
## State root
|
|
9
9
|
|
|
10
|
-
The store root defaults to `<
|
|
10
|
+
The store root defaults to `<dsh home>/rewind-snapshots/` — the dsh data
|
|
11
11
|
directory (`~/.dsh/rewind-snapshots/` when `DSH_HOME` is unset) — overridable in
|
|
12
12
|
order by the `snapshotDir` plugin config, then the `DSH_REWIND_SNAPSHOT_DIR`
|
|
13
13
|
environment variable. It is a sibling of the workspace, never a subtree of it.
|
|
@@ -46,7 +46,7 @@ Deleting the root only removes file backups; the store rebuilds from scratch.
|
|
|
46
46
|
- `store` is the session's store-format marker (a decimal version, written
|
|
47
47
|
atomically); a missing marker means the released v1 string format. `format` is
|
|
48
48
|
the DSH **session**-format marker the snapshots were anchored under (see
|
|
49
|
-
`
|
|
49
|
+
`SECURITY.md`) — the two are independent.
|
|
50
50
|
|
|
51
51
|
## Checkpoint entry
|
|
52
52
|
|
|
@@ -37,8 +37,8 @@ Also under `docs/` at the repo root: `persistence-catalog.md` (full
|
|
|
37
37
|
| `CommandDefinition`, `CommandInvocation` | [packages/interaction/commands/src/index.ts](https://github.com/deepseek-ai/deepseek-harness/blob/main/packages/interaction/commands/src/index.ts) |
|
|
38
38
|
| `Agent` (`status` / `session`) | [packages/core/agent/src/runtime-types.ts](https://github.com/deepseek-ai/deepseek-harness/blob/main/packages/core/agent/src/runtime-types.ts) |
|
|
39
39
|
| `tools/pre-execute` / `execute` / `post-execute` | [packages/core/tools/src/index.ts](https://github.com/deepseek-ai/deepseek-harness/blob/main/packages/core/tools/src/index.ts) |
|
|
40
|
-
| Client DOM anchors (`data-chat-flow-kind` / `data-chat-anchor-key`) | [packages/client/ui-
|
|
41
|
-
| User bubble rendering | [packages/client/ui-
|
|
40
|
+
| Client DOM anchors (`data-chat-flow-kind` / `data-chat-anchor-key`) | [packages/client/ui-chat/src/client/chat/ChatNodeSeat.tsx](https://github.com/deepseek-ai/deepseek-harness/blob/main/packages/client/ui-chat/src/client/chat/ChatNodeSeat.tsx) |
|
|
41
|
+
| User bubble rendering | [packages/client/ui-chat/src/client/chat/MessageItem.tsx](https://github.com/deepseek-ai/deepseek-harness/blob/main/packages/client/ui-chat/src/client/chat/MessageItem.tsx) |
|
|
42
42
|
| Client `SessionFace` (`command` / `cancel`) | [packages/api/session-controller/src/client/contract/session.ts](https://github.com/deepseek-ai/deepseek-harness/blob/main/packages/api/session-controller/src/client/contract/session.ts) |
|
|
43
43
|
| Client pending interaction (SessionPendingInteraction) | [packages/client/ui-session/src/client/index.ts](https://github.com/deepseek-ai/deepseek-harness/blob/main/packages/client/ui-session/src/client/index.ts) |
|
|
44
44
|
|
|
@@ -61,7 +61,9 @@ src/client/index.ts client plugin: /rewind command decoration + per-message
|
|
|
61
61
|
src/client/popover.ts mode-selection popover (both-mode impact confirm)
|
|
62
62
|
src/client/hidden.ts withdrawn-span computation (hiddenSeqsOf), pure
|
|
63
63
|
src/client/candidates.ts rewind candidate listing (rewindCandidatesOf), pure
|
|
64
|
-
src/client/pending.ts pending-steering bubble ↔
|
|
64
|
+
src/client/pending.ts pending-steering bubble ↔ inbox next-step (user-sourced) matching, pure
|
|
65
|
+
src/client/portals.tsx per-user-message ↶ button portals (React bridge into the actions row)
|
|
66
|
+
src/client/settings-card.tsx snapshot-cleanup form on the bundle page (plugins.bundle.config)
|
|
65
67
|
src/client/locales.ts zh / en copy (LocaleNamespaceMap)
|
|
66
68
|
src/client/styles.ts injected styles (dsh design tokens)
|
|
67
69
|
src/client/build-info.ts client build identity (__DSH_REWIND_VERSION__ / __DSH_REWIND_BUILD__)
|
|
@@ -70,6 +72,7 @@ scripts/build.mjs esbuild: lib/index.js (host ESM) + lib/client.js (loader
|
|
|
70
72
|
scripts/check-dsh-version.mjs DSH peer-tuple check (latest dist-tag vs peers)
|
|
71
73
|
scripts/update-badge.mjs regenerate the tests badge (CI only)
|
|
72
74
|
scripts/verify-host.mjs end-to-end host verification (full check suite)
|
|
75
|
+
scripts/session-decode.mjs / session-encode.mjs `.jsonl.zstd` codec (test fixtures)
|
|
73
76
|
tests/ vitest suites (rewind / snapshot / hidden / session-cwd / integration)
|
|
74
77
|
docs/ maintainer docs: contract/, compat/, release/ subdirectories
|
|
75
78
|
assets/screenshots/ UI screenshots
|
package/docs/release/release.md
CHANGED
|
@@ -43,9 +43,9 @@ The line being released determines the branch and the bump:
|
|
|
43
43
|
|
|
44
44
|
| Release | Branch | Bump | dist-tag |
|
|
45
45
|
| --- | --- | --- | --- |
|
|
46
|
-
| Stable patch (current line) | `release
|
|
46
|
+
| Stable patch (current line) | `release/<line>.x` | `npm version patch` | `latest` |
|
|
47
47
|
| Pre-release (next line) | `main` | `npm version prerelease --preid=alpha` | `alpha` |
|
|
48
|
-
| Stable (next line) | `main` | `npm version
|
|
48
|
+
| Stable (next line) | `main` | `npm version <next>` | `latest` |
|
|
49
49
|
|
|
50
50
|
Each release is `git push <branch>` followed by `git push <branch> --tags`.
|
|
51
51
|
|
|
@@ -79,7 +79,9 @@ outside it.
|
|
|
79
79
|
|
|
80
80
|
- **When to update**: when the verified range changes — a new DSH tuple, or a
|
|
81
81
|
deliberate narrowing (e.g. dropping the internal `alpha` series); a release
|
|
82
|
-
already inside the range changes nothing
|
|
82
|
+
already inside the range changes nothing **unless it changes interfaces inside
|
|
83
|
+
the tuple** (`0.1.6-alpha.2` removed the client session-ownership and
|
|
84
|
+
queue-mirror APIs, so the floor moved with it). All `@deepseek-ai/*` packages
|
|
83
85
|
release together; `npm view @deepseek-ai/dsh dist-tags` is the signal.
|
|
84
86
|
- **Published-tuple check (optional)**: `node scripts/check-dsh-version.mjs`
|
|
85
87
|
compares the `latest` dist-tag version against the tuple the peers cover
|
|
@@ -93,11 +95,10 @@ outside it.
|
|
|
93
95
|
`^0.1.x`); this section can then be deleted.
|
|
94
96
|
- **Declared minimum (`dsh.engines.dsh`)**: alongside the peer tuple, each
|
|
95
97
|
release declares the DSH runtime floor under `dsh.engines.dsh` (e.g.
|
|
96
|
-
`>=0.1.2-rc.1`)
|
|
98
|
+
`>=0.1.2-rc.1`). Nothing reads it on the current line yet, so it is a
|
|
99
|
+
forward-looking declaration rather than an enforced guard. Bump it in
|
|
97
100
|
the same release that changes the peer range; never leave code raised while
|
|
98
|
-
the declared floor stays behind. Only the `>=X.Y.Z[-pre]` form is
|
|
99
|
-
supported (`^`/`~`/multi-range are treated as "cannot verify" and
|
|
100
|
-
fail closed).
|
|
101
|
+
the declared floor stays behind. Only the `>=X.Y.Z[-pre]` form is used.
|
|
101
102
|
|
|
102
103
|
## Versioned-line release model
|
|
103
104
|
|
|
@@ -131,8 +132,7 @@ dist-tag named by its pre-release identifier (`0.9.0-alpha.1` → `alpha`,
|
|
|
131
132
|
|
|
132
133
|
**Support window / EOL.** A DSH line is supported within a declared window. By
|
|
133
134
|
default the window runs until the next DSH line ships as `latest`; after that
|
|
134
|
-
the line is EOL, frozen, and receives no further patches.
|
|
135
|
-
(`0.1.2-rc.1`) is supported until `0.9.x` (`0.1.3`) ships as `latest`.
|
|
135
|
+
the line is EOL, frozen, and receives no further patches.
|
|
136
136
|
|
|
137
137
|
**Bug-fix flow (forward-fix then backport).** A fix affecting multiple supported
|
|
138
138
|
lines is applied on `main` first, then backported to each still-supported
|
|
@@ -40,9 +40,9 @@ npm publish --access public
|
|
|
40
40
|
|
|
41
41
|
| 发布类型 | 分支 | 版本步进 | dist-tag |
|
|
42
42
|
| --- | --- | --- | --- |
|
|
43
|
-
| 当前线稳定补丁 | `release
|
|
43
|
+
| 当前线稳定补丁 | `release/<line>.x` | `npm version patch` | `latest` |
|
|
44
44
|
| 下一线 pre-release | `main` | `npm version prerelease --preid=alpha` | `alpha` |
|
|
45
|
-
| 下一线正式版 | `main` | `npm version
|
|
45
|
+
| 下一线正式版 | `main` | `npm version <next>` | `latest` |
|
|
46
46
|
|
|
47
47
|
每次发布为 `git push <分支>`,再 `git push <分支> --tags`。
|
|
48
48
|
|
|
@@ -69,8 +69,10 @@ DSH 仍在 rc 阶段,npm 的 prerelease 匹配规则要求 peer 范围与宿
|
|
|
69
69
|
**每一条 DSH 线一个 peer 元组**(如 `^0.1.2-rc.1`);范围是保守的,只声明实际验证过的内容。
|
|
70
70
|
|
|
71
71
|
- **何时需要更新**:**已验证范围**变化时——DSH 发新元组,或主动收窄(例如不再
|
|
72
|
-
声明内测的 DSH `alpha`
|
|
73
|
-
|
|
72
|
+
声明内测的 DSH `alpha` 系列);落在已声明范围内的发布不改变任何东西,**除非它在
|
|
73
|
+
同一元组内改变了接口**(`0.1.6-alpha.2` 删除了客户端会话所有权与 queue 镜像
|
|
74
|
+
API,下限随之移动)。DSH 所有包同版本发布;信号是
|
|
75
|
+
`npm view @deepseek-ai/dsh dist-tags`。
|
|
74
76
|
- **已发布元组检查(可选)**:`node scripts/check-dsh-version.mjs` 用 npm `latest`
|
|
75
77
|
dist-tag 版本对比 peer 覆盖的元组(exit 0 无需动作,exit 1 需要)。它**只读
|
|
76
78
|
`latest` tag**;发布在其它 tag 的 pre-release 走**手动发布前检查**
|
|
@@ -80,10 +82,9 @@ DSH 仍在 rc 阶段,npm 的 prerelease 匹配规则要求 peer 范围与宿
|
|
|
80
82
|
- **正式版后收敛**:DSH 发布 final 版本后,正式版不受 prerelease 元组规则
|
|
81
83
|
限制,peer 可收敛为稳定的 `^0.1.x` 单范围,此节即可删除。
|
|
82
84
|
- **声明的最低运行时(`dsh.engines.dsh`)**:与 peer 元组一起,每个发布在
|
|
83
|
-
`dsh.engines.dsh` 声明 DSH 运行时下限(如 `>=0.1.2-rc.1
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
「无法校验」而 fail-closed)。
|
|
85
|
+
`dsh.engines.dsh` 声明 DSH 运行时下限(如 `>=0.1.2-rc.1`)。当前线上还没有
|
|
86
|
+
任何读取方,因此它只是前置声明、尚未被强制执行。**与 peer 范围持平的同一发布里
|
|
87
|
+
一并 bump**;不可只升代码、声明下限停留在旧值。仅使用 `>=X.Y.Z[-pre]` 形式。
|
|
87
88
|
|
|
88
89
|
## 发布版本线模型
|
|
89
90
|
|
|
@@ -111,8 +112,7 @@ pre-release 发到与其 pre-release 标识符同名的 dist-tag(`0.9.0-alpha.
|
|
|
111
112
|
`alpha`、`0.9.0-rc.1` → `rc`)。pre-release 不占据 `latest`。
|
|
112
113
|
|
|
113
114
|
**支持窗口 / EOL。** 一条 DSH 线仅在声明的窗口内受支持。默认窗口到下一
|
|
114
|
-
DSH 线作为 `latest` 发布为止;此后该线 EOL
|
|
115
|
-
(`0.1.2-rc.1`)支持到 `0.9.x`(`0.1.3`)作为 `latest` 发布为止。
|
|
115
|
+
DSH 线作为 `latest` 发布为止;此后该线 EOL、冻结、不再发补丁。
|
|
116
116
|
|
|
117
117
|
**Bug 修复流程(先向前修,再回迁)。** 跨多条支持线的修复,先在 `main` 上
|
|
118
118
|
修复,再回迁到各仍受支持的 release 分支。仅特定线的修复,只在对应线修复。
|
package/docs/rewind-fix.md
CHANGED
|
@@ -18,7 +18,7 @@ The plugin is prepared in two parts, both shipped in the new version:
|
|
|
18
18
|
|
|
19
19
|
1. **New rewind markers use the new shape** (forward) — this is a **correct, low-risk**, long-term change aligned with the official `/compact` design (see the [README](../README.en.md), the "How it works" section), and the new shape is fully compatible with **both old and new** DSH.
|
|
20
20
|
|
|
21
|
-
2. **The `/dsh-rewind-fix` command** (backward) — for **already-existing** old sessions, the plugin
|
|
21
|
+
2. **The `/dsh-rewind-fix` command** (backward) — for **already-existing** old sessions, the plugin shipped an update command (removed in plugin `0.10.x`) that translated those old markers into the new shape so the sessions were usable again.
|
|
22
22
|
|
|
23
23
|
This document covers mainly the **update command**.
|
|
24
24
|
|
package/docs/rewind-fix.zh.md
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
1. **新产生的 rewind 标记换成新格式**(向前)——这一步是**正确、低风险**的长期改动(对标官方 `/compact` 设计,见 [README](../README.md)「原理」一节),新格式对**新旧版本** DSH 均完全兼容。
|
|
20
20
|
|
|
21
|
-
2. **提供 `/dsh-rewind-fix`
|
|
21
|
+
2. **提供 `/dsh-rewind-fix` 命令**(向后)——对于**已经存在**的旧会话,本插件曾提供便捷更新命令(已在插件 `0.10.x` 移除),把旧标记「翻译」成新格式,让会话重新可用。
|
|
22
22
|
|
|
23
23
|
本文档主要讲解**更新命令**的使用方法。
|
|
24
24
|
|