@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
@@ -7,7 +7,19 @@ class RuntimeManager {
7
7
  this.logger = logger;
8
8
  this.errorHandler = errorHandler;
9
9
  this.runtimeRoot = null;
10
- this.isPackaged = app.isPackaged;
10
+ // 更准确地判断是否为打包应用
11
+ // 在开发模式下,即使 app.isPackaged 为 true,我们的项目目录结构也不同于打包应用
12
+ this.isPackaged = this._checkIfActuallyPackaged();
13
+ }
14
+
15
+ _checkIfActuallyPackaged() {
16
+ // 简化环境检测逻辑
17
+ const appPath = app.getAppPath();
18
+ const isDev = appPath.includes('node_modules/electron') ||
19
+ process.env.NODE_ENV === 'development' ||
20
+ process.defaultApp;
21
+
22
+ return !isDev && app.isPackaged;
11
23
  }
12
24
 
13
25
  async ensureRuntimeEnvironment() {
@@ -51,15 +63,40 @@ class RuntimeManager {
51
63
  async _setupPackagedEnvironment() {
52
64
  this.logger.info('Setting up packaged environment');
53
65
 
54
- const packagedRoot = path.join(process.resourcesPath, 'prompt-manager');
66
+ // 在打包的 Electron 应用中,资源文件位于 app.asar
67
+ const packagedRoot = path.join(process.resourcesPath, 'app.asar');
55
68
  const runtimeRoot = path.join(app.getPath('userData'), 'prompt-manager');
56
69
 
57
- this.logger.debug('Environment paths', { packagedRoot, runtimeRoot });
70
+ this.logger.debug('Environment paths', {
71
+ packagedRoot,
72
+ runtimeRoot,
73
+ resourcesPath: process.resourcesPath,
74
+ isMountedVolume: process.resourcesPath.includes('/Volumes/')
75
+ });
58
76
 
59
- // 验证打包资源
60
- await this._validatePackagedResources(packagedRoot);
77
+ // 简化逻辑:仅检查是否是挂载卷
78
+ const isFromMountedVolume = process.resourcesPath.includes('/Volumes/');
79
+
80
+ if (isFromMountedVolume) {
81
+ this.logger.debug('Detected mounted volume, attempting to find appropriate path');
82
+
83
+ // 尝试主要路径
84
+ try {
85
+ await this._validatePackagedResources(packagedRoot);
86
+ this.logger.debug('Validated packaged resources from mounted volume path', { path: packagedRoot });
87
+ } catch (error) {
88
+ // 在挂载卷中,即使验证失败,我们也要继续执行
89
+ // 因为文件可能存在于挂载卷中,但由于权限问题无法验证
90
+ this.logger.warn('Could not validate packaged resources from mounted volume, continuing anyway', {
91
+ error: error.message
92
+ });
93
+ }
94
+ } else {
95
+ // 非挂载卷,使用正常验证流程
96
+ await this._validatePackagedResources(packagedRoot);
97
+ }
61
98
 
62
- // 设置运行时目录
99
+ // 设置运行时目录(仅复制必要的文件,不包括 ASAR 包)
63
100
  await this._setupRuntimeDirectory(packagedRoot, runtimeRoot);
64
101
 
65
102
  this.runtimeRoot = runtimeRoot;
@@ -68,8 +105,7 @@ class RuntimeManager {
68
105
 
69
106
  async _validateDevelopmentEnvironment(devRoot) {
70
107
  const requiredPaths = [
71
- path.join(devRoot, 'package.json'),
72
- path.join(devRoot, 'packages', 'server', 'server.js')
108
+ path.join(devRoot, 'package.json')
73
109
  ];
74
110
 
75
111
  for (const requiredPath of requiredPaths) {
@@ -80,17 +116,76 @@ class RuntimeManager {
80
116
  }
81
117
  }
82
118
 
119
+ // 检查 @becrafter/prompt-manager-core 在 node_modules 中是否存在
120
+ const coreLibPath = path.join(devRoot, 'node_modules', '@becrafter', 'prompt-manager-core', 'index.js');
121
+ try {
122
+ await fs.promises.access(coreLibPath, fs.constants.F_OK);
123
+ } catch (error) {
124
+ this.logger.debug('Core library not found in node_modules, checking for local packages/server');
125
+ // 如果 node_modules 中不存在,检查 local packages/server 目录
126
+ const localServerPath = path.join(devRoot, 'packages', 'server', 'server.js');
127
+ try {
128
+ await fs.promises.access(localServerPath, fs.constants.F_OK);
129
+ } catch (localError) {
130
+ throw new Error(`Development environment validation failed: neither core library nor local server found (${coreLibPath}, ${localServerPath})`);
131
+ }
132
+ }
133
+
83
134
  this.logger.debug('Development environment validation passed');
84
135
  }
85
136
 
86
137
  async _validatePackagedResources(packagedRoot) {
87
- try {
88
- await fs.promises.access(packagedRoot, fs.constants.F_OK);
89
- this.logger.debug('Packaged root exists', { path: packagedRoot });
90
- } catch (error) {
91
- throw new Error(`Packaged resources not found: ${packagedRoot}`);
138
+ this.logger.debug('Validating packaged resources', { packagedRoot });
139
+
140
+ // 检查 app.asar 文件是否存在
141
+ if (packagedRoot.endsWith('.asar')) {
142
+ // Electron 中,当代码在 ASAR 包内运行时,对 ASAR 文件的访问方式不同
143
+ // 我们需要检查文件是否存在,但不能依赖 stats.isFile()
144
+ try {
145
+ // 首先尝试使用 fs.access 来检查文件是否存在和可访问
146
+ await fs.promises.access(packagedRoot, fs.constants.F_OK);
147
+ this.logger.debug('Packaged ASAR is accessible via fs.access', { path: packagedRoot });
148
+ return; // Found ASAR file, validation passed
149
+ } catch (accessError) {
150
+ // 如果 fs.access 失败,尝试使用 fs.stat 并检查错误类型
151
+ try {
152
+ const stats = await fs.promises.stat(packagedRoot);
153
+ // 在 ASAR 环境中,即使文件存在,stats.isFile() 也可能返回 false
154
+ // 我们只检查是否存在错误,而不检查文件类型
155
+ this.logger.debug('Packaged ASAR exists via fs.stat', {
156
+ path: packagedRoot,
157
+ isFile: stats.isFile(),
158
+ isDirectory: stats.isDirectory()
159
+ });
160
+ return; // Found ASAR file, validation passed
161
+ } catch (statError) {
162
+ // 如果两种方法都失败,记录详细信息然后抛出错误
163
+ this.logger.error('Failed to validate packaged resources', {
164
+ path: packagedRoot,
165
+ accessError: accessError.message,
166
+ accessCode: accessError.code,
167
+ statError: statError.message,
168
+ statCode: statError.code,
169
+ processResourcesPath: process.resourcesPath,
170
+ appPath: app.getAppPath()
171
+ });
172
+ throw new Error(`Packaged resources not found: ${packagedRoot} (access: ${accessError.message}, stat: ${statError.message})`);
173
+ }
174
+ }
175
+ } else {
176
+ try {
177
+ const stats = await fs.promises.stat(packagedRoot);
178
+ if (stats.isDirectory() || stats.isFile()) {
179
+ this.logger.debug('Packaged root exists', { path: packagedRoot });
180
+ }
181
+ } catch (error) {
182
+ this.logger.error('Packaged root not found or not accessible', { packagedRoot, error: error.message });
183
+ throw new Error(`Packaged resources not found: ${packagedRoot}`);
184
+ }
92
185
  }
93
186
  }
187
+
188
+ // 移除了无用的 _generateVolumePaths 方法
94
189
 
95
190
  async _setupRuntimeDirectory(packagedRoot, runtimeRoot) {
96
191
  try {
@@ -101,7 +196,33 @@ class RuntimeManager {
101
196
  await fs.promises.mkdir(runtimeRoot, { recursive: true });
102
197
 
103
198
  this.logger.info('Copying packaged resources to runtime directory');
104
- await fs.promises.cp(packagedRoot, runtimeRoot, { recursive: true });
199
+
200
+ // 检查是否是 ASAR 文件
201
+ if (packagedRoot.endsWith('.asar')) {
202
+ // 对于 ASAR 文件,我们不需要解压整个包,只需要复制它
203
+ // 但我们需要确保文件存在且可访问
204
+ try {
205
+ await fs.promises.access(packagedRoot, fs.constants.F_OK);
206
+ this.logger.debug('ASAR file exists, copying to runtime directory');
207
+
208
+ // 复制 ASAR 文件到运行时目录
209
+ const targetAsarPath = path.join(runtimeRoot, 'app.asar');
210
+ await fs.promises.copyFile(packagedRoot, targetAsarPath);
211
+ this.logger.debug('Copied ASAR file to runtime directory', { source: packagedRoot, target: targetAsarPath });
212
+ } catch (copyError) {
213
+ this.logger.error('Failed to copy ASAR file to runtime directory', {
214
+ source: packagedRoot,
215
+ error: copyError.message
216
+ });
217
+
218
+ // 如果复制失败,记录错误但继续执行
219
+ // 应用程序可能仍然可以运行,因为它可以直接从原始位置访问 ASAR 文件
220
+ this.logger.warn('Continuing without copying ASAR file to runtime directory');
221
+ }
222
+ } else {
223
+ // 如果是普通目录,直接复制
224
+ await fs.promises.cp(packagedRoot, runtimeRoot, { recursive: true });
225
+ }
105
226
  }
106
227
  }
107
228
 
@@ -128,19 +249,47 @@ class RuntimeManager {
128
249
  }
129
250
 
130
251
  getPackageInfo() {
131
- if (!this.runtimeRoot) {
132
- throw new Error('Runtime environment not initialized');
133
- }
134
-
135
- const packagePath = path.join(this.runtimeRoot, 'package.json');
252
+ // 优先从 app.asar 压缩包中读取 package.json
253
+ const asarPackagePath = path.join(process.resourcesPath, 'app.asar', 'package.json');
136
254
 
255
+ // 尝试从 app.asar 中读取
137
256
  try {
138
- const packageContent = fs.readFileSync(packagePath, 'utf8');
257
+ const packageContent = fs.readFileSync(asarPackagePath, 'utf8');
258
+ this.logger.debug('Read package.json from app.asar', { path: asarPackagePath });
139
259
  return JSON.parse(packageContent);
140
- } catch (error) {
141
- this.logger.error('Failed to read package info', error);
142
- return { version: 'unknown' };
260
+ } catch (asarError) {
261
+ // 如果从 app.asar 读取失败,尝试从 app.getAppPath() 读取(开发环境或备用方案)
262
+ try {
263
+ const appPathPackagePath = path.join(app.getAppPath(), 'package.json');
264
+ const packageContent = fs.readFileSync(appPathPackagePath, 'utf8');
265
+ this.logger.debug('Read package.json from app path', { path: appPathPackagePath });
266
+ return JSON.parse(packageContent);
267
+ } catch (appPathError) {
268
+ // 最后尝试从 runtimeRoot 读取(向后兼容)
269
+ if (this.runtimeRoot) {
270
+ try {
271
+ const runtimePackagePath = path.join(this.runtimeRoot, 'package.json');
272
+ const packageContent = fs.readFileSync(runtimePackagePath, 'utf8');
273
+ this.logger.debug('Read package.json from runtime root', { path: runtimePackagePath });
274
+ return JSON.parse(packageContent);
275
+ } catch (runtimeError) {
276
+ this.logger.error('Failed to read package info from all locations', {
277
+ asarError: asarError.message,
278
+ appPathError: appPathError.message,
279
+ runtimeError: runtimeError.message
280
+ });
281
+ }
282
+ } else {
283
+ this.logger.error('Failed to read package info from app.asar and app path', {
284
+ asarError: asarError.message,
285
+ appPathError: appPathError.message
286
+ });
287
+ }
288
+ }
143
289
  }
290
+
291
+ // 所有尝试都失败,返回默认值
292
+ return { version: 'unknown' };
144
293
  }
145
294
 
146
295
  async cleanup() {
@@ -95,21 +95,20 @@ class UpdateManager {
95
95
 
96
96
  async showUpdateAvailableDialog(latestVersion, currentVersion) {
97
97
  const { response } = await dialog.showMessageBox({
98
- type: 'question',
98
+ type: 'info',
99
99
  title: '发现新版本',
100
100
  message: `发现新版本 ${latestVersion}`,
101
- detail: '升级期间服务会短暂停止,是否继续?',
102
- buttons: ['立即升级', '打开发布页', '取消'],
101
+ detail: `当前版本:${currentVersion}\n可前往发布页下载并手动更新。`,
102
+ buttons: ['打开发布页', '取消'],
103
103
  defaultId: 0,
104
- cancelId: 2
104
+ cancelId: 1
105
105
  });
106
106
 
107
- if (response === 1) {
107
+ if (response === 0) {
108
108
  shell.openExternal('https://github.com/BeCrafter/prompt-manager/releases/latest');
109
- return false;
110
109
  }
111
110
 
112
- return response === 0;
111
+ return false;
113
112
  }
114
113
 
115
114
  async performUpdate(version) {