mcp-osp-prompt 1.0.0 → 1.0.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.
package/server.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import process from 'process';
3
3
  import { initializePrompts, getToolsConfiguration } from './prompt-manager.js';
4
- import { handleDevTool, handleDevManual, handleDevFeedback, handleLoadResource } from './tools.js';
4
+ import { handleDevTool, handleDevManual, handleDevFeedback } from './tools.js';
5
5
  import { CFG } from './config.js';
6
6
  import {
7
7
  createSuccessResponse,
@@ -43,12 +43,12 @@ if (debug) {
43
43
 
44
44
  // 🔄 优雅关闭处理
45
45
  process.on('SIGTERM', () => {
46
- console.log('📴 [MCP-Server] Received SIGTERM, shutting down gracefully');
46
+ console.error('📴 [MCP-Server] Received SIGTERM, shutting down gracefully');
47
47
  process.exit(0);
48
48
  });
49
49
 
50
50
  process.on('SIGINT', () => {
51
- console.log('📴 [MCP-Server] Received SIGINT, shutting down gracefully');
51
+ console.error('📴 [MCP-Server] Received SIGINT, shutting down gracefully');
52
52
  process.exit(0);
53
53
  });
54
54
 
@@ -58,18 +58,35 @@ let isServerReady = false;
58
58
 
59
59
  // 同步初始化函数 - 阻塞式等待初始化完成
60
60
  async function initializeServerSync() {
61
+ // ✅ 添加keepAlive定时器,防止客户端超时
62
+ let keepAliveInterval;
63
+
61
64
  try {
62
65
  console.error('[MCP-Server] Starting synchronous initialization...');
63
66
 
67
+ // 每10秒输出一次日志,保持连接活跃
68
+ keepAliveInterval = setInterval(() => {
69
+ console.error('[MCP-KeepAlive] Initializing tools, please wait...');
70
+ }, 10000);
71
+
64
72
  // 同步初始化prompt管理器
65
73
  globalToolsConfig = await initializePrompts();
66
74
 
75
+ // 清理keepAlive定时器
76
+ clearInterval(keepAliveInterval);
77
+ keepAliveInterval = null;
78
+
67
79
  // 标记服务器就绪
68
80
  isServerReady = true;
69
81
  console.error(`[MCP-Server] ✅ Server ready with ${globalToolsConfig.length} tools`);
70
82
 
71
83
  return true;
72
84
  } catch (error) {
85
+ // 清理keepAlive定时器(如果还在运行)
86
+ if (keepAliveInterval) {
87
+ clearInterval(keepAliveInterval);
88
+ }
89
+
73
90
  console.error('[MCP-Server] ❌ Initialization failed:', error.message);
74
91
  console.error('[MCP-Server] Server will not accept requests');
75
92
  isServerReady = false;
@@ -216,9 +233,6 @@ async function handleToolCall(req) {
216
233
  ⚠️ **MANDATORY NEXT STEP REMINDER:** 在完成下一个实施步骤后,必须再次调用dev-feedback工具汇报进度并获取确认。每个步骤完成后都需要调用feedback工具 - 这是强制要求!`;
217
234
  }
218
235
  break;
219
- case 'handleLoadResource':
220
- resultText = await handleLoadResource(args);
221
- break;
222
236
  default:
223
237
  throw new Error(`Unknown handler: ${tool.handler}`);
224
238
  }
@@ -226,15 +240,44 @@ async function handleToolCall(req) {
226
240
  // Handle prompt-based tools
227
241
  const promptResult = await handleDevTool(name, args);
228
242
 
229
- // Add mandatory feedback reminder to all prompt-based tools
230
- resultText = `${promptResult}
243
+ // 根据AUTO模式附加不同的工作流指令
244
+ const isAutomatedMode = (process.env.AUTOMATED_MODE || 'false').toLowerCase() === 'true';
245
+
246
+ if (isAutomatedMode) {
247
+ // AUTO=true: 简洁提醒
248
+ resultText = `${promptResult}
231
249
 
232
- ⚠️ **CRITICAL WORKFLOW REQUIREMENT:**
233
- 1. 在制定好plan后,第一步开始执行前,必须调用dev-feedback工具将计划展示给用户确认
234
- 2. 每个实施步骤完成后,必须调用dev-feedback工具汇报进度并获取确认后再继续下一步
235
- 3. 这是强制要求,不可跳过!每次调用feedback后会自动提醒下一步也需要再次调用feedback
250
+ **工作流提醒:** 按计划执行,完成后汇报结果。`;
251
+ } else {
252
+ // AUTO=false: 强制分步确认+自检
253
+ resultText = `${promptResult}
236
254
 
237
- **请严格遵守此工作流程,确保每个步骤都有用户确认。**`;
255
+ ---
256
+ ## ⚠️ **CRITICAL WORKFLOW REQUIREMENT:**
257
+
258
+ **每完成一步,必须调用 \`dev-feedback\` 并展示以下信息:**
259
+
260
+ ### 展示内容
261
+ 1. **当前阶段**:完成的步骤/阶段名称
262
+ 2. **工作摘要**:完成的主要工作内容
263
+ 3. **自检结果**:
264
+ - 是否有多方案未选择
265
+ - 是否有信息不明确或需要澄清的内容
266
+ - 是否发现冲突(代码/逻辑/信息)
267
+ - 是否偏离计划需要调整
268
+ - 是否即将执行重要操作(删除代码、修改核心逻辑、数据库变更等)
269
+ - 是否存在"TBD"、"待确认"、"Question"等需要用户确认的内容
270
+ - 是否涉及项目/系统范围确认(无论已确认还是待确认,都必须调用 dev-feedback 让用户确认)
271
+ 4. **下一步**:下一步计划(如有)
272
+
273
+ **最后一步结束后,确认:是否满足所有需求和完成了计划?**
274
+
275
+ ### 规则
276
+ - 宁可多确认,不可漏确认
277
+ - 严禁将待确认内容留到最终文档
278
+
279
+ **⚠️ 立即调用 dev-feedback 开始确认!**`;
280
+ }
238
281
  } else {
239
282
  throw new Error(`Unknown tool type: ${tool.type}`);
240
283
  }
@@ -248,7 +291,7 @@ async function handleToolCall(req) {
248
291
 
249
292
  // 特殊处理:某些"错误"实际上是正常的用户交互结果
250
293
  if (error.message.includes('用户要求调整计划')) {
251
- console.log(`[MCP信息] 用户计划调整请求: ${error.message}`);
294
+ console.error(`[MCP信息] 用户计划调整请求: ${error.message}`);
252
295
  return createSuccessResponse(req.id, {
253
296
  content: [{ type: 'text', text: error.message }]
254
297
  });
@@ -260,7 +303,7 @@ async function handleToolCall(req) {
260
303
  // 针对常见错误场景提供更清晰的信息
261
304
  if (error.message.includes('fetch fail') || error.message.includes('API')) {
262
305
  errorMsg = `网络请求失败 - ${error.message}`;
263
- } else if (error.message.includes('RESOURCE_PATH')) {
306
+ } else if (error.message.includes('PROMPT_PATH')) {
264
307
  errorMsg = `配置错误 - ${error.message}`;
265
308
  } else if (error.message.includes('Unknown prompt file')) {
266
309
  errorMsg = `文件未找到 - ${error.message}`;
package/test.js CHANGED
@@ -9,7 +9,7 @@ console.log('🧪 Starting comprehensive MCP server tests...');
9
9
  (async () => {
10
10
  // Set automated mode to skip GUI dialogs and required environment variables
11
11
  process.env.AUTOMATED_MODE = 'true';
12
- process.env.RESOURCE_PATH = '../dev-arch'; // Use local test path (parent directory)
12
+ process.env.PROMPT_PATH = '../dev-arch'; // Use local test path (parent directory)
13
13
  process.env.GIT_TOKEN = 'test-token'; // Dummy token for testing
14
14
 
15
15
  const proc = spawn('node', ['server.js'], {
@@ -18,7 +18,7 @@ console.log('🧪 Starting comprehensive MCP server tests...');
18
18
  env: {
19
19
  ...process.env,
20
20
  AUTOMATED_MODE: 'true',
21
- RESOURCE_PATH: '../dev-arch',
21
+ PROMPT_PATH: '../dev-arch',
22
22
  GIT_TOKEN: 'test-token'
23
23
  }
24
24
  });
package/tools.js CHANGED
@@ -50,9 +50,6 @@ export function processPromptTemplate(content, context = {}) {
50
50
  const sourceText = context.source || '';
51
51
  processedContent = processedContent.replace(/\$\{input:source[^}]*}/g, sourceText);
52
52
 
53
- // Replace requirements variable (used in design.prompt.md)
54
- processedContent = processedContent.replace(/\$\{input:requirements[^}]*}/g, sourceText);
55
-
56
53
  // Inject project context if available
57
54
  if (context.projectInfo) {
58
55
  processedContent = processedContent.replace(/\$\{project:([^}]+)}/g, (match, key) => {
@@ -84,41 +81,13 @@ export function processPromptTemplate(content, context = {}) {
84
81
  export function generateStepModeInstructions(context = {}) {
85
82
  const sourceText = context.source || '未指定需求';
86
83
 
84
+ // 简化版:主要逻辑已统一移到server.js handleToolCall处理
85
+ // 这里只提供基本的需求上下文,避免重复
87
86
  return `
88
87
 
89
- ## 🔄 分步交互模式已启用
90
- 当前需求:${sourceText}
91
-
92
- ### 🎯 分步执行指南
93
- 1. **计划阶段**: 先分析需求并制定实施计划,然后调用 \`dev-feedback\` 工具请求用户确认
94
- 2. **实施阶段**: 每完成一个重要步骤后,使用 \`dev-feedback\` 工具询问用户是否继续
95
- 3. **实施阶段**: 连续出现3次执行错误,则使用 \`dev-feedback\` 工具请求用户确认是否需要继续或修改计划
96
- 4. **实施阶段**: 如果执行的过程中,需要使用不在计划中的新方案或新思路,则使用 \`dev-feedback\` 工具请求用户确认是否需要继续或修改计划
97
- 5. **确认选项**:
98
- - "继续" - 按计划继续执行
99
- - "修改" - 调整当前计划或步骤
100
- - "暂停" - 暂停开发等待进一步指示
101
-
102
- ### 📞 如何调用确认工具
103
-
104
- **调用方式** :
105
- 统一的弹窗选项,所有阶段都使用相同的简洁选择:
106
-
107
- - **所有阶段**: 统一使用 ["继续", "修改计划"] 两个选项
108
- - **用户体验**: 选择"继续"将按当前计划执行,选择"修改计划"将弹出输入框供用户提供调整意见
109
- - **简化设计**: 移除了复杂的多选项,采用二元选择 + 输入框的设计模式
110
-
111
- **示例调用**:
112
- \`\`\`
113
- 调用 dev-feedback 工具,参数:
114
- {
115
- "title": "开发计划确认",
116
- "message": "已分析需求并制定开发计划,包含以下步骤:1)设计数据模型 2)实现API接口 3)编写单元测试 4)集成测试。是否开始实施?",
117
- "phase": "planning"
118
- }
119
- \`\`\`
120
-
121
- **重要**: 在每个关键节点都要主动请求用户确认,确保开发方向正确。优先使用阶段特定的feedback调用方式。`;
88
+ ---
89
+ **当前需求:** ${sourceText}
90
+ ---`;
122
91
  }
123
92
 
124
93
  /**
@@ -276,8 +245,6 @@ export async function enhancedDevFeedback(feedbackInput = {}) {
276
245
  // 简化逻辑:直接传入options,函数内部自动判断场景
277
246
  const options = getStandardButtons(feedbackInput.options);
278
247
 
279
- console.log('📋 [ENHANCED-FEEDBACK] Applied unified standard buttons:', options);
280
-
281
248
  // Standard message processing - no version info in intermediate feedback
282
249
  let enhancedMessage = feedbackInput.message;
283
250
 
@@ -434,7 +401,7 @@ export async function handleDevTool(toolName, args) {
434
401
  let versionInfo = '';
435
402
  try {
436
403
  const info = await getLocalPromptInfo(fileName);
437
- versionInfo = `\n\n📌 V: ${info.version}`;
404
+ versionInfo = `\n\n📌 Prompt版本: ${info.version}`;
438
405
  } catch (error) {
439
406
  console.warn(`[Version] Failed to get version for ${fileName}:`, error.message);
440
407
  }
@@ -501,80 +468,6 @@ When creating directories or referencing dates, always use ${currentDate}.
501
468
  // Prepend date context to the beginning of the content
502
469
  content = dateContextHeader + content;
503
470
 
504
- // 🟢 GREEN: 统一注入完整的resources列表(projects + rules)
505
- try {
506
- // 动态导入避免循环依赖
507
- const { formatResourcesList } = await import('./resource-manager.js');
508
- const { UNIFIED_RESOURCES } = await import('./config.js');
509
-
510
- // 统一加载完整的projects和rules列表
511
- const resourcesList = await formatResourcesList(UNIFIED_RESOURCES);
512
-
513
- // 构建前置内容
514
- let prefixContent = '---\n\n';
515
- prefixContent += resourcesList + '\n';
516
-
517
- if (!automatedMode) {
518
- // 手动模式:要求通过feedback确认资源选择
519
- prefixContent += `
520
- **📋 执行规则 (MANDATORY EXECUTION RULES):**
521
-
522
- 1. **每阶段完成必须反馈**: 完成每个阶段/步骤后,必须调用 \`dev-feedback\` 工具汇报进度并获取确认。
523
- 2. **等待用户确认**: 每次feedback后必须等待用户确认才能继续下一步。
524
- 3. **这是强制要求**: 不是可选项,每个阶段都必须执行。
525
-
526
- ---
527
-
528
- **🎯 资源确认流程 (RESOURCE CONFIRMATION - auto=false 模式):**
529
-
530
- 在开始详细分析或实施工作之前:
531
-
532
- 1. **审查可用资源**: 仔细查看上方提供的projects和rules资源列表
533
- 2. **分析需求**: 根据需求/任务,判断需要使用哪些资源
534
- 3. **选择资源**:
535
- - **项目文档 (Projects)**: 选择相关的系统wiki文档
536
- - **开发规则 (Rules)**: 选择相关的编码规范和标准
537
- 4. **强制确认**: 必须调用 \`dev-feedback\` 工具向用户确认:
538
- - 需求范围总结
539
- - 选定的项目文档列表(说明原因)
540
- - 选定的规则文档列表(说明原因)
541
- - 询问:"确认范围正确吗?可以继续吗?"
542
- 5. **等待批准**: 在用户确认前不得继续
543
- 6. **加载资源**: 确认后,使用 \`load-resource\` 工具加载已批准的资源
544
-
545
- **此确认步骤是强制性的且阻塞性的 - 不能跳过。**
546
-
547
- ---
548
-
549
- `;
550
- } else {
551
- // 自动模式:AI自行选择并加载resources
552
- prefixContent += `
553
- **📋 AUTO 模式 - 自动资源管理:**
554
-
555
- 系统已提供完整的项目文档和开发规则列表。
556
-
557
- **工作流程:**
558
- 1. 根据任务需求,自行判断并选择需要的resources
559
- 2. 使用 \`load-resource\` 工具加载选定的资源内容
560
- 3. 所有projects和rules都可用,按需加载
561
-
562
- **可用资源:**
563
- - **Projects**: 所有系统项目文档
564
- - **Rules**: 所有开发规范和标准
565
-
566
- 直接开始分析和实施,根据需要使用 \`load-resource\` 工具。
567
-
568
- ---
569
-
570
- `;
571
- }
572
-
573
- content = prefixContent + content;
574
- } catch (error) {
575
- console.warn('[handleDevTool] Failed to inject resources list:', error.message);
576
- }
577
-
578
471
  // 版本信息现在在弹窗中显示,不再添加到response中
579
472
  return content;
580
473
  }
@@ -602,9 +495,10 @@ export async function handleDevFeedback(args) {
602
495
  // 简化逻辑:直接传入options,函数内部自动判断场景
603
496
  const finalOptions = getStandardButtons(options.length > 0 ? options : null);
604
497
 
605
- console.log('🔧 [BUTTON-MANAGEMENT] Applied unified standard buttons:', finalOptions);
606
-
607
- console.log('📞 [DEV-FEEDBACK] Showing dialog:', { title, message, options: finalOptions });
498
+ // 🆕 添加保活机制:在等待用户交互期间定期输出日志
499
+ const keepAliveInterval = setInterval(() => {
500
+ console.error('[MCP-KeepAlive] Waiting for user dialog interaction...');
501
+ }, 15000);
608
502
 
609
503
  try {
610
504
  const result = await showConfirmDialog({
@@ -613,9 +507,10 @@ export async function handleDevFeedback(args) {
613
507
  buttons: finalOptions
614
508
  });
615
509
 
510
+ clearInterval(keepAliveInterval); // 用户选择后清理定时器
511
+
616
512
  // If user selects a "modify" option, automatically show input dialog
617
513
  if (result && (result.includes('修改') || result.includes('调整') || result.includes('建议'))) {
618
- console.log('📝 [INPUT REQUEST] User wants to provide input, showing input dialog...');
619
514
 
620
515
  const userInput = await showInputDialog({
621
516
  title: '输入修改建议',
@@ -624,8 +519,6 @@ export async function handleDevFeedback(args) {
624
519
  rows: 5 // Use 5-row input for modification suggestions
625
520
  });
626
521
 
627
- console.log('✅ [USER INPUT]:', userInput);
628
-
629
522
  // Return structured feedback with clear indication for AI processing
630
523
  return {
631
524
  action: result,
@@ -635,9 +528,9 @@ export async function handleDevFeedback(args) {
635
528
  requiresAdjustment: true // Flag to indicate AI should adjust execution
636
529
  };
637
530
  }
638
- console.log('✅ [USER RESPONSE]:', result);
639
531
  return result;
640
532
  } catch (error) {
533
+ clearInterval(keepAliveInterval); // 出错时也要清理定时器
641
534
  console.error('❌ [FEEDBACK ERROR]:', error.message);
642
535
 
643
536
  // Check if this is a dialog system failure
@@ -672,30 +565,4 @@ export async function handleDevFeedback(args) {
672
565
  }
673
566
 
674
567
  // handleDevReload removed - configuration now loads automatically from environment and mcp.json
675
- // No manual reload needed as per user requirements
676
-
677
- /**
678
- * 🟢 GREEN: Handle load-resource tool
679
- * 加载resource的完整内容
680
- */
681
- export async function handleLoadResource(args) {
682
- const { resourceName } = args;
683
-
684
- if (!resourceName) {
685
- return `❌ Error: resourceName is required`;
686
- }
687
-
688
- try {
689
- // 动态导入避免循环依赖
690
- const { loadResourceContent } = await import('./resource-manager.js');
691
- const result = await loadResourceContent(resourceName);
692
-
693
- if (!result.success) {
694
- return `❌ Error loading resource "${resourceName}": ${result.error}`;
695
- }
696
-
697
- return `# Resource: ${result.filename} (${result.type})\n\n${result.content}`;
698
- } catch (error) {
699
- return `❌ Error: ${error.message}`;
700
- }
701
- }
568
+ // No manual reload needed as per user requirements