@becrafter/prompt-manager 0.1.18 → 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,330 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
- const { pathToFileURL } = require('url');
4
- const { spawn } = require('child_process');
5
- const { constants } = require('fs');
6
-
7
- class ModuleLoader {
8
- constructor(logger, errorHandler) {
9
- this.logger = logger;
10
- this.errorHandler = errorHandler;
11
- this.moduleCache = new Map();
12
- this.loadingPromises = new Map();
13
- }
14
-
15
- async loadServerModule(serverRoot, forceReload = false) {
16
- const cacheKey = serverRoot;
17
-
18
- // 如果正在加载,返回现有promise
19
- if (this.loadingPromises.has(cacheKey) && !forceReload) {
20
- this.logger.debug('Returning existing module loading promise');
21
- return this.loadingPromises.get(cacheKey);
22
- }
23
-
24
- // 强制重新加载时清理缓存
25
- if (forceReload) {
26
- this.logger.debug('Force reloading server module');
27
- this.moduleCache.delete(cacheKey);
28
- }
29
-
30
- // 检查缓存
31
- if (this.moduleCache.has(cacheKey)) {
32
- this.logger.debug('Returning cached server module');
33
- return this.moduleCache.get(cacheKey);
34
- }
35
-
36
- const loadingPromise = this._loadModuleInternal(serverRoot);
37
- this.loadingPromises.set(cacheKey, loadingPromise);
38
-
39
- try {
40
- const module = await loadingPromise;
41
- this.moduleCache.set(cacheKey, module);
42
- return module;
43
- } catch (error) {
44
- this.logger.error('Failed to load server module', error);
45
- throw error;
46
- } finally {
47
- this.loadingPromises.delete(cacheKey);
48
- }
49
- }
50
-
51
- async _loadModuleInternal(serverRoot) {
52
- this.logger.info('Loading server module', { serverRoot });
53
-
54
- // 判断是否为打包环境
55
- const isPackaged = this._isPackagedEnvironment();
56
- this.logger.debug('Environment check', { isPackaged, serverRoot });
57
-
58
- // 根据环境类型决定路径优先级
59
- let pathsToCheck;
60
-
61
- if (isPackaged) {
62
- // 打包环境:优先从 ASAR 包中加载
63
- pathsToCheck = [
64
- // 1. 优先从 app.asar 包中的 node_modules 加载
65
- path.join(process.resourcesPath, 'app.asar', 'node_modules', '@becrafter', 'prompt-manager-core', 'index.js'),
66
- // 2. 尝试从 app.asar 直接加载
67
- path.join(process.resourcesPath, 'app.asar', 'packages', 'server', 'index.js'),
68
- // 3. 尝试从应用目录的 packages/server 加载
69
- path.join(process.resourcesPath, 'packages', 'server', 'index.js'),
70
- // 4. 备用:从 serverRoot 加载
71
- path.join(serverRoot, 'packages', 'server', 'index.js'),
72
- ];
73
- } else {
74
- // 开发环境:优先从项目目录加载
75
- pathsToCheck = [
76
- // 1. 优先从 serverRoot 的 packages/server 加载(开发环境)
77
- path.join(serverRoot, 'packages', 'server', 'index.js'),
78
- // 2. 尝试从 serverRoot 的 node_modules 加载
79
- path.join(serverRoot, 'node_modules', '@becrafter', 'prompt-manager-core', 'index.js'),
80
- // 3. 尝试从当前目录的 node_modules 加载
81
- path.join(__dirname, '..', '..', '..', 'node_modules', '@becrafter', 'prompt-manager-core', 'index.js'),
82
- // 4. 最后尝试从 ASAR 路径(以防万一)
83
- path.join(process.resourcesPath, 'app.asar', 'node_modules', '@becrafter', 'prompt-manager-core', 'index.js'),
84
- ];
85
- }
86
-
87
- let lastError = null;
88
-
89
- for (const libPath of pathsToCheck) {
90
- try {
91
- if (await this._pathExists(libPath)) {
92
- this.logger.info('Found server module at path', { path: libPath });
93
-
94
- const entryUrl = pathToFileURL(libPath);
95
- // 添加版本参数以防止缓存
96
- entryUrl.searchParams.set('v', Date.now().toString());
97
-
98
- this.logger.debug('Attempting to import module', { url: entryUrl.href });
99
- const module = await import(entryUrl.href);
100
- this.logger.debug('Module imported successfully', { moduleKeys: Object.keys(module) });
101
- this._validateServerModule(module);
102
- this.logger.info('Server module loaded successfully');
103
- return module;
104
- }
105
- } catch (error) {
106
- lastError = error;
107
- this.logger.error('Failed to load from path', {
108
- path: libPath,
109
- error: error.message,
110
- stack: error.stack
111
- });
112
- continue;
113
- }
114
- }
115
-
116
- // 所有路径都失败,抛出详细的错误信息
117
- const errorMsg = `Could not find core library in any of the expected paths: ${pathsToCheck.join(', ')}`;
118
- this.logger.error(errorMsg, { lastError: lastError?.message });
119
- throw new Error(errorMsg);
120
- }
121
-
122
- /**
123
- * 判断是否为打包环境
124
- */
125
- _isPackagedEnvironment() {
126
- // 优先检查开发环境标志
127
- const isDevelopment = process.env.NODE_ENV === 'development' ||
128
- process.env.ELECTRON_IS_DEV === '1' ||
129
- __dirname.includes('node_modules') ||
130
- process.defaultApp === true;
131
-
132
- // 如果是开发环境,直接返回 false
133
- if (isDevelopment) {
134
- return false;
135
- }
136
-
137
- // 检查是否在 Electron 的打包环境中
138
- const appPath = process.resourcesPath || '';
139
- const isElectronPackaged = appPath.includes('app.asar') ||
140
- !appPath.includes('Electron.app');
141
-
142
- return isElectronPackaged;
143
- }
144
-
145
- async _pathExists(targetPath) {
146
- try {
147
- this.logger.debug('Checking if path exists', { path: targetPath });
148
-
149
- // 对于 ASAR 文件,使用多种方式验证存在性
150
- if (targetPath.includes('.asar')) {
151
- try {
152
- // 方法1:尝试使用 fs.stat(最可靠的方式)
153
- const stats = await fs.promises.stat(targetPath);
154
- if (stats.isFile() || stats.isDirectory()) {
155
- return true;
156
- }
157
- } catch (statError) {
158
- // 如果 stat 失败,尝试其他方法
159
- this.logger.debug('ASAR stat failed, trying alternative methods', {
160
- path: targetPath,
161
- error: statError.message
162
- });
163
- }
164
-
165
- try {
166
- // 方法2:尝试读取文件的前几个字节
167
- const buffer = Buffer.alloc(1);
168
- const fd = await fs.promises.open(targetPath, 'r');
169
- await fd.read(buffer, 0, 1, 0);
170
- await fd.close();
171
- return true;
172
- } catch (readError) {
173
- // 如果读取失败,尝试最后的方法
174
- this.logger.debug('ASAR read failed', {
175
- path: targetPath,
176
- error: readError.message
177
- });
178
- }
179
-
180
- try {
181
- // 方法3:尝试使用 fs.access(标准方法)
182
- await fs.promises.access(targetPath, constants.F_OK);
183
- return true;
184
- } catch (accessError) {
185
- this.logger.debug('ASAR access failed', {
186
- path: targetPath,
187
- error: accessError.message
188
- });
189
- return false;
190
- }
191
- }
192
-
193
- // 普通文件检查 - 使用 fs.stat 而不是 fs.access
194
- const stats = await fs.promises.stat(targetPath);
195
- this.logger.debug('File check successful', { path: targetPath, isFile: stats.isFile() });
196
- return stats.isFile();
197
- } catch (error) {
198
- this.logger.debug('File access check failed', {
199
- path: targetPath,
200
- error: error.message
201
- });
202
- return false;
203
- }
204
- }
205
-
206
- async _validateServerEntry(serverEntry) {
207
- try {
208
- // 验证库的 package.json 存在
209
- const packageJsonPath = path.join(serverEntry, 'package.json');
210
- await fs.promises.access(packageJsonPath, fs.constants.F_OK);
211
- this.logger.debug('Server module package.json exists', { serverEntry });
212
- } catch (error) {
213
- this.logger.error('Server module not found', error);
214
- throw new Error(`Server module not found: ${serverEntry}`);
215
- }
216
- }
217
-
218
- _validateServerModule(module) {
219
- if (!module || typeof module.startServer !== 'function') {
220
- throw new Error('Invalid server module: missing startServer function');
221
- }
222
-
223
- this.logger.debug('Server module validation passed');
224
- }
225
-
226
- async installDependencies(targetDir) {
227
- this.logger.info('Installing server dependencies', { targetDir });
228
-
229
- // 验证 package.json 存在
230
- await this._validatePackageJson(targetDir);
231
-
232
- // 检查并添加缺失的依赖
233
- await this._ensureRequiredDependencies(targetDir);
234
-
235
- return new Promise((resolve, reject) => {
236
- const npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm';
237
- const args = ['install', '--omit=dev', '--no-audit', '--no-fund'];
238
-
239
- this.logger.debug('Running npm install', { command: npmCommand, args });
240
-
241
- const child = spawn(npmCommand, args, {
242
- cwd: targetDir,
243
- stdio: ['ignore', 'pipe', 'pipe']
244
- });
245
-
246
- let stdout = '';
247
- let stderr = '';
248
-
249
- child.stdout.on('data', (data) => {
250
- const output = data.toString().trim();
251
- stdout += output;
252
- this.logger.debug(`[npm stdout] ${output}`);
253
- });
254
-
255
- child.stderr.on('data', (data) => {
256
- const output = data.toString().trim();
257
- stderr += output;
258
- this.logger.warn(`[npm stderr] ${output}`);
259
- });
260
-
261
- child.on('error', (error) => {
262
- this.logger.error('npm process error', error);
263
- reject(new Error(`Failed to start npm process: ${error.message}`));
264
- });
265
-
266
- child.on('close', (code) => {
267
- this.logger.debug('npm process exited', { code });
268
-
269
- if (code === 0) {
270
- this.logger.info('Dependencies installed successfully');
271
- resolve();
272
- } else {
273
- const errorMsg = `npm install failed with exit code ${code}`;
274
- this.logger.error(errorMsg, new Error(stderr));
275
- reject(new Error(errorMsg));
276
- }
277
- });
278
- });
279
- }
280
-
281
- async _validatePackageJson(targetDir) {
282
- const pkgPath = path.join(targetDir, 'package.json');
283
-
284
- try {
285
- await fs.promises.access(pkgPath, fs.constants.F_OK);
286
- this.logger.debug('package.json found in target directory');
287
- } catch (error) {
288
- this.logger.error('package.json not found in target directory', { pkgPath });
289
- throw new Error(`package.json not found in ${targetDir}`);
290
- }
291
- }
292
-
293
- async _ensureRequiredDependencies(targetDir) {
294
- const pkgPath = path.join(targetDir, 'package.json');
295
-
296
- try {
297
- const pkgContent = await fs.promises.readFile(pkgPath, 'utf8');
298
- const pkg = JSON.parse(pkgContent);
299
-
300
- pkg.dependencies = pkg.dependencies || {};
301
-
302
- // 确保 @becrafter/prompt-manager-core 依赖存在
303
- if (!pkg.dependencies['@becrafter/prompt-manager-core']) {
304
- pkg.dependencies['@becrafter/prompt-manager-core'] = '^0.0.19';
305
- await fs.promises.writeFile(pkgPath, JSON.stringify(pkg, null, 2), 'utf8');
306
- this.logger.info('Added @becrafter/prompt-manager-core to dependencies');
307
- }
308
-
309
- // 检查并添加 @modelcontextprotocol/sdk
310
- if (!pkg.dependencies['@modelcontextprotocol/sdk']) {
311
- pkg.dependencies['@modelcontextprotocol/sdk'] = '^1.20.2';
312
- await fs.promises.writeFile(pkgPath, JSON.stringify(pkg, null, 2), 'utf8');
313
- this.logger.info('Added @modelcontextprotocol/sdk to dependencies');
314
- }
315
- } catch (error) {
316
- this.logger.error('Error checking/adding dependencies', error);
317
- throw error;
318
- }
319
- }
320
-
321
- clearCache(serverRoot) {
322
- const cacheKey = serverRoot;
323
- if (this.moduleCache.has(cacheKey)) {
324
- this.moduleCache.delete(cacheKey);
325
- this.logger.debug('Cleared module cache', { serverRoot });
326
- }
327
- }
328
- }
329
-
330
- module.exports = ModuleLoader;