dsh-power-menu-mac 0.1.1 → 0.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 +6 -0
- package/lib/helper.cjs +63 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
本项目遵循 [Semantic Versioning](https://semver.org/spec/v2.0.0.html),格式参考 [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)。
|
|
4
4
|
|
|
5
|
+
## [0.1.2] - 2026-10-29
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- 重启 / 关闭时顺手把攒下来的 `dsh-auth-*` cookie 删到只剩最近 3 条。宿主每次启动都会下发一个**新名字**的 `dsh-auth-<随机>` cookie 且从不清理,而 cookie 不区分端口,所有端口上的宿主共用同一批;攒到 71 条时 `Cookie` 请求头就有 16.1 KB,越过 Node 默认的 16 KB 请求头上限,桌面版启动直接报 `desktop welcome: Web authentication failed`(2026-10-29 实测;用电源菜单反复重启会加速这个过程)。清理在 app 退出之后、重启之前进行,用 macOS 自带的 `/usr/bin/sqlite3` 改 Chromium 的 `Cookies` 库;只保留最近 3 条而不是全删,是为了不把同机另一个长期运行的 `dsh web`(浏览器里那个界面)当场登出。
|
|
10
|
+
|
|
5
11
|
## [0.1.1] - 2026-10-29
|
|
6
12
|
|
|
7
13
|
### Fixed
|
package/lib/helper.cjs
CHANGED
|
@@ -89,6 +89,62 @@ function readLaunchArgs() {
|
|
|
89
89
|
const WINDOW_VERIFY_TIMEOUT_MS = 20000
|
|
90
90
|
const WINDOW_POLL_MS = 500
|
|
91
91
|
|
|
92
|
+
/**
|
|
93
|
+
* 保留几条 dsh-auth cookie。见 `pruneAuthCookies`。
|
|
94
|
+
*/
|
|
95
|
+
const AUTH_COOKIE_KEEP = 3
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* app 的 Electron user-data 目录。relaunch 参数里带 `--user-data-dir` 时以它为准,
|
|
99
|
+
* 否则是 Electron 的默认 profile 目录。
|
|
100
|
+
*
|
|
101
|
+
* @param {string[]} argv - 重启时用的 argv。
|
|
102
|
+
* @returns {string} user-data 目录的绝对路径。
|
|
103
|
+
*/
|
|
104
|
+
function userDataDir(argv = []) {
|
|
105
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
106
|
+
const value = String(argv[index])
|
|
107
|
+
if (value === '--user-data-dir' && typeof argv[index + 1] === 'string') return path.resolve(argv[index + 1])
|
|
108
|
+
if (value.startsWith('--user-data-dir=')) return path.resolve(value.slice('--user-data-dir='.length))
|
|
109
|
+
}
|
|
110
|
+
return path.join(os.homedir(), 'Library', 'Application Support', '@deepseek-ai', 'dsh-desktop')
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* 把攒下来的 `dsh-auth-*` cookie 删到只剩最近几条。
|
|
115
|
+
*
|
|
116
|
+
* 宿主每次启动都会下发一个**新名字**的 `dsh-auth-<随机>` cookie,旧的一个都不清;
|
|
117
|
+
* 而 cookie 不区分端口,所有端口上的宿主共用同一批。攒到 71 条时 `Cookie` 请求头
|
|
118
|
+
* 就有 16.1 KB,越过 Node 默认的 16 KB 请求头上限,宿主回 431,桌面壳报
|
|
119
|
+
* "desktop welcome: Web authentication failed"(2026-10-29 实测,重启越频繁越快)。
|
|
120
|
+
*
|
|
121
|
+
* 退出/重启之后 app 已经关了,这时清理是安全的:新实例会自己下发一条新的。
|
|
122
|
+
* 只保留最近 3 条而不是全删,是为了不把同一台机器上另一个长期运行的 `dsh web`
|
|
123
|
+
* (浏览器里那个界面)当场登出。
|
|
124
|
+
*
|
|
125
|
+
* @param {string} label - 日志前缀(shutdown / restart)。
|
|
126
|
+
* @param {string[]} argv - 重启时用的 argv,用来定位 user-data 目录。
|
|
127
|
+
*/
|
|
128
|
+
function pruneAuthCookies(label, argv = []) {
|
|
129
|
+
const db = path.join(userDataDir(argv), 'Cookies')
|
|
130
|
+
if (!fs.existsSync(db)) {
|
|
131
|
+
note(`${label}: no cookie jar at ${db}; nothing to prune`)
|
|
132
|
+
return
|
|
133
|
+
}
|
|
134
|
+
const sql = [
|
|
135
|
+
"delete from cookies where name like 'dsh-auth-%' and rowid not in",
|
|
136
|
+
`(select rowid from cookies where name like 'dsh-auth-%' order by creation_utc desc limit ${AUTH_COOKIE_KEEP});`,
|
|
137
|
+
"select count(*) from cookies where name like 'dsh-auth-%';",
|
|
138
|
+
].join(' ')
|
|
139
|
+
try {
|
|
140
|
+
// macOS 自带 /usr/bin/sqlite3;Chromium 的 Cookies 就是一个 SQLite 库。
|
|
141
|
+
const left = execFileSync('/usr/bin/sqlite3', [db, sql], { encoding: 'utf8', timeout: 8000 }).trim()
|
|
142
|
+
note(`${label}: pruned stale dsh-auth cookies (kept ${left === '' ? '0' : left})`)
|
|
143
|
+
} catch (error) {
|
|
144
|
+
note(`${label}: could not prune dsh-auth cookies: ${String(error?.message ?? error)}`)
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
92
148
|
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))
|
|
93
149
|
|
|
94
150
|
let LOG_PATH = ''
|
|
@@ -401,6 +457,7 @@ async function performShutdown(handoff) {
|
|
|
401
457
|
note('shutdown: host exited on its own')
|
|
402
458
|
}
|
|
403
459
|
await cleanupOrphans(handoff.orphans, 'shutdown', !alive(handoff.hostPid))
|
|
460
|
+
pruneAuthCookies('shutdown', readLaunchArgs())
|
|
404
461
|
note('shutdown: complete')
|
|
405
462
|
}
|
|
406
463
|
|
|
@@ -490,6 +547,11 @@ async function performRestart(handoff) {
|
|
|
490
547
|
await cleanupOrphans(handoff.orphans, 'restart', !alive(handoff.hostPid))
|
|
491
548
|
await sleep(portFree ? 800 : 1500)
|
|
492
549
|
|
|
550
|
+
// The app is gone, so its cookie jar is free to edit. Prune the accumulated
|
|
551
|
+
// dsh-auth cookies before the new instance reads them (see pruneAuthCookies).
|
|
552
|
+
const relaunchArgs = readLaunchArgs()
|
|
553
|
+
pruneAuthCookies('restart', relaunchArgs)
|
|
554
|
+
|
|
493
555
|
const env = { ...process.env }
|
|
494
556
|
for (const key of Object.keys(env)) {
|
|
495
557
|
const upper = key.toUpperCase()
|
|
@@ -523,7 +585,7 @@ async function performRestart(handoff) {
|
|
|
523
585
|
}
|
|
524
586
|
let child = null
|
|
525
587
|
try {
|
|
526
|
-
child = spawn(exe,
|
|
588
|
+
child = spawn(exe, relaunchArgs, {
|
|
527
589
|
detached: true,
|
|
528
590
|
stdio: 'ignore',
|
|
529
591
|
cwd: exeDir,
|
package/package.json
CHANGED