@becrafter/prompt-manager 0.1.2 → 0.1.8
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/README.md +304 -121
- package/app/cli/commands/start.js +28 -4
- package/app/cli/support/argv.js +6 -0
- package/env.example +32 -0
- package/package.json +36 -6
- package/packages/server/api/admin.routes.js +409 -1
- package/packages/server/api/open.routes.js +7 -2
- package/packages/server/api/tool.routes.js +479 -0
- package/packages/server/app.js +97 -25
- package/packages/server/configs/models/built-in/bigmodel.yaml +6 -0
- package/packages/server/configs/models/providers.yaml +50 -0
- package/packages/server/configs/templates/built-in/general-iteration.yaml +60 -0
- package/packages/server/configs/templates/built-in/general-optimize.yaml +63 -0
- package/packages/server/configs/templates/built-in/output-format-optimize.yaml +95 -0
- package/packages/server/mcp/heartbeat-patch.js +73 -0
- package/packages/server/mcp/mcp.server.js +63 -314
- package/packages/server/mcp/prompt.handler.js +26 -0
- package/packages/server/mcp/thinking-toolkit.handler.js +380 -0
- package/packages/server/package.json +35 -3
- package/packages/server/server.js +114 -12
- package/packages/server/services/TerminalService.js +498 -0
- package/packages/server/services/WebSocketService.js +484 -0
- package/packages/server/services/manager.js +38 -7
- package/packages/server/services/model.service.js +473 -0
- package/packages/server/services/optimization.service.js +457 -0
- package/packages/server/services/template.service.js +333 -0
- package/packages/server/toolm/tool-description-generator-optimized.service.js +5 -2
- package/packages/server/toolm/tool-sync.service.js +47 -3
- package/packages/server/utils/config.js +8 -1
- package/packages/server/utils/port-checker.js +63 -0
- package/packages/server/utils/util.js +27 -0
- package/IFLOW.md +0 -175
- 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 +0 -147
- package/app/desktop/assets/tray.1.png +0 -0
- package/app/desktop/assets/tray.png +0 -0
- package/app/desktop/main.js +0 -241
- package/app/desktop/package-lock.json +0 -5026
- package/app/desktop/package.json +0 -100
- package/app/desktop/preload.js +0 -7
- package/app/desktop/src/core/error-handler.js +0 -108
- package/app/desktop/src/core/event-emitter.js +0 -84
- package/app/desktop/src/core/logger.js +0 -108
- package/app/desktop/src/core/state-manager.js +0 -125
- package/app/desktop/src/services/module-loader.js +0 -214
- package/app/desktop/src/services/runtime-manager.js +0 -301
- package/app/desktop/src/services/service-manager.js +0 -169
- package/app/desktop/src/services/update-manager.js +0 -267
- package/app/desktop/src/ui/about-dialog-manager.js +0 -208
- package/app/desktop/src/ui/admin-window-manager.js +0 -757
- package/app/desktop/src/ui/splash-manager.js +0 -253
- package/app/desktop/src/ui/tray-manager.js +0 -186
- package/app/desktop/src/utils/icon-manager.js +0 -133
- package/app/desktop/src/utils/path-utils.js +0 -58
- package/app/desktop/src/utils/resource-paths.js +0 -49
- package/app/desktop/src/utils/resource-sync.js +0 -260
- package/app/desktop/src/utils/runtime-sync.js +0 -241
- package/app/desktop/src/utils/template-renderer.js +0 -284
- package/app/desktop/src/utils/version-utils.js +0 -59
- package/examples/prompts/developer/code-review.yaml +0 -32
- package/examples/prompts/developer/code_refactoring.yaml +0 -31
- package/examples/prompts/developer/doc-generator.yaml +0 -36
- package/examples/prompts/developer/error-code-fixer.yaml +0 -35
- package/examples/prompts/engineer/engineer-professional.yaml +0 -92
- package/examples/prompts/engineer/laowang-engineer.yaml +0 -132
- package/examples/prompts/engineer/nekomata-engineer.yaml +0 -123
- package/examples/prompts/engineer/ojousama-engineer.yaml +0 -124
- package/examples/prompts/generator/gen_3d_edu_webpage_html.yaml +0 -117
- package/examples/prompts/generator/gen_3d_webpage_html.yaml +0 -75
- package/examples/prompts/generator/gen_bento_grid_html.yaml +0 -112
- package/examples/prompts/generator/gen_html_web_page.yaml +0 -88
- package/examples/prompts/generator/gen_knowledge_card_html.yaml +0 -83
- package/examples/prompts/generator/gen_magazine_card_html.yaml +0 -82
- package/examples/prompts/generator/gen_mimeng_headline_title.yaml +0 -71
- package/examples/prompts/generator/gen_podcast_script.yaml +0 -69
- package/examples/prompts/generator/gen_prd_prototype_html.yaml +0 -175
- package/examples/prompts/generator/gen_summarize.yaml +0 -157
- package/examples/prompts/generator/gen_title.yaml +0 -119
- package/examples/prompts/generator/others/api_documentation.yaml +0 -32
- package/examples/prompts/generator/others/build_mcp_server.yaml +0 -26
- package/examples/prompts/generator/others/project_architecture.yaml +0 -31
- package/examples/prompts/generator/others/test_case_generator.yaml +0 -30
- package/examples/prompts/generator/others/writing_assistant.yaml +0 -72
- package/examples/prompts/recommend/human_3-0_growth_diagnostic_coach_prompt.yaml +0 -105
- package/examples/prompts/workflow/sixstep-workflow.yaml +0 -192
- package/packages/admin-ui/.babelrc +0 -3
- package/packages/admin-ui/admin.html +0 -412
- package/packages/admin-ui/css/codemirror-theme_xq-light.css +0 -43
- package/packages/admin-ui/css/codemirror.css +0 -344
- package/packages/admin-ui/css/main.css +0 -2592
- package/packages/admin-ui/css/recommended-prompts.css +0 -610
- package/packages/admin-ui/package-lock.json +0 -6973
- package/packages/admin-ui/package.json +0 -36
- package/packages/admin-ui/src/codemirror.js +0 -53
- package/packages/admin-ui/src/index.js +0 -3188
- package/packages/admin-ui/webpack.config.js +0 -76
- package/packages/server/toolm/test-tools.js +0 -264
- package/scripts/build-icons.js +0 -135
- package/scripts/build.sh +0 -57
- package/scripts/postinstall.js +0 -34
- package/scripts/surge/CNAME +0 -1
- package/scripts/surge/README.md +0 -47
- package/scripts/surge/package-lock.json +0 -34
- package/scripts/surge/package.json +0 -20
- package/scripts/surge/sync-to-surge.js +0 -151
package/app/desktop/package.json
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@becrafter/prompt-desktop",
|
|
3
|
-
"version": "0.1.2",
|
|
4
|
-
"description": "Menu bar desktop wrapper for @becrafter/prompt-manager",
|
|
5
|
-
"author": "BeCrafter",
|
|
6
|
-
"homepage": "https://github.com/BeCrafter/prompt-manager",
|
|
7
|
-
"private": true,
|
|
8
|
-
"main": "main.js",
|
|
9
|
-
"scripts": {
|
|
10
|
-
"dev": "electron .",
|
|
11
|
-
"start": "npm run dev",
|
|
12
|
-
"prebuild": "cd ../.. && npm run build:icons",
|
|
13
|
-
"build": "electron-builder"
|
|
14
|
-
},
|
|
15
|
-
"devDependencies": {
|
|
16
|
-
"electron": "^39.0.0",
|
|
17
|
-
"electron-builder": "^24.13.3"
|
|
18
|
-
},
|
|
19
|
-
"dependencies": {
|
|
20
|
-
"@becrafter/prompt-manager-core": "file:../../packages/server",
|
|
21
|
-
"@modelcontextprotocol/sdk": "^1.20.2",
|
|
22
|
-
"http-proxy-middleware": "^3.0.5",
|
|
23
|
-
"tar": "^7.5.2"
|
|
24
|
-
},
|
|
25
|
-
"build": {
|
|
26
|
-
"appId": "com.becrafter.promptserver",
|
|
27
|
-
"productName": "Prompt Manager",
|
|
28
|
-
"icon": "assets/icons/icon.png",
|
|
29
|
-
"files": [
|
|
30
|
-
"**/*",
|
|
31
|
-
"assets/**/*",
|
|
32
|
-
"!docs",
|
|
33
|
-
"!.npmignore",
|
|
34
|
-
"!assets/**/*.1.png",
|
|
35
|
-
"!node_modules/**/test/**",
|
|
36
|
-
"!node_modules/**/example/**",
|
|
37
|
-
"!node_modules/**/*.md",
|
|
38
|
-
"!node_modules/**/LICENSE",
|
|
39
|
-
{
|
|
40
|
-
"from": "../../packages/web/",
|
|
41
|
-
"to": "web/",
|
|
42
|
-
"filter": ["**/*"]
|
|
43
|
-
}
|
|
44
|
-
],
|
|
45
|
-
"directories": {
|
|
46
|
-
"output": "../../dist",
|
|
47
|
-
"buildResources": "assets"
|
|
48
|
-
},
|
|
49
|
-
"extraResources": [
|
|
50
|
-
{
|
|
51
|
-
"from": "../../packages/resources/tools/",
|
|
52
|
-
"to": "runtime/toolbox/",
|
|
53
|
-
"filter": ["**/*"]
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
"from": "../../env.example",
|
|
57
|
-
"to": "runtime/.env"
|
|
58
|
-
}
|
|
59
|
-
],
|
|
60
|
-
"mac": {
|
|
61
|
-
"category": "public.app-category.productivity",
|
|
62
|
-
"icon": "assets/icons/icon.icns",
|
|
63
|
-
"target": [
|
|
64
|
-
{
|
|
65
|
-
"target": "dmg",
|
|
66
|
-
"arch": [
|
|
67
|
-
"x64",
|
|
68
|
-
"arm64"
|
|
69
|
-
]
|
|
70
|
-
}
|
|
71
|
-
]
|
|
72
|
-
},
|
|
73
|
-
"win": {
|
|
74
|
-
"target": [
|
|
75
|
-
{
|
|
76
|
-
"target": "nsis",
|
|
77
|
-
"arch": [
|
|
78
|
-
"x64",
|
|
79
|
-
"arm64"
|
|
80
|
-
]
|
|
81
|
-
}
|
|
82
|
-
],
|
|
83
|
-
"icon": "assets/icons/icon.ico"
|
|
84
|
-
},
|
|
85
|
-
"linux": {
|
|
86
|
-
"target": [
|
|
87
|
-
"AppImage",
|
|
88
|
-
"tar.xz"
|
|
89
|
-
],
|
|
90
|
-
"category": "Utility",
|
|
91
|
-
"maintainer": "support@becrafter.com",
|
|
92
|
-
"synopsis": "Menu bar desktop wrapper for Prompt Manager",
|
|
93
|
-
"description": "Prompt Manager is a desktop application that provides a menu bar interface for managing prompts via MCP (Model Context Protocol).",
|
|
94
|
-
"desktop": {
|
|
95
|
-
"StartupNotify": "true"
|
|
96
|
-
},
|
|
97
|
-
"artifactName": "${productName}-${version}.${ext}"
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
package/app/desktop/preload.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
const { contextBridge, ipcRenderer } = require('electron');
|
|
2
|
-
|
|
3
|
-
// 安全地暴露API到渲染进程
|
|
4
|
-
contextBridge.exposeInMainWorld('electronAPI', {
|
|
5
|
-
sendAboutWindowClick: (data) => ipcRenderer.send('about-window-click', data),
|
|
6
|
-
onAboutWindowClick: (callback) => ipcRenderer.on('about-window-click-response', callback)
|
|
7
|
-
});
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
const { dialog } = require('electron');
|
|
2
|
-
|
|
3
|
-
class ErrorHandler {
|
|
4
|
-
constructor(logger) {
|
|
5
|
-
this.logger = logger;
|
|
6
|
-
this.errorMessages = {
|
|
7
|
-
MODULE_LOAD_FAILED: '模块加载失败',
|
|
8
|
-
SERVER_INIT_FAILED: '服务器初始化失败',
|
|
9
|
-
DEPENDENCY_INSTALL_FAILED: '依赖安装失败',
|
|
10
|
-
SERVICE_START_FAILED: '服务启动失败',
|
|
11
|
-
SERVICE_STOP_FAILED: '服务停止失败',
|
|
12
|
-
UPGRADE_FAILED: '升级失败',
|
|
13
|
-
ICON_LOAD_FAILED: '图标加载失败'
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
handleError(errorType, error, context = {}) {
|
|
18
|
-
const errorMessage = this.formatErrorMessage(errorType, error, context);
|
|
19
|
-
|
|
20
|
-
// 记录错误日志
|
|
21
|
-
this.logger.error(errorMessage, error, {
|
|
22
|
-
errorType,
|
|
23
|
-
context,
|
|
24
|
-
timestamp: new Date().toISOString()
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
// 显示用户友好的错误提示
|
|
28
|
-
this.showErrorDialog(errorType, errorMessage, context);
|
|
29
|
-
|
|
30
|
-
return errorMessage;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
formatErrorMessage(errorType, error, context) {
|
|
34
|
-
const baseMessage = this.errorMessages[errorType] || '发生未知错误';
|
|
35
|
-
const detailMessage = error?.message || String(error);
|
|
36
|
-
|
|
37
|
-
let fullMessage = `${baseMessage}: ${detailMessage}`;
|
|
38
|
-
|
|
39
|
-
if (context.logFilePath) {
|
|
40
|
-
fullMessage += `\n\n请查看日志文件: ${context.logFilePath}`;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return fullMessage;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
showErrorDialog(errorType, message, context = {}) {
|
|
47
|
-
const options = {
|
|
48
|
-
type: 'error',
|
|
49
|
-
title: '错误',
|
|
50
|
-
message: message.split('\n')[0], // 第一行作为标题
|
|
51
|
-
detail: message.split('\n').slice(1).join('\n') // 其余作为详情
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
// 特殊错误类型的自定义处理
|
|
55
|
-
switch (errorType) {
|
|
56
|
-
case 'SERVICE_START_FAILED':
|
|
57
|
-
if (context.failureCount >= 3) {
|
|
58
|
-
options.buttons = ['重启应用', '取消'];
|
|
59
|
-
options.defaultId = 0;
|
|
60
|
-
options.cancelId = 1;
|
|
61
|
-
options.message = '服务启动失败';
|
|
62
|
-
options.detail = '多次尝试启动服务均失败,建议重启应用以恢复正常状态。';
|
|
63
|
-
}
|
|
64
|
-
break;
|
|
65
|
-
|
|
66
|
-
case 'DEPENDENCY_INSTALL_FAILED':
|
|
67
|
-
options.message = '依赖安装失败';
|
|
68
|
-
options.detail = `无法安装服务器依赖: ${context.detail || '未知错误'}\n\n请查看日志文件获取更多信息。`;
|
|
69
|
-
break;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return dialog.showMessageBox(options);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
async handleServiceStartError(error, failureCount, logFilePath) {
|
|
76
|
-
const context = { failureCount, logFilePath };
|
|
77
|
-
|
|
78
|
-
if (failureCount >= 3) {
|
|
79
|
-
const { response } = await this.showErrorDialog('SERVICE_START_FAILED', '', context);
|
|
80
|
-
return response === 0; // 返回是否需要重启
|
|
81
|
-
} else {
|
|
82
|
-
this.handleError('SERVICE_START_FAILED', error, context);
|
|
83
|
-
return false;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
handleModuleLoadError(error, context = {}) {
|
|
88
|
-
return this.handleError('MODULE_LOAD_FAILED', error, context);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
handleServerInitError(error, context = {}) {
|
|
92
|
-
return this.handleError('SERVER_INIT_FAILED', error, context);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
handleDependencyInstallError(error, context = {}) {
|
|
96
|
-
return this.handleError('DEPENDENCY_INSTALL_FAILED', error, context);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
handleUpgradeError(error, context = {}) {
|
|
100
|
-
return this.handleError('UPGRADE_FAILED', error, context);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
handleIconLoadError(error, context = {}) {
|
|
104
|
-
return this.handleError('ICON_LOAD_FAILED', error, context);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
module.exports = ErrorHandler;
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 事件发射器基类
|
|
3
|
-
* 提供标准化的事件处理功能
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
class EventEmitter {
|
|
7
|
-
constructor() {
|
|
8
|
-
this.listeners = {};
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* 添加事件监听器
|
|
13
|
-
* @param {string} event - 事件名称
|
|
14
|
-
* @param {function} listener - 监听器函数
|
|
15
|
-
*/
|
|
16
|
-
on(event, listener) {
|
|
17
|
-
if (!this.listeners[event]) {
|
|
18
|
-
this.listeners[event] = [];
|
|
19
|
-
}
|
|
20
|
-
this.listeners[event].push(listener);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* 移除事件监听器
|
|
25
|
-
* @param {string} event - 事件名称
|
|
26
|
-
* @param {function} listener - 监听器函数
|
|
27
|
-
*/
|
|
28
|
-
off(event, listener) {
|
|
29
|
-
if (!this.listeners[event]) return;
|
|
30
|
-
|
|
31
|
-
const index = this.listeners[event].indexOf(listener);
|
|
32
|
-
if (index > -1) {
|
|
33
|
-
this.listeners[event].splice(index, 1);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* 发射事件
|
|
39
|
-
* @param {string} event - 事件名称
|
|
40
|
-
* @param {...any} args - 传递给监听器的参数
|
|
41
|
-
*/
|
|
42
|
-
emit(event, ...args) {
|
|
43
|
-
if (!this.listeners[event]) return;
|
|
44
|
-
|
|
45
|
-
this.listeners[event].forEach(listener => {
|
|
46
|
-
try {
|
|
47
|
-
listener(...args);
|
|
48
|
-
} catch (error) {
|
|
49
|
-
console.error(`Error in event listener for ${event}:`, error);
|
|
50
|
-
}
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* 移除指定事件的所有监听器
|
|
56
|
-
* @param {string} event - 事件名称
|
|
57
|
-
*/
|
|
58
|
-
removeAllListeners(event) {
|
|
59
|
-
if (event) {
|
|
60
|
-
delete this.listeners[event];
|
|
61
|
-
} else {
|
|
62
|
-
this.listeners = {};
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* 获取指定事件的监听器数量
|
|
68
|
-
* @param {string} event - 事件名称
|
|
69
|
-
* @returns {number} - 监听器数量
|
|
70
|
-
*/
|
|
71
|
-
listenerCount(event) {
|
|
72
|
-
return this.listeners[event] ? this.listeners[event].length : 0;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* 获取所有事件名称
|
|
77
|
-
* @returns {string[]} - 事件名称数组
|
|
78
|
-
*/
|
|
79
|
-
eventNames() {
|
|
80
|
-
return Object.keys(this.listeners);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
module.exports = EventEmitter;
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
const { app } = require('electron');
|
|
4
|
-
|
|
5
|
-
class Logger {
|
|
6
|
-
constructor(options = {}) {
|
|
7
|
-
this.logFilePath = options.logFilePath || path.join(app.getPath('userData'), 'prompt-manager-desktop.log');
|
|
8
|
-
this.debugEnabled = options.debugEnabled || false;
|
|
9
|
-
this.logStream = null;
|
|
10
|
-
this.initialized = false;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
async initialize() {
|
|
14
|
-
if (this.initialized) return;
|
|
15
|
-
|
|
16
|
-
try {
|
|
17
|
-
const logDir = path.dirname(this.logFilePath);
|
|
18
|
-
if (!fs.existsSync(logDir)) {
|
|
19
|
-
fs.mkdirSync(logDir, { recursive: true });
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
this.logStream = fs.createWriteStream(this.logFilePath, { flags: 'a' });
|
|
23
|
-
this.initialized = true;
|
|
24
|
-
|
|
25
|
-
this.info('Logging initialized', { logFile: this.logFilePath });
|
|
26
|
-
this.info(`Debug logging is ${this.debugEnabled ? 'enabled' : 'disabled'}`);
|
|
27
|
-
} catch (error) {
|
|
28
|
-
console.error('Failed to initialize logging:', error);
|
|
29
|
-
throw error;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
formatMessage(level, message, meta = {}) {
|
|
34
|
-
const timestamp = new Date().toISOString();
|
|
35
|
-
const metaStr = Object.keys(meta).length ? ` ${JSON.stringify(meta)}` : '';
|
|
36
|
-
return `[${timestamp}] [${level.toUpperCase()}] ${message}${metaStr}\n`;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
write(level, message, meta = {}) {
|
|
40
|
-
if (!this.initialized && level !== 'error') return;
|
|
41
|
-
|
|
42
|
-
const formattedMessage = this.formatMessage(level, message, meta);
|
|
43
|
-
|
|
44
|
-
// 始终输出到控制台
|
|
45
|
-
if (level === 'error') {
|
|
46
|
-
process.stderr.write(formattedMessage);
|
|
47
|
-
} else {
|
|
48
|
-
process.stdout.write(formattedMessage);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// 写入日志文件
|
|
52
|
-
if (this.logStream) {
|
|
53
|
-
const shouldWrite = level === 'error' ||
|
|
54
|
-
(this.debugEnabled && ['debug', 'warn'].includes(level)) ||
|
|
55
|
-
(!this.debugEnabled && ['info'].includes(level));
|
|
56
|
-
|
|
57
|
-
if (shouldWrite) {
|
|
58
|
-
this.logStream.write(formattedMessage);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
info(message, meta = {}) {
|
|
64
|
-
this.write('info', message, meta);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
error(message, error = null, meta = {}) {
|
|
68
|
-
const errorMeta = { ...meta };
|
|
69
|
-
if (error) {
|
|
70
|
-
errorMeta.error = error.message || String(error);
|
|
71
|
-
errorMeta.stack = error.stack;
|
|
72
|
-
}
|
|
73
|
-
this.write('error', message, errorMeta);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
warn(message, meta = {}) {
|
|
77
|
-
this.write('warn', message, meta);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
debug(message, meta = {}) {
|
|
81
|
-
if (this.debugEnabled) {
|
|
82
|
-
this.write('debug', message, meta);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
setDebugEnabled(enabled) {
|
|
87
|
-
this.debugEnabled = enabled;
|
|
88
|
-
this.info(`Debug logging ${enabled ? 'enabled' : 'disabled'}`);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
getLogFilePath() {
|
|
92
|
-
return this.logFilePath;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
async close() {
|
|
96
|
-
if (this.logStream) {
|
|
97
|
-
return new Promise((resolve) => {
|
|
98
|
-
this.logStream.end(() => {
|
|
99
|
-
this.logStream = null;
|
|
100
|
-
this.initialized = false;
|
|
101
|
-
resolve();
|
|
102
|
-
});
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
module.exports = Logger;
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
const { app } = require('electron');
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* 应用状态管理器
|
|
5
|
-
* 遵循单一职责原则,集中管理应用状态
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
class AppState {
|
|
9
|
-
constructor() {
|
|
10
|
-
this.state = {
|
|
11
|
-
service: 'stopped', // stopped | starting | running | stopping | error
|
|
12
|
-
server: null,
|
|
13
|
-
module: null,
|
|
14
|
-
moduleVersion: 0,
|
|
15
|
-
moduleLoading: null,
|
|
16
|
-
isQuitting: false,
|
|
17
|
-
runtimeRoot: null,
|
|
18
|
-
failureCount: 0,
|
|
19
|
-
debugEnabled: false
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
this.clickCounters = {
|
|
23
|
-
aboutButton: { count: 0, lastTime: 0 },
|
|
24
|
-
aboutWindow: { count: 0, lastTime: 0 }
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
this.ui = {
|
|
28
|
-
tray: null,
|
|
29
|
-
adminWindow: null,
|
|
30
|
-
aboutWindow: null
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
get(key) {
|
|
35
|
-
return key ? this.state[key] : { ...this.state };
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
set(key, value) {
|
|
39
|
-
if (typeof key === 'object') {
|
|
40
|
-
Object.assign(this.state, key);
|
|
41
|
-
} else {
|
|
42
|
-
this.state[key] = value;
|
|
43
|
-
}
|
|
44
|
-
return this;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
getServiceStatus() {
|
|
48
|
-
const statusMap = {
|
|
49
|
-
running: '运行中',
|
|
50
|
-
starting: '启动中',
|
|
51
|
-
stopping: '停止中',
|
|
52
|
-
error: '启动失败',
|
|
53
|
-
stopped: '已停止'
|
|
54
|
-
};
|
|
55
|
-
return statusMap[this.state.service] || '未知状态';
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
getClickCounter(type) {
|
|
59
|
-
return this.clickCounters[type] || { count: 0, lastTime: 0 };
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
updateClickCounter(type, increment = 1) {
|
|
63
|
-
const now = Date.now();
|
|
64
|
-
const counter = this.clickCounters[type];
|
|
65
|
-
|
|
66
|
-
if (now - counter.lastTime > 3000) {
|
|
67
|
-
counter.count = 0;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
counter.count += increment;
|
|
71
|
-
counter.lastTime = now;
|
|
72
|
-
|
|
73
|
-
return counter.count;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
resetClickCounter(type) {
|
|
77
|
-
this.clickCounters[type] = { count: 0, lastTime: 0 };
|
|
78
|
-
return this;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
getUI(component) {
|
|
82
|
-
return component ? this.ui[component] : { ...this.ui };
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
setUI(component, instance) {
|
|
86
|
-
this.ui[component] = instance;
|
|
87
|
-
return this;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
isServiceRunning() {
|
|
91
|
-
return this.state.service === 'running';
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
isServiceStarting() {
|
|
95
|
-
return this.state.service === 'starting';
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
isServiceStopping() {
|
|
99
|
-
return this.state.service === 'stopping';
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
canStartService() {
|
|
103
|
-
return ['stopped', 'error'].includes(this.state.service);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
canStopService() {
|
|
107
|
-
return ['running', 'error'].includes(this.state.service);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
incrementFailureCount() {
|
|
111
|
-
this.state.failureCount++;
|
|
112
|
-
return this.state.failureCount;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
resetFailureCount() {
|
|
116
|
-
this.state.failureCount = 0;
|
|
117
|
-
return this;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
shouldPromptForRestart() {
|
|
121
|
-
return this.state.failureCount >= 3;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
module.exports = AppState;
|