dsh-deepseek-import 0.1.2 → 0.2.0
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 +230 -230
- package/README.zh.md +277 -264
- package/cordis.patch.yml +4 -0
- package/dsh-import.cmd +65 -65
- package/dsh-import.mjs +2 -1
- package/icon.svg +6 -0
- package/index.js +105 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +25 -2
- package/repair-session.mjs +219 -219
package/README.zh.md
CHANGED
|
@@ -1,264 +1,277 @@
|
|
|
1
|
-
# DSH 对话迁移
|
|
2
|
-
|
|
3
|
-
[English](README.md) | 中文
|
|
4
|
-
|
|
5
|
-
从 **Edge** 抓取 `chat.deepseek.com` 的对话(单个或多个),导出 JSON,再由本地脚本重建为 DeepSeek Harness 的可继续会话。
|
|
6
|
-
|
|
7
|
-
```
|
|
8
|
-
Edge 扩展 ──导出──▶ dsh-deepseek-*.json ──dsh-import.cmd──▶ ~/.dsh/sessions + workspace.json
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## 安装
|
|
12
|
-
|
|
13
|
-
需要 **Node.js 22+**(会话压缩用了内置 zstd)。
|
|
14
|
-
|
|
15
|
-
```powershell
|
|
16
|
-
# 从 npm(发布后)
|
|
17
|
-
npm i -g dsh-deepseek-import
|
|
18
|
-
dsh-import --list
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
`
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
node dsh-import.mjs
|
|
117
|
-
node dsh-import.mjs
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
-
|
|
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
|
-
|
|
165
|
-
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
**
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
1
|
+
# DSH 对话迁移
|
|
2
|
+
|
|
3
|
+
[English](README.md) | 中文
|
|
4
|
+
|
|
5
|
+
从 **Edge** 抓取 `chat.deepseek.com` 的对话(单个或多个),导出 JSON,再由本地脚本重建为 DeepSeek Harness 的可继续会话。
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
Edge 扩展 ──导出──▶ dsh-deepseek-*.json ──dsh-import.cmd──▶ ~/.dsh/sessions + workspace.json
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 安装
|
|
12
|
+
|
|
13
|
+
需要 **Node.js 22+**(会话压缩用了内置 zstd)。
|
|
14
|
+
|
|
15
|
+
```powershell
|
|
16
|
+
# 从 npm(发布后)
|
|
17
|
+
npm i -g dsh-deepseek-import
|
|
18
|
+
dsh-import --list
|
|
19
|
+
# 或直接用源码,不装全局
|
|
20
|
+
git clone https://github.com/Hungry-M/dsh-deepseek-import.git
|
|
21
|
+
cd dsh-deepseek-import
|
|
22
|
+
node dsh-import.mjs --list
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
扩展必须单独加载(见下一节)——浏览器扩展没法随 npm 包一起装。
|
|
26
|
+
|
|
27
|
+
### 作为 DSH 插件安装(可选)
|
|
28
|
+
|
|
29
|
+
同一个包也是 DSH 的 Host 插件,装上后可以直接在对话里让模型导入:
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
dsh plugin add dsh-deepseek-import
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
它会注册工具 `import_deepseek_chat`,之后一句话就行:
|
|
36
|
+
|
|
37
|
+
> 把 `D:\Downloads\dsh-import\dsh-deepseek-20261103.json` 导入到当前工作区
|
|
38
|
+
|
|
39
|
+
插件只负责「导入」,**扩展仍需单独加载**。新会话在侧栏下次刷新时出现;若没出现,重启 DSH。
|
|
40
|
+
|
|
41
|
+
## 一、安装扩展(一次性)
|
|
42
|
+
|
|
43
|
+
1. Edge 地址栏打开 `edge://extensions/`
|
|
44
|
+
2. 打开左下角 **开发人员模式**
|
|
45
|
+
3. 点 **加载解压缩的扩展**,选择本目录下的 `edge-extension` 文件夹
|
|
46
|
+
4. 固定到工具栏(可选)
|
|
47
|
+
|
|
48
|
+
## 二、抓取对话
|
|
49
|
+
|
|
50
|
+
1. 在 Edge 打开 `chat.deepseek.com` 的任意对话,**等它加载完**(消息出现即可)。
|
|
51
|
+
2. 点扩展图标,列表里会出现这条对话(标题 + 消息条数)。
|
|
52
|
+
3. 想看多条:逐个打开对话,每次都会自动捕获,列表累积。
|
|
53
|
+
4. 勾选要导出的对话 → **导出选中** → 保存 JSON。
|
|
54
|
+
|
|
55
|
+
> 原理:扩展在页面主世界给 `fetch`/XHR 挂了只读嗅探,只读取 DeepSeek 自己的响应体,不发额外请求、不上传任何东西。
|
|
56
|
+
> 如果某条对话没被捕获,打开它然后点扩展的 **抓取对话**(会按「本地缓存 → 逐屏回溯 → 当前屏」依次尝试)。
|
|
57
|
+
|
|
58
|
+
### 超长对话怎么抓全
|
|
59
|
+
|
|
60
|
+
DeepSeek 的长对话是**分页加载**的,每次只能看到一屏。扩展做了两件事:
|
|
61
|
+
|
|
62
|
+
1. **按消息身份合并**:每页消息带 `message_id`,扩展把它当唯一键取并集,再按 id 排序。所以往上翻、往下翻、重复抓同一页,都只会**累加**,不会覆盖已经拿到的部分。
|
|
63
|
+
2. **抓取对话**:一个按钮搞定三种来源——先读浏览器本地缓存(IndexedDB 里有全量),读不到再逐屏向上回溯,最后退回只抓当前屏。
|
|
64
|
+
|
|
65
|
+
> 为什么 DOM 只抓到一屏也不怕:滚动时的分页请求会被扩展嗅探到,那份数据是带 id 的完整消息;DOM 抓取只是补充。
|
|
66
|
+
|
|
67
|
+
## 三、导入到 DSH
|
|
68
|
+
|
|
69
|
+
双击工作区里的 **`dsh-import.cmd`**,或把 JSON 拖到它上面。
|
|
70
|
+
|
|
71
|
+
- 会列出 DSH 里的工作区,选序号决定导入到哪个工作区
|
|
72
|
+
- 每个对话重建为一个会话,标题、顺序、正文(含代码块/表格等 Markdown)原样保留
|
|
73
|
+
- **附件**(图片、txt、pdf、docx…):**仅当数据源带附件时**才落盘到 `<工作区>/.dsh-imported/<sessionId>/`,保留原文件名;下载不到时退化成 `[附件未下载:文件名(大小) 原链接]`,由你本机匹配。DeepSeek 的 IndexedDB 缓存副本通常不含附件
|
|
74
|
+
- **思考过程**写进同目录的 `thinking.md`(旁挂存档,不进入对话上下文)
|
|
75
|
+
- **编辑/重新生成留下的多个版本**:正文只保留当前分支,全部版本写进同目录的 `revisions.md`
|
|
76
|
+
- 改动 `workspace.json` 前自动备份为 `workspace.json.bak-<时间>`
|
|
77
|
+
- 所有输出同时写进 `import.log`,窗口一闪而过也能查原因
|
|
78
|
+
|
|
79
|
+
### 重要:导入后要重启 DSH
|
|
80
|
+
|
|
81
|
+
侧边栏列表读自 `~/.dsh/storages/workspace.json`,DSH **只在启动时加载**。导入完成后请**完全退出并重新打开** DeepSeek Harness,否则新会话不会出现。
|
|
82
|
+
|
|
83
|
+
如果重启后还是看不到,顺序改成:**先完全退出 DSH → 再双击 `dsh-import.cmd` → 再启动 DSH**。因为 DSH 运行时可能用内存里的旧列表覆盖 `workspace.json`。
|
|
84
|
+
|
|
85
|
+
### 配置(CLI / TUI / 扩展共用一套约定)
|
|
86
|
+
|
|
87
|
+
`import.config.json`(与本文件同目录):
|
|
88
|
+
|
|
89
|
+
```json
|
|
90
|
+
{ "downloadDir": "D:\\Downloads", "subdir": "dsh-import", "lang": "zh" }
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
| 字段 | 作用 |
|
|
94
|
+
|---|---|
|
|
95
|
+
| `downloadDir` | 去哪个目录找导出文件(默认读系统真实下载目录) |
|
|
96
|
+
| `subdir` | 下载子目录约定:扩展存到 `<下载目录>/<subdir>/`,CLI/TUI 也扫这里 |
|
|
97
|
+
| `lang` | `zh` / `en`,影响 TUI 与扩展界面 |
|
|
98
|
+
| `autoTrim` | 默认 `true`:超过阈值的长对话自动截断 |
|
|
99
|
+
| `autoTrimChars` | 触发阈值,默认 `120000` 字 |
|
|
100
|
+
| `autoTrimTurns` | 最多保留轮数,默认 `20` |
|
|
101
|
+
| `autoTrimBudget` | 保留部分的字符预算,默认 `60000` 字(从最后一条往前累加到超预算) |
|
|
102
|
+
|
|
103
|
+
`--no-auto-trim` 可单次关闭;`--tail N` 显式指定保留轮数。
|
|
104
|
+
|
|
105
|
+
旁挂文件默认写在 `<工作区>/.dsh-imported/`,可以改位置:`--no-sidecar`(写到 `~/.dsh/import-archive/`)或 `--sidecar-dir <路径>`。
|
|
106
|
+
|
|
107
|
+
旁挂文件的位置也能在设置里选:勾 **旁挂文件写到 DSH 目录** 就不往工作区写 .dsh-imported(等价于 CLI 的 `--no-sidecar`)。
|
|
108
|
+
|
|
109
|
+
这四个参数也可以在**扩展的 ⚙ 设置**里改:勾选框控制开关,下面的「高级参数」是默认折叠的,里面是三个数字。扩展会把它们写进导出 JSON 的 `options`,导入时按这个优先级生效:
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
命令行参数 > 导出文件里的 options(扩展设置) > import.config.json > 内置默认值
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
```powershell
|
|
116
|
+
node dsh-import.mjs --set-dir "E:\chat" # 写入配置
|
|
117
|
+
node dsh-import.mjs --dir "E:\chat" # 只本次生效,不改配置
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
扩展侧:面板右上 ⚙ → **保存子目录**(留空=直接存下载目录)。浏览器不允许扩展写任意绝对路径,所以「共享」靠的是这个子目录约定,而不是写死某个盘符。
|
|
121
|
+
|
|
122
|
+
### 命令行接口(给 AI / 脚本用)
|
|
123
|
+
|
|
124
|
+
```powershell
|
|
125
|
+
node dsh-import.mjs --list # 只列工作区
|
|
126
|
+
node dsh-import.mjs # 自动用下载目录里最新的导出
|
|
127
|
+
node dsh-import.mjs 导出.json -w "D:\proj" # 直接指定工作区
|
|
128
|
+
node dsh-import.mjs 导出.json --dry-run # 只解析不写盘
|
|
129
|
+
node dsh-import.mjs 导出.json --thinking # 另外把思考塞进正文(默认只写 thinking.md)
|
|
130
|
+
node dsh-import.mjs 导出.json --json # 机器可读输出:{ok, workspace, created[]}
|
|
131
|
+
node dsh-import.mjs 导出.json --keep-versions # 保留编辑前的旧版本(默认只留当前分支)
|
|
132
|
+
node dsh-import.mjs 导出.json --keep-interrupted # 保留不完整的中断输出(默认只留编号占位符)
|
|
133
|
+
node dsh-import.mjs 导出.json --only "<对话 id>" # 只导指定对话(逗号分隔可多个)
|
|
134
|
+
node dsh-import.mjs 导出.json --from-match "某句话" # 从匹配到的用户消息开始分支
|
|
135
|
+
node dsh-import.mjs 导出.json --from-index 157 # 按消息序号分支
|
|
136
|
+
node dsh-import.mjs --audit # 体检已导入会话(system 头是否完好)
|
|
137
|
+
node dsh-import.mjs --repair # 批量修掉有隐患的会话
|
|
138
|
+
|
|
139
|
+
> --tail 与 --from-index/--from-match 互斥(一个是取最后 N 轮,一个是从指定位置开始),同时给出会直接报错退出;--from-* 只能用于单个对话。
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### 中断输出怎么处理
|
|
143
|
+
|
|
144
|
+
被手动中止的回答,默认在会话里只留一行带编号的占位符:
|
|
145
|
+
|
|
146
|
+
```
|
|
147
|
+
[中断输出 #2:未产生完整正文,思考过程见 thinking.md]
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
- 编号来自 `message_id`,用来证明「这里确实有过一次中断输出」
|
|
151
|
+
- 思考照常进 `thinking.md`
|
|
152
|
+
- 加 `--keep-interrupted` 才保留原始的不完整正文;正文本来就空的仍然用占位符
|
|
153
|
+
- 识别依据:消息的 `status` 不是 `FINISHED`、或 `incomplete_message` 为真、或正文为空;老数据没有 `status` 时只能靠「正文为空」判断
|
|
154
|
+
|
|
155
|
+
### 从某条消息开始分支
|
|
156
|
+
|
|
157
|
+
想把会话“截断”在某个位置重新开始,而不是只用最后 N 轮:
|
|
158
|
+
|
|
159
|
+
```powershell
|
|
160
|
+
node dsh-import.mjs 导出.json --from-match "照你的顺序来吧"
|
|
161
|
+
node dsh-import.mjs 导出.json --from-index 157
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
- `--from-match` 在**用户消息**里做不区分大小写的全文匹配,命中第一条
|
|
165
|
+
- 同一句话被编辑过、出现多次时,TUI 会把它们按时间顺序编号列出来让你选:
|
|
166
|
+
```
|
|
167
|
+
1 #158 照你的顺序来吧,只要你不忘记清单。…
|
|
168
|
+
2 #160 照你的顺序来吧,只要你不忘记清单。…
|
|
169
|
+
选择序号(回车=1,共 2 条匹配):
|
|
170
|
+
```
|
|
171
|
+
- 选了分支点就不再自动截断(尊重你的选择),完整原文照样写进 `transcript.md`
|
|
172
|
+
|
|
173
|
+
### 超长对话别整段导入
|
|
174
|
+
|
|
175
|
+
一份 227 条、52 万字符的对话大约 25–35 万 tokens,直接导入必然超过上下文窗口。DSH 会自动压缩(`dsh-compaction-basic`),但压缩后只逐字保留约 16% 的近期内容,其余变成摘要——等于白导。
|
|
176
|
+
|
|
177
|
+
```powershell
|
|
178
|
+
node dsh-import.mjs 导出.json --tail 20
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
- 只导入**最后 20 轮**,全文另存 `.dsh-imported/<sessionId>/transcript.md`
|
|
182
|
+
- 第一条消息里会附一行说明 + 旁挂文件索引,模型需要早期细节时可以自己 grep 那个文件
|
|
183
|
+
- 超过 15 万字符的对话即使不加 `--tail` 也会自动留一份 `transcript.md`
|
|
184
|
+
|
|
185
|
+
`dsh-import.mjs` 同时是模块,可被引用:```js
|
|
186
|
+
import { runImport, getWorkspaces, listExports, peekExport } from './dsh-import.mjs';
|
|
187
|
+
await runImport({ files: ['x.json'], workspacePath: 'D:\\proj', only: ['<对话 id>'] });
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### 交互界面
|
|
191
|
+
|
|
192
|
+
```powershell
|
|
193
|
+
node dsh-import-tui.mjs
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
菜单流程:选导出文件(带大小/时间)→ 预览对话(条数/字数/思考段数/附件数)→ 多选(`all`、`1,3`、`1-2`)→ 选工作区 → 确认导入。
|
|
197
|
+
|
|
198
|
+
### 旁挂文件怎么被读到
|
|
199
|
+
|
|
200
|
+
导入时会在**第一条用户消息末尾**附一行索引:
|
|
201
|
+
|
|
202
|
+
```
|
|
203
|
+
[导入存档(需要时可直接读取):思考 2 段 → .dsh-imported/<sessionId>/thinking.md;附件 → .dsh-imported/<sessionId>/]
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
这些文件都在工作区目录内,后续对话里模型可以随时用文件工具按需读取(不会自动塞进上下文)。
|
|
207
|
+
|
|
208
|
+
## 常见问题
|
|
209
|
+
|
|
210
|
+
**复制工作区后 DSH 列表全空?**
|
|
211
|
+
DSH 要求 **Session ID 全局唯一**,同一个 ID 出现在两个项目目录会让整个会话列表加载失败(`duplicate JSONL session id`)。`copy-workspace.mjs` 现在会为每条复制出的会话**重新生成 UUID**,并同步改写 header 与事件里的引用。改完先体检再启动:
|
|
212
|
+
|
|
213
|
+
```powershell
|
|
214
|
+
node check-sessions.mjs
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
它会检查重复 ID、目录名与 header.id 是否一致、每帧能否解压、seq 是否连续、workspace.json 与磁盘是否对账。退出码 0 才启动 DSH。
|
|
218
|
+
|
|
219
|
+
如果已经出了重复,把冲突的项目目录整体移出 `~/.dsh/sessions`(DSH 只扫这一层),再从 workspace.json 移除对应条目,重启即可恢复——原会话文件不会损坏。
|
|
220
|
+
|
|
221
|
+
**双击 cmd 提示「找不到 Node.js」?**
|
|
222
|
+
脚本按这个顺序找:`node-path.txt`(同目录,可手写一行路径)→ PATH → `Program Files\nodejs` → `Program Files (x86)\nodejs` → `%LOCALAPPDATA%\Programs\nodejs` → `%APPDATA%\npm` → 同目录的 `node.exe`。都没命中就装一个 Node 22+,或把 `node.exe` 放到脚本旁边。
|
|
223
|
+
|
|
224
|
+
**cmd 到底会导入哪个文件?**
|
|
225
|
+
不带参数:`~/Downloads` 里**最新**的 `dsh-deepseek-*.json`。也可以把文件(或整个文件夹)拖到 cmd 上,或自己传多个路径。工作区是运行时从 `workspace.json` 列出来让你选序号的。
|
|
226
|
+
|
|
227
|
+
**测试时要不要删掉 Downloads 里的旧 json?**
|
|
228
|
+
不用。脚本只取最新一份,旧的不会混进来。想批量导入就拖多个文件上去,或传一个目录(目录里所有 `.json` 都会被读)。
|
|
229
|
+
|
|
230
|
+
**双击 cmd,窗口一闪而过什么都没发生?**
|
|
231
|
+
旧版本的文件用了 LF 换行,`cmd.exe` 解析失败,脚本根本没执行。现在的版本改用 CRLF,并且无论成败都会停在 `pause`,输出同时写入 `import.log`。如果仍然闪退,直接看 `import.log`。
|
|
232
|
+
|
|
233
|
+
**导入成功但侧边栏没有?**
|
|
234
|
+
先按上面「重要」那段重启;还不行就按「先退出 → 再导入 → 再启动」的顺序来。
|
|
235
|
+
|
|
236
|
+
**正文只抓到一小段?**
|
|
237
|
+
说明命中的不是完整历史接口。打开 DeepSeek 页面 → 点扩展的 **诊断** → 会导出 `dsh-debug-*.json`(含页面请求的 URL、content-type、非 JSON 响应样本)。把它发给我即可定位真实接口。注意:文件里有会话 id 和 URL,介意可自行打码。
|
|
238
|
+
|
|
239
|
+
## 已知限制
|
|
240
|
+
|
|
241
|
+
- **引用与附件取决于数据源**:DeepSeek 的 IndexedDB 缓存副本只保留正文和思考,`references` 表与 `files` 字段通常不在里面。因此 `references.md` 和附件目录**只在数据源带这两类数据时才会生成**,没有生成是正常结果,不是失败。想找回图片只能回原网页另存。
|
|
242
|
+
|
|
243
|
+
- **思考过程旁挂**:写进 `thinking.md`,不进上下文。DSH 的 reasoning 块带 provider 签名,硬塞正文会污染后续请求;想看时直接翻文件,或加 `--thinking` 强制内联。
|
|
244
|
+
- **附件不进 DSH 附件库**:DSH 的图片是内容寻址附件(`~/.dsh/attachments/v1/objects/...`),伪造引用有损坏历史的风险;这里改为落盘 + 路径引用,模型可以用工具读。拿不到下载地址时只留文件名与大小。
|
|
245
|
+
- **正文完整性**:历史接口 `/api/v0/chat/history_messages` 返回的正文可能偏短;回答生成时的 `/api/v0/chat/completion` 是 `text/event-stream` 补丁流(`THINK` 片段=思考,其余片段=正文),扩展会边读边拼,生成完即写入捕获。所以**新回答**是完整的;很久以前的老回答以历史接口返回的内容为准。
|
|
246
|
+
- **只迁移文本与附件**:DeepSeek 工具调用、联网搜索的结果没有结构化导出,只能作为正文的一部分。
|
|
247
|
+
- **会话格式是 DSH 内部实现**(v4 JSONL + zstd,多帧拼接)。DSH 升级若改格式,本工具需要跟着改;导入前建议确认版本。
|
|
248
|
+
- 扩展依赖 DeepSeek 页面自己的接口响应;页面大改版导致捕获不到时,用 **抓取对话** 兜底。
|
|
249
|
+
|
|
250
|
+
## 四、把导入的会话换到别的工作区
|
|
251
|
+
|
|
252
|
+
```powershell
|
|
253
|
+
node move-session.mjs --list # 看每个工作区有哪些会话
|
|
254
|
+
node move-session.mjs <session-id> --to "D:\某个工作区" # 换过去
|
|
255
|
+
node move-session.mjs <session-id> --to "D:\某个工作区" --dry-run # 先看要动什么
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
同时改四处:会话日志里的 `cwd`、会话目录所在的项目文件夹、`workspace.json` 的 `sessionIds`、`.dsh-imported/<id>` 里的附件。改完重启 DSH 生效。
|
|
259
|
+
|
|
260
|
+
## 回滚
|
|
261
|
+
|
|
262
|
+
- 删除会话目录:`~/.dsh/sessions/--<工作区>--/session-<uuid>/`
|
|
263
|
+
- 恢复列表:用同名的 `workspace.json.bak-*` 覆盖 `workspace.json`
|
|
264
|
+
- 单个会话:`node remove-session.mjs <session-id>`
|
|
265
|
+
|
|
266
|
+
## 目录结构
|
|
267
|
+
|
|
268
|
+
```
|
|
269
|
+
edge-extension/
|
|
270
|
+
manifest.json MV3 清单
|
|
271
|
+
inject.js 主世界:只读嗅探 fetch/XHR 响应
|
|
272
|
+
content.js 隔离世界:归一化、DOM 兜底、图片转 dataURL
|
|
273
|
+
background.js 存储捕获结果
|
|
274
|
+
popup.html/js/css 选择与导出界面
|
|
275
|
+
dsh-import.mjs 导出 JSON → DSH 会话
|
|
276
|
+
dsh-import.cmd 双击入口
|
|
277
|
+
```
|
package/cordis.patch.yml
ADDED