dsh-auto-maximize

uitested: passnpmMIT

Maximizes the DeepSeek Harness desktop window automatically on startup, equivalent to clicking the maximize button once. Cross-platform (Windows/macOS/Linux), best-effort, host-only.

下载量 / Downloads
1,321
依赖体积 / node_modules
0.09 MB
测试时间 / Tested
2026-11-06
DSH 版本 / Version
0.2.2-rc.1

Install

dsh plugin --profile web add dsh-auto-maximize

Sandbox test results

StageResult
1 install✓
2 list✓
3 mount✓
4 boot—

Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).

README

dsh-auto-maximize

DeepSeek Harness 桌面版插件:启动自动最大化主窗口(等同于手动点击最大化按钮)

适用于 DSH desktop profile,以及所有基于 Electron / 系统窗口运行 DSH 的场景。

原理与平台支持

插件是 host-only 插件,随桌面版 host 进程在应用启动时加载。host 进程是 Node 子进程

(ELECTRON_RUN_AS_NODE=1,由 Electron 主进程拉起),拿不到 BrowserWindow,

因此按平台调用系统级「最大化」能力,全部尽力而为、失败只记日志、绝不 crash host:

平台 · 策略 · 依赖 · 备注

Windows · ① 进程内 FFI:宿主同一进程里用 DSH 自带的 koffi 调 Win32 ShowWindow(hwnd, SW_MAXIMIZE)<br>② 回退:pwsh 7 → Windows PowerShell 5.1 子进程 · ① 无(koffi 随 DSH 安装)<br>② pwsh 7,缺失时自动用 5.1(Windows 自带) · ① 不再起子进程,实测 60–210ms(本来就已最大化时 ~60ms;真正切换含一次 200ms 校验等待);koffi 不可用时自动回退 ②。PowerShell 按 PATH 解析、不写死安装路径

macOS · 把窗口设为主屏可视区大小(NSScreen.visibleFrame,即「向窗口发送最大化指令」);该调用失败时再点击绿色 AXZoomButton 作为补救 · osascript(系统自带) · 需要「辅助功能/Accessibility」授权,未授权会给出指引日志;processName 可覆盖应用名

Linux · wmctrl → xdotool 设置 _NET_WM_STATE_MAXIMIZED · 通常未预装,需自行安装 · 尽力而为;两者都缺则跳过

窗口定位(Windows):先用 QueryFullProcessImageNameW 取窗口所属进程的镜像路径,只认与宿主

同一可执行文件的窗口;同镜像多窗口时优先 pid = 宿主父进程(Electron 主进程),再按面积取最大

(主窗口,不是欢迎小窗)。只考虑带 WS_MAXIMIZEBOX 的窗口。FFI 路径拿不到结果时,回退的

PowerShell 策略仍按「父进程 PID + 可执行路径」定位。

为什么不能直接调 BrowserWindow.maximize():host 进程是纯 Node(ELECTRON_RUN_AS_NODE=1,

实测 require('electron') 抛 MODULE_NOT_FOUND),插件只能拿到系统级窗口句柄——因此「自动最大化」

被实现为「等价于用户点击一次最大化按钮」的系统调用,而非 Electron API 调用。

FFI 的依赖来源:koffi 是 DSH 桌面版自带的运行时依赖

(@deepseek-ai/dsh-desktop-host 的 dependencies,原生二进制在 app.asar.unpacked 内,

desktop-host 自己的 cli.js 就用它装 Ctrl-C handler)。插件只是借用 DSH 安装里的这一份,

包本身仍是零运行时依赖。

安装

方式一:通过插件市场 / npm(推荐,发布后可用)

dsh plugin --profile desktop add dsh-auto-maximize

方式二:本地工程安装(开发调试)

在 profile 目录(如 ~/.dsh/profiles/desktop):

// package.json
{
  "dependencies": { "dsh-auto-maximize": "file:./plugins/dsh-auto-maximize" },
  "dsh": { "profile": { "bundles": [ /* 追加 */ "dsh-auto-maximize" ] } }
}

然后 pnpm install,重启 DeepSeek Harness 桌面版。

配置

在 profile 的 cordis.patch.yml 中覆盖 auto-maximize 行即可:

- id: auto-maximize
  config:
    enabled: false        # 禁用
    engine: auto          # Windows 策略:auto | ffi | powershell(默认 auto)
    timeoutMs: 5000       # 等待窗口出现的超时(毫秒,默认 5000)
    processName: 'DeepSeek Harness'   # macOS/Linux 定位窗口用的进程名
    logKeepRuns: 5        # 日志保留最近几次启动(默认 5)
    logKeepLines: 200     # 单个运行块最多保留多少行(默认 200)

配置项:

配置 · 类型 · 默认 · 说明

enabled · boolean · true · false 时整个插件不做事

engine · 'auto' \ · 'ffi' \ · 'powershell' · 'auto' · Windows 策略:auto=进程内 FFI 优先、失败回退子进程;ffi/powershell 强制只用其一(排查用)

timeoutMs · number · 5000 · 启动后持续寻找窗口的最长时间(毫秒)。窗口正常在启动后 1s 内出现,5s 还没等到基本可判定异常;engine: auto 下 FFI 与 PowerShell 各自计时,最坏情况约 2 倍

processName · string · 可执行文件名 · macOS/Linux 定位窗口用的进程/窗口标题名

logFile · boolean \ · string · ~/.dsh/auto-maximize.log · 诊断日志:false 关闭文件日志;字符串指定自定义路径;删除文件即清空

logKeepRuns · number · 5 · 日志文件里保留最近几次启动(每次启动一个 ===== … ===== 分隔块)

logKeepLines · number · 200 · 单个运行块最多保留多少行(超出时丢中间、保留开头与最近的尾部;当前块写满即停)

macOS:需要「辅助功能」授权

macOS 出于安全限制,用 osascript(System Events)控制其他 App 的窗口必须先获得

「辅助功能 / Accessibility」授权。

⚠️ 注意事项:指令形式同样需要授权。 插件把窗口直接设为 set position/size(「向窗口发送
最大化指令」)还是点击 AXZoomButton,**两种方式都走同一套 macOS Accessibility API,都需要
辅助功能授权**。原因:要挪动另一个进程的窗口只能走该 API,系统的闸门拦的是 API 本身、不是进程
身份——哪怕 osascript 是 DSH 自己的子进程也一样(TCC 会把授权追溯归属到 DSH 应用,所以勾选
DeepSeek Harness 即可覆盖它,但这并不豁免授权)。换成 Windows 那样的进程内 FFI 也绕不过:
macOS 没有「给窗口发个消息就能最大化」的跨进程调用,zoom 只能经 Accessibility API,而那正是被
授权闸门拦住的入口。真正免授权的路径只有让 DSH 主进程自己调 BrowserWindow.maximize()
(启动参数 / host→main IPC),需要 DSH 本体提供通道,插件作为外部方做不到。因此请保留授权。

插件未获授权时会在 host 日志输出指引(关键字 dsh-auto-maximize),按以下步骤授权后重启即可:

1. 打开 系统设置 → 隐私与安全性 → 辅助功能;

2. 勾选 DeepSeek Harness(以及承载/启动它的终端或启动器,如有);

3. 重启 DeepSeek Harness(授权对已运行的进程不生效)。

仍无效时,可用 processName 指定实际的进程名——打包后应用显示名可能与可执行文件名不同。

诊断日志:插件每一步都会写入 ~/.dsh/auto-maximize.log

(Windows:%USERPROFILE%\.dsh\auto-maximize.log)。只有一个文件,最新的运行在最上面:

每块以 ===== 时间 run(pid=…, version=…) ===== 开头,下面是本次启动的日志;保留最近

logKeepRuns 次启动(默认 5),单个运行块最多 logKeepLines 行(默认 200,超出时丢中间、

保留表头与最近的尾部)。顺序按表头时间戳判定,文件被手工调换顺序也能正确归位;表头不可解析

(手改坏了、乱码、旧格式残留)的块按「最旧」处理,会在下次启动时被淘汰,不会影响本次记录。

排查「没生效」时直接看这个文件:Windows 上会看到 ffi: koffi … via … /

ffi: maximized hwnd=… / koffi unavailable,macOS 上会看到 perm:(缺授权)/

nowindow:(没找到窗口)/ maximized-bounds(成功)。不需要日志时用 logFile: false 关闭,

或直接删除该文件清空。

对比:Windows 端不需要任何额外权限——ShowWindow(hwnd, SW_MAXIMIZE) 是直接 Win32 API
调用(非模拟点击),对同一用户的窗口无需提权。
macOS 为什么没有对应的「进程内」路径:Windows 的最大化是发给窗口的消息,任何进程都能对
任意 hwnd 调用;macOS 的 zoom 是窗口对象(AppKit NSWindow)自己的操作,跨进程只能走
Accessibility API(AXUIElement + kAXZoomAction),而调用 Accessibility API **本身就需要
辅助功能授权**。所以 macOS 上只有「系统 API + 授权」这一条路——进程内 FFI 既省不掉授权,也
换不来新能力,这正是本插件在 macOS 上仍走 osascript 的原因。

卸载

从 profile 的 package.json 两处(dependencies + dsh.profile.bundles)移除

dsh-auto-maximize,再执行 pnpm install,重启应用。

开发

npm install   # 包本身无第三方运行时依赖(FFI 借用 DSH 自带的 koffi);dev 仅测试需要 node:test
npm test      # 36 条:模块加载 / 禁用分支 / 效果注册 / koffi 锚点回退 / 窗口挑选 / 引擎顺序 /
              # 日志开关 / 免重启验证脚本
npm pack      # 生成可发布的 tarball(prepack 会先跑测试)

测试与打包都用 DSH_AUTO_MAXIMIZE_NO_LOG=1 关掉文件日志,不会写、也不会轮转你真实的

~/.dsh/auto-maximize.log。

验证:不用重启 DSH

插件是「每次挂载跑一次」:cordis 调用 apply() 时把当时已存在的窗口最大化一次。所以**重新挂载

bundle 就等于重跑插件**——「设置 → 插件」里关掉再打开即可,不必重启桌面版。

scripts/verify-live.ps1 就按这个方式检查:读日志里最新一次挂载,再用 Win32 独立确认窗口真的

最大化了。

发布到 npm

npm login                                   # 首次
npm publish --registry https://registry.npmjs.org

发布后即可在 dsh-market 插件市场的

「申请收录插件 ↗」入口提交收录(指向 awesome-dsh-plugin

的 data/plugins/<owner>__<repo>.yml,见 [提交指南](https://github.com/awesome

…(truncated)

Rendered from the README published on npm. Formatted only, not edited.

Versions

Published on npm::3,最后更新 2026-10-22

Links

GitHub · Homepage · npm

Same category