@becrafter/prompt-manager 0.1.2 → 0.1.9

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 (110) hide show
  1. package/README.md +304 -121
  2. package/app/cli/commands/start.js +65 -4
  3. package/app/cli/support/argv.js +6 -0
  4. package/env.example +32 -0
  5. package/package.json +36 -7
  6. package/packages/server/api/admin.routes.js +409 -1
  7. package/packages/server/api/open.routes.js +7 -2
  8. package/packages/server/api/tool.routes.js +479 -0
  9. package/packages/server/app.js +97 -25
  10. package/packages/server/configs/models/built-in/bigmodel.yaml +6 -0
  11. package/packages/server/configs/models/providers.yaml +50 -0
  12. package/packages/server/configs/templates/built-in/general-iteration.yaml +60 -0
  13. package/packages/server/configs/templates/built-in/general-optimize.yaml +63 -0
  14. package/packages/server/configs/templates/built-in/output-format-optimize.yaml +95 -0
  15. package/packages/server/mcp/heartbeat-patch.js +73 -0
  16. package/packages/server/mcp/mcp.server.js +63 -314
  17. package/packages/server/mcp/prompt.handler.js +26 -0
  18. package/packages/server/mcp/thinking-toolkit.handler.js +380 -0
  19. package/packages/server/package.json +35 -3
  20. package/packages/server/server.js +114 -12
  21. package/packages/server/services/TerminalService.js +498 -0
  22. package/packages/server/services/WebSocketService.js +484 -0
  23. package/packages/server/services/manager.js +38 -7
  24. package/packages/server/services/model.service.js +473 -0
  25. package/packages/server/services/optimization.service.js +457 -0
  26. package/packages/server/services/template.service.js +333 -0
  27. package/packages/server/toolm/tool-description-generator-optimized.service.js +5 -2
  28. package/packages/server/toolm/tool-sync.service.js +47 -3
  29. package/packages/server/utils/config.js +8 -1
  30. package/packages/server/utils/port-checker.js +63 -0
  31. package/packages/server/utils/util.js +27 -0
  32. package/IFLOW.md +0 -175
  33. package/app/desktop/assets/app.1.png +0 -0
  34. package/app/desktop/assets/app.png +0 -0
  35. package/app/desktop/assets/icons/icon.icns +0 -0
  36. package/app/desktop/assets/icons/icon.ico +0 -0
  37. package/app/desktop/assets/icons/icon.png +0 -0
  38. package/app/desktop/assets/icons/tray.png +0 -0
  39. package/app/desktop/assets/templates/about.html +0 -147
  40. package/app/desktop/assets/tray.1.png +0 -0
  41. package/app/desktop/assets/tray.png +0 -0
  42. package/app/desktop/main.js +0 -241
  43. package/app/desktop/package-lock.json +0 -5026
  44. package/app/desktop/package.json +0 -100
  45. package/app/desktop/preload.js +0 -7
  46. package/app/desktop/src/core/error-handler.js +0 -108
  47. package/app/desktop/src/core/event-emitter.js +0 -84
  48. package/app/desktop/src/core/logger.js +0 -108
  49. package/app/desktop/src/core/state-manager.js +0 -125
  50. package/app/desktop/src/services/module-loader.js +0 -214
  51. package/app/desktop/src/services/runtime-manager.js +0 -301
  52. package/app/desktop/src/services/service-manager.js +0 -169
  53. package/app/desktop/src/services/update-manager.js +0 -267
  54. package/app/desktop/src/ui/about-dialog-manager.js +0 -208
  55. package/app/desktop/src/ui/admin-window-manager.js +0 -757
  56. package/app/desktop/src/ui/splash-manager.js +0 -253
  57. package/app/desktop/src/ui/tray-manager.js +0 -186
  58. package/app/desktop/src/utils/icon-manager.js +0 -133
  59. package/app/desktop/src/utils/path-utils.js +0 -58
  60. package/app/desktop/src/utils/resource-paths.js +0 -49
  61. package/app/desktop/src/utils/resource-sync.js +0 -260
  62. package/app/desktop/src/utils/runtime-sync.js +0 -241
  63. package/app/desktop/src/utils/template-renderer.js +0 -284
  64. package/app/desktop/src/utils/version-utils.js +0 -59
  65. package/examples/prompts/developer/code-review.yaml +0 -32
  66. package/examples/prompts/developer/code_refactoring.yaml +0 -31
  67. package/examples/prompts/developer/doc-generator.yaml +0 -36
  68. package/examples/prompts/developer/error-code-fixer.yaml +0 -35
  69. package/examples/prompts/engineer/engineer-professional.yaml +0 -92
  70. package/examples/prompts/engineer/laowang-engineer.yaml +0 -132
  71. package/examples/prompts/engineer/nekomata-engineer.yaml +0 -123
  72. package/examples/prompts/engineer/ojousama-engineer.yaml +0 -124
  73. package/examples/prompts/generator/gen_3d_edu_webpage_html.yaml +0 -117
  74. package/examples/prompts/generator/gen_3d_webpage_html.yaml +0 -75
  75. package/examples/prompts/generator/gen_bento_grid_html.yaml +0 -112
  76. package/examples/prompts/generator/gen_html_web_page.yaml +0 -88
  77. package/examples/prompts/generator/gen_knowledge_card_html.yaml +0 -83
  78. package/examples/prompts/generator/gen_magazine_card_html.yaml +0 -82
  79. package/examples/prompts/generator/gen_mimeng_headline_title.yaml +0 -71
  80. package/examples/prompts/generator/gen_podcast_script.yaml +0 -69
  81. package/examples/prompts/generator/gen_prd_prototype_html.yaml +0 -175
  82. package/examples/prompts/generator/gen_summarize.yaml +0 -157
  83. package/examples/prompts/generator/gen_title.yaml +0 -119
  84. package/examples/prompts/generator/others/api_documentation.yaml +0 -32
  85. package/examples/prompts/generator/others/build_mcp_server.yaml +0 -26
  86. package/examples/prompts/generator/others/project_architecture.yaml +0 -31
  87. package/examples/prompts/generator/others/test_case_generator.yaml +0 -30
  88. package/examples/prompts/generator/others/writing_assistant.yaml +0 -72
  89. package/examples/prompts/recommend/human_3-0_growth_diagnostic_coach_prompt.yaml +0 -105
  90. package/examples/prompts/workflow/sixstep-workflow.yaml +0 -192
  91. package/packages/admin-ui/.babelrc +0 -3
  92. package/packages/admin-ui/admin.html +0 -412
  93. package/packages/admin-ui/css/codemirror-theme_xq-light.css +0 -43
  94. package/packages/admin-ui/css/codemirror.css +0 -344
  95. package/packages/admin-ui/css/main.css +0 -2592
  96. package/packages/admin-ui/css/recommended-prompts.css +0 -610
  97. package/packages/admin-ui/package-lock.json +0 -6973
  98. package/packages/admin-ui/package.json +0 -36
  99. package/packages/admin-ui/src/codemirror.js +0 -53
  100. package/packages/admin-ui/src/index.js +0 -3188
  101. package/packages/admin-ui/webpack.config.js +0 -76
  102. package/packages/server/toolm/test-tools.js +0 -264
  103. package/scripts/build-icons.js +0 -135
  104. package/scripts/build.sh +0 -57
  105. package/scripts/postinstall.js +0 -34
  106. package/scripts/surge/CNAME +0 -1
  107. package/scripts/surge/README.md +0 -47
  108. package/scripts/surge/package-lock.json +0 -34
  109. package/scripts/surge/package.json +0 -20
  110. package/scripts/surge/sync-to-surge.js +0 -151
@@ -0,0 +1,498 @@
1
+ /**
2
+ * TerminalService - 终端服务管理类
3
+ *
4
+ * 提供跨平台终端会话管理,支持PTY(伪终端)和实时交互
5
+ * 支持Windows、macOS和Linux系统的原生终端命令
6
+ */
7
+
8
+ import { spawn } from 'child_process';
9
+ import { randomUUID } from 'crypto';
10
+ import { logger } from '../utils/logger.js';
11
+ import path from 'path';
12
+ import os from 'os';
13
+
14
+ // 延迟加载 node-pty,避免编译错误
15
+ let pty = null;
16
+ let PTY_AVAILABLE = false;
17
+ let PTY_LOAD_ERROR = null;
18
+
19
+ /**
20
+ * 尝试加载 node-pty 模块
21
+ */
22
+ async function tryLoadNodePty() {
23
+ try {
24
+ const ptyModule = await import('node-pty');
25
+ pty = ptyModule;
26
+ // 测试模块是否真正可用
27
+ if (pty && pty.default && pty.default.spawn) {
28
+ PTY_AVAILABLE = true;
29
+ logger.info('node-pty 模块加载成功');
30
+ return true;
31
+ }
32
+ } catch (error) {
33
+ PTY_LOAD_ERROR = error;
34
+ PTY_AVAILABLE = false;
35
+ logger.warn('node-pty 模块不可用,终端功能将被禁用:', error.message);
36
+ logger.warn('提示: 运行 "npm rebuild node-pty" 来修复此问题');
37
+ return false;
38
+ }
39
+ return false;
40
+ }
41
+
42
+ /**
43
+ * 终端会话类
44
+ */
45
+ class TerminalSession {
46
+ constructor(id, ptyProcess, options = {}) {
47
+ this.id = id;
48
+ this.pty = ptyProcess;
49
+ this.createdAt = new Date();
50
+ this.lastActivity = new Date();
51
+ this.workingDirectory = options.workingDirectory || os.homedir();
52
+ this.shell = options.shell || this.getDefaultShell();
53
+ this.platform = options.platform || process.platform;
54
+ this.size = options.size || { cols: 80, rows: 24 };
55
+ this.environment = options.environment || process.env;
56
+ this.isActive = true;
57
+ this.isFallback = options.isFallback || false; // 标记是否使用回退方案
58
+
59
+ // 绑定PTY事件
60
+ this.setupPtyEvents();
61
+ }
62
+
63
+ /**
64
+ * 获取默认Shell
65
+ */
66
+ getDefaultShell() {
67
+ switch (process.platform) {
68
+ case 'win32':
69
+ return process.env.COMSPEC || 'cmd.exe';
70
+ case 'darwin':
71
+ return process.env.SHELL || '/bin/bash';
72
+ case 'linux':
73
+ return process.env.SHELL || '/bin/bash';
74
+ default:
75
+ return '/bin/sh';
76
+ }
77
+ }
78
+
79
+ /**
80
+ * 设置PTY事件监听
81
+ */
82
+ setupPtyEvents() {
83
+ if (!this.pty) return;
84
+
85
+ this.pty.on('data', (data) => {
86
+ this.lastActivity = new Date();
87
+ this.emit('data', data);
88
+ });
89
+
90
+ this.pty.on('exit', (exitCode, signal) => {
91
+ this.isActive = false;
92
+ this.emit('exit', { exitCode, signal });
93
+ });
94
+ }
95
+
96
+ /**
97
+ * 写入数据到终端
98
+ */
99
+ write(data) {
100
+ if (!this.isActive || !this.pty) {
101
+ throw new Error('Terminal session is not active');
102
+ }
103
+ this.pty.write(data);
104
+ this.lastActivity = new Date();
105
+ }
106
+
107
+ /**
108
+ * 调整终端大小
109
+ */
110
+ resize(cols, rows) {
111
+ if (!this.isActive || !this.pty) {
112
+ throw new Error('Terminal session is not active');
113
+ }
114
+ this.pty.resize(cols, rows);
115
+ this.size = { cols, rows };
116
+ }
117
+
118
+ /**
119
+ * 终止会话
120
+ */
121
+ terminate() {
122
+ if (this.pty) {
123
+ this.pty.kill();
124
+ }
125
+ this.isActive = false;
126
+ }
127
+
128
+ /**
129
+ * 获取会话信息
130
+ */
131
+ getInfo() {
132
+ return {
133
+ id: this.id,
134
+ shell: this.shell,
135
+ workingDirectory: this.workingDirectory,
136
+ platform: this.platform,
137
+ size: this.size,
138
+ createdAt: this.createdAt,
139
+ lastActivity: this.lastActivity,
140
+ isActive: this.isActive
141
+ };
142
+ }
143
+
144
+ /**
145
+ * 简单的事件发射器实现
146
+ */
147
+ emit(event, ...args) {
148
+ if (this._events && this._events[event]) {
149
+ this._events[event].forEach(callback => callback(...args));
150
+ }
151
+ }
152
+
153
+ /**
154
+ * 事件监听器
155
+ */
156
+ on(event, callback) {
157
+ if (!this._events) this._events = {};
158
+ if (!this._events[event]) this._events[event] = [];
159
+ this._events[event].push(callback);
160
+ }
161
+
162
+ /**
163
+ * 移除事件监听器
164
+ */
165
+ off(event, callback) {
166
+ if (!this._events || !this._events[event]) return;
167
+ const index = this._events[event].indexOf(callback);
168
+ if (index > -1) {
169
+ this._events[event].splice(index, 1);
170
+ }
171
+ }
172
+ }
173
+
174
+ /**
175
+ * TerminalService 主类
176
+ */
177
+ export class TerminalService {
178
+ constructor(options = {}) {
179
+ this.sessions = new Map();
180
+ this.defaultOptions = {
181
+ shell: null, // 自动检测
182
+ workingDirectory: os.homedir(),
183
+ size: { cols: 80, rows: 24 },
184
+ timeout: 300000, // 5分钟超时
185
+ maxSessions: 10, // 最大会话数
186
+ ...options
187
+ };
188
+
189
+ // 定期清理非活跃会话
190
+ this.cleanupInterval = setInterval(() => {
191
+ this.cleanupInactiveSessions();
192
+ }, 60000); // 每分钟检查一次
193
+
194
+ logger.info('TerminalService initialized');
195
+ }
196
+
197
+ /**
198
+ * 创建新的终端会话
199
+ */
200
+ async createSession(options = {}) {
201
+ // 首次使用时尝试加载 node-pty
202
+ if (pty === null && PTY_AVAILABLE === false) {
203
+ await tryLoadNodePty();
204
+ }
205
+
206
+ // 检查PTY是否可用
207
+ if (!PTY_AVAILABLE) {
208
+ throw new Error('Terminal functionality is disabled - node-pty module is not available. Run "npm rebuild node-pty" to fix this.');
209
+ }
210
+
211
+ const sessionId = options.id || randomUUID();
212
+ const sessionOptions = { ...this.defaultOptions, ...options };
213
+
214
+ // 检查会话数限制
215
+ if (this.sessions.size >= sessionOptions.maxSessions) {
216
+ throw new Error(`Maximum sessions limit reached: ${sessionOptions.maxSessions}`);
217
+ }
218
+
219
+ // 检查会话ID是否已存在
220
+ if (this.sessions.has(sessionId)) {
221
+ throw new Error(`Session with ID ${sessionId} already exists`);
222
+ }
223
+
224
+ try {
225
+ const ptyProcess = await this.createPtyProcess(sessionOptions);
226
+ const session = new TerminalSession(sessionId, ptyProcess, sessionOptions);
227
+
228
+ // 添加事件监听
229
+ session.on('data', (data) => {
230
+ this.handleSessionData(sessionId, data);
231
+ });
232
+
233
+ session.on('exit', (info) => {
234
+ this.handleSessionExit(sessionId, info);
235
+ });
236
+
237
+ // 存储会话
238
+ this.sessions.set(sessionId, session);
239
+
240
+ logger.info(`Terminal session created: ${sessionId}`);
241
+ return session;
242
+ } catch (error) {
243
+ logger.error(`Failed to create terminal session: ${error.message}`);
244
+ throw error;
245
+ }
246
+ }
247
+
248
+ /**
249
+ * 创建PTY进程
250
+ */
251
+ async createPtyProcess(options) {
252
+ const shell = options.shell || this.getDefaultShellForPlatform();
253
+ const args = this.getShellArgs(shell);
254
+ const cwd = options.workingDirectory || os.homedir();
255
+ const env = { ...process.env, ...options.environment };
256
+
257
+ logger.debug(`Creating PTY with shell: ${shell}, args: ${args.join(' ')}, cwd: ${cwd}`);
258
+
259
+ return pty.default.spawn(shell, args, {
260
+ name: 'xterm-color',
261
+ cols: options.size.cols,
262
+ rows: options.size.rows,
263
+ cwd: cwd,
264
+ env: env
265
+ });
266
+ }
267
+
268
+ /**
269
+ * 获取平台对应的默认Shell
270
+ */
271
+ getDefaultShellForPlatform() {
272
+ switch (process.platform) {
273
+ case 'win32':
274
+ return process.env.COMSPEC || 'cmd.exe';
275
+ case 'darwin':
276
+ return process.env.SHELL || '/bin/bash';
277
+ case 'linux':
278
+ return process.env.SHELL || '/bin/bash';
279
+ default:
280
+ return '/bin/sh';
281
+ }
282
+ }
283
+
284
+ /**
285
+ * 获取Shell启动参数
286
+ */
287
+ getShellArgs(shell) {
288
+ if (process.platform === 'win32') {
289
+ if (shell.includes('powershell') || shell.includes('pwsh')) {
290
+ return ['-NoLogo', '-ExecutionPolicy', 'Bypass', '-NoExit'];
291
+ }
292
+ return ['/c'];
293
+ }
294
+ return ['-l'];
295
+ }
296
+
297
+ /**
298
+ * 获取会话
299
+ */
300
+ getSession(sessionId) {
301
+ return this.sessions.get(sessionId);
302
+ }
303
+
304
+ /**
305
+ * 获取所有会话
306
+ */
307
+ getAllSessions() {
308
+ return Array.from(this.sessions.values());
309
+ }
310
+
311
+ /**
312
+ * 会话是否存在
313
+ */
314
+ hasSession(sessionId) {
315
+ return this.sessions.has(sessionId);
316
+ }
317
+
318
+ /**
319
+ * 删除会话
320
+ */
321
+ async removeSession(sessionId) {
322
+ const session = this.sessions.get(sessionId);
323
+ if (session) {
324
+ session.terminate();
325
+ this.sessions.delete(sessionId);
326
+ logger.info(`Terminal session removed: ${sessionId}`);
327
+ return true;
328
+ }
329
+ return false;
330
+ }
331
+
332
+ /**
333
+ * 处理会话数据
334
+ */
335
+ handleSessionData(sessionId, data) {
336
+ // 这里可以添加数据处理逻辑,如日志记录、过滤等
337
+ logger.debug(`Session ${sessionId} data: ${data.length} bytes`);
338
+ }
339
+
340
+ /**
341
+ * 处理会话退出
342
+ */
343
+ handleSessionExit(sessionId, exitInfo) {
344
+ logger.info(`Terminal session ${sessionId} exited: ${JSON.stringify(exitInfo)}`);
345
+ this.sessions.delete(sessionId);
346
+ }
347
+
348
+ /**
349
+ * 清理非活跃会话
350
+ */
351
+ cleanupInactiveSessions() {
352
+ const now = new Date();
353
+ const timeoutMs = this.defaultOptions.timeout;
354
+
355
+ for (const [sessionId, session] of this.sessions) {
356
+ if (!session.isActive || (now - session.lastActivity) > timeoutMs) {
357
+ logger.info(`Cleaning up inactive session: ${sessionId}`);
358
+ this.removeSession(sessionId);
359
+ }
360
+ }
361
+ }
362
+
363
+ /**
364
+ * 执行命令(非交互式)
365
+ */
366
+ async executeCommand(command, options = {}) {
367
+ return new Promise((resolve, reject) => {
368
+ const shell = this.getDefaultShellForPlatform();
369
+ const args = process.platform === 'win32' ? ['/c', command] : ['-c', command];
370
+ const cwd = options.workingDirectory || this.defaultOptions.workingDirectory;
371
+
372
+ const child = spawn(shell, args, {
373
+ cwd: cwd,
374
+ env: { ...process.env, ...options.environment },
375
+ stdio: ['pipe', 'pipe', 'pipe']
376
+ });
377
+
378
+ let stdout = '';
379
+ let stderr = '';
380
+
381
+ child.stdout?.on('data', (data) => {
382
+ stdout += data.toString();
383
+ });
384
+
385
+ child.stderr?.on('data', (data) => {
386
+ stderr += data.toString();
387
+ });
388
+
389
+ child.on('close', (code) => {
390
+ resolve({
391
+ exitCode: code,
392
+ stdout: stdout,
393
+ stderr: stderr
394
+ });
395
+ });
396
+
397
+ child.on('error', (error) => {
398
+ reject(error);
399
+ });
400
+
401
+ // 超时处理
402
+ if (options.timeout) {
403
+ setTimeout(() => {
404
+ child.kill();
405
+ reject(new Error(`Command execution timeout: ${command}`));
406
+ }, options.timeout);
407
+ }
408
+ });
409
+ }
410
+
411
+ /**
412
+ * 获取工作目录
413
+ */
414
+ async getWorkingDirectory(sessionId) {
415
+ const session = this.getSession(sessionId);
416
+ if (session) {
417
+ return session.workingDirectory;
418
+ }
419
+
420
+ // 如果没有会话,返回默认工作目录
421
+ return this.defaultOptions.workingDirectory;
422
+ }
423
+
424
+ /**
425
+ * 设置工作目录
426
+ */
427
+ async setWorkingDirectory(sessionId, directory) {
428
+ const session = this.getSession(sessionId);
429
+ if (session) {
430
+ session.workingDirectory = directory;
431
+ // 发送cd命令到终端
432
+ session.write(`cd "${directory}"\n`);
433
+ return true;
434
+ }
435
+ return false;
436
+ }
437
+
438
+ /**
439
+ * 获取服务状态
440
+ */
441
+ getStatus() {
442
+ const activeSessions = this.getAllSessions().filter(s => s.isActive);
443
+ return {
444
+ totalSessions: this.sessions.size,
445
+ activeSessions: activeSessions.length,
446
+ maxSessions: this.defaultOptions.maxSessions,
447
+ uptime: process.uptime(),
448
+ platform: process.platform,
449
+ nodeVersion: process.version
450
+ };
451
+ }
452
+
453
+ /**
454
+ * 关闭服务
455
+ */
456
+ async shutdown() {
457
+ // 清理所有会话
458
+ for (const [sessionId, session] of this.sessions) {
459
+ session.terminate();
460
+ }
461
+ this.sessions.clear();
462
+
463
+ // 清理定时器
464
+ if (this.cleanupInterval) {
465
+ clearInterval(this.cleanupInterval);
466
+ }
467
+
468
+ logger.info('TerminalService shutdown');
469
+ }
470
+ }
471
+
472
+ /**
473
+ * 获取 PTY 状态信息
474
+ */
475
+ export function getPtyStatus() {
476
+ return {
477
+ available: PTY_AVAILABLE,
478
+ loadError: PTY_LOAD_ERROR ? PTY_LOAD_ERROR.message : null,
479
+ nodeVersion: process.version,
480
+ platform: process.platform
481
+ };
482
+ }
483
+
484
+ /**
485
+ * 尝试重新加载 PTY 模块
486
+ */
487
+ export async function reloadPty() {
488
+ PTY_AVAILABLE = false;
489
+ PTY_LOAD_ERROR = null;
490
+ pty = null;
491
+ return await tryLoadNodePty();
492
+ }
493
+
494
+ // 创建单例实例
495
+ export const terminalService = new TerminalService();
496
+
497
+ // 导出类型定义
498
+ export { TerminalSession };