dsh-windows-tray 1.0.2 → 1.0.3

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/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 jankin_lv
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 jankin_lv
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,146 +1,146 @@
1
- # dsh-windows-tray
2
-
3
- > DeepSeek Harness(dsh)的 Windows 系统托盘管家:**官方鲸鱼状态图标 + Web/TUI 双状态显示 + 一键启停**。
4
- > 纯 PowerShell + WinForms 实现,零依赖、无编译、不改 dsh 源码,卸载即还原。
5
-
6
- [![npm](https://img.shields.io/npm/v/dsh-windows-tray?style=flat-square)](https://www.npmjs.com/package/dsh-windows-tray)
7
- [![npm downloads](https://img.shields.io/npm/dm/dsh-windows-tray?style=flat-square)](https://www.npmjs.com/package/dsh-windows-tray)
8
- [![Platform](https://img.shields.io/badge/platform-Windows%2010%2F11-blue?style=flat-square)](https://www.npmjs.com/package/dsh-windows-tray)
9
- [![License](https://img.shields.io/npm/l/dsh-windows-tray?style=flat-square)](https://github.com/)
10
-
11
- ## 是什么
12
-
13
- dsh 默认在终端前台运行 `dsh web`——必须留着一个命令行窗口。本工具把它变成**一个标准的 Windows 托盘应用**:
14
-
15
- - 🐋 **状态一目了然**:品牌蓝鲸鱼 = Web 运行中;灰鲸鱼 = 未运行(图标由官方 favicon 渲染生成)
16
- - 📊 **DSH / TUI 双状态**:菜单顶部同屏显示 Web 与 TUI 各自的运行状态(含 PID),互不干扰
17
- - 🖱️ **零窗口操作**:双击开界面,右键通过 DSH / TUI 分组子菜单一键启停,不用再碰命令行
18
- - 👁️ **独立旁观者**:托盘是独立常驻进程,dsh 停止时它依然在(显示未运行 + 一键启动),退出托盘不影响 dsh
19
- - 🎨 **浅色圆角菜单**:白底、圆角、投影阴影,贴合现代桌面应用审美
20
-
21
- ## 功能特性
22
-
23
- | 交互 | 行为 |
24
- | :--- | :--- |
25
- | **图标** | 蓝鲸鱼 = Web 运行中(PID);灰鲸鱼 = 未运行 |
26
- | **悬停提示** | `Web UI 运行中 · 127.0.0.1:3088` / `Web UI 未运行 · 右键可启动` |
27
- | **双击** | 打开 Web UI(未运行先提示启动) |
28
- | **右键菜单** | 顶部 `Web UI 状态` / `TUI 状态` 双状态行;`Web UI ▸`(打开 Web UI / 启动 / 停止(带确认) / 重启);`TUI ▸`(启动 / 停止);打开日志目录 / `版本信息 ▸`(版本 / 检查更新 / 更新到最新版)/ 退出托盘 |
29
- | **菜单智能禁用** | Web 运行中禁用「启动 Web UI」;TUI 运行中禁用「启动 TUI」 |
30
- | **自更新** | 「版本信息 ▸」子菜单(位于退出托盘上方,非日常功能区):查看版本 / 检查更新 / 一键更新到最新版(自动重部署 + 重启托盘) |
31
- | **状态通知** | Web/TUI 启动与停止瞬间弹系统通知;托盘就绪弹一次提示 |
32
- | **开机自启** | 登录后托盘自动出现(启动文件夹快捷方式,安装时自动创建) |
33
-
34
- ## 适配与依赖
35
-
36
- | 项 | 说明 |
37
- | :--- | :--- |
38
- | **dsh 内核** | 适配 `@deepseek-ai/dsh` **v0.1.1-rc.2 系列**(共享核心 `@deepseek-ai/dsh-base` 同版本);dsh 升级不影响托盘 |
39
- | **Web 服务** | dsh web 默认监听 `127.0.0.1:3088`(即浏览器里的 Web UI)——托盘通过 TCP 探测该端口判断 Web 状态(端口被改时同步修改 `dsh-lib.ps1` 的 `$PORT` 即可) |
40
- | **TUI 插件** | 适配 `@deepseek-harness-tui/dsh-tui` **^0.9.2**(通过 dsh-profile `dsh-profile-dsh-tui` 挂载);托盘按进程命令行 `dsh-tui` 检测,与插件版本解耦 |
41
- | **Node.js** | ≥ 18(dsh 本体运行所需) |
42
- | **PowerShell** | 7(托盘常驻进程;缺省回退 Windows PowerShell 5.1) |
43
- | **运行时依赖** | **零 npm 依赖**——纯 PowerShell + WinForms + 系统 API;托盘不修改 dsh、不注入任何内容,纯旁观者 |
44
-
45
- ## 界面预览
46
-
47
- | 运行中(品牌蓝 `#4176E6`) | 未运行(中性灰 `#81858C`) |
48
- | :---: | :---: |
49
- | ![running](build/dsh-tray-running-preview.png) | ![stopped](build/dsh-tray-stopped-preview.png) |
50
-
51
- > 图标源 = dsh Web 前端官方 favicon(鲸鱼),多尺寸 16~256px;可随时用 `dsh-tray icons` 重新生成。
52
-
53
- ## 快速开始
54
-
55
- 前置:Windows 10/11 + [PowerShell 7](https://github.com/PowerShell/PowerShell/releases)(7.x;缺失时自动回退 Windows PowerShell 5.1)+ Node.js **≥ 18** + 已安装 dsh(任意位置)。
56
-
57
- ```powershell
58
- # 1. 全局安装
59
- npm i -g dsh-windows-tray
60
-
61
- # 2. 一键部署(自动探测 dsh/pwsh/node 路径 → 安装到 ~\.dsh\launcher
62
- # → 按本机路径改写配置 → 创建开机自启+桌面快捷方式 → 启动托盘)
63
- dsh-tray install
64
-
65
- # 3. 首次使用:把任务栏 ^ 溢出区里的鲸鱼拖到任务栏(一次性,Windows 会记住)
66
- ```
67
-
68
- 部署完成后即可双击鲸鱼打开 Web UI,右键管理一切。
69
-
70
- ## 常用命令
71
-
72
- | 命令 | 作用 |
73
- | :--- | :--- |
74
- | `dsh-tray` | 启动托盘(已有实例则提示,不重复启动) |
75
- | `dsh-tray install` | 一键部署 / 重新部署(可透传 `-DshRoot` 等参数) |
76
- | `dsh-tray icons` | 重新生成鲸鱼图标(内置 512px 源图,无需浏览器) |
77
- | `dsh-tray info` | 查看版本 / 安装位置 / 部署状态 |
78
- | `npm up -g dsh-windows-tray` | 命令行更新(更新后建议 `dsh-tray install` 重部署) |
79
-
80
- ## 如何更新
81
-
82
- 两种方式任选:
83
-
84
- **方式一:托盘一键更新(推荐)**——托盘菜单「版本信息 ▸」→「检查更新」对比 npm 最新版,发现新版后点「更新到最新版」:自动 `npm install -g` → 重新部署(含本机路径改写)→ 自动重启托盘,全程约 1 分钟,失败不影响当前托盘。
85
-
86
- **方式二:npm 标准流程**——与普通 npm 包一致:
87
-
88
- ```powershell
89
- npm up -g dsh-windows-tray # 拉取最新版
90
- dsh-tray install # 重新部署(自动改写本机路径 + 刷新快捷方式)
91
- dsh-tray # 重启托盘(或右键「退出托盘」后重新登录/双击快捷方式)
92
- ```
93
-
94
- > 部署目录固定为 `~\.dsh\launcher`,重装/更新都会覆盖旧文件,不会残留;`dsh-tray info` 可查看当前版本与部署状态。
95
-
96
- ## 卸载
97
-
98
- ```powershell
99
- npm rm -g dsh-windows-tray # ① 移除 npm 包本体
100
- # ② 删除快捷方式: 启动文件夹 + 桌面 各一个「DSH 系统托盘.lnk」
101
- # ③ 删除部署目录 ~\.dsh\launcher (如与 dsh 控制台共用, 确认无需保留再删)
102
- ```
103
-
104
- ## 工作原理
105
-
106
- ```
107
- 托盘(pwsh 常驻) ──2s 轮询──► 127.0.0.1:3088 (Web UI 端口)
108
- │ └──────────────► node 进程命令行含 'dsh-tui' (TUI 进程)
109
- ├── 菜单动作 ──► dsh-actions.ps1 (独立隐藏进程, 不卡 UI)
110
- ├── 自更新 ──► dsh-update.ps1 (npm 安装→重部署→重启)
111
- └── 单实例 ──► 命名互斥锁 (被强杀遗留的锁自动接管)
112
- ```
113
-
114
- - **状态检测**:Web 用 TCP 端口探测(物理单实例);TUI 按命令行匹配(多实例安全:全查全杀);TUI 检测 20s 节流,打开菜单时强制刷新
115
- - **动作隔离**:启动/停止/重启在独立进程执行,托盘 UI 永不卡顿
116
- - **日志**:`~\.dsh\logs\dsh-tray.log`(状态变化)+ `dsh-tray-actions.log`(动作)
117
- - **单点配置**:端口/路径等常量集中在 `launcher/dsh-lib.ps1`,安装时按本机自动改写——**包本身与机器无关**
118
-
119
- ## 配置
120
-
121
- | 项 | 位置 | 默认 |
122
- | :--- | :--- | :--- |
123
- | 监控端口 | `~\.dsh\launcher\dsh-lib.ps1` 顶部 `$PORT` | `3088` |
124
- | dsh 路径 | 同上(安装时自动改写) | 自动探测 |
125
- | 图标颜色 | `build/build-tray-icons.ps1`(运行蓝/停止灰) | `#4176E6` / `#81858C` |
126
-
127
- ## 常见问题
128
-
129
- | 问题 | 处理 |
130
- | :--- | :--- |
131
- | 任务栏看不到鲸鱼 | 点开 `^` 溢出区,把鲸鱼拖到任务栏(一次性) |
132
- | 停止 Web UI 会关掉浏览器界面 | 对——停止前有确认框;Web 与当前会话在 3088 端口上 |
133
- | 托盘退出了怎么唤回 | 双击桌面「DSH 系统托盘」快捷方式 / 重新登录(开机自启)/ `dsh-tray` |
134
- | 怎么更新到新版 | 托盘菜单「版本信息 ▸ → 更新到最新版」一键完成;或 `npm up -g dsh-windows-tray` + `dsh-tray install`(见「如何更新」) |
135
- | 检查更新失败 | 网络或 npm 不可用;托盘继续正常工作,稍后再试 |
136
- | dsh 内核升级了,托盘要动吗 | 不用——托盘只探测 3088 端口与 TUI 进程命令行,与内核版本解耦 |
137
- | 想彻底卸载 | `npm rm -g dsh-windows-tray` + 删除两个「DSH 系统托盘.lnk」+ 删除 `~\.dsh\launcher` |
138
-
139
- ## 文档
140
-
141
- - `docs/system-tray-guide.md` — 使用手册(安装部署 / 功能一览 / 更新 / 卸载 / 故障排查)
142
- - `docs/tray-dev-archive.md` — 开发归档(架构决策与历史记录)
143
-
144
- ## 许可
145
-
146
- MIT
1
+ # dsh-windows-tray
2
+
3
+ > DeepSeek Harness(dsh)的 Windows 系统托盘管家:**官方鲸鱼状态图标 + Web/TUI 双状态显示 + 一键启停**。
4
+ > 纯 PowerShell + WinForms 实现,零依赖、无编译、不改 dsh 源码,卸载即还原。
5
+
6
+ [![npm](https://img.shields.io/npm/v/dsh-windows-tray?style=flat-square)](https://www.npmjs.com/package/dsh-windows-tray)
7
+ [![npm downloads](https://img.shields.io/npm/dm/dsh-windows-tray?style=flat-square)](https://www.npmjs.com/package/dsh-windows-tray)
8
+ [![Platform](https://img.shields.io/badge/platform-Windows%2010%2F11-blue?style=flat-square)](https://www.npmjs.com/package/dsh-windows-tray)
9
+ [![License](https://img.shields.io/npm/l/dsh-windows-tray?style=flat-square)](https://github.com/)
10
+
11
+ ## 是什么
12
+
13
+ dsh 默认在终端前台运行 `dsh web`——必须留着一个命令行窗口。本工具把它变成**一个标准的 Windows 托盘应用**:
14
+
15
+ - 🐋 **状态一目了然**:品牌蓝鲸鱼 = Web 运行中;灰鲸鱼 = 未运行(图标由官方 favicon 渲染生成)
16
+ - 📊 **DSH / TUI 双状态**:菜单顶部同屏显示 Web 与 TUI 各自的运行状态(含 PID),互不干扰
17
+ - 🖱️ **零窗口操作**:双击开界面,右键通过 DSH / TUI 分组子菜单一键启停,不用再碰命令行
18
+ - 👁️ **独立旁观者**:托盘是独立常驻进程,dsh 停止时它依然在(显示未运行 + 一键启动),退出托盘不影响 dsh
19
+ - 🎨 **浅色圆角菜单**:白底、圆角、投影阴影,贴合现代桌面应用审美
20
+
21
+ ## 功能特性
22
+
23
+ | 交互 | 行为 |
24
+ | :--- | :--- |
25
+ | **图标** | 蓝鲸鱼 = Web 运行中(PID);灰鲸鱼 = 未运行 |
26
+ | **悬停提示** | `Web UI 运行中 · 127.0.0.1:3088` / `Web UI 未运行 · 右键可启动` |
27
+ | **双击** | 打开 Web UI(未运行先提示启动) |
28
+ | **右键菜单** | 顶部 `Web UI 状态` / `TUI 状态` 双状态行;`Web UI ▸`(打开 Web UI / 启动 / 停止(带确认) / 重启);`TUI ▸`(启动 / 停止);打开日志目录 / `版本信息 ▸`(版本 / 检查更新 / 更新到最新版)/ 退出托盘 |
29
+ | **菜单智能禁用** | Web 运行中禁用「启动 Web UI」;TUI 运行中禁用「启动 TUI」 |
30
+ | **自更新** | 「版本信息 ▸」子菜单(位于退出托盘上方,非日常功能区):查看版本 / 检查更新 / 一键更新到最新版(自动重部署 + 重启托盘) |
31
+ | **状态通知** | Web/TUI 启动与停止瞬间弹系统通知;托盘就绪弹一次提示 |
32
+ | **开机自启** | 登录后托盘自动出现(启动文件夹快捷方式,安装时自动创建) |
33
+
34
+ ## 适配与依赖
35
+
36
+ | 项 | 说明 |
37
+ | :--- | :--- |
38
+ | **dsh 内核** | 适配 `@deepseek-ai/dsh` **v0.1.1-rc.2 系列**(共享核心 `@deepseek-ai/dsh-base` 同版本);dsh 升级不影响托盘 |
39
+ | **Web 服务** | dsh web 默认监听 `127.0.0.1:3088`(即浏览器里的 Web UI)——托盘通过 TCP 探测该端口判断 Web 状态(端口被改时同步修改 `dsh-lib.ps1` 的 `$PORT` 即可) |
40
+ | **TUI 插件** | 适配 `@deepseek-harness-tui/dsh-tui` **^0.9.2**(通过 dsh-profile `dsh-profile-dsh-tui` 挂载);托盘按进程命令行 `dsh-tui` 检测,与插件版本解耦 |
41
+ | **Node.js** | ≥ 18(dsh 本体运行所需) |
42
+ | **PowerShell** | 7(托盘常驻进程;缺省回退 Windows PowerShell 5.1) |
43
+ | **运行时依赖** | **零 npm 依赖**——纯 PowerShell + WinForms + 系统 API;托盘不修改 dsh、不注入任何内容,纯旁观者 |
44
+
45
+ ## 界面预览
46
+
47
+ | 运行中(品牌蓝 `#4176E6`) | 未运行(中性灰 `#81858C`) |
48
+ | :---: | :---: |
49
+ | ![running](build/dsh-tray-running-preview.png) | ![stopped](build/dsh-tray-stopped-preview.png) |
50
+
51
+ > 图标源 = dsh Web 前端官方 favicon(鲸鱼),多尺寸 16~256px;可随时用 `dsh-tray icons` 重新生成。
52
+
53
+ ## 快速开始
54
+
55
+ 前置:Windows 10/11 + [PowerShell 7](https://github.com/PowerShell/PowerShell/releases)(7.x;缺失时自动回退 Windows PowerShell 5.1)+ Node.js **≥ 18** + 已安装 dsh(任意位置)。
56
+
57
+ ```powershell
58
+ # 1. 全局安装
59
+ npm i -g dsh-windows-tray
60
+
61
+ # 2. 一键部署(自动探测 dsh/pwsh/node 路径 → 安装到 ~\.dsh\launcher
62
+ # → 按本机路径改写配置 → 创建开机自启+桌面快捷方式 → 启动托盘)
63
+ dsh-tray install
64
+
65
+ # 3. 首次使用:把任务栏 ^ 溢出区里的鲸鱼拖到任务栏(一次性,Windows 会记住)
66
+ ```
67
+
68
+ 部署完成后即可双击鲸鱼打开 Web UI,右键管理一切。
69
+
70
+ ## 常用命令
71
+
72
+ | 命令 | 作用 |
73
+ | :--- | :--- |
74
+ | `dsh-tray` | 启动托盘(已有实例则提示,不重复启动) |
75
+ | `dsh-tray install` | 一键部署 / 重新部署(可透传 `-DshRoot` 等参数) |
76
+ | `dsh-tray icons` | 重新生成鲸鱼图标(内置 512px 源图,无需浏览器) |
77
+ | `dsh-tray info` | 查看版本 / 安装位置 / 部署状态 |
78
+ | `npm up -g dsh-windows-tray` | 命令行更新(更新后建议 `dsh-tray install` 重部署) |
79
+
80
+ ## 如何更新
81
+
82
+ 两种方式任选:
83
+
84
+ **方式一:托盘一键更新(推荐)**——托盘菜单「版本信息 ▸」→「检查更新」对比 npm 最新版,发现新版后点「更新到最新版」:自动 `npm install -g` → 重新部署(含本机路径改写)→ 自动重启托盘,全程约 1 分钟,失败不影响当前托盘。
85
+
86
+ **方式二:npm 标准流程**——与普通 npm 包一致:
87
+
88
+ ```powershell
89
+ npm up -g dsh-windows-tray # 拉取最新版
90
+ dsh-tray install # 重新部署(自动改写本机路径 + 刷新快捷方式)
91
+ dsh-tray # 重启托盘(或右键「退出托盘」后重新登录/双击快捷方式)
92
+ ```
93
+
94
+ > 部署目录固定为 `~\.dsh\launcher`,重装/更新都会覆盖旧文件,不会残留;`dsh-tray info` 可查看当前版本与部署状态。
95
+
96
+ ## 卸载
97
+
98
+ ```powershell
99
+ npm rm -g dsh-windows-tray # ① 移除 npm 包本体
100
+ # ② 删除快捷方式: 启动文件夹 + 桌面 各一个「DSH 系统托盘.lnk」
101
+ # ③ 删除部署目录 ~\.dsh\launcher (如与 dsh 控制台共用, 确认无需保留再删)
102
+ ```
103
+
104
+ ## 工作原理
105
+
106
+ ```
107
+ 托盘(pwsh 常驻) ──2s 轮询──► 127.0.0.1:3088 (Web UI 端口)
108
+ │ └──────────────► node 进程命令行含 'dsh-tui' (TUI 进程)
109
+ ├── 菜单动作 ──► dsh-actions.ps1 (独立隐藏进程, 不卡 UI)
110
+ ├── 自更新 ──► dsh-update.ps1 (npm 安装→重部署→重启)
111
+ └── 单实例 ──► 命名互斥锁 (被强杀遗留的锁自动接管)
112
+ ```
113
+
114
+ - **状态检测**:Web 用 TCP 端口探测(物理单实例);TUI 按命令行匹配(多实例安全:全查全杀);TUI 检测 20s 节流,打开菜单时强制刷新
115
+ - **动作隔离**:启动/停止/重启在独立进程执行,托盘 UI 永不卡顿
116
+ - **日志**:`~\.dsh\logs\dsh-tray.log`(状态变化)+ `dsh-tray-actions.log`(动作)
117
+ - **单点配置**:端口/路径等常量集中在 `launcher/dsh-lib.ps1`,安装时按本机自动改写——**包本身与机器无关**
118
+
119
+ ## 配置
120
+
121
+ | 项 | 位置 | 默认 |
122
+ | :--- | :--- | :--- |
123
+ | 监控端口 | `~\.dsh\launcher\dsh-lib.ps1` 顶部 `$PORT` | `3088` |
124
+ | dsh 路径 | 同上(安装时自动改写) | 自动探测 |
125
+ | 图标颜色 | `build/build-tray-icons.ps1`(运行蓝/停止灰) | `#4176E6` / `#81858C` |
126
+
127
+ ## 常见问题
128
+
129
+ | 问题 | 处理 |
130
+ | :--- | :--- |
131
+ | 任务栏看不到鲸鱼 | 点开 `^` 溢出区,把鲸鱼拖到任务栏(一次性) |
132
+ | 停止 Web UI 会关掉浏览器界面 | 对——停止前有确认框;Web 与当前会话在 3088 端口上 |
133
+ | 托盘退出了怎么唤回 | 双击桌面「DSH 系统托盘」快捷方式 / 重新登录(开机自启)/ `dsh-tray` |
134
+ | 怎么更新到新版 | 托盘菜单「版本信息 ▸ → 更新到最新版」一键完成;或 `npm up -g dsh-windows-tray` + `dsh-tray install`(见「如何更新」) |
135
+ | 检查更新失败 | 网络或 npm 不可用;托盘继续正常工作,稍后再试 |
136
+ | dsh 内核升级了,托盘要动吗 | 不用——托盘只探测 3088 端口与 TUI 进程命令行,与内核版本解耦 |
137
+ | 想彻底卸载 | `npm rm -g dsh-windows-tray` + 删除两个「DSH 系统托盘.lnk」+ 删除 `~\.dsh\launcher` |
138
+
139
+ ## 文档
140
+
141
+ - `docs/system-tray-guide.md` — 使用手册(安装部署 / 功能一览 / 更新 / 卸载 / 故障排查)
142
+ - `docs/tray-dev-archive.md` — 开发归档(架构决策与历史记录)
143
+
144
+ ## 许可
145
+
146
+ MIT
package/bin/dsh-tray.js CHANGED
@@ -1,100 +1,100 @@
1
- #!/usr/bin/env node
2
- // dsh-tray —— DSH 系统托盘的 npm 命令行入口
3
- // 用法:
4
- // dsh-tray 启动托盘 (后台, 从已部署目录 ~\.dsh\launcher 运行)
5
- // dsh-tray install 一键部署到 ~\.dsh\launcher (自动探测路径+快捷方式+启动)
6
- // dsh-tray icons 重新生成鲸鱼图标 (build/build-tray-icons.ps1)
7
- // dsh-tray info 显示版本/安装位置/pwsh 路径
8
- 'use strict';
9
- const { spawn } = require('child_process');
10
- const path = require('path');
11
- const fs = require('fs');
12
-
13
- const root = path.join(__dirname, '..');
14
- const pkg = require(path.join(root, 'package.json'));
15
- const home = process.env.USERPROFILE || process.env.HOME || '';
16
- const deployDir = path.join(home, '.dsh', 'launcher');
17
-
18
- function findPwsh() {
19
- const candidates = [
20
- process.env.PWSH,
21
- 'C:\\Program Files\\PowerShell\\7\\pwsh.exe',
22
- 'D:\\Program Files (x86)\\PowerShell-7.6.4\\pwsh.exe',
23
- path.join(process.env.ProgramW6432 || 'C:\\Program Files', 'PowerShell\\7\\pwsh.exe'),
24
- ].filter(Boolean);
25
- for (const c of candidates) { try { if (fs.existsSync(c)) return c; } catch (_) { /* ignore */ } }
26
- return 'pwsh'; // 最后让 PATH 解析
27
- }
28
-
29
- const cmd = process.argv[2] || 'run';
30
- const pwsh = findPwsh();
31
-
32
- switch (cmd) {
33
- case 'install':
34
- // 交互式部署: 继承终端, 等安装完成
35
- spawn(pwsh, ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-File',
36
- path.join(root, 'install.ps1'), ...process.argv.slice(3)],
37
- { stdio: 'inherit', windowsHide: true })
38
- .on('exit', (code) => process.exit(code == null ? 1 : code));
39
- break;
40
-
41
- case 'icons':
42
- spawn(pwsh, ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-File',
43
- path.join(root, 'build', 'build-tray-icons.ps1')],
44
- { stdio: 'inherit', windowsHide: true })
45
- .on('exit', (code) => process.exit(code == null ? 1 : code));
46
- break;
47
-
48
- case 'info':
49
- console.log(`dsh-tray v${pkg.version}`);
50
- console.log(`包安装位置: ${root}`);
51
- console.log(`部署目录: ${deployDir}`);
52
- console.log(`pwsh: ${pwsh}`);
53
- console.log(`部署状态: ${fs.existsSync(path.join(deployDir, 'dsh-tray.ps1')) ? '已部署' : '未部署 (先运行 dsh-tray install)'}`);
54
- break;
55
-
56
- case 'run':
57
- default: {
58
- // 托盘是常驻进程: 优先跑已部署(路径已改写)的副本
59
- const script = fs.existsSync(path.join(deployDir, 'dsh-tray.ps1'))
60
- ? path.join(deployDir, 'dsh-tray.ps1')
61
- : path.join(root, 'launcher', 'dsh-tray.ps1');
62
- const fromDeploy = script.startsWith(deployDir);
63
- // 反馈模式: 快速退出(单实例锁/失败)立即报告; 存活 3 秒 = 挂载成功
64
- const child = spawn(pwsh, ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-WindowStyle', 'Hidden', '-File', script], {
65
- stdio: ['ignore', 'ignore', 'pipe'],
66
- windowsHide: true,
67
- });
68
- let errText = '';
69
- let settled = false;
70
- child.stderr.on('data', (d) => (errText += d));
71
- child.on('error', (e) => {
72
- if (settled) return;
73
- settled = true;
74
- console.error(`dsh-tray: 启动失败 — ${e.message}`);
75
- process.exit(1);
76
- });
77
- child.on('exit', (code) => {
78
- if (settled) return;
79
- settled = true;
80
- if (code === 0) {
81
- console.log('dsh-tray: 已有托盘实例在运行(单实例保护),本次不重复启动。');
82
- process.exit(0);
83
- }
84
- const lastLine = errText.trim().split(/\r?\n/).pop();
85
- console.error(`dsh-tray: 启动失败(退出码 ${code})${lastLine ? ' — ' + lastLine : ''}`);
86
- console.error(fromDeploy ? ' 提示: 日志见 ~\\.dsh\\logs\\dsh-tray.log' : ' 提示: 先运行 dsh-tray install 部署');
87
- process.exit(1);
88
- });
89
- // 子进程存活超过观察窗口 = 托盘已挂载, 视为启动成功
90
- setTimeout(() => {
91
- if (settled) return;
92
- settled = true;
93
- console.log(fromDeploy
94
- ? 'dsh-tray: 托盘已后台运行(找不到图标就点任务栏 ^ 折叠区)。'
95
- : 'dsh-tray: 托盘已后台运行。提示: 未检测到部署, 建议先运行 dsh-tray install 适配本机路径');
96
- process.exit(0);
97
- }, 3000);
98
- break;
99
- }
100
- }
1
+ #!/usr/bin/env node
2
+ // dsh-tray —— DSH 系统托盘的 npm 命令行入口
3
+ // 用法:
4
+ // dsh-tray 启动托盘 (后台, 从已部署目录 ~\.dsh\launcher 运行)
5
+ // dsh-tray install 一键部署到 ~\.dsh\launcher (自动探测路径+快捷方式+启动)
6
+ // dsh-tray icons 重新生成鲸鱼图标 (build/build-tray-icons.ps1)
7
+ // dsh-tray info 显示版本/安装位置/pwsh 路径
8
+ 'use strict';
9
+ const { spawn } = require('child_process');
10
+ const path = require('path');
11
+ const fs = require('fs');
12
+
13
+ const root = path.join(__dirname, '..');
14
+ const pkg = require(path.join(root, 'package.json'));
15
+ const home = process.env.USERPROFILE || process.env.HOME || '';
16
+ const deployDir = path.join(home, '.dsh', 'launcher');
17
+
18
+ function findPwsh() {
19
+ const candidates = [
20
+ process.env.PWSH,
21
+ 'C:\\Program Files\\PowerShell\\7\\pwsh.exe',
22
+ 'D:\\Program Files (x86)\\PowerShell-7.6.4\\pwsh.exe',
23
+ path.join(process.env.ProgramW6432 || 'C:\\Program Files', 'PowerShell\\7\\pwsh.exe'),
24
+ ].filter(Boolean);
25
+ for (const c of candidates) { try { if (fs.existsSync(c)) return c; } catch (_) { /* ignore */ } }
26
+ return 'pwsh'; // 最后让 PATH 解析
27
+ }
28
+
29
+ const cmd = process.argv[2] || 'run';
30
+ const pwsh = findPwsh();
31
+
32
+ switch (cmd) {
33
+ case 'install':
34
+ // 交互式部署: 继承终端, 等安装完成
35
+ spawn(pwsh, ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-File',
36
+ path.join(root, 'install.ps1'), ...process.argv.slice(3)],
37
+ { stdio: 'inherit', windowsHide: true })
38
+ .on('exit', (code) => process.exit(code == null ? 1 : code));
39
+ break;
40
+
41
+ case 'icons':
42
+ spawn(pwsh, ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-File',
43
+ path.join(root, 'build', 'build-tray-icons.ps1')],
44
+ { stdio: 'inherit', windowsHide: true })
45
+ .on('exit', (code) => process.exit(code == null ? 1 : code));
46
+ break;
47
+
48
+ case 'info':
49
+ console.log(`dsh-tray v${pkg.version}`);
50
+ console.log(`包安装位置: ${root}`);
51
+ console.log(`部署目录: ${deployDir}`);
52
+ console.log(`pwsh: ${pwsh}`);
53
+ console.log(`部署状态: ${fs.existsSync(path.join(deployDir, 'dsh-tray.ps1')) ? '已部署' : '未部署 (先运行 dsh-tray install)'}`);
54
+ break;
55
+
56
+ case 'run':
57
+ default: {
58
+ // 托盘是常驻进程: 优先跑已部署(路径已改写)的副本
59
+ const script = fs.existsSync(path.join(deployDir, 'dsh-tray.ps1'))
60
+ ? path.join(deployDir, 'dsh-tray.ps1')
61
+ : path.join(root, 'launcher', 'dsh-tray.ps1');
62
+ const fromDeploy = script.startsWith(deployDir);
63
+ // 反馈模式: 快速退出(单实例锁/失败)立即报告; 存活 3 秒 = 挂载成功
64
+ const child = spawn(pwsh, ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-WindowStyle', 'Hidden', '-File', script], {
65
+ stdio: ['ignore', 'ignore', 'pipe'],
66
+ windowsHide: true,
67
+ });
68
+ let errText = '';
69
+ let settled = false;
70
+ child.stderr.on('data', (d) => (errText += d));
71
+ child.on('error', (e) => {
72
+ if (settled) return;
73
+ settled = true;
74
+ console.error(`dsh-tray: 启动失败 — ${e.message}`);
75
+ process.exit(1);
76
+ });
77
+ child.on('exit', (code) => {
78
+ if (settled) return;
79
+ settled = true;
80
+ if (code === 0) {
81
+ console.log('dsh-tray: 已有托盘实例在运行(单实例保护),本次不重复启动。');
82
+ process.exit(0);
83
+ }
84
+ const lastLine = errText.trim().split(/\r?\n/).pop();
85
+ console.error(`dsh-tray: 启动失败(退出码 ${code})${lastLine ? ' — ' + lastLine : ''}`);
86
+ console.error(fromDeploy ? ' 提示: 日志见 ~\\.dsh\\logs\\dsh-tray.log' : ' 提示: 先运行 dsh-tray install 部署');
87
+ process.exit(1);
88
+ });
89
+ // 子进程存活超过观察窗口 = 托盘已挂载, 视为启动成功
90
+ setTimeout(() => {
91
+ if (settled) return;
92
+ settled = true;
93
+ console.log(fromDeploy
94
+ ? 'dsh-tray: 托盘已后台运行(找不到图标就点任务栏 ^ 折叠区)。'
95
+ : 'dsh-tray: 托盘已后台运行。提示: 未检测到部署, 建议先运行 dsh-tray install 适配本机路径');
96
+ process.exit(0);
97
+ }, 3000);
98
+ break;
99
+ }
100
+ }