@becrafter/prompt-manager 0.1.17 → 0.1.20

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.
Files changed (63) hide show
  1. package/env.example +1 -1
  2. package/package.json +19 -7
  3. package/packages/server/server.js +2 -1
  4. package/packages/server/services/TerminalService.js +247 -13
  5. package/packages/server/toolm/tool-sync.service.js +8 -0
  6. package/packages/server/utils/config.js +1 -1
  7. package/packages/web/css/{main.3b61356b384d2f11f47f.css → main.196f434e6a88cd448158.css} +10 -0
  8. package/packages/web/index.html +1 -1
  9. package/packages/web/{main.77c2c4b553ca3fac223b.js → main.b427a9e6f77a32a2f87f.js} +2 -2
  10. package/app/desktop/assets/app.1.png +0 -0
  11. package/app/desktop/assets/app.png +0 -0
  12. package/app/desktop/assets/icons/icon.icns +0 -0
  13. package/app/desktop/assets/icons/icon.ico +0 -0
  14. package/app/desktop/assets/icons/icon.png +0 -0
  15. package/app/desktop/assets/icons/tray.png +0 -0
  16. package/app/desktop/assets/templates/about.html +0 -147
  17. package/app/desktop/assets/tray.1.png +0 -0
  18. package/app/desktop/assets/tray.png +0 -0
  19. package/app/desktop/docs/ASSETS_PLANNING.md +0 -351
  20. package/app/desktop/docs/REFACTORING_SUMMARY.md +0 -205
  21. package/app/desktop/main.js +0 -340
  22. package/app/desktop/package-lock.json +0 -6912
  23. package/app/desktop/package.json +0 -119
  24. package/app/desktop/preload.js +0 -7
  25. package/app/desktop/src/core/error-handler.js +0 -108
  26. package/app/desktop/src/core/event-emitter.js +0 -84
  27. package/app/desktop/src/core/logger.js +0 -130
  28. package/app/desktop/src/core/state-manager.js +0 -125
  29. package/app/desktop/src/services/module-loader.js +0 -330
  30. package/app/desktop/src/services/runtime-manager.js +0 -398
  31. package/app/desktop/src/services/service-manager.js +0 -210
  32. package/app/desktop/src/services/update-manager.js +0 -267
  33. package/app/desktop/src/ui/about-dialog-manager.js +0 -208
  34. package/app/desktop/src/ui/admin-window-manager.js +0 -757
  35. package/app/desktop/src/ui/splash-manager.js +0 -253
  36. package/app/desktop/src/ui/tray-manager.js +0 -186
  37. package/app/desktop/src/utils/icon-manager.js +0 -133
  38. package/app/desktop/src/utils/path-utils.js +0 -58
  39. package/app/desktop/src/utils/resource-paths.js +0 -49
  40. package/app/desktop/src/utils/resource-sync.js +0 -260
  41. package/app/desktop/src/utils/runtime-sync.js +0 -241
  42. package/app/desktop/src/utils/self-check.js +0 -288
  43. package/app/desktop/src/utils/template-renderer.js +0 -284
  44. package/app/desktop/src/utils/version-utils.js +0 -59
  45. package/packages/server/.eslintrc.js +0 -70
  46. package/packages/server/.husky/pre-commit +0 -8
  47. package/packages/server/.husky/pre-push +0 -8
  48. package/packages/server/.prettierrc +0 -14
  49. package/packages/server/dev-server.js +0 -90
  50. package/packages/server/jsdoc.conf.json +0 -39
  51. package/packages/server/package.json +0 -85
  52. package/packages/server/playwright.config.js +0 -62
  53. package/packages/server/scripts/generate-docs.js +0 -300
  54. package/packages/server/tests/e2e/terminal-e2e.test.js +0 -315
  55. package/packages/server/tests/integration/terminal-websocket.test.js +0 -372
  56. package/packages/server/tests/integration/tools.test.js +0 -264
  57. package/packages/server/tests/setup.js +0 -45
  58. package/packages/server/tests/unit/TerminalService.test.js +0 -410
  59. package/packages/server/tests/unit/WebSocketService.test.js +0 -403
  60. package/packages/server/tests/unit/core.test.js +0 -94
  61. package/packages/server/typedoc.json +0 -52
  62. package/packages/server/vitest.config.js +0 -74
  63. /package/packages/web/{main.77c2c4b553ca3fac223b.js.LICENSE.txt → main.b427a9e6f77a32a2f87f.js.LICENSE.txt} +0 -0
@@ -1,119 +0,0 @@
1
- {
2
- "name": "@becrafter/prompt-desktop",
3
- "version": "0.1.17",
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/rebuild": "^4.0.2",
17
- "electron": "39.0.0",
18
- "electron-builder": "^24.13.3",
19
- "electron-rebuild": "^3.2.9"
20
- },
21
- "dependencies": {
22
- "@becrafter/prompt-manager-core": "file:../../packages/server",
23
- "@modelcontextprotocol/sdk": "^1.20.2",
24
- "cors": "^2.8.5",
25
- "dotenv": "^17.2.3",
26
- "express": "^5.1.0",
27
- "fs-extra": "^11.2.0",
28
- "http-proxy-middleware": "^3.0.5",
29
- "js-yaml": "^4.1.0",
30
- "multer": "^2.0.2",
31
- "node-pty": "^1.0.0",
32
- "tar": "^7.5.2",
33
- "ws": "^8.18.0",
34
- "yaml": "^2.4.1",
35
- "zod": "^3.23.8"
36
- },
37
- "build": {
38
- "appId": "com.becrafter.promptserver",
39
- "productName": "Prompt Manager",
40
- "icon": "assets/icons/icon.png",
41
- "npmRebuild": true,
42
- "files": [
43
- "**/*",
44
- "assets/**/*",
45
- "!docs",
46
- "!.npmignore",
47
- "!assets/**/*.1.png",
48
- "!node_modules/**/test/**",
49
- "!node_modules/**/example/**",
50
- "!node_modules/**/*.md",
51
- "!node_modules/**/LICENSE",
52
- {
53
- "from": "../../packages/web/",
54
- "to": "web/",
55
- "filter": [
56
- "**/*"
57
- ]
58
- }
59
- ],
60
- "directories": {
61
- "output": "../../dist",
62
- "buildResources": "assets"
63
- },
64
- "extraResources": [
65
- {
66
- "from": "../../packages/resources/tools/",
67
- "to": "runtime/toolbox/",
68
- "filter": [
69
- "**/*"
70
- ]
71
- },
72
- {
73
- "from": "../../env.example",
74
- "to": "runtime/.env"
75
- },
76
- {
77
- "from": "../../packages/server/configs/",
78
- "to": "runtime/configs/"
79
- }
80
- ],
81
- "mac": {
82
- "category": "public.app-category.productivity",
83
- "icon": "assets/icons/icon.icns",
84
- "target": [
85
- {
86
- "target": "dmg",
87
- "arch": [
88
- "x64",
89
- "arm64"
90
- ]
91
- }
92
- ]
93
- },
94
- "win": {
95
- "target": [
96
- {
97
- "target": "nsis",
98
- "arch": [
99
- "x64",
100
- "arm64"
101
- ]
102
- }
103
- ],
104
- "icon": "assets/icons/icon.ico"
105
- },
106
- "linux": {
107
- "target": [
108
- "AppImage",
109
- "tar.xz"
110
- ],
111
- "category": "Utility",
112
- "maintainer": "support@becrafter.com",
113
- "synopsis": "Menu bar desktop wrapper for Prompt Manager",
114
- "description": "Prompt Manager is a desktop application that provides a menu bar interface for managing prompts via MCP (Model Context Protocol).",
115
- "desktop": {},
116
- "artifactName": "${productName}-${version}.${ext}"
117
- }
118
- }
119
- }
@@ -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,130 +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
- try {
45
- // 始终输出到控制台,但先检查流是否可写
46
- if (level === 'error') {
47
- if (process.stderr && process.stderr.writable) {
48
- process.stderr.write(formattedMessage);
49
- } else {
50
- // 如果 stderr 不可用,使用 console.error 作为后备
51
- console.error(formattedMessage.trim());
52
- }
53
- } else {
54
- if (process.stdout && process.stdout.writable) {
55
- process.stdout.write(formattedMessage);
56
- } else {
57
- // 如果 stdout 不可用,使用 console.log 作为后备
58
- console.log(formattedMessage.trim());
59
- }
60
- }
61
-
62
- // 写入日志文件,检查流是否可写
63
- if (this.logStream && this.logStream.writable) {
64
- const shouldWrite = level === 'error' ||
65
- (this.debugEnabled && ['debug', 'warn'].includes(level)) ||
66
- (!this.debugEnabled && ['info'].includes(level));
67
-
68
- if (shouldWrite) {
69
- this.logStream.write(formattedMessage);
70
- }
71
- }
72
- } catch (error) {
73
- // 静默处理写入错误,避免应用崩溃
74
- // 只在调试模式下记录错误
75
- if (this.debugEnabled) {
76
- try {
77
- console.error(`Logger write error: ${error.message}`);
78
- } catch (e) {
79
- // 如果连 console.error 都失败,就放弃
80
- }
81
- }
82
- }
83
- }
84
-
85
- info(message, meta = {}) {
86
- this.write('info', message, meta);
87
- }
88
-
89
- error(message, error = null, meta = {}) {
90
- const errorMeta = { ...meta };
91
- if (error) {
92
- errorMeta.error = error.message || String(error);
93
- errorMeta.stack = error.stack;
94
- }
95
- this.write('error', message, errorMeta);
96
- }
97
-
98
- warn(message, meta = {}) {
99
- this.write('warn', message, meta);
100
- }
101
-
102
- debug(message, meta = {}) {
103
- if (this.debugEnabled) {
104
- this.write('debug', message, meta);
105
- }
106
- }
107
-
108
- setDebugEnabled(enabled) {
109
- this.debugEnabled = enabled;
110
- this.info(`Debug logging ${enabled ? 'enabled' : 'disabled'}`);
111
- }
112
-
113
- getLogFilePath() {
114
- return this.logFilePath;
115
- }
116
-
117
- async close() {
118
- if (this.logStream) {
119
- return new Promise((resolve) => {
120
- this.logStream.end(() => {
121
- this.logStream = null;
122
- this.initialized = false;
123
- resolve();
124
- });
125
- });
126
- }
127
- }
128
- }
129
-
130
- 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;