@tianyulinfeng1/dsh-plugin-deepseek-chat 1.0.0 → 1.1.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.
@@ -0,0 +1,149 @@
1
+ # dsh-plugin-deepseek-chat v1.1.2 发布说明
2
+
3
+ **DeepSeek Harness(DSH)桌面版侧栏「DeepSeek 聊天」面板 —— 修复 v1.1.1 的 web boot 启动失败(duplicate factory registration)。**
4
+
5
+ 本次是一个**紧急修复版本**:v1.1.1 上线后,DSH 桌面版在启动阶段会因为本插件的 client bundle 工厂 id 与包名不一致,重复执行 bundle、抛出 `duplicate factory registration`,最终报 `Error: web boot: 1 entry did not activate`,导致整个页面启动失败。v1.1.2 只修正这一处 id 并加上回归断言,其余功能与 v1.1.1 完全一致。
6
+
7
+ ## Requires(环境要求)
8
+
9
+ | 项 | 要求 |
10
+ |---|---|
11
+ | DSH Desktop | `>= 0.2.2-rc.1`(含 `0.2.2-rc.1`) |
12
+ | Node.js | `>= 20` |
13
+ | 平台 | Windows / macOS / Linux 桌面壳 |
14
+
15
+ ## ⚠️ 重点:修复 `crash-2026-11-09T08-27-01-314Z-web-boot.log` 中的 web boot 启动失败
16
+
17
+ ### 崩溃日志
18
+
19
+ 用户提供的崩溃日志文件:
20
+
21
+ ```
22
+ C:\Users\Administrator\AppData\Roaming\@deepseek-ai\dsh-desktop\logs\crash-2026-11-09T08-27-01-314Z-web-boot.log
23
+ ```
24
+
25
+ 日志头部记录的运行环境(原文):
26
+
27
+ ```
28
+ time: 2026-11-09T08:27:01.314Z
29
+ source: web-boot
30
+ app: @deepseek-ai/dsh-desktop 0.2.2-rc.1
31
+ win32 x64
32
+ electron 44.7.0
33
+ node 24.21.0
34
+ locale zh-CN
35
+ ```
36
+
37
+ 日志中的原始报错文本(原文):
38
+
39
+ ```
40
+ Error: web boot: 1 entry did not activate
41
+ @tianyulinfeng1/dsh-plugin-deepseek-chat: import failed (see console for the import error)
42
+ ```
43
+
44
+ 渲染进程(renderer)控制台中的原始报错(原文):
45
+
46
+ ```
47
+ client-modules: duplicate factory registration for "dsh-plugin-deepseek-chat" (bundle executed twice without invalidate?)
48
+ ```
49
+
50
+ ### 结论先行
51
+
52
+ 这是 **v1.1.1 的打包回归**,与插件的业务逻辑(聊天面板、登录态、账号状态展示、崩溃隔离)无关。日志里 `dshmarket` 反复出现的 install / remove 只是**历史操作记录**,不是本次崩溃的原因;真正的原因是**工厂 id 没有跟着 npm 包名一起改**。
53
+
54
+ ### 逐条根因链
55
+
56
+ 1. **v1.1.1 改了包名**:为了在 npm 上以项目自己拥有的名字发布,v1.1.1 把 `package.json` 的 `name` 从无 scope 的短名 `dsh-plugin-deepseek-chat` 改成了带 scope 的完整包名 `@tianyulinfeng1/dsh-plugin-deepseek-chat`(`cordis.patch.yml` 也同步了这个名字)。
57
+ 2. **工厂 id 没跟着改**:`lib/client.js` 里通过 `window.__ModuleLoader__.load({ id: ..., factory: ... })` 注册浏览器半侧的模块工厂,这个 `id` 在 v1.1.1 中仍然是旧的短名 `dsh-plugin-deepseek-chat`。于是出现了「client 图行 id 用带 scope 包名、工厂注册 id 用短名」的不一致。
58
+ 3. **Host 用包名作图行 id**:DSH 的 `dsh-client-modules` Host 半侧以 `package.json` 的 `name`(即带 scope 的完整包名)作为 client 图中该包那一行的 id。
59
+ 4. **执行后检查失败**:`arrive()` 执行完某个 bundle 脚本之后,会检查 `factories.has(<行 id>)`,用来确认「这个包确实注册过工厂」。由于工厂实际只注册在短名 `dsh-plugin-deepseek-chat` 下,对 `@tianyulinfeng1/dsh-plugin-deepseek-chat` 的检查结果是 `false`,Host 便判定该包**没有注册**。
60
+ 5. **重复执行同一 bundle**:基于「没有注册」的判断,Host 把同一个 bundle 脚本**再执行一次**,试图让它完成注册。
61
+ 6. **二次注册抛错**:第二次执行时,短名 id `dsh-plugin-deepseek-chat` 在工厂表里已经存在,于是抛出 `client-modules: duplicate factory registration for "dsh-plugin-deepseek-chat" (bundle executed twice without invalidate?)`。
62
+ 7. **entry 未激活、页面启动失败**:该包因此被记为 `@tianyulinfeng1/dsh-plugin-deepseek-chat: import failed (see console for the import error)`;web boot 统计到「1 个 entry 未激活」,抛出 `Error: web boot: 1 entry did not activate`。由于 web boot 是页面启动的总入口,**整个页面启动失败**、界面打不开。
63
+
64
+ 一句话:`package.json` 的 `name` 是 Host 认的名字,工厂 id 是 bundle 自己报的名字;两者对不上,Host 就以为包没装好、把脚本跑了两遍,第二遍自己把自己撞死了。
65
+
66
+ ### 修改点与原理
67
+
68
+ **改了哪里**:只修改 `lib/client.js` 中 `window.__ModuleLoader__.load({ id: ... })` 的工厂 `id`,把它从短名 `dsh-plugin-deepseek-chat` 改成与 `package.json` 的 `name` **完全一致**的:
69
+
70
+ ```
71
+ @tianyulinfeng1/dsh-plugin-deepseek-chat
72
+ ```
73
+
74
+ 没有改动包内的任何其他运行时逻辑。
75
+
76
+ **为什么这样能解决**:工厂 id 与 client 图行 id 对齐之后,`arrive()` 在 bundle 执行完做 `factories.has(<行 id>)` 检查时结果为 `true`,Host 认为该包已经正常注册,**不会**再重复执行同一份 bundle 脚本;没有第二次执行,就不会有第二次注册,也就不会抛出 `duplicate factory registration`,该 entry 正常激活,web boot 顺利完成。
77
+
78
+ **回归防护**:`test/check-client.mjs` 新增了一条断言——**「工厂 id 必须等于 `package.json` 的 `name`」**。以后任何人再改包名却忘了同步 `lib/client.js` 的工厂 id,离线自检会立刻失败,同样的回归不会再被带进发布包。
79
+
80
+ ## What's fixed(修复内容)
81
+
82
+ - 修复 v1.1.1 因 client bundle 工厂 id 与 npm 包名不一致导致的 web boot 启动失败(`duplicate factory registration` / `1 entry did not activate`),详见上面的重点段落。
83
+ - 新增「工厂 id == `package.json` 的 `name`」回归断言,防止同类打包回归再次发布。
84
+ - v1.1.1 已修复的登录态问题(固定 guest 分区、账号状态仅展示、崩溃隔离等)在 v1.1.2 中保持不变。
85
+
86
+ ## What changed(逐文件改动)
87
+
88
+ | 文件 | 改动 |
89
+ |---|---|
90
+ | `lib/client.js` | 把 `window.__ModuleLoader__.load({ id: ... })` 的工厂 id 从 `dsh-plugin-deepseek-chat` 改为 `@tianyulinfeng1/dsh-plugin-deepseek-chat`,与 `package.json` 的 `name` 完全一致;源码注释补充了「id 必须等于包名,否则 Host 会重复执行 bundle」的说明。 |
91
+ | `test/check-client.mjs` | 新增回归断言:读取 `package.json` 的 `name`,断言 client bundle 注册的工厂 id 与之相等;离线自检仍为 35 项,全部通过。 |
92
+ | `package.json` | 版本号 `1.1.1` → `1.1.2`(包名、`engines`、安装路由均不变)。 |
93
+ | `CHANGELOG.md` | 新增 `1.1.2` 章节,重点记录崩溃日志、根因、修改点、验证与打包。 |
94
+ | `README.md` / `README.en.md` | 当前版本改为 v1.1.2;功能/版本历史补充 web boot 崩溃修复说明。 |
95
+ | `docs/RELEASE_NOTES_v1.1.2.md` | 本文件,完整发布说明。 |
96
+
97
+ > 注:`lib/client.js` 与 `test/check-client.mjs` 的改动由发布流程的代码负责人完成,本文档仅作如实记录。
98
+
99
+ ## Verification(验证结果)
100
+
101
+ - **离线自检 35 项全部通过**:`node test/check-client.mjs`,输出 `RESULT: PASS`;其中包含新增的「工厂 id 必须等于 `package.json` 的 `name`」回归断言。
102
+ - **全量一致性扫描**:对当前 DSH profile 下全部 **30 个 web client bundle** 逐一核对「工厂 id / 包名」一致性,结果 **0 处不匹配**,确认不存在其他同类隐患。
103
+ - 崩溃日志中复现路径已按上述根因链逐条对照:修复后 `arrive()` 不再重复执行 bundle,`duplicate factory registration` 与 `1 entry did not activate` 不再出现。
104
+
105
+ ## Upgrade(如何升级)
106
+
107
+ > 建议先退出 DSH 桌面版再升级,升级完成后重新启动。已从 v1.1.1(或更早版本)安装的,直接覆盖安装即可;也可先 `remove` 再 `add`。
108
+
109
+ ### 方式一:npm(推荐)
110
+
111
+ ```powershell
112
+ dsh plugin --profile desktop remove @tianyulinfeng1/dsh-plugin-deepseek-chat
113
+ dsh plugin --profile desktop add @tianyulinfeng1/dsh-plugin-deepseek-chat
114
+ ```
115
+
116
+ 插件页「安装第三方插件」里也可以直接填包名 `@tianyulinfeng1/dsh-plugin-deepseek-chat`(会拉取最新版本 `1.1.2`)。
117
+
118
+ ### 方式二:GitHub
119
+
120
+ ```powershell
121
+ dsh plugin --profile desktop add github:sweet560/dsh-plugin-deepseek-chat
122
+ ```
123
+
124
+ 或在插件页「安装第三方插件」中填入 `github:sweet560/dsh-plugin-deepseek-chat` / `https://github.com/sweet560/dsh-plugin-deepseek-chat`。
125
+
126
+ ### 方式三:Gitee 镜像
127
+
128
+ ```powershell
129
+ dsh plugin --profile desktop add https://gitee.com/wtt520wyl/dsh-plugin-deepseek-chat
130
+ ```
131
+
132
+ 或在插件页「安装第三方插件」中填入 Gitee 镜像地址 `https://gitee.com/wtt520wyl/dsh-plugin-deepseek-chat`。
133
+
134
+ ### 方式四:本地 tgz / 目录
135
+
136
+ ```powershell
137
+ dsh plugin --profile desktop add file:"<dsh-plugin-deepseek-chat-1.1.2.tgz 的绝对路径>"
138
+ ```
139
+
140
+ 装完打开 **插件 → 已安装插件**,确认「DeepSeek 聊天」处于启用状态,并确认版本显示为 `1.1.2`。
141
+
142
+ ## Assets(发布产物)
143
+
144
+ - `dsh-plugin-deepseek-chat-1.1.2.tgz` —— 完整可安装的 npm / bundle 包(沿用 v1.1.1 的 Release 附件命名;`npm pack` 对 scoped 包的原生输出名为 `tianyulinfeng1-dsh-plugin-deepseek-chat-1.1.2.tgz`)。
145
+ - `Source code (zip / tar.gz)` —— 由 GitHub / Gitee 自动生成的源码归档。
146
+
147
+ ## Honest limitation(诚实限制)
148
+
149
+ 沿用 v1.1.1 的源码结论:**纯插件无法让 `chat.deepseek.com` 复用 DSH 已登录的账号、做不到免扫码**。DSH 桌面版用的是 platform.deepseek.com 的 `x-dsh-auth-token`,网页版用的是站点自带的 Token;渲染层桥 `globalThis.dshDesktop` 没有读 token / 写 cookie / 打开 Platform 取 token 的 API,归档里也没有 SSO 或 cookie 注入入口。因此首次仍需在网页里扫码登录一次。可选的「持久分区补丁」(见 [login-persistence.md](login-persistence.md))只能让这次登录的 cookie 在重启 DSH 后保留,并不能把 DSH token 兑换成网页登录态。
@@ -0,0 +1,187 @@
1
+ # 让「DeepSeek 聊天」在 DSH 重启后免登录
2
+
3
+ > **TL;DR** — DSH 桌面壳目前给内嵌浏览器的是**内存分区**,进程退出即清空 cookie,所以本插件每次重启都要重新登录。把 `resources/app.asar` 里 `lib/main.js` 的那行分区名改成**固定且带 `persist:` 前缀**的值(等长字节替换 + **同步 ASAR 逐文件 SHA256 integrity**),登录一次后即可长期免登录。本文给出原因、完整步骤、脚本、验证与回滚方式。
4
+ >
5
+ > **版本核对**:已在 DSH Desktop `0.2.2-rc.1`(`app.asar` 版本 `0.2.2-rc.1`,构建提交 `c59d10a`)中核对并**实际应用**:`DesktopBrowserGuests.acquire()` 原本使用 `dsh-sidebar-browser-${randomUUID()}`、无 `persist:` 前缀;该构建 **22102 个文件全部带 integrity**,因此必须使用会重算哈希的 `patch-dsh-persistent-partition.cjs`,纯字节替换会导致 DSH 重启崩溃。补丁后全量校验 20519 文件、0 失败。`dshDesktop.browser` 的 `protocolVersion` 仍为 `1`,`acquire()` 仍返回 `{ lease, partition }`。插件 v1.1.1 要求 DSH ≥ `0.2.2-rc.1`。
6
+ >
7
+ > **两件不同的事,请勿混淆**:
8
+ > - **切换面板/会话回来就要重新扫码** → 这是插件 v1.1.0 的回归(分区被绑到异步账号状态),**v1.1.1 已修复**,无需改 `app.asar`,见 README「关于免扫码的真相」。
9
+ > - **重启 DSH 后要重新扫码** → 这才是本文补丁要解决的问题(内存分区不落盘),需要改 `app.asar`。
10
+ > - **想让网页直接复用 DSH 已登录账号、完全不扫码** → 纯插件做不到(两套 token、渲染层无 token/cookie 通道、归档中 `chat.deepseek.com` 零引用),本文补丁也做不到,它只保留首次扫码后的网页 cookie。
11
+
12
+ ---
13
+
14
+ ## 1. 现象与原因
15
+
16
+ **现象**:在「DeepSeek 聊天」面板登录 chat.deepseek.com 后,关掉 DSH 再打开,又回到登录页。
17
+
18
+ **原因**:DSH 桌面主进程给每个浏览器 guest 分配的是**内存分区**:
19
+
20
+ ```js
21
+ // resources/app.asar → lib/main.js(DesktopBrowserGuests.acquire)
22
+ let partition = this.partitions.get(workspace);
23
+ if (partition === void 0) {
24
+ partition = `dsh-sidebar-browser-${randomUUID()}`; // ← 没有 persist: 前缀
25
+ this.configureSession(session.fromPartition(partition));
26
+ this.partitions.set(workspace, partition);
27
+ }
28
+ ```
29
+
30
+ Electron 的 `partition` 只有在带 `persist:` 前缀时才会把 cookie、localStorage、IndexedDB 等写到磁盘:
31
+
32
+ | 分区名 | 存储位置 | 进程退出后 |
33
+ |---|---|---|
34
+ | `dsh-sidebar-browser-<uuid>` | 内存 | **清空** |
35
+ | `persist:dsh-sidebar-browser-chat-v1` | `…/Partitions/dsh-sidebar-browser-chat-v1/` | **保留** |
36
+
37
+ 而且这里的 `randomUUID()` 每次启动都不同,所以连"跨进程复用同一分区"都做不到。
38
+
39
+ **为什么插件自己解决不了**:分区名由桌面主进程决定,渲染层只能使用桥(`window.dshDesktop.browser.acquire()`)返回的 `partition`,插件无权指定。因此只能在主进程侧改这一行。
40
+
41
+ ---
42
+
43
+ ## 2. 解决思路
44
+
45
+ 把上面那行改成固定名字 + `persist:` 前缀:
46
+
47
+ ```js
48
+ // 修改前(分区名 36 字符,整条语句 50 字节)
49
+ partition = `dsh-sidebar-browser-${randomUUID()}`;
50
+
51
+ // 修改后(分区名同为 36 字符,整条语句同为 50 字节)
52
+ partition = `persist:dsh-sidebar-browser-chat-v1`;
53
+ ```
54
+
55
+ 两条语句**字节数完全相同**(均 50 字节),因此可以在 `app.asar` 里做等长字节替换,ASAR 头部记录的文件偏移与大小都不变。
56
+
57
+ > **⚠️ 关键(0.2.1-rc.3+,含当前 0.2.2-rc.1):必须同步 ASAR integrity**
58
+ > 该构建的 ASAR 头部为**每个文件**记录了 SHA256 `integrity`(`hash` + 按 `blockSize` 分块的 `blocks`),Electron 读取时会校验。实测 0.2.2-rc.1 的 `app.asar` 有 **22102 个文件带 integrity**(`lib/main.js` 单块 4 MiB)。
59
+ > **只替换字节而不重算并重填 `lib/main.js` 的哈希,DSH 重启会直接 `ASAR Integrity Violation` 退出。** 因此不要用「纯字节替换」脚本;必须使用下方会同步哈希并做全量校验的 `patch-dsh-persistent-partition.cjs`(来自上游仓库 sweet560/dsh-plugin-deepseek-chat)。
60
+
61
+ 替换后的效果:
62
+
63
+ - 登录状态写入 `%APPDATA%\@deepseek-ai\dsh-desktop\Partitions\dsh-sidebar-browser-chat-v1\`;
64
+ - 重启 DSH 直接带着 cookie,不再扫码/输密码;
65
+ - 左侧栏「DeepSeek 聊天」和右侧栏内置浏览器**共用**这个分区,两边登录态一致。
66
+
67
+ ---
68
+
69
+ ## 3. 操作步骤(Windows)
70
+
71
+ > 适用于 DSH Desktop `0.2.2-rc.1`(在 Windows 上核对并应用;`0.2.1-rc.2` / `0.2.1-rc.3` 亦适用)。其他版本请先按第 5 节用 `--dry-run` 确认待替换的字符串存在、且 integrity 校验能通过。
72
+ >
73
+ > 注意:`partitions` 是**进程内** Map,按传入 `acquire()` 的 workspace 字符串缓存;`release()` 只销毁 guest、不清 cookie。本插件 v1.1.1 起 workspace 恒为 `panel:deepseek-chat`,补丁后的固定 `persist:` 分区在**同一进程内切换面板**和**重启后同名分区**都能保留 cookie。
74
+
75
+ 1. **完全退出 DSH**:托盘图标右键 → 退出(只关窗口是隐藏到托盘,`app.asar` 仍被独占锁定,脚本会写入失败)。
76
+ 2. **备份** `F:\DeepSeek Harness\resources\app.asar`(脚本会自动生成带时间戳的 `.bak-*`)。
77
+ 3. 用仓库自带的 [scripts/patch-dsh-persistent-partition.cjs](../scripts/patch-dsh-persistent-partition.cjs) 打补丁(Node 18+,零依赖),见下。
78
+ 4. 重新启动 DSH,打开「DeepSeek 聊天」,**扫码登录一次**。
79
+ 5. 退出 DSH 再打开,验证仍是登录状态——此后不再需要扫码。
80
+
81
+ ### 脚本(唯一推荐)
82
+
83
+ 上游仓库配套的 `patch-dsh-persistent-partition.cjs` 已适配逐文件 ASAR integrity,支持 `--dry-run`、幂等重跑、自动备份与**全量哈希校验**:
84
+
85
+ ```powershell
86
+ cd dsh-plugin-deepseek-chat
87
+ $asar = "F:\DeepSeek Harness\resources\app.asar"
88
+
89
+ # 1) 先只看不改:确认目标唯一、等长、全量 integrity 无失败
90
+ node scripts/patch-dsh-persistent-partition.cjs $asar --dry-run
91
+
92
+ # 2) 完全退出 DSH 后应用(自动备份;重算 lib/main.js 的 SHA256 并同步头部)
93
+ node scripts/patch-dsh-persistent-partition.cjs $asar
94
+
95
+ # 3) 已打过补丁时再跑也安全(幂等,会再次全量校验)
96
+ node scripts/patch-dsh-persistent-partition.cjs $asar --dry-run
97
+ ```
98
+
99
+ 成功输出形如:
100
+
101
+ ```
102
+ dry-run: patch would be applied
103
+ integrity: 20519 file(s) verified, 0 failed
104
+ ```
105
+
106
+ 脚本行为:
107
+ - **等长替换**:两条语句均 50 字节,补丁后文件大小不变,ASAR 偏移不受影响;
108
+ - **integrity 同步(关键)**:检测 `lib/main.js` 的 `integrity`,用补丁后的字节重算 SHA256,替换头部 JSON 中的 `hash`/`blocks`(长度不变);多块布局会拒绝而不是猜测;
109
+ - **全量校验**:写入前后遍历所有文件的 integrity 分块逐块核对,任一失败即拒绝写入(实测 0.2.2-rc.1 为 20519 个文件、0 失败);
110
+ - **幂等**:已是补丁态直接返回 0 并复验;
111
+ - **自动备份**:写入前生成 `app.asar.bak-<时间戳>`;
112
+ - **安全兜底**:目标不存在/出现多次、长度不一致、头部 JSON 长度变化、多块 integrity 等情况一律中止。
113
+
114
+ 退出码:`0` 成功或已是补丁态,`1` 拒绝/校验失败,`2` 参数错误。
115
+
116
+ > `scripts/patch-dsh-persistent-partition.mjs` 是早期**纯字节替换**版本,缺少 integrity 同步,会让 0.2.1-rc.3+ 的 DSH 重启崩溃,已废弃(运行即报错退出)。**不要使用**。
117
+
118
+ ### 验证是否生效
119
+
120
+ ```powershell
121
+ # 1) 补丁本身:再跑一次 dry-run,应显示 already patched + 全量 integrity 0 failed
122
+ node scripts/patch-dsh-persistent-partition.cjs "F:\DeepSeek Harness\resources\app.asar" --dry-run
123
+
124
+ # 2) 登录一次后,确认分区目录和 cookie 已落盘
125
+ Get-Item "$env:APPDATA\@deepseek-ai\dsh-desktop\Partitions\dsh-sidebar-browser-chat-v1\Cookies" |
126
+ Select-Object FullName, Length, LastWriteTime
127
+ ```
128
+
129
+ - `already patched` + `integrity: … 0 failed` → ASAR 完整性没问题,重启不会崩;
130
+ - `Cookies` 存在且非 0 → 分区已持久化;
131
+ - 重启 DSH 打开聊天面板仍是登录态 → 完成。
132
+
133
+ ### 回滚
134
+
135
+ ```powershell
136
+ # 先完全退出 DSH
137
+ Copy-Item "F:\DeepSeek Harness\resources\app.asar.bak-<时间戳>" "F:\DeepSeek Harness\resources\app.asar" -Force
138
+ ```
139
+
140
+ 备份是**补丁前**的完整字节副本(含原始 integrity),直接覆盖即可恢复。磁盘上的 `Partitions\dsh-sidebar-browser-chat-v1\` 数据不会被删,之后重新打补丁仍可复用。
141
+
142
+ ---
143
+
144
+ ## 4. 其他平台路径
145
+
146
+ | 平台 | `app.asar` | 分区数据目录 |
147
+ |---|---|---|
148
+ | Windows | `…\DeepSeek Harness\resources\app.asar` | `%APPDATA%\@deepseek-ai\dsh-desktop\Partitions\…` |
149
+ | macOS | `/Applications/DeepSeek Harness.app/Contents/Resources/app.asar` | `~/Library/Application Support/@deepseek-ai/dsh-desktop/Partitions/…` |
150
+ | Linux | `<安装目录>/resources/app.asar` | `~/.config/@deepseek-ai/dsh-desktop/Partitions/…` |
151
+
152
+ macOS 上若应用有代码签名,修改 `app.asar` 可能破坏签名校验,需要自行重新签名或使用未签名构建;替换前请先备份。
153
+
154
+ ---
155
+
156
+ ## 5. 注意事项与风险
157
+
158
+ - **非官方修改**:改动已安装应用的 `app.asar` 不在 DSH 支持范围内,出问题请用备份回滚;请在动手前确认你接受这个风险。
159
+ - **DSH 升级会覆盖 `app.asar`**:每次更新后需要重新执行一次本补丁;`Partitions` 目录里的登录数据不会丢,重新打补丁后照旧免登录。
160
+ - **版本相关 + integrity 是硬性要求**:字符串在不同 DSH 版本可能变化,且 `0.2.1-rc.3+` 起 ASAR 带逐文件 SHA256 integrity。补丁前**必须**用 `--dry-run` 全量体检:
161
+
162
+ ```powershell
163
+ node scripts/patch-dsh-persistent-partition.cjs "F:\DeepSeek Harness\resources\app.asar" --dry-run
164
+ ```
165
+
166
+ 输出 `dry-run: patch would be applied` + `integrity: … 0 failed` 才可打;`target statement not found` 表示该版本已变化或官方已内置 `persist:`。**千万不要用纯字节替换脚本**,否则重启必崩。
167
+ - **等长是硬性要求**:脚本会校验长度,不等长直接中止(修改长度会破坏 ASAR 头部记录的偏移)。若要自定义分区名,必须把名字凑成与 `${randomUUID()}` 等长(`persist:` + `dsh-sidebar-browser-` + 7 字符)。
168
+ - **未来版本**:如果 DSH 官方把 guest 分区改成 `persist:`,就不再需要本补丁——升级后先检查原文是否还在,不在即说明已内置支持。
169
+ - **共享分区**:补丁对**所有**浏览器 guest 生效,左侧聊天面板与右侧内置浏览器会共用同一个持久分区(这是有意为之:两边登录态一致)。若你希望两者隔离,需要改为按 workspace 区分的固定分区名(保持总长度不变)。
170
+
171
+ ---
172
+
173
+ ## 6. 与 DSH 账号的关系(v1.1.1 核对)
174
+
175
+ DSH 自身的登录是 platform.deepseek.com 的 OAuth 授权(Host `deepseekAccount` 服务,`x-dsh-auth-token`),而 chat.deepseek.com 用的是**站点自带的 Token**(`api/v0/users/current` 无 token 返回 `40002 Missing Token`),两者不同源、不同凭据,归档中 `chat.deepseek.com` 零引用、**没有任何官方兑换/SSO/cookie 注入入口**。因此本方案的实际效果是:
176
+
177
+ > 首次用你的 DeepSeek 账号登录一次 chat.deepseek.com,之后长期记住、点开即用;而不是让网页版复用 DSH 的 token。
178
+
179
+ **渲染层也拿不到 DSH token**:`globalThis.dshDesktop` 只暴露 `browser.acquire/release/onOpenRequested` 等,没有 `getAuthToken`、写 cookie、打开 Platform 取 token 的 API;`getAuthToken()` 只存在于桌面壳内嵌 Platform 页(`usage`/`top_up`)的专用 preload 且受主帧 + origin 限制。`browserAcquire` IPC 只按 workspace 分配分区/租约,`configureSession()` 不注入凭据。所以**纯插件无法免扫码**。
180
+
181
+ **v1.1.1 起,本插件的账号状态条仅作展示**:读取 `ctx.remote.account.getState()` / `getProfile()` 显示昵称与登录状态,但**绝不参与 guest 分区或生命周期**。v1.1.0 曾把分区绑到账号状态,导致 `getState()` 瞬时失败就换分区、每次切回面板都要重新扫码——这是已修复的回归,不是「账号同步」的应有行为。
182
+
183
+ 本文的持久分区补丁负责「网页 cookie 不因**重启**丢失」;v1.1.1 的固定分区负责「网页 cookie 不因**切换面板**丢失」。两者都保留首次扫码后的网页会话,都不能把 DSH token 变成网页登录态。
184
+
185
+ ---
186
+
187
+ *本文档基于 DSH Desktop `0.2.2-rc.1` / Windows 核对(原文字符串仍在;早期验证于 `0.2.1-rc.2`);其他版本请以第 5 节的检查结果为准。*
Binary file