@tianyulinfeng1/dsh-plugin-deepseek-chat 1.1.1 → 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.
- package/CHANGELOG.md +137 -67
- package/README.en.md +169 -166
- package/README.md +189 -186
- package/docs/RELEASE_NOTES_v1.1.1.md +64 -64
- package/docs/RELEASE_NOTES_v1.1.2.md +149 -0
- package/docs/login-persistence.md +187 -187
- package/lib/client.js +948 -942
- package/locale/en.json +6 -6
- package/locale/zh.json +6 -6
- package/package.json +68 -67
- package/scripts/patch-dsh-persistent-partition.cjs +174 -174
- package/scripts/patch-dsh-persistent-partition.mjs +16 -16
package/CHANGELOG.md
CHANGED
|
@@ -1,67 +1,137 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to this project are documented here.
|
|
4
|
-
|
|
5
|
-
## 1.1.
|
|
6
|
-
|
|
7
|
-
###
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project are documented here.
|
|
4
|
+
|
|
5
|
+
## 1.1.2 — 2026-11-09
|
|
6
|
+
|
|
7
|
+
### ⚠️ 重点修复:web boot 崩溃(duplicate factory registration)
|
|
8
|
+
|
|
9
|
+
这是 **v1.1.1 的打包回归**:升级到 v1.1.1 后,DSH 桌面版页面在启动阶段
|
|
10
|
+
直接失败、整个界面打不开。用户提供的崩溃日志文件为
|
|
11
|
+
`C:\Users\Administrator\AppData\Roaming\@deepseek-ai\dsh-desktop\logs\crash-2026-11-09T08-27-01-314Z-web-boot.log`。
|
|
12
|
+
|
|
13
|
+
日志环境(原文):`time: 2026-11-09T08:27:01.314Z`、`source: web-boot`、
|
|
14
|
+
`app: @deepseek-ai/dsh-desktop 0.2.2-rc.1`、`win32 x64`、
|
|
15
|
+
`electron 44.7.0`、`node 24.21.0`、`locale zh-CN`。
|
|
16
|
+
|
|
17
|
+
日志中的原始报错文本(原文):
|
|
18
|
+
|
|
19
|
+
> `Error: web boot: 1 entry did not activate`
|
|
20
|
+
>
|
|
21
|
+
> `@tianyulinfeng1/dsh-plugin-deepseek-chat: import failed (see console for the import error)`
|
|
22
|
+
|
|
23
|
+
渲染进程(renderer)控制台的原始报错(原文):
|
|
24
|
+
|
|
25
|
+
> `client-modules: duplicate factory registration for "dsh-plugin-deepseek-chat" (bundle executed twice without invalidate?)`
|
|
26
|
+
|
|
27
|
+
根因链(逐条):
|
|
28
|
+
|
|
29
|
+
1. v1.1.1 把 npm 包名从无 scope 的 `dsh-plugin-deepseek-chat` 改成了带
|
|
30
|
+
scope 的 `@tianyulinfeng1/dsh-plugin-deepseek-chat`(`package.json` 的 `name`)。
|
|
31
|
+
2. 但 `lib/client.js` 里 `window.__ModuleLoader__.load({ id: ... })` 注册的
|
|
32
|
+
工厂 id 仍是旧的短名 `dsh-plugin-deepseek-chat`,**工厂 id 与包名不一致**。
|
|
33
|
+
3. DSH 的 `dsh-client-modules` Host 半侧用 `package.json` 的 `name`(带 scope
|
|
34
|
+
的完整包名)作为 client 图的行 id。
|
|
35
|
+
4. `arrive()` 执行完 bundle 脚本后会检查 `factories.has(<行 id>)`;因为工厂
|
|
36
|
+
实际只注册在短名下,对 `@tianyulinfeng1/dsh-plugin-deepseek-chat` 的检查
|
|
37
|
+
结果为 `false`,Host 便判定该包「没有注册」。
|
|
38
|
+
5. Host 因此把**同一个 bundle 脚本再执行一次**。
|
|
39
|
+
6. 第二次注册时短名 id `dsh-plugin-deepseek-chat` 已存在,于是抛出
|
|
40
|
+
`duplicate factory registration ... (bundle executed twice without invalidate?)`。
|
|
41
|
+
7. 该包被记为 `import failed`,web boot 统计到「1 个 entry 未激活」,抛出
|
|
42
|
+
`Error: web boot: 1 entry did not activate`,**整个页面启动失败**。
|
|
43
|
+
8. 日志里 `dshmarket` 反复 install/remove 只是历史操作记录,**不是**本次崩溃
|
|
44
|
+
的原因。
|
|
45
|
+
|
|
46
|
+
**修改了哪里、为什么能解决**:只改 `lib/client.js` 中
|
|
47
|
+
`window.__ModuleLoader__.load({ id: ... })` 的工厂 `id`,把它从短名
|
|
48
|
+
`dsh-plugin-deepseek-chat` 改为与 `package.json` 的 `name` 完全一致的
|
|
49
|
+
`@tianyulinfeng1/dsh-plugin-deepseek-chat`。对齐之后,`arrive()` 的
|
|
50
|
+
`factories.has(<行 id>)` 在 bundle 执行完即为 `true`,Host 认为该包已正常
|
|
51
|
+
注册,不会再重复执行同一脚本,也就不会出现二次注册和
|
|
52
|
+
`duplicate factory registration`;entry 正常激活,web boot 完成。
|
|
53
|
+
|
|
54
|
+
**回归防护**:`test/check-client.mjs` 新增断言——「工厂 id 必须等于
|
|
55
|
+
`package.json` 的 `name`」。今后再改包名而忘了同步工厂 id,离线自检会立刻
|
|
56
|
+
失败,不会把同样的回归带进发布包。
|
|
57
|
+
|
|
58
|
+
### Verification
|
|
59
|
+
|
|
60
|
+
- 离线自检 35 项全部通过(`RESULT: PASS`),其中包含新增的「工厂 id 必须
|
|
61
|
+
等于 `package.json` 的 `name`」回归断言。
|
|
62
|
+
- 扫描当前 DSH profile 全部 **30 个 web client bundle** 的 id / 包名一致性,
|
|
63
|
+
**0 处不匹配**。
|
|
64
|
+
- 完整发布说明见 `docs/RELEASE_NOTES_v1.1.2.md`。
|
|
65
|
+
|
|
66
|
+
### Packaging
|
|
67
|
+
|
|
68
|
+
- 版本 `1.1.2`,npm 包名保持 `@tianyulinfeng1/dsh-plugin-deepseek-chat` 不变;
|
|
69
|
+
GitHub / Gitee 安装路由不变。
|
|
70
|
+
- 发布产物:`dsh-plugin-deepseek-chat-1.1.2.tgz`(`npm pack` 对 scoped 包的
|
|
71
|
+
原生输出名为 `tianyulinfeng1-dsh-plugin-deepseek-chat-1.1.2.tgz`)。
|
|
72
|
+
- 本次只修 client bundle 的工厂 id,其余功能(固定 guest 分区、账号状态仅
|
|
73
|
+
展示、崩溃隔离等)与 v1.1.1 相同。
|
|
74
|
+
|
|
75
|
+
## 1.1.1 — 2026-11-09
|
|
76
|
+
|
|
77
|
+
### Fixed
|
|
78
|
+
|
|
79
|
+
- **Switching panels/sessions no longer asks for a fresh QR scan.** v1.1.0 keyed the
|
|
80
|
+
desktop guest partition to the asynchronous DSH account probe. DSH's
|
|
81
|
+
`getState()` can transiently fail during a reconnect, so the partition changed
|
|
82
|
+
and handed the panel a brand-new cookie jar. The guest workspace is now the
|
|
83
|
+
constant `panel:deepseek-chat` and the conversation key is the constant
|
|
84
|
+
`dsh-plugin-deepseek-chat:last-url`.
|
|
85
|
+
- The DSH account status strip is now **display only**: it never feeds the lease
|
|
86
|
+
identity, an epoch, or the guest lifecycle. A transient `unknown` is ignored;
|
|
87
|
+
only a confirmed `signed-out` updates the strip.
|
|
88
|
+
- The guest starts on mount immediately instead of waiting for the async account
|
|
89
|
+
Remote, so a failed/late probe never blocks chat.
|
|
90
|
+
|
|
91
|
+
### Documentation
|
|
92
|
+
|
|
93
|
+
- Documented, with source evidence, why a pure plugin **cannot** make
|
|
94
|
+
`chat.deepseek.com` reuse the already-signed-in DSH account: the two use
|
|
95
|
+
different credentials (Platform `x-dsh-auth-token` vs the site's own Token),
|
|
96
|
+
the renderer bridge exposes no token/cookie API, and the archive has no SSO or
|
|
97
|
+
cookie-injection entry point.
|
|
98
|
+
- Reworked `docs/login-persistence.md` around the upstream
|
|
99
|
+
`docs/patch-dsh-persistent-partition.cjs`: DSH `0.2.1-rc.3+` (including
|
|
100
|
+
`0.2.2-rc.1`) ships per-file SHA256 **ASAR integrity**, so the patch must
|
|
101
|
+
recompute and sync `lib/main.js`'s hash. A byte-only replacement would crash
|
|
102
|
+
DSH on restart with "ASAR Integrity Violation".
|
|
103
|
+
- Added `scripts/patch-dsh-persistent-partition.cjs` (upstream script: equal-length
|
|
104
|
+
replacement, integrity re-sync, full-archive verification, `--dry-run`,
|
|
105
|
+
idempotency, automatic backup). The earlier byte-only `.mjs` script is
|
|
106
|
+
deprecated and now fails loudly.
|
|
107
|
+
|
|
108
|
+
### Verification
|
|
109
|
+
|
|
110
|
+
- Offline self-check: 35 cases, all passing (fixed partition, no rebuild on
|
|
111
|
+
account-state churn, partition reuse across panel switches, envelope parsing,
|
|
112
|
+
crash containment, popup allowlist).
|
|
113
|
+
- `app.asar` patch verified independently: 20519 files, 0 integrity failures;
|
|
114
|
+
`lib/main.js` header hash matches the actual SHA256 of the patched bytes.
|
|
115
|
+
|
|
116
|
+
### Packaging
|
|
117
|
+
|
|
118
|
+
- Published to npm as **`@tianyulinfeng1/dsh-plugin-deepseek-chat`** (the
|
|
119
|
+
registry name this project owns). `package.json` and `cordis.patch.yml` now
|
|
120
|
+
carry that scoped package name so an npm-installed copy mounts under the same
|
|
121
|
+
`deepseek-chat` bundle id; the GitHub install routes (`github:sweet560/...`)
|
|
122
|
+
are unchanged.
|
|
123
|
+
|
|
124
|
+
## 1.1.0 — 2026-11-09
|
|
125
|
+
|
|
126
|
+
- Added support for DSH `0.2.2-rc.1` (`engines.dsh >=0.2.2-rc.1`).
|
|
127
|
+
- Added a DSH account status strip via the official `ctx.remote.account` Remote
|
|
128
|
+
(correct generated `{ ok, value }` envelope parsing).
|
|
129
|
+
- Tightened conversation and popup URL validation; removed the dead guest element
|
|
130
|
+
before showing Retry.
|
|
131
|
+
- **Note:** keyed the guest partition to account state, which broke login
|
|
132
|
+
persistence. Fixed in 1.1.1.
|
|
133
|
+
|
|
134
|
+
## 1.0.0
|
|
135
|
+
|
|
136
|
+
First local release: sidebar entry, full-width embedded chat, last-conversation
|
|
137
|
+
memory, and crash containment.
|
package/README.en.md
CHANGED
|
@@ -1,166 +1,169 @@
|
|
|
1
|
-
# dsh-plugin-deepseek-chat
|
|
2
|
-
|
|
3
|
-
English | [中文](README.md)
|
|
4
|
-
|
|
5
|
-
> **Current version: v1.1.
|
|
6
|
-
|
|
7
|
-
Adds a **DeepSeek Chat** entry to the **DeepSeek Harness (DSH) desktop** sidebar. Clicking it opens `chat.deepseek.com` full-width in the main area, remembers the last conversation, and shows the current DSH account state.
|
|
8
|
-
|
|
9
|
-
> Repository: [GitHub](https://github.com/sweet560/dsh-plugin-deepseek-chat) | [Gitee mirror](https://gitee.com/wtt520wyl/dsh-plugin-deepseek-chat)
|
|
10
|
-
|
|
11
|
-

|
|
12
|
-
|
|
13
|
-
## Features
|
|
14
|
-
|
|
15
|
-
- Sidebar icon entry, placed between **Plugins** and **Scheduled tasks**.
|
|
16
|
-
- Full-width embedded `https://chat.deepseek.com/` (Electron `<webview>` through the desktop guest-lease bridge `window.dshDesktop.browser`).
|
|
17
|
-
- **Last-conversation memory**: switching panels/sessions or restarting the app reopens the conversation you left, not a new chat.
|
|
18
|
-
- Auth pages never overwrite that memory; a dead conversation falls back to the site root.
|
|
19
|
-
- **Stable login session (fixed in v1.1.1)**: the guest partition is the constant `panel:deepseek-chat`; switching panels/sessions back no longer rebuilds the partition or asks for a fresh QR scan.
|
|
20
|
-
- **DSH account status**: a strip shows "Synced with the DSH account · name" / "No account" / "Account state unavailable" via the official `ctx.remote.account` Remote. **Display only — it never participates in the guest lifecycle.**
|
|
21
|
-
- **Crash containment**: if the embedded page's process dies, is destroyed, or never starts, the panel shows a Retry card — the app window no longer goes blank (fixed in v0.4.0).
|
|
22
|
-
- Inert on the plain Web surface (`dsh web`): the site sends `frame-ancestors 'none'`, so an iframe cannot carry it, and the guest bridge only exists in the desktop shell.
|
|
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
|
-
|
|
117
|
-
-
|
|
118
|
-
-
|
|
119
|
-
-
|
|
120
|
-
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
|
135
|
-
|
|
136
|
-
| 1.
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
lib/
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
1
|
+
# dsh-plugin-deepseek-chat
|
|
2
|
+
|
|
3
|
+
English | [中文](README.md)
|
|
4
|
+
|
|
5
|
+
> **Current version: v1.1.2** | Targets DSH **0.2.2-rc.1**
|
|
6
|
+
|
|
7
|
+
Adds a **DeepSeek Chat** entry to the **DeepSeek Harness (DSH) desktop** sidebar. Clicking it opens `chat.deepseek.com` full-width in the main area, remembers the last conversation, and shows the current DSH account state.
|
|
8
|
+
|
|
9
|
+
> Repository: [GitHub](https://github.com/sweet560/dsh-plugin-deepseek-chat) | [Gitee mirror](https://gitee.com/wtt520wyl/dsh-plugin-deepseek-chat)
|
|
10
|
+
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
- Sidebar icon entry, placed between **Plugins** and **Scheduled tasks**.
|
|
16
|
+
- Full-width embedded `https://chat.deepseek.com/` (Electron `<webview>` through the desktop guest-lease bridge `window.dshDesktop.browser`).
|
|
17
|
+
- **Last-conversation memory**: switching panels/sessions or restarting the app reopens the conversation you left, not a new chat.
|
|
18
|
+
- Auth pages never overwrite that memory; a dead conversation falls back to the site root.
|
|
19
|
+
- **Stable login session (fixed in v1.1.1)**: the guest partition is the constant `panel:deepseek-chat`; switching panels/sessions back no longer rebuilds the partition or asks for a fresh QR scan.
|
|
20
|
+
- **DSH account status**: a strip shows "Synced with the DSH account · name" / "No account" / "Account state unavailable" via the official `ctx.remote.account` Remote. **Display only — it never participates in the guest lifecycle.**
|
|
21
|
+
- **Crash containment**: if the embedded page's process dies, is destroyed, or never starts, the panel shows a Retry card — the app window no longer goes blank (fixed in v0.4.0).
|
|
22
|
+
- Inert on the plain Web surface (`dsh web`): the site sends `frame-ancestors 'none'`, so an iframe cannot carry it, and the guest bridge only exists in the desktop shell.
|
|
23
|
+
|
|
24
|
+
> **v1.1.2 web boot crash fix**: v1.1.1 renamed the npm package to the scoped `@tianyulinfeng1/dsh-plugin-deepseek-chat`, but the client-bundle factory id in `lib/client.js` stayed the old short name `dsh-plugin-deepseek-chat`. That mismatch made the DSH Host re-execute the same bundle and throw `duplicate factory registration`, ending in `web boot: 1 entry did not activate` and a failed page boot. v1.1.2 aligns the factory id with the full package name and adds a regression assertion that the factory id must equal `package.json`'s `name`. See [docs/RELEASE_NOTES_v1.1.2.md](docs/RELEASE_NOTES_v1.1.2.md).
|
|
25
|
+
|
|
26
|
+
## Requirements
|
|
27
|
+
|
|
28
|
+
| Item | Requirement |
|
|
29
|
+
|---|---|
|
|
30
|
+
| DSH | Desktop `0.2.2-rc.1` or newer |
|
|
31
|
+
| Platform | Windows / macOS / Linux desktop shell |
|
|
32
|
+
| git | Only for the GitHub install route (pnpm fetches the repository) |
|
|
33
|
+
|
|
34
|
+
## Install
|
|
35
|
+
|
|
36
|
+
npm package: **`@tianyulinfeng1/dsh-plugin-deepseek-chat`** (the GitHub repository is still named `dsh-plugin-deepseek-chat`).
|
|
37
|
+
|
|
38
|
+
### Option 1 — npm (recommended)
|
|
39
|
+
|
|
40
|
+
```powershell
|
|
41
|
+
dsh plugin --profile desktop add @tianyulinfeng1/dsh-plugin-deepseek-chat
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
You can also enter the package name `@tianyulinfeng1/dsh-plugin-deepseek-chat` in the Plugins page.
|
|
45
|
+
|
|
46
|
+
### Option 2 — Plugins page (GitHub)
|
|
47
|
+
|
|
48
|
+
1. Open DSH desktop and click **Plugins** in the sidebar.
|
|
49
|
+
2. Click **Install a third-party plugin** above the list.
|
|
50
|
+
3. Enter:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
github:sweet560/dsh-plugin-deepseek-chat
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`https://github.com/sweet560/dsh-plugin-deepseek-chat` works too.
|
|
57
|
+
4. Click **Install** and wait for pnpm to finish.
|
|
58
|
+
5. The plugin is enabled automatically; **DeepSeek Chat** appears in the sidebar.
|
|
59
|
+
|
|
60
|
+
### Option 3 — CLI (GitHub)
|
|
61
|
+
|
|
62
|
+
```powershell
|
|
63
|
+
dsh plugin --profile desktop add github:sweet560/dsh-plugin-deepseek-chat
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Then open **Plugins → Installed plugins** and make sure **DeepSeek Chat** is switched on (the CLI only installs the package).
|
|
67
|
+
|
|
68
|
+
### Option 4 — local checkout (development)
|
|
69
|
+
|
|
70
|
+
```powershell
|
|
71
|
+
dsh plugin --profile desktop add file:"<absolute path to this repository>"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Why the web chat cannot reuse the DSH sign-in
|
|
75
|
+
|
|
76
|
+
**A pure plugin cannot make chat.deepseek.com reuse the already-signed-in DSH account.** This is an architecture limit of DSH 0.2.2-rc.1, verified against its source:
|
|
77
|
+
|
|
78
|
+
| | DSH desktop account | chat.deepseek.com web |
|
|
79
|
+
|---|---|---|
|
|
80
|
+
| Credential | platform.deepseek.com `x-dsh-auth-token` (Host-only `getPlatformSession()`) | the site's own Token (`api/v0/users/current` returns `40002 Missing Token` without it) |
|
|
81
|
+
| Storage | Host credential store | httpOnly cookie in the guest session |
|
|
82
|
+
| Exchange | **None** — zero `chat.deepseek.com` references, no SSO, no cookie injection in the whole archive | — |
|
|
83
|
+
|
|
84
|
+
- The renderer bridge `globalThis.dshDesktop` exposes only `browser.acquire/release/onOpenRequested` etc. — **no** `getAuthToken`, cookie write, or "open Platform to fetch token" API. `getAuthToken()` exists only in the desktop shell's embedded Platform view (`usage` / `top_up`) preload, main-frame + origin restricted.
|
|
85
|
+
- The `browserAcquire` IPC only allocates a partition/lease by workspace string; `configureSession()` sets permissions and download interception, **it injects no credentials**. The guest is forced to `sandbox / contextIsolation / webSecurity`.
|
|
86
|
+
- So the DSH account state can only be **displayed**; it cannot become a web-session login. One manual QR sign-in is still required.
|
|
87
|
+
|
|
88
|
+
**What went wrong in v1.1.0 (fixed in v1.1.1)**: the guest partition had been keyed to the asynchronous account probe. DSH's `getState()` can transiently fail during a reconnect or session switch; changing the partition hands the panel a brand-new cookie jar → a fresh QR scan every time you switched back. Now:
|
|
89
|
+
|
|
90
|
+
- `acquire()`'s workspace is the constant `panel:deepseek-chat`, and the conversation key is the constant `dsh-plugin-deepseek-chat:last-url`;
|
|
91
|
+
- account state changes only update the strip — no epoch, no guest rebuild, no partition change;
|
|
92
|
+
- a transient `unknown` is ignored; only a confirmed `signed-out` updates the display;
|
|
93
|
+
- the guest starts on mount immediately, without waiting for the async Remote (a failed probe never blocks chat);
|
|
94
|
+
- popup navigation is allowlisted to `chat.deepseek.com` and `platform.deepseek.com` (HTTPS, default port).
|
|
95
|
+
|
|
96
|
+
> To also avoid re-scanning **after restarting DSH**, run [scripts/patch-dsh-persistent-partition.cjs](scripts/patch-dsh-persistent-partition.cjs) per [docs/login-persistence.md](docs/login-persistence.md) to change DSH's random in-memory partition into a deterministic `persist:` one (an `app.asar` edit — modifying the installed app, at your own risk). **It also syncs the per-file SHA256 ASAR integrity required by 0.2.2-rc.1** — a byte-only replacement (the deprecated `.mjs` script) would crash DSH on restart. It requires fully exiting DSH first. That patch preserves web cookies across restarts; it does not make the web chat reuse the DSH token.
|
|
97
|
+
|
|
98
|
+
## Usage
|
|
99
|
+
|
|
100
|
+
- The first visit shows the chat.deepseek.com sign-in page; sign in once.
|
|
101
|
+
- Within one app run, switching panels or sessions keeps you signed in (fixed partition since v1.1.1).
|
|
102
|
+
- **Sign in again after restarting DSH**: DSH currently gives embedded browsers a random in-memory partition (`dsh-sidebar-browser-<uuid>`, no `persist:` prefix), so cookies are dropped when the process exits. This plugin does not modify DSH's installation files; to sign in once and stay signed in, apply the equal-length byte patch described in **[docs/login-persistence.md](docs/login-persistence.md)**.
|
|
103
|
+
- The conversation URL is stored under the fixed key `dsh-plugin-deepseek-chat:last-url`, so the last conversation is restored after a restart (while signed in and while it still exists).
|
|
104
|
+
|
|
105
|
+
## Persistent login (optional)
|
|
106
|
+
|
|
107
|
+
DSH hands embedded browsers an **in-memory partition** (`dsh-sidebar-browser-${randomUUID()}`, no `persist:` prefix), so every app restart drops the cookies. To sign in once and stay signed in, replace that partition with a fixed `persist:` one inside `resources/app.asar` — the two statements are the same length, so the archive can be patched byte-for-byte in place.
|
|
108
|
+
|
|
109
|
+
Cause, script, verification, rollback and per-platform paths:
|
|
110
|
+
|
|
111
|
+
**→ [docs/login-persistence.md](docs/login-persistence.md)**
|
|
112
|
+
|
|
113
|
+
Note: this modifies the installed application and is outside DSH's support; a DSH update overwrites `app.asar` and the patch must be re-applied (the `Partitions` data survives). Back up first and proceed at your own risk.
|
|
114
|
+
|
|
115
|
+
## Known limitations
|
|
116
|
+
|
|
117
|
+
- chat.deepseek.com detects the Electron embedding and occasionally shows a "usage environment is abnormal" notice. That is site-side behaviour, unrelated to this plugin.
|
|
118
|
+
- Desktop only; `dsh web` in a browser shows no entry.
|
|
119
|
+
- If the site changes its conversation URL scheme (currently `/a/chat/s/<id>`), the memory falls back to the site root.
|
|
120
|
+
- The DSH account status is display-only; it cannot turn the DSH OAuth token into a chat.deepseek.com web session, so the web chat still needs one manual sign-in on first use.
|
|
121
|
+
- `getProfile()` is used only for the display name. If it is temporarily unavailable the strip may lag briefly, but it **never** affects the guest or the login state.
|
|
122
|
+
- Restarting DSH still requires a fresh web sign-in unless the persistent-partition patch in [docs/login-persistence.md](docs/login-persistence.md) is applied.
|
|
123
|
+
|
|
124
|
+
## Crash containment (v0.4.0)
|
|
125
|
+
|
|
126
|
+
Earlier versions could leave the whole app a blank window a second or two after opening the panel, with no crash dialog and no `crash-*.log`.
|
|
127
|
+
|
|
128
|
+
Root cause: React runs effect cleanups after it has removed the DOM, and Electron's `<webview>` throws from `getURL()` once detached. DSH treats any uncaught plugin error as `slot entry crashed in 'root'` and unmounts the root slot — the entire UI.
|
|
129
|
+
|
|
130
|
+
The current implementation guards every guest call behind an `isConnected` check and `try/catch`, reads the URL before removing the element, wraps every event handler, puts a React error boundary around the panel, listens for `render-process-gone` / `destroyed` / `did-fail-load`, and has a 15-second start watchdog. On failure the dead guest element is removed **before** the Retry card, so retrying cannot stack webviews; a listener-registration failure never starts a guest, and popup URLs are allowlisted (v1.1.0).
|
|
131
|
+
|
|
132
|
+
## Version history
|
|
133
|
+
|
|
134
|
+
| Version | Changes |
|
|
135
|
+
|---|---|
|
|
136
|
+
| **1.1.2** | **Fixes the v1.1.1 web boot crash (highlight)**: the client-bundle factory id did not match the npm package name, so DSH re-executed the same bundle, threw `duplicate factory registration`, and failed with `1 entry did not activate` — the whole page would not boot. The factory id in `lib/client.js` is now aligned to `@tianyulinfeng1/dsh-plugin-deepseek-chat`, with a new regression assertion that it must equal `package.json`'s `name`; 35/35 offline checks pass and all 30 client bundles scan with 0 mismatches. See [docs/RELEASE_NOTES_v1.1.2.md](docs/RELEASE_NOTES_v1.1.2.md). |
|
|
137
|
+
| **1.1.1** | **Fixes the "scan the QR code again on every panel switch" regression**: the guest partition and conversation key are constants; account state is display-only and never touches the guest lifecycle; a transient `unknown` is ignored; the guest no longer waits for the async probe; self-check now asserts a fixed partition and no rebuild on state churn (35 cases). Documents why a pure plugin cannot reuse the DSH token. |
|
|
138
|
+
| 1.1.0 | DSH `0.2.2-rc.1`: DSH account status strip; correct generated Remote envelope parsing; stricter conversation and popup URL validation; dead guest removal on failure. **This release keyed the partition to account state and broke login persistence (fixed in 1.1.1).** |
|
|
139
|
+
| 1.0.0 | First local release: sidebar entry, full-width chat, conversation memory, crash containment. |
|
|
140
|
+
|
|
141
|
+
## Development
|
|
142
|
+
|
|
143
|
+
```powershell
|
|
144
|
+
git clone https://github.com/sweet560/dsh-plugin-deepseek-chat.git
|
|
145
|
+
cd dsh-plugin-deepseek-chat
|
|
146
|
+
node test/check-client.mjs
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
`test/check-client.mjs` loads `lib/client.js` in a `node:vm` sandbox with fake React/DOM/bridge objects and checks registration, Remote envelope parsing, a fixed partition/key, no rebuild on account-state churn, partition reuse across panel switches, conversation memory, lease release, popup allowlisting and crash containment.
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
lib/index.js host half (empty; it only gives the client bundle a Loader entry)
|
|
153
|
+
lib/client.js browser half: entry, panel, account status strip, webview lifecycle, crash containment
|
|
154
|
+
cordis.patch.yml bundle patch that inserts this plugin's Loader row
|
|
155
|
+
locale/{zh,en}.json Plugins-page title/description
|
|
156
|
+
icon.svg Plugins-page icon
|
|
157
|
+
docs/login-persistence.md optional byte patch for DSH's in-memory browser partition
|
|
158
|
+
test/check-client.mjs offline self-check
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Uninstall
|
|
162
|
+
|
|
163
|
+
```powershell
|
|
164
|
+
dsh plugin --profile desktop remove @tianyulinfeng1/dsh-plugin-deepseek-chat
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## License
|
|
168
|
+
|
|
169
|
+
[MIT](LICENSE)
|