@becrafter/prompt-manager 0.0.19 → 0.1.2

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 (104) hide show
  1. package/README.md +145 -234
  2. package/app/desktop/assets/app.1.png +0 -0
  3. package/app/desktop/assets/app.png +0 -0
  4. package/app/desktop/assets/icons/icon.icns +0 -0
  5. package/app/desktop/assets/icons/icon.ico +0 -0
  6. package/app/desktop/assets/icons/icon.png +0 -0
  7. package/app/desktop/assets/icons/tray.png +0 -0
  8. package/app/desktop/assets/tray.1.png +0 -0
  9. package/app/desktop/assets/tray.png +0 -0
  10. package/app/desktop/main.js +27 -0
  11. package/app/desktop/package-lock.json +201 -4
  12. package/app/desktop/package.json +23 -29
  13. package/app/desktop/src/services/module-loader.js +43 -22
  14. package/app/desktop/src/services/runtime-manager.js +172 -23
  15. package/app/desktop/src/services/update-manager.js +6 -7
  16. package/app/desktop/src/ui/admin-window-manager.js +757 -0
  17. package/app/desktop/src/ui/splash-manager.js +253 -0
  18. package/app/desktop/src/ui/tray-manager.js +8 -24
  19. package/app/desktop/src/utils/icon-manager.js +39 -47
  20. package/app/desktop/src/utils/resource-paths.js +0 -23
  21. package/app/desktop/src/utils/resource-sync.js +260 -0
  22. package/app/desktop/src/utils/runtime-sync.js +241 -0
  23. package/examples/prompts/recommend/human_3-0_growth_diagnostic_coach_prompt.yaml +105 -0
  24. package/package.json +16 -13
  25. package/packages/admin-ui/.babelrc +3 -0
  26. package/packages/admin-ui/admin.html +237 -4784
  27. package/packages/admin-ui/css/main.css +2592 -0
  28. package/packages/admin-ui/css/recommended-prompts.css +610 -0
  29. package/packages/admin-ui/package-lock.json +6973 -0
  30. package/packages/admin-ui/package.json +36 -0
  31. package/packages/admin-ui/src/codemirror.js +53 -0
  32. package/packages/admin-ui/src/index.js +3188 -0
  33. package/packages/admin-ui/webpack.config.js +76 -0
  34. package/packages/resources/tools/chrome-devtools/README.md +310 -0
  35. package/packages/resources/tools/chrome-devtools/chrome-devtools.tool.js +1703 -0
  36. package/packages/resources/tools/file-reader/README.md +289 -0
  37. package/packages/resources/tools/file-reader/file-reader.tool.js +1545 -0
  38. package/packages/resources/tools/filesystem/README.md +359 -0
  39. package/packages/resources/tools/filesystem/filesystem.tool.js +514 -160
  40. package/packages/resources/tools/ollama-remote/README.md +192 -0
  41. package/packages/resources/tools/ollama-remote/ollama-remote.tool.js +421 -0
  42. package/packages/resources/tools/pdf-reader/README.md +236 -0
  43. package/packages/resources/tools/pdf-reader/pdf-reader.tool.js +565 -0
  44. package/packages/resources/tools/playwright/README.md +306 -0
  45. package/packages/resources/tools/playwright/playwright.tool.js +1186 -0
  46. package/packages/resources/tools/todolist/README.md +394 -0
  47. package/packages/resources/tools/todolist/todolist.tool.js +1312 -0
  48. package/packages/server/README.md +142 -0
  49. package/packages/server/api/admin.routes.js +42 -11
  50. package/packages/server/api/surge.routes.js +43 -0
  51. package/packages/server/app.js +119 -14
  52. package/packages/server/index.js +39 -0
  53. package/packages/server/mcp/mcp.server.js +324 -105
  54. package/packages/server/mcp/sequential-thinking.handler.js +318 -0
  55. package/packages/server/mcp/think-plan.handler.js +274 -0
  56. package/packages/server/middlewares/auth.middleware.js +6 -0
  57. package/packages/server/package.json +51 -0
  58. package/packages/server/server.js +37 -1
  59. package/packages/server/toolm/index.js +9 -0
  60. package/packages/server/toolm/package-installer.service.js +267 -0
  61. package/packages/server/toolm/test-tools.js +264 -0
  62. package/packages/server/toolm/tool-context.service.js +334 -0
  63. package/packages/server/toolm/tool-dependency.service.js +168 -0
  64. package/packages/server/toolm/tool-description-generator-optimized.service.js +375 -0
  65. package/packages/server/toolm/tool-description-generator.service.js +312 -0
  66. package/packages/server/toolm/tool-environment.service.js +200 -0
  67. package/packages/server/toolm/tool-execution.service.js +277 -0
  68. package/packages/server/toolm/tool-loader.service.js +219 -0
  69. package/packages/server/toolm/tool-logger.service.js +223 -0
  70. package/packages/server/toolm/tool-manager.handler.js +65 -0
  71. package/packages/server/toolm/tool-manual-generator.service.js +389 -0
  72. package/packages/server/toolm/tool-mode-handlers.service.js +224 -0
  73. package/packages/server/toolm/tool-storage.service.js +111 -0
  74. package/packages/server/toolm/tool-sync.service.js +138 -0
  75. package/packages/server/toolm/tool-utils.js +20 -0
  76. package/packages/server/toolm/tool-yaml-parser.service.js +81 -0
  77. package/packages/server/toolm/validate-system.js +421 -0
  78. package/packages/server/utils/config.js +49 -5
  79. package/packages/server/utils/util.js +65 -10
  80. package/scripts/build-icons.js +99 -69
  81. package/scripts/build.sh +57 -0
  82. package/scripts/surge/CNAME +1 -0
  83. package/scripts/surge/README.md +47 -0
  84. package/scripts/surge/package-lock.json +34 -0
  85. package/scripts/surge/package.json +20 -0
  86. package/scripts/surge/sync-to-surge.js +151 -0
  87. package/app/desktop/assets/icons/icon_1024x1024.png +0 -0
  88. package/app/desktop/assets/icons/icon_128x128.png +0 -0
  89. package/app/desktop/assets/icons/icon_16x16.png +0 -0
  90. package/app/desktop/assets/icons/icon_24x24.png +0 -0
  91. package/app/desktop/assets/icons/icon_256x256.png +0 -0
  92. package/app/desktop/assets/icons/icon_32x32.png +0 -0
  93. package/app/desktop/assets/icons/icon_48x48.png +0 -0
  94. package/app/desktop/assets/icons/icon_512x512.png +0 -0
  95. package/app/desktop/assets/icons/icon_64x64.png +0 -0
  96. package/app/desktop/assets/icons/icon_96x96.png +0 -0
  97. package/packages/admin-ui/js/closebrackets.min.js +0 -8
  98. package/packages/admin-ui/js/codemirror.min.js +0 -8
  99. package/packages/admin-ui/js/js-yaml.min.js +0 -2
  100. package/packages/admin-ui/js/markdown.min.js +0 -8
  101. package/packages/resources/tools/index.js +0 -16
  102. package/packages/server/mcp/toolx.handler.js +0 -131
  103. package/scripts/icns-builder/package.json +0 -12
  104. /package/packages/server/mcp/{mcp.handler.js → prompt.handler.js} +0 -0
@@ -0,0 +1,253 @@
1
+ const { BrowserWindow, nativeImage } = require('electron');
2
+ const path = require('path');
3
+
4
+ class SplashManager {
5
+ constructor(logger, iconManager) {
6
+ this.logger = logger;
7
+ this.iconManager = iconManager;
8
+ this.splashWindow = null;
9
+ }
10
+
11
+ /**
12
+ * 创建并显示启动画面
13
+ */
14
+ async showSplash() {
15
+ this.logger.info('Showing splash screen');
16
+
17
+ // 如果启动画面已存在,直接返回
18
+ if (this.splashWindow) {
19
+ return;
20
+ }
21
+
22
+ try {
23
+ // 创建启动窗口
24
+ this.splashWindow = this.createSplashWindow();
25
+
26
+ // 加载启动画面内容
27
+ const htmlContent = this.generateSplashHTML();
28
+ this.splashWindow.loadURL(`data:text/html;charset=utf-8,${encodeURIComponent(htmlContent)}`);
29
+
30
+ // 设置窗口事件
31
+ this.setupWindowEvents();
32
+
33
+ this.logger.info('Splash screen shown successfully');
34
+
35
+ } catch (error) {
36
+ this.logger.error('Failed to show splash screen', error);
37
+ // 如果启动画面失败,不阻塞主流程
38
+ }
39
+ }
40
+
41
+ /**
42
+ * 创建启动窗口
43
+ */
44
+ createSplashWindow() {
45
+ return new BrowserWindow({
46
+ width: 400,
47
+ height: 100,
48
+ transparent: true,
49
+ frame: false,
50
+ resizable: false,
51
+ movable: false,
52
+ fullscreenable: false,
53
+ hasShadow: false,
54
+ alwaysOnTop: true,
55
+ show: false,
56
+ webPreferences: {
57
+ contextIsolation: true,
58
+ nodeIntegration: false,
59
+ sandbox: false
60
+ }
61
+ });
62
+ }
63
+
64
+ /**
65
+ * 生成启动画面HTML内容
66
+ */
67
+ generateSplashHTML() {
68
+ return `<!DOCTYPE html>
69
+ <html>
70
+ <head>
71
+ <meta charset="UTF-8">
72
+ <title>Prompt Manager - Loading</title>
73
+ <style>
74
+ body {
75
+ margin: 0;
76
+ padding: 0;
77
+ background: transparent;
78
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
79
+ display: flex;
80
+ align-items: center;
81
+ justify-content: center;
82
+ height: 100vh;
83
+ overflow: hidden;
84
+ }
85
+
86
+ .container {
87
+ width: 360px;
88
+ padding: 20px;
89
+ background: white;
90
+ border: 2px solid #1a1a1a;
91
+ border-radius: 8px;
92
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
93
+ text-align: center;
94
+ }
95
+
96
+ .title {
97
+ font-size: 20px;
98
+ font-weight: 580;
99
+ color: #666;
100
+ margin: 0 0 16px 0;
101
+ letter-spacing: -0.02em;
102
+ font-family: "SF Pro Display", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Microsoft YaHei", sans-serif;
103
+ position: relative;
104
+ }
105
+
106
+ .title::after {
107
+ content: '';
108
+ position: absolute;
109
+ bottom: -8px;
110
+ left: 50%;
111
+ transform: translateX(-50%);
112
+ width: 40px;
113
+ height: 1px;
114
+ background: linear-gradient(to right, transparent, #ccc, transparent);
115
+ }
116
+
117
+ .loading-container {
118
+ display: flex;
119
+ align-items: center;
120
+ justify-content: center;
121
+ gap: 12px;
122
+ }
123
+
124
+ .loading-text {
125
+ font-size: 14px;
126
+ color: #999;
127
+ }
128
+
129
+ .dots {
130
+ display: flex;
131
+ gap: 4px;
132
+ }
133
+
134
+ .dot {
135
+ width: 6px;
136
+ height: 6px;
137
+ background: #aaa;
138
+ border-radius: 50%;
139
+ animation: pulse 1.5s infinite ease-in-out;
140
+ }
141
+
142
+ .dot:nth-child(1) { animation-delay: -0.32s; }
143
+ .dot:nth-child(2) { animation-delay: -0.16s; }
144
+
145
+ @keyframes pulse {
146
+ 0%, 80%, 100% {
147
+ transform: scale(0);
148
+ opacity: 0.5;
149
+ }
150
+ 40% {
151
+ transform: scale(1);
152
+ opacity: 1;
153
+ }
154
+ }
155
+ </style>
156
+ </head>
157
+ <body>
158
+ <div class="container">
159
+ <div class="title">Prompt Manager</div>
160
+ <div class="loading-container">
161
+ <div class="loading-text">正在启动</div>
162
+ <div class="dots">
163
+ <div class="dot"></div>
164
+ <div class="dot"></div>
165
+ <div class="dot"></div>
166
+ </div>
167
+ </div>
168
+ </div>
169
+
170
+ <script>
171
+ // 简单的动画效果增强
172
+ let dotIndex = 0;
173
+ const dots = document.querySelectorAll('.dot');
174
+
175
+ setInterval(() => {
176
+ // 重置所有点
177
+ dots.forEach(dot => {
178
+ dot.style.animation = 'none';
179
+ setTimeout(() => {
180
+ dot.style.animation = 'pulse 1.5s infinite ease-in-out';
181
+ }, 10);
182
+ });
183
+
184
+ // 依次激活点
185
+ dotIndex = (dotIndex + 1) % dots.length;
186
+ }, 1500);
187
+ </script>
188
+ </body>
189
+ </html>`;
190
+ }
191
+
192
+ /**
193
+ * 更新启动状态
194
+ * @param {string} message - 状态消息
195
+ * @param {number} progress - 进度百分比 (0-100)
196
+ */
197
+ updateStatus(message, progress) {
198
+ if (!this.splashWindow || this.splashWindow.isDestroyed()) {
199
+ return;
200
+ }
201
+
202
+ try {
203
+ this.splashWindow.webContents.executeJavaScript(`
204
+ (function() {
205
+ const statusElement = document.getElementById('status');
206
+ const progressElement = document.getElementById('progress');
207
+ if (statusElement) statusElement.textContent = "${message}";
208
+ if (progressElement && ${progress} >= 0) {
209
+ progressElement.style.width = "${progress}%";
210
+ }
211
+ })();
212
+ `);
213
+ } catch (error) {
214
+ this.logger.warn('Failed to update splash status', error);
215
+ }
216
+ }
217
+
218
+ /**
219
+ * 设置窗口事件
220
+ */
221
+ setupWindowEvents() {
222
+ if (!this.splashWindow) return;
223
+
224
+ this.splashWindow.once('ready-to-show', () => {
225
+ if (this.splashWindow) {
226
+ this.splashWindow.show();
227
+ }
228
+ });
229
+
230
+ this.splashWindow.on('closed', () => {
231
+ this.splashWindow = null;
232
+ this.logger.info('Splash screen closed');
233
+ });
234
+ }
235
+
236
+ /**
237
+ * 关闭启动画面
238
+ */
239
+ async closeSplash() {
240
+ this.logger.info('Closing splash screen');
241
+
242
+ if (this.splashWindow) {
243
+ try {
244
+ this.splashWindow.close();
245
+ this.splashWindow = null;
246
+ } catch (error) {
247
+ this.logger.warn('Failed to close splash window', error);
248
+ }
249
+ }
250
+ }
251
+ }
252
+
253
+ module.exports = SplashManager;
@@ -1,7 +1,8 @@
1
- const { Tray, Menu, clipboard, nativeImage, dialog, shell, BrowserWindow } = require('electron');
1
+ const { Tray, Menu, clipboard, nativeImage, dialog, shell } = require('electron');
2
2
  const fs = require('fs');
3
3
  const path = require('path');
4
4
  const EventEmitter = require('../core/event-emitter');
5
+ const AdminWindowManager = require('./admin-window-manager');
5
6
 
6
7
  class TrayManager extends EventEmitter {
7
8
  constructor(logger, errorHandler, iconManager) {
@@ -13,7 +14,7 @@ class TrayManager extends EventEmitter {
13
14
  this.menuTemplate = [];
14
15
  this.iconPaths = [];
15
16
  this.currentState = null;
16
- this.adminWindow = null; // 添加adminWindow引用
17
+ this.adminWindowManager = new AdminWindowManager(logger, iconManager);
17
18
  }
18
19
 
19
20
  async initialize(stateManager) {
@@ -142,29 +143,13 @@ class TrayManager extends EventEmitter {
142
143
  }
143
144
 
144
145
  openAdminWindow(adminUrl) {
145
- if (this.adminWindow) {
146
- this.adminWindow.focus();
146
+ if (this.adminWindowManager.hasWindow()) {
147
+ this.adminWindowManager.getWindow().focus();
147
148
  return;
148
149
  }
149
150
 
150
151
  try {
151
- this.adminWindow = new BrowserWindow({
152
- width: 1200,
153
- height: 800,
154
- title: 'Prompt Server 管理后台',
155
- webPreferences: {
156
- contextIsolation: true,
157
- nodeIntegration: false
158
- }
159
- });
160
-
161
- this.adminWindow.loadURL(adminUrl);
162
-
163
- this.adminWindow.on('closed', () => {
164
- this.adminWindow = null;
165
- });
166
-
167
- this.logger.info('Admin window opened', { url: adminUrl });
152
+ this.adminWindowManager.openAdminWindow(adminUrl);
168
153
  } catch (error) {
169
154
  this.logger.error('Failed to open admin window', error);
170
155
  }
@@ -192,9 +177,8 @@ class TrayManager extends EventEmitter {
192
177
  this.logger.info('Tray destroyed');
193
178
  }
194
179
 
195
- if (this.adminWindow) {
196
- this.adminWindow.close();
197
- this.adminWindow = null;
180
+ if (this.adminWindowManager) {
181
+ this.adminWindowManager.closeAdminWindow();
198
182
  }
199
183
  }
200
184
  }
@@ -20,69 +20,62 @@ class IconManager {
20
20
  const basePath = path.join(__dirname, '..', '..', 'assets', 'icons');
21
21
 
22
22
  return {
23
- '16': path.join(basePath, 'icon_16x16.png'),
24
- '24': path.join(basePath, 'icon_24x24.png'),
25
- '32': path.join(basePath, 'icon_32x32.png'),
26
- '48': path.join(basePath, 'icon_48x48.png'),
27
- '64': path.join(basePath, 'icon_64x64.png'),
28
- '96': path.join(basePath, 'icon_96x96.png'),
29
- '128': path.join(basePath, 'icon_128x128.png'),
30
- '256': path.join(basePath, 'icon_256x256.png'),
31
- '512': path.join(basePath, 'icon_512x512.png'),
32
- '1024': path.join(basePath, 'icon_1024x1024.png'),
33
- 'default': path.join(basePath, 'icon.png'),
34
- 'ico': path.join(basePath, 'icon.ico'),
35
- 'icns': path.join(basePath, 'icon.icns')
23
+ 'icns': path.join(basePath, 'icon.icns'),
24
+ 'ico': path.join(basePath, 'icon.ico'),
25
+ 'png': path.join(basePath, 'icon.png'),
26
+ 'tray': path.join(basePath, 'tray.png'),
36
27
  };
37
28
  }
38
29
 
39
30
  /**
40
- * 获取指定尺寸的图标
31
+ * 获取应用程序图标
32
+ * @returns {nativeImage|null} - 图标对象
33
+ */
34
+ getAppIcon() {
35
+ const platform = process.platform;
36
+ if (platform === 'darwin') {
37
+ const iconPath = this.iconPaths['icns'];
38
+ return fs.existsSync(iconPath) ? nativeImage.createFromPath(iconPath) : null;
39
+ } else if (platform === 'win32') {
40
+ const iconPath = this.iconPaths['ico'];
41
+ return fs.existsSync(iconPath) ? nativeImage.createFromPath(iconPath) : null;
42
+ }
43
+ const iconPath = this.iconPaths['png'];
44
+ return fs.existsSync(iconPath) ? nativeImage.createFromPath(iconPath) : null;
45
+ }
46
+
47
+ /**
48
+ * 获取指定尺寸的托盘图标
41
49
  * @param {string|number} size - 图标尺寸
42
50
  * @returns {nativeImage|null} - 图标对象
43
51
  */
44
- getIcon(size = 'default') {
52
+ getTrayIconBySize(size) {
45
53
  const sizeKey = String(size);
46
54
 
47
- if (this.iconCache.has(sizeKey)) {
48
- return this.iconCache.get(sizeKey);
55
+ if (this.iconCache.has(`tray-${sizeKey}`)) {
56
+ return this.iconCache.get(`tray-${sizeKey}`);
49
57
  }
50
58
 
51
- const iconPath = this.iconPaths[sizeKey];
59
+ const iconPath = this.iconPaths['tray'];
52
60
  if (!iconPath || !fs.existsSync(iconPath)) {
53
- // 防止递归调用:如果正在请求默认图标但找不到,返回 null
54
- if (sizeKey === 'default') {
55
- console.warn(`Default icon not found at ${iconPath}`);
56
- return null;
57
- }
58
-
59
- console.warn(`Icon not found for size ${sizeKey}, trying default`);
60
- return this.getIcon('default');
61
+ console.warn(`Tray icon not found for size ${sizeKey}`);
62
+ return null;
61
63
  }
62
64
 
63
65
  try {
64
66
  const icon = nativeImage.createFromPath(iconPath);
67
+ icon.resize({ width: size, height: size });
65
68
 
66
69
  if (icon.isEmpty()) {
67
- console.warn(`Failed to load icon from ${iconPath}`);
68
- // 如果是默认图标加载失败,返回 null 避免递归
69
- if (sizeKey === 'default') {
70
- return null;
71
- }
72
- // 否则尝试加载默认图标
73
- return this.getIcon('default');
70
+ console.warn(`Failed to load tray icon from ${iconPath}`);
71
+ return null;
74
72
  }
75
73
 
76
- this.iconCache.set(sizeKey, icon);
74
+ this.iconCache.set(`tray-${sizeKey}`, icon);
77
75
  return icon;
78
76
  } catch (error) {
79
- console.error(`Error loading icon ${iconPath}:`, error);
80
- // 如果是默认图标加载失败,返回 null 避免递归
81
- if (sizeKey === 'default') {
82
- return null;
83
- }
84
- // 否则尝试加载默认图标
85
- return this.getIcon('default');
77
+ console.error(`Error loading tray icon ${iconPath}:`, error);
78
+ return null;
86
79
  }
87
80
  }
88
81
 
@@ -104,11 +97,7 @@ class IconManager {
104
97
  iconSize = '24'; // Linux 推荐 24x24
105
98
  }
106
99
 
107
- let icon = this.getIcon(iconSize);
108
-
109
- if (!icon) {
110
- icon = this.getIcon('default');
111
- }
100
+ let icon = this.getTrayIconBySize(iconSize);
112
101
 
113
102
  // macOS 特殊处理
114
103
  if (platform === 'darwin' && icon) {
@@ -127,7 +116,10 @@ class IconManager {
127
116
  * 获取关于对话框图标
128
117
  */
129
118
  getAboutDialogIcon() {
130
- return this.getIcon('64') || this.getIcon('default');
119
+ // 优先使用应用图标,如果没有则使用较大的托盘图标
120
+ const iconPath = this.iconPaths['png'];
121
+ let icon = nativeImage.createFromPath(iconPath)
122
+ return icon.resize({ width: 64, height: 64 });
131
123
  }
132
124
 
133
125
  /**
@@ -11,29 +11,6 @@ class ResourcePaths {
11
11
  this.assetsPath = path.join(this.basePath, 'assets');
12
12
  }
13
13
 
14
- /**
15
- * 图标路径
16
- */
17
- static get icons() {
18
- const iconsPath = path.join(__dirname, '..', '..', 'assets', 'icons');
19
- return {
20
- base: iconsPath,
21
- '16': path.join(iconsPath, 'icon_16x16.png'),
22
- '24': path.join(iconsPath, 'icon_24x24.png'),
23
- '32': path.join(iconsPath, 'icon_32x32.png'),
24
- '48': path.join(iconsPath, 'icon_48x48.png'),
25
- '64': path.join(iconsPath, 'icon_64x64.png'),
26
- '96': path.join(iconsPath, 'icon_96x96.png'),
27
- '128': path.join(iconsPath, 'icon_128x128.png'),
28
- '256': path.join(iconsPath, 'icon_256x256.png'),
29
- '512': path.join(iconsPath, 'icon_512x512.png'),
30
- '1024': path.join(iconsPath, 'icon_1024x1024.png'),
31
- 'default': path.join(iconsPath, 'icon.png'),
32
- 'ico': path.join(iconsPath, 'icon.ico'),
33
- 'icns': path.join(iconsPath, 'icon.icns')
34
- };
35
- }
36
-
37
14
  /**
38
15
  * 模板路径
39
16
  */