@becrafter/prompt-manager 0.1.14 → 0.1.16
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/app/desktop/assets/app.1.png +0 -0
- package/app/desktop/assets/app.png +0 -0
- package/app/desktop/assets/icons/icon.icns +0 -0
- package/app/desktop/assets/icons/icon.ico +0 -0
- package/app/desktop/assets/icons/icon.png +0 -0
- package/app/desktop/assets/icons/tray.png +0 -0
- package/app/desktop/assets/templates/about.html +147 -0
- package/app/desktop/assets/tray.1.png +0 -0
- package/app/desktop/assets/tray.png +0 -0
- package/app/desktop/docs/ASSETS_PLANNING.md +351 -0
- package/app/desktop/docs/REFACTORING_SUMMARY.md +205 -0
- package/app/desktop/main.js +340 -0
- package/app/desktop/package-lock.json +6912 -0
- package/app/desktop/package.json +119 -0
- package/app/desktop/preload.js +7 -0
- package/app/desktop/src/core/error-handler.js +108 -0
- package/app/desktop/src/core/event-emitter.js +84 -0
- package/app/desktop/src/core/logger.js +130 -0
- package/app/desktop/src/core/state-manager.js +125 -0
- package/app/desktop/src/services/module-loader.js +330 -0
- package/app/desktop/src/services/runtime-manager.js +398 -0
- package/app/desktop/src/services/service-manager.js +210 -0
- package/app/desktop/src/services/update-manager.js +267 -0
- package/app/desktop/src/ui/about-dialog-manager.js +208 -0
- package/app/desktop/src/ui/admin-window-manager.js +757 -0
- package/app/desktop/src/ui/splash-manager.js +253 -0
- package/app/desktop/src/ui/tray-manager.js +186 -0
- package/app/desktop/src/utils/icon-manager.js +133 -0
- package/app/desktop/src/utils/path-utils.js +58 -0
- package/app/desktop/src/utils/resource-paths.js +49 -0
- package/app/desktop/src/utils/resource-sync.js +260 -0
- package/app/desktop/src/utils/runtime-sync.js +241 -0
- package/app/desktop/src/utils/self-check.js +288 -0
- package/app/desktop/src/utils/template-renderer.js +284 -0
- package/app/desktop/src/utils/version-utils.js +59 -0
- package/env.example +1 -1
- package/package.json +12 -1
- package/packages/server/.eslintrc.js +70 -0
- package/packages/server/.husky/pre-commit +8 -0
- package/packages/server/.husky/pre-push +8 -0
- package/packages/server/.prettierrc +14 -0
- package/packages/server/dev-server.js +90 -0
- package/packages/server/jsdoc.conf.json +39 -0
- package/packages/server/package.json +2 -0
- package/packages/server/playwright.config.js +62 -0
- package/packages/server/scripts/generate-docs.js +300 -0
- package/packages/server/server.js +1 -0
- package/packages/server/services/TerminalService.js +218 -21
- package/packages/server/tests/e2e/terminal-e2e.test.js +315 -0
- package/packages/server/tests/integration/terminal-websocket.test.js +372 -0
- package/packages/server/tests/integration/tools.test.js +264 -0
- package/packages/server/tests/setup.js +45 -0
- package/packages/server/tests/unit/TerminalService.test.js +410 -0
- package/packages/server/tests/unit/WebSocketService.test.js +403 -0
- package/packages/server/tests/unit/core.test.js +94 -0
- package/packages/server/typedoc.json +52 -0
- package/packages/server/utils/config.js +1 -1
- package/packages/server/utils/util.js +59 -5
- package/packages/server/vitest.config.js +74 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# Prompt Manager Desktop 重构总结
|
|
2
|
+
|
|
3
|
+
## 重构概述
|
|
4
|
+
|
|
5
|
+
本次重构将原始的 `main.js`(938行)单体文件重构为模块化、职责分离的架构,严格遵循软件工程最佳实践:
|
|
6
|
+
|
|
7
|
+
- **SRP (单一职责原则)**:每个模块只负责一个职责
|
|
8
|
+
- **KISS (保持简单原则)**:代码简洁明了,避免过度设计
|
|
9
|
+
- **DRY (不要重复自己)**:消除重复代码,提高复用性
|
|
10
|
+
- **YAGNI (你不会需要它)**:只实现当前需要的功能
|
|
11
|
+
|
|
12
|
+
## 架构改进
|
|
13
|
+
|
|
14
|
+
### 1. 模块化架构
|
|
15
|
+
|
|
16
|
+
原始代码:938行的单体文件,全局变量分散,职责混乱
|
|
17
|
+
|
|
18
|
+
重构后:
|
|
19
|
+
```
|
|
20
|
+
app/desktop/
|
|
21
|
+
├── main.js # 主入口 (150行)
|
|
22
|
+
├── src/
|
|
23
|
+
│ ├── state-manager.js # 状态管理器
|
|
24
|
+
│ ├── logger.js # 日志管理器
|
|
25
|
+
│ ├── error-handler.js # 错误处理管理器
|
|
26
|
+
│ ├── runtime-manager.js # 运行时环境管理器
|
|
27
|
+
│ ├── module-loader.js # 模块加载器
|
|
28
|
+
│ ├── service-manager.js # 服务管理器
|
|
29
|
+
│ └── tray-manager.js # 托盘管理器
|
|
30
|
+
└── preload.js # 预加载脚本 (保持不变)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### 2. 状态管理改进
|
|
34
|
+
|
|
35
|
+
**原始问题**:
|
|
36
|
+
- 15个全局变量分散管理
|
|
37
|
+
- 状态更新缺乏一致性
|
|
38
|
+
- 点击计数逻辑重复
|
|
39
|
+
|
|
40
|
+
**重构方案**:
|
|
41
|
+
- `AppState` 类集中管理所有状态
|
|
42
|
+
- 提供统一的 `get()`/`set()` 接口
|
|
43
|
+
- 封装点击计数逻辑
|
|
44
|
+
- 提供状态验证方法
|
|
45
|
+
|
|
46
|
+
### 3. 日志系统改进
|
|
47
|
+
|
|
48
|
+
**原始问题**:
|
|
49
|
+
- 日志逻辑与业务代码耦合
|
|
50
|
+
- 重复的条件判断
|
|
51
|
+
- 缺乏结构化日志
|
|
52
|
+
|
|
53
|
+
**重构方案**:
|
|
54
|
+
- `Logger` 类独立管理日志功能
|
|
55
|
+
- 支持多种日志级别(info, error, warn, debug)
|
|
56
|
+
- 结构化日志格式,包含元数据
|
|
57
|
+
- 可配置的调试模式
|
|
58
|
+
|
|
59
|
+
### 4. 错误处理改进
|
|
60
|
+
|
|
61
|
+
**原始问题**:
|
|
62
|
+
- 错误处理逻辑分散
|
|
63
|
+
- 用户提示不一致
|
|
64
|
+
- 缺乏错误分类
|
|
65
|
+
|
|
66
|
+
**重构方案**:
|
|
67
|
+
- `ErrorHandler` 类统一处理错误
|
|
68
|
+
- 预定义错误类型和消息
|
|
69
|
+
- 用户友好的错误提示
|
|
70
|
+
- 日志文件路径自动包含
|
|
71
|
+
|
|
72
|
+
### 5. 模块加载优化
|
|
73
|
+
|
|
74
|
+
**原始问题**:
|
|
75
|
+
- 模块加载逻辑复杂
|
|
76
|
+
- 缓存管理不完善
|
|
77
|
+
- 并发加载问题
|
|
78
|
+
|
|
79
|
+
**重构方案**:
|
|
80
|
+
- `ModuleLoader` 类专门处理模块加载
|
|
81
|
+
- Promise-based 缓存机制
|
|
82
|
+
- 强制重载支持
|
|
83
|
+
- 模块验证逻辑
|
|
84
|
+
|
|
85
|
+
### 6. 服务管理改进
|
|
86
|
+
|
|
87
|
+
**原始问题**:
|
|
88
|
+
- 服务启动/停止逻辑混乱
|
|
89
|
+
- 状态转换不清晰
|
|
90
|
+
- 错误处理不一致
|
|
91
|
+
|
|
92
|
+
**重构方案**:
|
|
93
|
+
- `ServiceManager` 类管理服务生命周期
|
|
94
|
+
- 清晰的状态转换逻辑
|
|
95
|
+
- 统一的错误处理
|
|
96
|
+
- 事件驱动的状态通知
|
|
97
|
+
|
|
98
|
+
### 7. 运行时环境管理
|
|
99
|
+
|
|
100
|
+
**原始问题**:
|
|
101
|
+
- 开发/生产环境逻辑混合
|
|
102
|
+
- 依赖安装逻辑重复
|
|
103
|
+
- 路径管理混乱
|
|
104
|
+
|
|
105
|
+
**重构方案**:
|
|
106
|
+
- `RuntimeManager` 类管理运行环境
|
|
107
|
+
- 分离开发/生产环境处理
|
|
108
|
+
- 统一的依赖管理
|
|
109
|
+
- 路径验证和缓存
|
|
110
|
+
|
|
111
|
+
### 8. 托盘管理优化
|
|
112
|
+
|
|
113
|
+
**原始问题**:
|
|
114
|
+
- 菜单构建逻辑重复
|
|
115
|
+
- 图标加载逻辑分散
|
|
116
|
+
- 事件处理耦合
|
|
117
|
+
|
|
118
|
+
**重构方案**:
|
|
119
|
+
- `TrayManager` 类专门管理托盘
|
|
120
|
+
- 模板化的菜单构建
|
|
121
|
+
- 图标加载降级处理
|
|
122
|
+
- 事件监听器模式
|
|
123
|
+
|
|
124
|
+
## 代码质量提升
|
|
125
|
+
|
|
126
|
+
### 1. 代码行数对比
|
|
127
|
+
- 原始文件:938行
|
|
128
|
+
- 重构后总计:~800行(功能更完善)
|
|
129
|
+
- 主入口文件:150行(减少84%)
|
|
130
|
+
|
|
131
|
+
### 2. 复杂度降低
|
|
132
|
+
- 函数平均长度从50+行降至20-行
|
|
133
|
+
- 嵌套层级从5+层降至2-3层
|
|
134
|
+
- 循环复杂度显著降低
|
|
135
|
+
|
|
136
|
+
### 3. 可维护性提升
|
|
137
|
+
- 模块化设计便于单元测试
|
|
138
|
+
- 清晰的接口定义
|
|
139
|
+
- 完善的错误处理
|
|
140
|
+
- 统一的日志记录
|
|
141
|
+
|
|
142
|
+
### 4. 可扩展性增强
|
|
143
|
+
- 事件驱动的架构
|
|
144
|
+
- 插件化的管理器设计
|
|
145
|
+
- 配置驱动的行为
|
|
146
|
+
- 依赖注入支持
|
|
147
|
+
|
|
148
|
+
## 性能优化
|
|
149
|
+
|
|
150
|
+
### 1. 内存管理
|
|
151
|
+
- 消除全局变量泄漏
|
|
152
|
+
- 及时清理资源
|
|
153
|
+
- 缓存策略优化
|
|
154
|
+
|
|
155
|
+
### 2. 异步处理
|
|
156
|
+
- Promise-based 异步流程
|
|
157
|
+
- 并发控制优化
|
|
158
|
+
- 错误传播改进
|
|
159
|
+
|
|
160
|
+
### 3. 启动性能
|
|
161
|
+
- 延迟初始化
|
|
162
|
+
- 并行化启动流程
|
|
163
|
+
- 缓存预热策略
|
|
164
|
+
|
|
165
|
+
## 安全改进
|
|
166
|
+
|
|
167
|
+
### 1. 错误安全
|
|
168
|
+
- 完善的异常处理
|
|
169
|
+
- 降级策略
|
|
170
|
+
- 用户友好的错误提示
|
|
171
|
+
|
|
172
|
+
### 2. 资源安全
|
|
173
|
+
- 文件系统访问验证
|
|
174
|
+
- 资源释放保证
|
|
175
|
+
- 内存泄漏防护
|
|
176
|
+
|
|
177
|
+
### 3. 状态安全
|
|
178
|
+
- 状态转换验证
|
|
179
|
+
- 并发状态保护
|
|
180
|
+
- 状态一致性检查
|
|
181
|
+
|
|
182
|
+
## 测试友好性
|
|
183
|
+
|
|
184
|
+
### 1. 可测试性设计
|
|
185
|
+
- 依赖注入支持
|
|
186
|
+
- 接口抽象
|
|
187
|
+
- 副作用隔离
|
|
188
|
+
|
|
189
|
+
### 2. 模拟支持
|
|
190
|
+
- 外部依赖抽象
|
|
191
|
+
- 配置驱动行为
|
|
192
|
+
- 测试钩子支持
|
|
193
|
+
|
|
194
|
+
## 后续优化建议
|
|
195
|
+
|
|
196
|
+
1. **配置管理**:引入配置文件支持
|
|
197
|
+
2. **插件系统**:支持动态加载插件
|
|
198
|
+
3. **监控指标**:添加性能监控
|
|
199
|
+
4. **国际化**:支持多语言界面
|
|
200
|
+
5. **单元测试**:为各模块编写测试用例
|
|
201
|
+
6. **集成测试**:添加端到端测试
|
|
202
|
+
|
|
203
|
+
## 总结
|
|
204
|
+
|
|
205
|
+
本次重构将单体应用转变为模块化、可维护、可扩展的桌面应用架构。通过严格遵循软件工程原则,显著提升了代码质量、可维护性和可扩展性,为后续功能开发奠定了坚实基础。
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 应用主入口
|
|
3
|
+
* 重构后的主程序,遵循SRP、KISS、DRY、YAGNI原则
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { app, BrowserWindow, ipcMain, globalShortcut } = require('electron');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
|
|
9
|
+
// 导入管理器模块
|
|
10
|
+
const AppState = require('./src/core/state-manager');
|
|
11
|
+
const Logger = require('./src/core/logger');
|
|
12
|
+
const ErrorHandler = require('./src/core/error-handler');
|
|
13
|
+
const RuntimeManager = require('./src/services/runtime-manager');
|
|
14
|
+
const ModuleLoader = require('./src/services/module-loader');
|
|
15
|
+
const ServiceManager = require('./src/services/service-manager');
|
|
16
|
+
const TrayManager = require('./src/ui/tray-manager');
|
|
17
|
+
const UpdateManager = require('./src/services/update-manager');
|
|
18
|
+
const AboutDialogManager = require('./src/ui/about-dialog-manager');
|
|
19
|
+
const SplashManager = require('./src/ui/splash-manager');
|
|
20
|
+
const IconManager = require('./src/utils/icon-manager');
|
|
21
|
+
const RuntimeSync = require('./src/utils/runtime-sync');
|
|
22
|
+
const SelfCheck = require('./src/utils/self-check');
|
|
23
|
+
|
|
24
|
+
class PromptManagerApp {
|
|
25
|
+
constructor() {
|
|
26
|
+
this.stateManager = new AppState();
|
|
27
|
+
this.logger = new Logger({ debugEnabled: false });
|
|
28
|
+
this.errorHandler = new ErrorHandler(this.logger);
|
|
29
|
+
this.runtimeManager = new RuntimeManager(this.logger, this.errorHandler);
|
|
30
|
+
this.moduleLoader = new ModuleLoader(this.logger, this.errorHandler);
|
|
31
|
+
this.iconManager = new IconManager();
|
|
32
|
+
this.serviceManager = new ServiceManager(this.logger, this.errorHandler, this.moduleLoader);
|
|
33
|
+
this.updateManager = new UpdateManager(this.logger, this.errorHandler, this.runtimeManager);
|
|
34
|
+
this.aboutDialogManager = new AboutDialogManager(this.logger, this.runtimeManager, this.iconManager);
|
|
35
|
+
this.trayManager = new TrayManager(this.logger, this.errorHandler, this.iconManager);
|
|
36
|
+
this.splashManager = new SplashManager(this.logger, this.iconManager);
|
|
37
|
+
|
|
38
|
+
this.isInitialized = false;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async initialize() {
|
|
42
|
+
if (this.isInitialized) return;
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
this.logger.info('Initializing Prompt Manager Desktop Application');
|
|
46
|
+
|
|
47
|
+
// 显示启动画面
|
|
48
|
+
await this.splashManager.showSplash();
|
|
49
|
+
this.splashManager.updateStatus('正在初始化...', 10);
|
|
50
|
+
|
|
51
|
+
// 运行应用自检
|
|
52
|
+
this.splashManager.updateStatus('正在检查应用环境...', 20);
|
|
53
|
+
const selfCheck = new SelfCheck(this.logger);
|
|
54
|
+
const selfCheckPassed = await selfCheck.run();
|
|
55
|
+
|
|
56
|
+
if (!selfCheckPassed) {
|
|
57
|
+
const report = selfCheck.getReport();
|
|
58
|
+
this.logger.warn('Application self-check found issues:\n' + report);
|
|
59
|
+
|
|
60
|
+
// 即使自检有问题,也继续启动,但记录警告
|
|
61
|
+
this.splashManager.updateStatus('应用环境检查完成(发现一些问题)...', 25);
|
|
62
|
+
} else {
|
|
63
|
+
this.splashManager.updateStatus('应用环境检查完成...', 25);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// 同步环境配置
|
|
67
|
+
await RuntimeSync.syncRuntime();
|
|
68
|
+
this.splashManager.updateStatus('正在同步工具箱...', 35);
|
|
69
|
+
|
|
70
|
+
// 初始化日志系统
|
|
71
|
+
await this.logger.initialize();
|
|
72
|
+
|
|
73
|
+
// 设置应用菜单
|
|
74
|
+
this.setupApplicationMenu();
|
|
75
|
+
|
|
76
|
+
// 初始化系统托盘
|
|
77
|
+
this.splashManager.updateStatus('正在启动托盘服务...', 60);
|
|
78
|
+
await this.trayManager.initialize(this.stateManager);
|
|
79
|
+
|
|
80
|
+
// 设置事件监听
|
|
81
|
+
this.setupEventListeners();
|
|
82
|
+
|
|
83
|
+
// 确保运行时环境
|
|
84
|
+
this.splashManager.updateStatus('正在准备运行时环境...', 70);
|
|
85
|
+
const serverRoot = await this.runtimeManager.ensureRuntimeEnvironment();
|
|
86
|
+
this.stateManager.set('runtimeRoot', serverRoot);
|
|
87
|
+
|
|
88
|
+
// 启动服务
|
|
89
|
+
this.splashManager.updateStatus('正在启动核心服务...', 80);
|
|
90
|
+
await this.startService();
|
|
91
|
+
|
|
92
|
+
this.isInitialized = true;
|
|
93
|
+
this.logger.info('Application initialized successfully');
|
|
94
|
+
|
|
95
|
+
// 关闭启动画面
|
|
96
|
+
this.splashManager.updateStatus('准备就绪...', 100);
|
|
97
|
+
setTimeout(() => {
|
|
98
|
+
this.splashManager.closeSplash();
|
|
99
|
+
}, 500); // 短暂延迟以显示完成状态
|
|
100
|
+
|
|
101
|
+
} catch (error) {
|
|
102
|
+
this.logger.error('Application initialization failed', error);
|
|
103
|
+
|
|
104
|
+
// 关闭启动画面
|
|
105
|
+
this.splashManager.closeSplash();
|
|
106
|
+
|
|
107
|
+
this.errorHandler.handleError('APP_INIT_FAILED', error, {
|
|
108
|
+
logFilePath: this.logger.getLogFilePath()
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
throw error;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
setupApplicationMenu() {
|
|
116
|
+
if (process.platform === 'darwin') {
|
|
117
|
+
app.dock.hide();
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 隐藏默认应用菜单
|
|
121
|
+
const { Menu } = require('electron');
|
|
122
|
+
Menu.setApplicationMenu(null);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
setupEventListeners() {
|
|
126
|
+
// 托盘事件
|
|
127
|
+
this.trayManager.on('service-start-requested', () => this.startService());
|
|
128
|
+
this.trayManager.on('service-stop-requested', () => this.stopService());
|
|
129
|
+
this.trayManager.on('update-check-requested', () => this.checkForUpdates());
|
|
130
|
+
this.trayManager.on('about-dialog-requested', () => this.showAboutDialog());
|
|
131
|
+
this.trayManager.on('quit-requested', () => this.quitApplication());
|
|
132
|
+
|
|
133
|
+
// 服务管理器事件
|
|
134
|
+
this.serviceManager.on('status-update', () => this.trayManager.updateMenu());
|
|
135
|
+
this.serviceManager.on('restart-requested', () => this.restartApplication());
|
|
136
|
+
|
|
137
|
+
// IPC事件
|
|
138
|
+
ipcMain.on('about-window-click', (event, data) => {
|
|
139
|
+
this.aboutDialogManager.handleAboutWindowClick(data);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// 应用事件
|
|
143
|
+
app.on('window-all-closed', (event) => {
|
|
144
|
+
event.preventDefault(); // 防止应用退出
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
app.on('before-quit', async (event) => {
|
|
148
|
+
if (this.stateManager.get('isQuitting')) return;
|
|
149
|
+
|
|
150
|
+
event.preventDefault();
|
|
151
|
+
await this.quitApplication();
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
app.on('activate', () => {
|
|
155
|
+
if (!this.trayManager.tray) {
|
|
156
|
+
this.trayManager.initialize(this.stateManager);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
// 注册全局快捷键
|
|
161
|
+
this.registerGlobalShortcuts();
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* 注册全局快捷键
|
|
166
|
+
*/
|
|
167
|
+
registerGlobalShortcuts() {
|
|
168
|
+
// 注册显示应用的快捷键
|
|
169
|
+
const showAccelerator = process.platform === 'darwin' ? 'Option+Command+P' : 'Alt+Shift+P';
|
|
170
|
+
|
|
171
|
+
const ret = globalShortcut.register(showAccelerator, () => {
|
|
172
|
+
this.logger.info('Global shortcut triggered:', showAccelerator);
|
|
173
|
+
this.bringToFront();
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
if (!ret) {
|
|
177
|
+
this.logger.warn('Failed to register global shortcut:', showAccelerator);
|
|
178
|
+
} else {
|
|
179
|
+
this.logger.info('Global shortcut registered successfully:', showAccelerator);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// 注册隐藏应用的快捷键
|
|
183
|
+
const hideAccelerator = process.platform === 'darwin' ? 'Option+Command+H' : 'Alt+Shift+H';
|
|
184
|
+
|
|
185
|
+
const hideRet = globalShortcut.register(hideAccelerator, () => {
|
|
186
|
+
this.logger.info('Hide shortcut triggered:', hideAccelerator);
|
|
187
|
+
this.sendToBackground();
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
if (!hideRet) {
|
|
191
|
+
this.logger.warn('Failed to register hide shortcut:', hideAccelerator);
|
|
192
|
+
} else {
|
|
193
|
+
this.logger.info('Hide shortcut registered successfully:', hideAccelerator);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// 应用退出时注销所有全局快捷键
|
|
197
|
+
app.on('will-quit', () => {
|
|
198
|
+
globalShortcut.unregisterAll();
|
|
199
|
+
this.logger.info('All global shortcuts unregistered');
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* 将应用带到前台
|
|
205
|
+
*/
|
|
206
|
+
bringToFront() {
|
|
207
|
+
// 显示 Dock 图标 (macOS)
|
|
208
|
+
if (process.platform === 'darwin') {
|
|
209
|
+
app.dock.show();
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// 打开管理后台窗口
|
|
213
|
+
const state = this.stateManager.get();
|
|
214
|
+
const serverAddress = state.server?.address || 'http://127.0.0.1:5621';
|
|
215
|
+
const adminUrl = state.server?.adminPath ?
|
|
216
|
+
`${serverAddress}${state.server.adminPath}` :
|
|
217
|
+
`${serverAddress}/admin`;
|
|
218
|
+
|
|
219
|
+
// 如果服务正在运行,打开管理后台
|
|
220
|
+
if (this.stateManager.isServiceRunning()) {
|
|
221
|
+
this.trayManager.openAdminWindow(adminUrl);
|
|
222
|
+
} else {
|
|
223
|
+
// 如果服务未运行,启动服务
|
|
224
|
+
this.logger.info('Service not running, starting service...');
|
|
225
|
+
this.startService();
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* 将应用隐藏到后台
|
|
231
|
+
*/
|
|
232
|
+
sendToBackground() {
|
|
233
|
+
// 关闭所有窗口
|
|
234
|
+
this.trayManager.adminWindowManager.closeAdminWindow();
|
|
235
|
+
|
|
236
|
+
// 隐藏 Dock 图标 (macOS)
|
|
237
|
+
if (process.platform === 'darwin') {
|
|
238
|
+
app.dock.hide();
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
this.logger.info('Application sent to background');
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
async startService() {
|
|
245
|
+
const serverRoot = this.stateManager.get('runtimeRoot');
|
|
246
|
+
if (!serverRoot) {
|
|
247
|
+
this.logger.error('Cannot start service: runtime root not set');
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
return await this.serviceManager.startService(serverRoot, this.stateManager);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
async stopService() {
|
|
255
|
+
return await this.serviceManager.stopService(this.stateManager);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
async checkForUpdates() {
|
|
259
|
+
try {
|
|
260
|
+
await this.updateManager.checkForUpdates();
|
|
261
|
+
} catch (error) {
|
|
262
|
+
this.logger.error('Update check failed', error);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
showAboutDialog() {
|
|
267
|
+
this.aboutDialogManager.showAboutDialog();
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
handleAboutWindowClick(data) {
|
|
271
|
+
// 委托给AboutDialogManager处理
|
|
272
|
+
this.aboutDialogManager.handleAboutWindowClick(data);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
async restartApplication() {
|
|
276
|
+
this.logger.info('Restarting application');
|
|
277
|
+
|
|
278
|
+
try {
|
|
279
|
+
await this.stopService();
|
|
280
|
+
app.relaunch();
|
|
281
|
+
app.exit(0);
|
|
282
|
+
} catch (error) {
|
|
283
|
+
this.logger.error('Failed to restart application', error);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
async quitApplication() {
|
|
288
|
+
this.logger.info('Quitting application');
|
|
289
|
+
|
|
290
|
+
try {
|
|
291
|
+
this.stateManager.set('isQuitting', true);
|
|
292
|
+
|
|
293
|
+
// 关闭启动画面
|
|
294
|
+
await this.splashManager.closeSplash();
|
|
295
|
+
|
|
296
|
+
// 停止服务
|
|
297
|
+
await this.stopService();
|
|
298
|
+
|
|
299
|
+
// 清理资源
|
|
300
|
+
await this.aboutDialogManager.closeAboutDialog();
|
|
301
|
+
|
|
302
|
+
this.trayManager.destroy();
|
|
303
|
+
await this.logger.close();
|
|
304
|
+
await this.runtimeManager.cleanup();
|
|
305
|
+
|
|
306
|
+
app.quit();
|
|
307
|
+
} catch (error) {
|
|
308
|
+
this.logger.error('Error during application shutdown', error);
|
|
309
|
+
app.quit(); // 强制退出
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// 应用启动
|
|
315
|
+
const promptManagerApp = new PromptManagerApp();
|
|
316
|
+
|
|
317
|
+
app.whenReady().then(async () => {
|
|
318
|
+
try {
|
|
319
|
+
await promptManagerApp.initialize();
|
|
320
|
+
} catch (error) {
|
|
321
|
+
console.error('Failed to start application:', error);
|
|
322
|
+
app.quit();
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
// 异常处理
|
|
327
|
+
process.on('uncaughtException', (error) => {
|
|
328
|
+
console.error('Uncaught Exception:', error);
|
|
329
|
+
if (promptManagerApp.logger) {
|
|
330
|
+
promptManagerApp.logger.error('Uncaught Exception', error);
|
|
331
|
+
}
|
|
332
|
+
app.quit();
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
336
|
+
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
|
|
337
|
+
if (promptManagerApp.logger) {
|
|
338
|
+
promptManagerApp.logger.error('Unhandled Rejection', reason);
|
|
339
|
+
}
|
|
340
|
+
});
|