dsh-retrace 0.4.25 → 0.4.26
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 +106 -24
- package/README.zh.md +83 -22
- package/bin/retrace.mjs +1 -1
- package/lib/adapter/contract.js +403 -6
- package/lib/adapter/dsh-writer.js +304 -184
- package/lib/adapter/dsh.js +190 -119
- package/lib/archaeology-cli.js +9 -14
- package/lib/artifact-store.js +5 -1
- package/lib/badge.js +2 -2
- package/lib/client.bundle.js +141 -17
- package/lib/client.js +74 -23
- package/lib/close-guard-client.js +2 -2
- package/lib/close-guard.js +8 -8
- package/lib/dynamic-client.js +142 -18
- package/lib/dynamic-host.js +1476 -298
- package/lib/host-core.js +147 -109
- package/lib/http.js +23 -17
- package/lib/index.js +44 -29
- package/lib/interrupt-guard.js +2 -2
- package/lib/marker-carrier.js +408 -0
- package/lib/message-list.js +49 -32
- package/lib/migration-traces.js +142 -0
- package/lib/platform/session-paths.js +236 -0
- package/lib/prewrite-guard.js +24 -56
- package/lib/session-adapter.js +30 -15
- package/lib/span-semantics.js +172 -0
- package/lib/version-index.js +15 -5
- package/lib/versioning.js +11 -5
- package/lib/watchdog.js +25 -21
- package/package.json +3 -5
package/README.md
CHANGED
|
@@ -77,21 +77,6 @@ Full steps in [📦 Installation](#-installation).
|
|
|
77
77
|
| 🧭 | **Jump-to-conversation** | one click from a version to that point in the conversation (auto-loads history, anchor highlight) |
|
|
78
78
|
| 🧹 | **Bounded storage** | snapshots keep the most recent N versions (default 50); throttled background sweep prunes truncated ones |
|
|
79
79
|
|
|
80
|
-
**Close guard (don't lose work by accident)** — before you exit or reload, know what is still running:
|
|
81
|
-
|
|
82
|
-
| | What | |
|
|
83
|
-
|---|---|---|
|
|
84
|
-
| 🛡️ | **Running-work detection** | every session is scanned for live work: agent running, queued inbox items, background jobs, unclosed turns |
|
|
85
|
-
| 📋 | **Running banner** | sessions with live work show a persistent in-page banner (short session code + reasons), so you can see it before quitting |
|
|
86
|
-
| ⚠️ | **Exit prompt** | on plugin dispose (app exit / reload) a Chinese notice lists each running session and why it is considered busy — it only warns, it never cancels your running agent |
|
|
87
|
-
| 🔒 | **Page-close interception (Web)** | `beforeunload` interception: a strong confirm when work is running (details modal, `[仍关闭]` = confirm-and-go), a light confirm otherwise |
|
|
88
|
-
| 🔎 | **Query surface** | `retrace.runningState` (host RPC) + `GET|POST /api/plugins/retrace/runningState` (HTTP) — same shape on both transports |
|
|
89
|
-
|
|
90
|
-
> Desktop note: the Electron shell destroys the window on quit, so the page-level
|
|
91
|
-
> `beforeunload` hook cannot fire there and the host exposes no plugin quit-veto seam —
|
|
92
|
-
> Desktop is covered by the running banner plus the dispose notice; Web gets the full
|
|
93
|
-
> interception.
|
|
94
|
-
|
|
95
80
|
**Why it's different** (the interaction layer — the guarantees above are the storage layer):
|
|
96
81
|
|
|
97
82
|
- 🎯 **Whole-round recall** — removes the input *and* its output (tool rows included), not just a single bubble.
|
|
@@ -129,8 +114,11 @@ The same result with plain file edits and `pnpm` — exactly the steps
|
|
|
129
114
|
> steps below with the dependency line pointing at the folder:
|
|
130
115
|
> `"dsh-retrace": "file:~/plugins/dsh-retrace"`.
|
|
131
116
|
|
|
132
|
-
1. Open the profile manifest (defaults:
|
|
133
|
-
Desktop,
|
|
117
|
+
1. Open the profile manifest (defaults: `<plugin data home>/profiles/desktop`
|
|
118
|
+
on DSH Desktop, `<plugin data home>/profiles/web` for standalone Web — where
|
|
119
|
+
`<plugin data home>` is `$DSH_HOME` when set, otherwise the **active session
|
|
120
|
+
base**, e.g. a newer `DSH_HOME` directory; `~/.dsh/profiles` is only the
|
|
121
|
+
pre-migration fallback) and add **both** the
|
|
134
122
|
dependency and the bundle-layer entry:
|
|
135
123
|
|
|
136
124
|
```json
|
|
@@ -156,7 +144,7 @@ The same result with plain file edits and `pnpm` — exactly the steps
|
|
|
156
144
|
2. Install inside the profile directory:
|
|
157
145
|
|
|
158
146
|
```sh
|
|
159
|
-
cd
|
|
147
|
+
cd "$DSH_HOME/profiles/<name>" && pnpm install # or the active base you use
|
|
160
148
|
```
|
|
161
149
|
|
|
162
150
|
3. Restart DSH Desktop / the `dsh` process (see above).
|
|
@@ -209,7 +197,7 @@ The dynamic host registers the same operations behind the package-private
|
|
|
209
197
|
| **Start a fresh conversation after editing** | off | Hide earlier messages too, so the conversation looks like a fresh start (the whole surface is rewound before re-sending). Default off: only the edited round's context is replaced. |
|
|
210
198
|
| **Hide shadowed messages per marker** | on | On (default): recall/edit/regenerate hide the replaced round per their markers. Off: every message stays visible; markers only show the notice and reference (review the full history). A single marker that would hide more than 40% of the conversation degrades to notice-only (history never silently vanishes). |
|
|
211
199
|
| **Version & artifact snapshots** | on | On: every recall/edit records a version (messages and touched files) powering the timeline and artifact rollback. Off: only rewinds context — no version records, no artifact tracking (lightest). |
|
|
212
|
-
| **Git integration** | on | On: use git to record and roll back when the workspace is a repository (never auto-commits, never touches your branches); non-repo workspaces can enable git from the timeline. Off: built-in snapshots under
|
|
200
|
+
| **Git integration** | on | On: use git to record and roll back when the workspace is a repository (never auto-commits, never touches your branches); non-repo workspaces can enable git from the timeline. Off: built-in snapshots under the plugin data home only — the plugin never touches the workspace git state; features are equivalent. |
|
|
213
201
|
| **Version retention limit** | 50 | File snapshots are kept for the most recent N versions; older ones are pruned automatically (timeline records and the audit trail are always kept). |
|
|
214
202
|
|
|
215
203
|
---
|
|
@@ -257,6 +245,84 @@ The dynamic host registers the same operations behind the package-private
|
|
|
257
245
|
|
|
258
246
|
---
|
|
259
247
|
|
|
248
|
+
## 🔺 Compatibility & upgrade notes
|
|
249
|
+
|
|
250
|
+
`dsh-retrace` is a **bundle plugin**: it plugs into whatever host surface it is
|
|
251
|
+
installed into. A host release that *removes* a package or a client service can
|
|
252
|
+
therefore break an older plugin build even though nothing in that build changed —
|
|
253
|
+
the symptom is usually a failed boot, not a wrong-looking feature.
|
|
254
|
+
|
|
255
|
+
This section exists so you can tell **host-side breakage** from **plugin-side bugs**.
|
|
256
|
+
Read it before filing an issue.
|
|
257
|
+
|
|
258
|
+
### Host-side breaking changes that `0.4.26` adapts to — *not caused by this plugin*
|
|
259
|
+
|
|
260
|
+
1. **`@deepseek-ai/dsh-session` dropped `decodeStorageRecord` from its public export surface (in `0.1.5-rc.1`; the function still exists internally but is no longer exported from the package root and is unreachable via the exports map).**
|
|
261
|
+
`dsh-retrace` itself never imported it, but its dependency `dsh-log-contract` did.
|
|
262
|
+
With no such export the loader aborts with
|
|
263
|
+
`plugin tree failed to load … does not provide an export named 'decodeStorageRecord'`
|
|
264
|
+
and **the whole plugin tree fails to load — not just this plugin**, so the app does
|
|
265
|
+
not start. `0.4.26` requires a `dsh-log-contract` build that decodes through its own
|
|
266
|
+
local compatibility layer instead of the removed host export.
|
|
267
|
+
→ **Dependency note:** needs `dsh-log-contract >= 0.3.12`.
|
|
268
|
+
2. **A client **service** disappeared: `conversationEvents`** — it used to be provided by
|
|
269
|
+
the legacy client runtime `@deepseek-ai/dsh-client-runtime`, which has been removed
|
|
270
|
+
(the string `conversationEvents` no longer occurs anywhere in the host). A plugin whose
|
|
271
|
+
client half still declares that service in `export const inject` never becomes ready:
|
|
272
|
+
its fiber stays **pending**, which the host reports as
|
|
273
|
+
`renderer boot failed (plugins: …): The client Loader did not provide an error message.`
|
|
274
|
+
— no error text at all, the window does not finish starting, and the only way in is to
|
|
275
|
+
disable the plugin.
|
|
276
|
+
`0.4.26` drops the service from `inject` and resolves it **defensively** in `apply`
|
|
277
|
+
(`uiConversation`, falling back to the legacy name), so it runs on hosts that provide
|
|
278
|
+
the new service *and* on older hosts that still provide the old one.
|
|
279
|
+
> Note: declaring a **package** that no longer exists in `dsh.client.inject` is *not*
|
|
280
|
+
> what breaks the boot — the client loader skips unknown entries silently. The
|
|
281
|
+
> breakage comes from the **service name** the plugin waits for.
|
|
282
|
+
|
|
283
|
+
> Both items above are **host-side removals**, documented here on purpose: if you hit
|
|
284
|
+
> either symptom right after a host upgrade, the first question is "does this plugin
|
|
285
|
+
> build predate the removal?", not "what did the plugin break?".
|
|
286
|
+
|
|
287
|
+
### Plugin-side fixes in `0.4.26` (these are ours)
|
|
288
|
+
|
|
289
|
+
- **Data home and session base are now one source.** The plugin previously resolved its
|
|
290
|
+
own data directory through the host's home resolver (`$DSH_HOME` → `~/.dsh`), which
|
|
291
|
+
does not know about a migrated base (for example a newer `DSH_HOME` directory). With
|
|
292
|
+
`$DSH_HOME` unset,
|
|
293
|
+
sessions were read from one base while snapshots and the artifact store were written
|
|
294
|
+
to another. Snapshots, version stores and `verify-install` now follow the **active
|
|
295
|
+
session base**. When `$DSH_HOME` is set, behaviour is unchanged.
|
|
296
|
+
- **No user-visible string hard-codes `~/.dsh` any more** (the settings hint used to say
|
|
297
|
+
snapshots live under `~/.dsh`).
|
|
298
|
+
- Stale peer declarations with no remaining import site removed
|
|
299
|
+
(`@deepseek-ai/dsh-home-paths`, `@deepseek-ai/dsh-client-runtime`).
|
|
300
|
+
|
|
301
|
+
### Upgrading
|
|
302
|
+
|
|
303
|
+
```bash
|
|
304
|
+
dsh plugin --profile desktop add dsh-retrace@0.4.26
|
|
305
|
+
# then restart DSH — plugins are not hot-reloaded
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
If the app **fails to boot after an upgrade**, a single failing plugin can take the
|
|
309
|
+
whole tree down, so recover first and diagnose second:
|
|
310
|
+
|
|
311
|
+
1. remove `dsh-retrace` from the profile's `dsh.profile.bundles` **and** its
|
|
312
|
+
`dependencies` entry, restart, and confirm you can get back in;
|
|
313
|
+
2. read the host log —
|
|
314
|
+
macOS: `~/Library/Application Support/DSH Desktop/logs/host/dsh-<date>.error.log`;
|
|
315
|
+
3. `plugin tree failed to load` is the **host** half; `renderer boot failed` is the
|
|
316
|
+
**client** half. Both name the offending plugin/package — start there.
|
|
317
|
+
|
|
318
|
+
### Pinning
|
|
319
|
+
|
|
320
|
+
Pin an exact plugin version (`dsh-retrace@0.4.26`) and let `dsh-log-contract` resolve to
|
|
321
|
+
`>=0.3.12`. Do not rely on `^0.4` across a host upgrade: compatibility here is decided by
|
|
322
|
+
the **host surface**, not by semver alone.
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
260
326
|
## ⚠️ Requirements & limitations
|
|
261
327
|
|
|
262
328
|
- Only **user messages** can be edited; recall works on user and assistant
|
|
@@ -286,8 +352,24 @@ The dynamic host registers the same operations behind the package-private
|
|
|
286
352
|
- **Real-time watchdog** — snapshots the log at the first sign of concurrent writes.
|
|
287
353
|
- Companion **`dsh-log-contract`**: 30+ offline contract rules + in-place repair
|
|
288
354
|
(`fix --neutralize` / `--clip-crossstep`) for sessions that would fail `/compact`.
|
|
355
|
+
**Close guard (don't lose work by accident)** — before you exit or reload, know what is still running:
|
|
356
|
+
|
|
357
|
+
| | What | |
|
|
358
|
+
|---|---|---|
|
|
359
|
+
| 🛡️ | **Running-work detection** | every session is scanned for live work: agent running, queued inbox items, background jobs, unclosed turns |
|
|
360
|
+
| 📋 | **Running banner** | sessions with live work show a persistent in-page banner (short session code + reasons), so you can see it before quitting |
|
|
361
|
+
| ⚠️ | **Exit prompt** | on plugin dispose (app exit / reload) a Chinese notice lists each running session and why it is considered busy — it only warns, it never cancels your running agent |
|
|
362
|
+
| 🔒 | **Page-close interception (Web)** | `beforeunload` interception: a strong confirm when work is running (details modal, `[仍关闭]` = confirm-and-go), a light confirm otherwise |
|
|
363
|
+
| 🔎 | **Query surface** | `retrace.runningState` (host RPC) + `GET|POST /api/plugins/retrace/runningState` (HTTP) — same shape on both transports |
|
|
364
|
+
|
|
365
|
+
> Desktop note: the Electron shell destroys the window on quit, so the page-level
|
|
366
|
+
> `beforeunload` hook cannot fire there and the host exposes no plugin quit-veto seam —
|
|
367
|
+
> Desktop is covered by the running banner plus the dispose notice; Web gets the full
|
|
368
|
+
> interception.
|
|
369
|
+
|
|
370
|
+
> Command surface: `retrace.runningState` (host RPC) + `GET|POST /api/plugins/retrace/runningState` (HTTP).
|
|
289
371
|
|
|
290
|
-
**What's next** — see the [public roadmap](
|
|
372
|
+
**What's next** — see the [public roadmap](https://github.com/yamingmou/dsh-retrace/blob/main/docs/ROADMAP.md) for the agent
|
|
291
373
|
business-layer plan (runtime guard, interruption governance, ecosystem-facing
|
|
292
374
|
interfaces). This README only describes what is already shipped.
|
|
293
375
|
|
|
@@ -328,7 +410,7 @@ npm pack --dry-run # verify the published file list
|
|
|
328
410
|
> one and only swaps the transport (`host.call` vs the HTTP route) via
|
|
329
411
|
> `__setMessageEditorWire`.
|
|
330
412
|
|
|
331
|
-
PRs and issues are welcome —
|
|
413
|
+
PRs and issues are welcome — a `CONTRIBUTING.md` is coming soon
|
|
332
414
|
and the [issue tracker](https://github.com/yamingmou/dsh-retrace/issues).
|
|
333
415
|
|
|
334
416
|
---
|
|
@@ -338,7 +420,7 @@ and the [issue tracker](https://github.com/yamingmou/dsh-retrace/issues).
|
|
|
338
420
|
Listed on the [dsh-plugin topic](https://github.com/topics/dsh-plugin).
|
|
339
421
|
|
|
340
422
|
Part of the **Agent business layer (production-grade guarantees)** — see the
|
|
341
|
-
[public roadmap](
|
|
423
|
+
[public roadmap](https://github.com/yamingmou/dsh-retrace/blob/main/docs/ROADMAP.md) for the framework-agnostic layer and how
|
|
342
424
|
dsh-retrace is its DeepSeek Harness implementation. Companion components:
|
|
343
425
|
|
|
344
426
|
- [**dsh-log-contract**](https://github.com/yamingmou/dsh-log-contract) — the
|
|
@@ -352,7 +434,7 @@ dsh-retrace is its DeepSeek Harness implementation. Companion components:
|
|
|
352
434
|
> ```sh
|
|
353
435
|
> dsh plugin --profile desktop add github:yamingmou/dsh-retrace
|
|
354
436
|
> # or with pnpm directly into a profile:
|
|
355
|
-
> cd
|
|
437
|
+
> cd "$DSH_HOME/profiles/desktop" && pnpm add github:yamingmou/dsh-retrace
|
|
356
438
|
> ```
|
|
357
439
|
>
|
|
358
440
|
> Then restart DSH Desktop as usual. The `dsh-log-contract` dependency is
|
|
@@ -392,7 +474,7 @@ retrace lineage <session> # parent-chain lineage (A4)
|
|
|
392
474
|
```
|
|
393
475
|
|
|
394
476
|
`<session>` is a full log path or a sessionId (auto-looked-up under
|
|
395
|
-
`~/.dsh/sessions`). All read-only.
|
|
477
|
+
the active session base — `$DSH_HOME/sessions`, else a newer base, else `~/.dsh/sessions`). All read-only.
|
|
396
478
|
|
|
397
479
|
**Session lineage in the fork map (A4, UI)**: the Fork map view header shows the
|
|
398
480
|
current session's `parentSession` chain (session → parent → root, `←` direction).
|
package/README.zh.md
CHANGED
|
@@ -45,7 +45,6 @@ dsh plugin --profile desktop add dshmarket # 只需一次
|
|
|
45
45
|
重启后,悬停任意助手回复 → **↩ / ↻**;任意用户消息 → **✎**。详细步骤见
|
|
46
46
|
[📦 安装](#-安装)。
|
|
47
47
|
|
|
48
|
-
---
|
|
49
48
|
---
|
|
50
49
|
|
|
51
50
|
## 🛡️ 生产级保证(0.4.x 全部已上线)
|
|
@@ -109,8 +108,9 @@ dsh plugin --profile <name> add dsh-retrace
|
|
|
109
108
|
> 然后执行 `dsh plugin --profile desktop add ~/plugins/dsh-retrace`;或按下面步骤,
|
|
110
109
|
> 把依赖行指向该文件夹:`"dsh-retrace": "file:~/plugins/dsh-retrace"`。
|
|
111
110
|
|
|
112
|
-
1. 打开 profile 清单(默认位置:DSH Desktop 为
|
|
113
|
-
独立 Web 为
|
|
111
|
+
1. 打开 profile 清单(默认位置:DSH Desktop 为 `<插件数据家>/profiles/desktop`,
|
|
112
|
+
独立 Web 为 `<插件数据家>/profiles/web` —— 插件数据家在设了 `$DSH_HOME` 时就是它,
|
|
113
|
+
否则跟随**活动会话基座**;`~/.dsh/profiles` 只是迁移前的兜底),同时加入依赖**和** bundle 层条目:
|
|
114
114
|
|
|
115
115
|
```json
|
|
116
116
|
{
|
|
@@ -134,7 +134,7 @@ dsh plugin --profile <name> add dsh-retrace
|
|
|
134
134
|
2. 在 profile 目录里安装:
|
|
135
135
|
|
|
136
136
|
```sh
|
|
137
|
-
cd
|
|
137
|
+
cd "$DSH_HOME/profiles/<name>" && pnpm install # 或你实际使用的基座
|
|
138
138
|
```
|
|
139
139
|
|
|
140
140
|
3. 重启 DSH Desktop / `dsh` 进程(见上文)。
|
|
@@ -180,7 +180,7 @@ Client 半区会依据包内 `dsh.client` 元数据被自动打包进 Web 客户
|
|
|
180
180
|
| **编辑后从新对话开始** | 关 | 编辑后连此前的消息也一并隐藏,让对话看起来像从新消息重新开始(重发前回退整个表面)。默认关:只替换被编辑那一轮的上下文。 |
|
|
181
181
|
| **按标记隐藏被编辑/撤回的消息** | 开 | 开(默认):撤回/编辑/重新生成按标记隐藏被替换的那一轮消息。关:所有消息保持可见,标记仅显示提示与对照(查看完整历史用)。单个 marker 要隐藏超过 40% 的对话时自动降级为不隐藏(历史永不静默消失)。 |
|
|
182
182
|
| **版本与产物快照** | 开 | 开:每次撤回/编辑记录一个版本(消息与触碰文件),提供时间线与产物回退;关:仅回退上下文,不记录版本、不追踪产物(最省资源)。 |
|
|
183
|
-
| **启用 git 集成** | 开 | 开:工作区是 git 仓库时用 git
|
|
183
|
+
| **启用 git 集成** | 开 | 开:工作区是 git 仓库时用 git 记录与回退(不自动提交、不动你的分支),非仓库可在时间线里一键启用;关:一律用内置快照(存于插件数据家),不触碰工作区 git 状态,功能等价。 |
|
|
184
184
|
| **版本保留上限** | 50 | 文件快照只保留最近 N 个版本,超出自动清理最旧的;时间线记录与审计痕迹始终保留。 |
|
|
185
185
|
|
|
186
186
|
---
|
|
@@ -221,6 +221,70 @@ Client 半区会依据包内 `dsh.client` 元数据被自动打包进 Web 客户
|
|
|
221
221
|
|
|
222
222
|
---
|
|
223
223
|
|
|
224
|
+
## 🔺 兼容性与升级须知
|
|
225
|
+
|
|
226
|
+
`dsh-retrace` 是 **bundle 型插件**:它插进哪套宿主,就依赖那套宿主暴露的面。因此宿主
|
|
227
|
+
**移除**一个包或一个客户端服务时,**旧版插件即使一行没改也会坏** —— 而且症状通常是
|
|
228
|
+
「起不来」,不是「某个功能看起来不对」。
|
|
229
|
+
|
|
230
|
+
本节的目的:让你能分清 **宿主侧破坏性变更** 与 **插件侧缺陷**。提 issue 前请先看这节。
|
|
231
|
+
|
|
232
|
+
### `0.4.26` 适配的宿主侧破坏性变更 —— *不是本插件造成的*
|
|
233
|
+
|
|
234
|
+
1. **`@deepseek-ai/dsh-session` 把 `decodeStorageRecord` 从公开导出面拿掉了(`0.1.5-rc.1`;函数仍在内部模块里,但不再从包根导出、exports map 子路径也不可达)。**
|
|
235
|
+
本插件自己从未 import 它,但它的依赖 `dsh-log-contract` import 了。宿主不再导出该符号时,
|
|
236
|
+
加载器会以
|
|
237
|
+
`plugin tree failed to load … does not provide an export named 'decodeStorageRecord'`
|
|
238
|
+
中止,而且**整棵插件树一起失败——不只是本插件**,于是 App 起不来。`0.4.26` 改为要求
|
|
239
|
+
一个通过**自身兼容层**解码、不再依赖该已移除导出的 `dsh-log-contract`。
|
|
240
|
+
→ **依赖说明:** 需要 `dsh-log-contract >= 0.3.12`。
|
|
241
|
+
2. **一个客户端**服务**消失了:`conversationEvents`** —— 它原先由旧客户端运行时
|
|
242
|
+
`@deepseek-ai/dsh-client-runtime` 提供,而该运行时已被移除(`conversationEvents`
|
|
243
|
+
这个串在宿主里**已 0 命中**)。插件的客户端半若仍在 `export const inject` 里声明它,
|
|
244
|
+
就**永远不就绪**:fiber 停在 **pending**,宿主据此报
|
|
245
|
+
`renderer boot failed (plugins: …): The client Loader did not provide an error message.`
|
|
246
|
+
—— **一个字的错误信息都没有**,窗口起不来,唯一的进法是把插件禁用。
|
|
247
|
+
`0.4.26` 已把它从 `inject` 中删掉,并改在 `apply` 里**防御性解析**
|
|
248
|
+
(`uiConversation`,取不到则回退旧名),因此:**既能在提供新服务的宿主上跑,
|
|
249
|
+
也仍兼容还提供旧服务的老宿主**。
|
|
250
|
+
> 注意:在 `dsh.client.inject` 里声明一个**已不存在的包**,**不会**导致启动失败 ——
|
|
251
|
+
> 客户端加载器对认不出的条目是**静默跳过**的。真正致命的是插件等待的那个**服务名**。
|
|
252
|
+
|
|
253
|
+
> 上面两条都是**宿主侧移除**,写在这里是有意的:如果你在**升级宿主之后**立刻遇到这两种症状,
|
|
254
|
+
> 第一个该问的是「这份插件构建是不是早于这次移除?」,而不是「插件改坏了什么?」。
|
|
255
|
+
|
|
256
|
+
### `0.4.26` 里的插件侧修复(这些是我们自己的)
|
|
257
|
+
|
|
258
|
+
- **插件数据家与会话基座合并为同一来源。** 此前插件用宿主的 home 解析器
|
|
259
|
+
(`$DSH_HOME` → `~/.dsh`)决定自己的数据目录,而它不认识迁移后的基座(例如一个更新的 `DSH_HOME` 目录)。
|
|
260
|
+
于是当 `$DSH_HOME` 未设时,**会话从一个基座读、快照与产物库写到另一个基座**。现在快照、
|
|
261
|
+
版本库与 `verify-install` 都跟随**活动会话基座**;`$DSH_HOME` 已设时行为不变。
|
|
262
|
+
- **不再有任何用户可见文案写死 `~/.dsh`**(设置页原先提示快照存于 `~/.dsh`)。
|
|
263
|
+
- 删掉已无任何引用点的陈旧 peer 声明(`@deepseek-ai/dsh-home-paths`、
|
|
264
|
+
`@deepseek-ai/dsh-client-runtime`)。
|
|
265
|
+
|
|
266
|
+
### 升级
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
dsh plugin --profile desktop add dsh-retrace@0.4.26
|
|
270
|
+
# 然后重启 DSH —— 插件不会热重载
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
如果**升级后 App 起不来**:一个插件失败就能拖垮整棵树,所以**先恢复、再排查**:
|
|
274
|
+
|
|
275
|
+
1. 把 `dsh-retrace` 从 profile 的 `dsh.profile.bundles` **和** `dependencies` 里删掉,重启,
|
|
276
|
+
确认能先进得来;
|
|
277
|
+
2. 读宿主日志 —— macOS:`~/Library/Application Support/DSH Desktop/logs/host/dsh-<日期>.error.log`;
|
|
278
|
+
3. `plugin tree failed to load` 是**宿主侧**;`renderer boot failed` 是**客户端侧**。
|
|
279
|
+
两者都会点名出问题的插件/包 —— 从那里查起。
|
|
280
|
+
|
|
281
|
+
### 版本固定建议
|
|
282
|
+
|
|
283
|
+
请固定到确切版本(`dsh-retrace@0.4.26`),并让 `dsh-log-contract` 解析到 `>=0.3.12`。
|
|
284
|
+
**不要在跨宿主升级时依赖 `^0.4` 这种范围**:这里的兼容性由**宿主的面**决定,光看 semver 不够。
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
224
288
|
## ⚠️ 要求与限制
|
|
225
289
|
|
|
226
290
|
- 只有**用户消息**可以编辑;撤回同时适用于用户与助手消息。工具结果会随区间一并
|
|
@@ -233,6 +297,15 @@ Client 半区会依据包内 `dsh.client` 元数据被自动打包进 Web 客户
|
|
|
233
297
|
|
|
234
298
|
---
|
|
235
299
|
|
|
300
|
+
## 🗺️ 路线图
|
|
301
|
+
|
|
302
|
+
**当前已具备(0.4.x):**
|
|
303
|
+
|
|
304
|
+
- 撤回 / 编辑重发 / 重新生成——每次回退都过**三层写前校验**与安全编辑路径(自动停 agent、临时 step 包裹 marker),**不会损坏日志、不会破坏 /compact**。
|
|
305
|
+
- 单会话**版本时间线** + **产物回退**(git 优先 + 快照兜底、干跑预览、跳转对话)。
|
|
306
|
+
- 对话视图内的**分叉图** + **会话谱系**。
|
|
307
|
+
- **实时看门狗**——并发写入第一时间快照日志。
|
|
308
|
+
- 配套 **`dsh-log-contract`**:30+ 条离线契约规则 + 原地修复(`fix --neutralize` / `--clip-crossstep`),能处理会让 /compact 永久失败的会话。
|
|
236
309
|
**关闭守卫(防误关丢进度)** —— 退出/重载前先看清还有什么在跑:
|
|
237
310
|
|
|
238
311
|
| | 是什么 | |
|
|
@@ -246,19 +319,7 @@ Client 半区会依据包内 `dsh.client` 元数据被自动打包进 Web 客户
|
|
|
246
319
|
> 桌面说明:Electron 宿主退出时销毁窗口,页面 `beforeunload` 不会触发,宿主也未暴露
|
|
247
320
|
> 插件可用的退出否决点——桌面侧由运行中横幅 + dispose 提示覆盖;Web 端拦截完整生效。
|
|
248
321
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
## 🗺️ 路线图
|
|
252
|
-
|
|
253
|
-
**当前已具备(0.4.x):**
|
|
254
|
-
|
|
255
|
-
- 撤回 / 编辑重发 / 重新生成——每次回退都过**三层写前校验**与安全编辑路径(自动停 agent、临时 step 包裹 marker),**不会损坏日志、不会破坏 /compact**。
|
|
256
|
-
- 单会话**版本时间线** + **产物回退**(git 优先 + 快照兜底、干跑预览、跳转对话)。
|
|
257
|
-
- 对话视图内的**分叉图** + **会话谱系**。
|
|
258
|
-
- **实时看门狗**——并发写入第一时间快照日志。
|
|
259
|
-
- 配套 **`dsh-log-contract`**:30+ 条离线契约规则 + 原地修复(`fix --neutralize` / `--clip-crossstep`),能处理会让 /compact 永久失败的会话。
|
|
260
|
-
|
|
261
|
-
**未来计划**——见 [公开路线图](./docs/ROADMAP.md)(agent 业务层规划:运行时守护、中断治理、生态开放接口)。本 README 只描述已上线的能力。
|
|
322
|
+
**未来计划**——见 [公开路线图](https://github.com/yamingmou/dsh-retrace/blob/main/docs/ROADMAP.md)(agent 业务层规划:运行时守护、中断治理、生态开放接口)。本 README 只描述已上线的能力。
|
|
262
323
|
|
|
263
324
|
---
|
|
264
325
|
|
|
@@ -296,7 +357,7 @@ npm pack --dry-run # 校验发布文件清单
|
|
|
296
357
|
> 发布版共用同一份 client 源码,仅通过 `__setMessageEditorWire` 切换传输层
|
|
297
358
|
> (`host.call` vs HTTP 路由)。
|
|
298
359
|
|
|
299
|
-
欢迎提交 PR 与 issue ——
|
|
360
|
+
欢迎提交 PR 与 issue —— `CONTRIBUTING.md` 筹备中,先与
|
|
300
361
|
[问题追踪](https://github.com/yamingmou/dsh-retrace/issues)。
|
|
301
362
|
|
|
302
363
|
---
|
|
@@ -305,7 +366,7 @@ npm pack --dry-run # 校验发布文件清单
|
|
|
305
366
|
|
|
306
367
|
收录于 [dsh-plugin topic](https://github.com/topics/dsh-plugin)。
|
|
307
368
|
|
|
308
|
-
**Agent 业务层(生产级保证)** 的一部分——见 [公开路线图](
|
|
369
|
+
**Agent 业务层(生产级保证)** 的一部分——见 [公开路线图](https://github.com/yamingmou/dsh-retrace/blob/main/docs/ROADMAP.md)
|
|
309
370
|
(框架无关的业务层定义,dsh-retrace 是它在 DeepSeek Harness 上的实现)。配套组件:
|
|
310
371
|
|
|
311
372
|
- [**dsh-log-contract**](https://github.com/yamingmou/dsh-log-contract) —— 业务层的
|
|
@@ -317,7 +378,7 @@ npm pack --dry-run # 校验发布文件清单
|
|
|
317
378
|
> ```sh
|
|
318
379
|
> dsh plugin --profile desktop add github:yamingmou/dsh-retrace
|
|
319
380
|
> # 或直接用 pnpm 装进 profile:
|
|
320
|
-
> cd
|
|
381
|
+
> cd "$DSH_HOME/profiles/desktop" && pnpm add github:yamingmou/dsh-retrace
|
|
321
382
|
> ```
|
|
322
383
|
>
|
|
323
384
|
> 然后照常重启 DSH Desktop。`dsh-log-contract` 依赖会自动带上。
|
|
@@ -354,7 +415,7 @@ retrace file-diff <session> <path> 0 5 # 两版本行级 diff(A3)
|
|
|
354
415
|
retrace lineage <session> # 会话 parent 链谱系(A4)
|
|
355
416
|
```
|
|
356
417
|
|
|
357
|
-
<session> 为完整日志路径或 sessionId
|
|
418
|
+
<session> 为完整日志路径或 sessionId(自动在**活动会话基座**查找:`$DSH_HOME/sessions`,否则更新的基座,最后才是 `~/.dsh/sessions`)。全部只读。
|
|
358
419
|
|
|
359
420
|
**分叉图里的会话谱系(A4, UI)**:Fork map 视图头部展示当前会话的
|
|
360
421
|
`parentSession` 接续链(当前会话 → 父 → 根,`←` 方向)。数据来自
|
package/bin/retrace.mjs
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* retrace lineage <session> [--json]
|
|
18
18
|
* 会话 parent 链谱系(A4,分叉图数据源)
|
|
19
19
|
*
|
|
20
|
-
* <session> 为完整文件路径或 sessionId
|
|
20
|
+
* <session> 为完整文件路径或 sessionId(按 sessions 基座候选查找:$DSH_HOME/~/.dsh/~/dsh-v3)。
|
|
21
21
|
*/
|
|
22
22
|
import fs from 'node:fs';
|
|
23
23
|
import { loadSessionLog, extractToolOutputs, auditToolCalls } from 'dsh-log-contract';
|