mcp-osp-prompt 1.0.0

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/tools.js ADDED
@@ -0,0 +1,701 @@
1
+ import { getPrompt } from './fetcher.js';
2
+ import { getToolsConfiguration, getLocalPromptInfo } from './prompt-manager.js';
3
+ import { showInputDialog, showConfirmDialog, showSelectDialog, showPlanAdjustmentDialog } from './dialog/index.js';
4
+ // ✅ UNIFIED: 导入统一的按钮管理常量
5
+ import { BASE_DIALOG_BUTTONS, getSafeButtons, getStandardButtons } from './dialog/constants.js';
6
+
7
+ // 动态获取工具的source映射
8
+ function getToolSource(toolName) {
9
+ const toolsConfig = getToolsConfiguration();
10
+ const tool = toolsConfig.find(t => t.name === toolName && t.type === 'prompt');
11
+ return tool?.source;
12
+ }
13
+
14
+ // Legacy export for backward compatibility - 动态映射
15
+ export const PROMPT_FILES = new Proxy({}, {
16
+ get(target, prop) {
17
+ return getToolSource(prop);
18
+ },
19
+ ownKeys() {
20
+ const toolsConfig = getToolsConfiguration();
21
+ return toolsConfig.filter(t => t.type === 'prompt').map(t => t.name);
22
+ },
23
+ has(target, prop) {
24
+ return getToolSource(prop) !== undefined;
25
+ }
26
+ });
27
+
28
+ /**
29
+ * Generate current date in YYYYMMDD format for directory naming
30
+ * @returns {string} Current date in YYYYMMDD format
31
+ */
32
+ export function getCurrentDateString() {
33
+ const now = new Date();
34
+ const year = now.getFullYear();
35
+ const month = String(now.getMonth() + 1).padStart(2, '0');
36
+ const day = String(now.getDate()).padStart(2, '0');
37
+ return `${year}${month}${day}`;
38
+ }
39
+
40
+ /**
41
+ * Enhanced prompt template processing with variable replacement and context injection
42
+ * @param {string} content - The template content
43
+ * @param {object} context - Context object with source, projectInfo, etc.
44
+ * @returns {string} Processed content
45
+ */
46
+ export function processPromptTemplate(content, context = {}) {
47
+ let processedContent = content;
48
+
49
+ // Replace basic source variable
50
+ const sourceText = context.source || '';
51
+ processedContent = processedContent.replace(/\$\{input:source[^}]*}/g, sourceText);
52
+
53
+ // Replace requirements variable (used in design.prompt.md)
54
+ processedContent = processedContent.replace(/\$\{input:requirements[^}]*}/g, sourceText);
55
+
56
+ // Inject project context if available
57
+ if (context.projectInfo) {
58
+ processedContent = processedContent.replace(/\$\{project:([^}]+)}/g, (match, key) => {
59
+ const value = context.projectInfo[key];
60
+ return value !== undefined ? value : `[未找到项目信息: ${key}]`;
61
+ });
62
+ }
63
+
64
+ // Inject current date - ensure using correct current date
65
+ const currentDate = getCurrentDateString();
66
+ processedContent = processedContent.replace(/\$\{date:current\}/g, currentDate);
67
+ processedContent = processedContent.replace(/\{YYYYMMDD\}/g, currentDate);
68
+ processedContent = processedContent.replace(/\{yyyyMMdd\}/g, currentDate);
69
+
70
+ // Add step mode instructions if needed
71
+ const defaultAuto = (process.env.AUTOMATED_MODE || 'true').toLowerCase() === 'true';
72
+ if (context.stepMode || (!defaultAuto && context.source)) {
73
+ processedContent += generateStepModeInstructions(context);
74
+ }
75
+
76
+ return processedContent;
77
+ }
78
+
79
+ /**
80
+ * Generate step-by-step interaction instructions
81
+ * @param {object} context - Context with source requirement
82
+ * @returns {string} Step mode instructions
83
+ */
84
+ export function generateStepModeInstructions(context = {}) {
85
+ const sourceText = context.source || '未指定需求';
86
+
87
+ return `
88
+
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调用方式。`;
122
+ }
123
+
124
+ /**
125
+ * Get project context information from current workspace
126
+ * @returns {object} Project information
127
+ */
128
+ export function getProjectContext() {
129
+ // This is a placeholder implementation
130
+ // In a real scenario, this would read package.json, git info, etc.
131
+ return {
132
+ name: 'osp-prompt',
133
+ language: 'JavaScript',
134
+ stack: 'Node.js + MCP',
135
+ framework: 'None'
136
+ };
137
+ }
138
+
139
+ /**
140
+ * Validate feedback input parameters
141
+ * @param {object} input - Feedback input object
142
+ * @returns {object} Validation result with isValid and errors
143
+ */
144
+ export function validateFeedbackInput(input = {}) {
145
+ const errors = [];
146
+
147
+ if (!input.title || typeof input.title !== 'string') {
148
+ errors.push('Title is required');
149
+ }
150
+
151
+ if (!input.message || typeof input.message !== 'string') {
152
+ errors.push('Message is required');
153
+ }
154
+
155
+ // Validate plan adjustment parameters if provided
156
+ if (input.allowPlanAdjustment && typeof input.allowPlanAdjustment !== 'boolean') {
157
+ errors.push('allowPlanAdjustment must be a boolean');
158
+ }
159
+
160
+ if (input.currentPlan && typeof input.currentPlan !== 'string') {
161
+ errors.push('currentPlan must be a string');
162
+ }
163
+
164
+ return {
165
+ isValid: errors.length === 0,
166
+ errors
167
+ };
168
+ }
169
+
170
+ /**
171
+ * Create detailed descriptions for all development tools
172
+ * @returns {object} Tool descriptions with usage scenarios
173
+ */
174
+ export function createToolDescriptions() {
175
+ return {
176
+ 'dev-feature': '🚀 新功能完整开发 - 使用TDD流程从需求分析到实现的完整开发周期,适合复杂功能开发',
177
+ 'dev-design': '📐 系统架构设计 - 技术规格文档生成和系统架构设计,适合新项目启动或架构升级',
178
+ 'dev-refactor': '🔧 代码重构优化 - 代码质量提升和架构优化,适合技术债务处理和性能优化',
179
+ 'dev-small': '⚡ 快速开发修复 - 小功能开发、Bug修复和简单改进,适合热修复和快速迭代',
180
+ 'dev-tests': '🧪 测试完善覆盖 - 90%+测试覆盖率实现,自动化测试创建和修复,适合质量保障',
181
+ 'dev-bugfix': '🐛 精准问题修复 - 系统化问题分析,最小影响修复,针对性测试,适合生产问题处理'
182
+ };
183
+ }
184
+
185
+ /**
186
+ * Format tool options for selection dialog with emojis and descriptions
187
+ * @returns {Array} Formatted tool options
188
+ */
189
+ export function formatToolOptions() {
190
+ const descriptions = createToolDescriptions();
191
+ return Object.entries(descriptions).map(([tool, desc]) => {
192
+ return `${desc.split(' - ')[0]} - ${tool} - ${desc.split(' - ')[1]}`;
193
+ });
194
+ }
195
+
196
+ /**
197
+ * Extract tool name from formatted option string
198
+ * @param {string} formattedOption - Formatted option from dialog
199
+ * @returns {string} Tool name
200
+ */
201
+ export function extractToolFromOption(formattedOption) {
202
+ // Extract tool name from format: "🚀 新功能完整开发 - dev-feature - 描述"
203
+ const parts = formattedOption.split(' - ');
204
+ if (parts.length >= 2) {
205
+ return parts[1].trim();
206
+ }
207
+
208
+ // Fallback: try to find dev-* pattern in the string
209
+ const match = formattedOption.match(/dev-[a-z-]+/);
210
+ if (match) {
211
+ return match[0];
212
+ }
213
+
214
+ return formattedOption.trim();
215
+ }
216
+
217
+ /**
218
+ * Validate and enhance requirement input
219
+ * @param {string} input - User requirement input
220
+ * @returns {object} Validation result with suggestions
221
+ */
222
+ export function validateRequirementInput(input = '') {
223
+ const trimmedInput = input.trim();
224
+ const errors = [];
225
+ const suggestions = [];
226
+
227
+ if (!trimmedInput) {
228
+ errors.push('需求描述不能为空');
229
+ suggestions.push(
230
+ '💡 建议包含以下信息:',
231
+ '• 功能目标:要实现什么功能',
232
+ '• 技术要求:使用什么技术栈',
233
+ '• 验收标准:怎样算完成',
234
+ '',
235
+ '📝 示例:',
236
+ '• "实现用户登录功能,支持邮箱和手机号登录,使用JWT令牌"',
237
+ '• "重构用户管理模块,提升代码可读性和性能"',
238
+ '• "修复Safari浏览器下按钮显示异常的问题"'
239
+ );
240
+ } else if (trimmedInput.length < 10) {
241
+ suggestions.push(
242
+ '💡 建议补充更多细节:',
243
+ '• 具体的实现要求',
244
+ '• 技术约束或偏好',
245
+ '• 预期的用户体验'
246
+ );
247
+ } else {
248
+ suggestions.push(
249
+ '✨ 输入很好!可以考虑补充:',
250
+ '• 性能要求',
251
+ '• 兼容性需求',
252
+ '• 安全考虑'
253
+ );
254
+ }
255
+
256
+ return {
257
+ isValid: errors.length === 0,
258
+ errors,
259
+ suggestions,
260
+ enhancedInput: trimmedInput
261
+ };
262
+ }
263
+
264
+ /**
265
+ * Enhanced feedback handler with phase-specific options and context
266
+ * @param {object} feedbackInput - Enhanced feedback configuration
267
+ * @returns {string|object} User's selected option or plan adjustment data
268
+ */
269
+ export async function enhancedDevFeedback(feedbackInput = {}) {
270
+ // Validate input
271
+ const validation = validateFeedbackInput(feedbackInput);
272
+ if (!validation.isValid) {
273
+ throw new Error(`Invalid feedback input: ${validation.errors.join(', ')}`);
274
+ }
275
+
276
+ // 简化逻辑:直接传入options,函数内部自动判断场景
277
+ const options = getStandardButtons(feedbackInput.options);
278
+
279
+ console.log('📋 [ENHANCED-FEEDBACK] Applied unified standard buttons:', options);
280
+
281
+ // Standard message processing - no version info in intermediate feedback
282
+ let enhancedMessage = feedbackInput.message;
283
+
284
+ // Add context information to message if available
285
+ if (feedbackInput.context) {
286
+ const { currentStep, totalSteps, stepDescription } = feedbackInput.context;
287
+ if (currentStep && totalSteps) {
288
+ enhancedMessage += `\n\n📍 当前进度: 步骤 ${currentStep}/${totalSteps}`;
289
+ if (stepDescription) {
290
+ enhancedMessage += ` - ${stepDescription}`;
291
+ }
292
+ }
293
+ }
294
+
295
+ // For automated mode (testing only), return first option
296
+ if (process.env.AUTOMATED_MODE === 'true') {
297
+ console.log('🤖 [AUTOMATED_MODE] Returning:', options[0]);
298
+ return options[0];
299
+ }
300
+
301
+ // Check if this is a plan adjustment enabled feedback
302
+ const allowPlanAdjustment = feedbackInput.allowPlanAdjustment || false;
303
+ const currentPlan = feedbackInput.currentPlan || '';
304
+
305
+ // If plan adjustment is allowed, use the new plan adjustment dialog
306
+ if (allowPlanAdjustment) {
307
+
308
+ const result = await showPlanAdjustmentDialog({
309
+ title: feedbackInput.title,
310
+ message: enhancedMessage,
311
+ currentPlan: currentPlan,
312
+ options: options,
313
+ allowInput: true,
314
+ inputPrompt: '请描述您希望如何调整当前计划或步骤:'
315
+ });
316
+
317
+ // If result is an object, it means user provided plan adjustment input
318
+ if (typeof result === 'object' && result.action && result.input) {
319
+ return {
320
+ action: result.action,
321
+ planAdjustment: result.input,
322
+ adjustmentRequested: true
323
+ };
324
+ }
325
+
326
+ return result;
327
+ }
328
+
329
+ // For standard feedback without plan adjustment, use handleDevFeedback
330
+ const result = await handleDevFeedback({
331
+ title: feedbackInput.title,
332
+ message: enhancedMessage,
333
+ options: options
334
+ });
335
+
336
+ // Handle the new input format from handleDevFeedback
337
+ if (typeof result === 'object' && result.hasUserInput) {
338
+ return {
339
+ action: result.action,
340
+ planAdjustment: result.input,
341
+ adjustmentRequested: true
342
+ };
343
+ }
344
+
345
+ return result;
346
+ }
347
+
348
+ /**
349
+ * Enhanced dev-manual with better UI and validation
350
+ * @returns {string} Generated prompt result
351
+ */
352
+ export async function enhancedDevManual() {
353
+ if (process.env.AUTOMATED_MODE === 'true') {
354
+ // Use default values for automated testing
355
+ return await handleDevTool('dev-feature', { source: 'automated test requirement for enhanced manual' });
356
+ }
357
+
358
+ try {
359
+ // Show enhanced tool selection
360
+ const toolOptions = formatToolOptions();
361
+ const selectedOption = await showSelectDialog({
362
+ title: '选择开发类型',
363
+ message: '请选择要执行的开发类型:\n\n🎯 每种类型都有对应的最佳实践和流程指导',
364
+ items: toolOptions
365
+ });
366
+
367
+ if (!selectedOption) {
368
+ throw new Error('未选择开发类型');
369
+ }
370
+
371
+ // Extract tool name from formatted option
372
+ const toolName = extractToolFromOption(selectedOption);
373
+
374
+ if (!toolName) {
375
+ throw new Error('无法识别选择的工具');
376
+ }
377
+
378
+ // Show enhanced requirement input dialog
379
+ let requirementInput = '';
380
+ let isValidInput = false;
381
+ let attempts = 0;
382
+ const maxAttempts = 3;
383
+
384
+ while (!isValidInput && attempts < maxAttempts) {
385
+ const promptMessage = attempts === 0
386
+ ? '请输入详细的需求描述:\n\n💡 好的需求描述应该包含:功能目标、技术要求、验收标准'
387
+ : `请重新输入需求描述 (尝试 ${attempts + 1}/${maxAttempts}):\n\n💡 建议:更详细地描述您的需求`;
388
+
389
+ requirementInput = await showInputDialog({
390
+ title: '需求描述',
391
+ message: promptMessage,
392
+ defaultValue: attempts > 0 ? requirementInput : '',
393
+ rows: 5 // Use 5-row input for requirement descriptions
394
+ });
395
+
396
+ const validation = validateRequirementInput(requirementInput);
397
+
398
+ if (validation.isValid) {
399
+ isValidInput = true;
400
+ } else {
401
+ // In a real implementation, we might show validation feedback
402
+ // For now, we'll allow shorter inputs after first attempt
403
+ if (attempts > 0 && requirementInput.trim().length > 0) {
404
+ isValidInput = true;
405
+ }
406
+ }
407
+
408
+ attempts++;
409
+ }
410
+
411
+ if (!isValidInput) {
412
+ throw new Error('需求描述验证失败');
413
+ }
414
+
415
+ // Call the selected tool with the requirement
416
+ return await handleDevTool(toolName, { source: requirementInput });
417
+
418
+ } catch (error) {
419
+ throw new Error(`Enhanced dev-manual failed: ${error.message}`);
420
+ }
421
+ }
422
+
423
+ export async function handleDevTool(toolName, args) {
424
+ // dev-feature etc. triggered programmatically or by dev-manual selection
425
+ const fileName = getToolSource(toolName);
426
+ if (!fileName) throw new Error(`invalid tool ${toolName}`);
427
+
428
+ const sourceText = args?.source || 'No description';
429
+
430
+ // If step mode is enabled, show initial confirmation dialog
431
+ const automatedMode = (process.env.AUTOMATED_MODE || 'true').toLowerCase() === 'true';
432
+ if (!automatedMode) {
433
+ // Version info - simplified for unified manager
434
+ let versionInfo = '';
435
+ try {
436
+ const info = await getLocalPromptInfo(fileName);
437
+ versionInfo = `\n\n📌 V: ${info.version}`;
438
+ } catch (error) {
439
+ console.warn(`[Version] Failed to get version for ${fileName}:`, error.message);
440
+ }
441
+
442
+ const initialConfirmation = await enhancedDevFeedback({
443
+ title: '开始开发确认',
444
+ message: `准备开始执行: ${toolName}${versionInfo}\n\n需求描述: ${sourceText}\n\n是否开始分步执行?`,
445
+ phase: 'planning',
446
+ context: {
447
+ currentStep: 0,
448
+ totalSteps: '待确定',
449
+ stepDescription: '初始确认'
450
+ }
451
+ });
452
+
453
+ // 检查用户是否选择了修改计划
454
+ if (
455
+ (typeof initialConfirmation === 'object' && initialConfirmation.adjustmentRequested) ||
456
+ (typeof initialConfirmation === 'string' && initialConfirmation.includes('修改计划'))
457
+ ) {
458
+ // 提取用户的调整意见
459
+ const adjustmentMessage = typeof initialConfirmation === 'object'
460
+ ? initialConfirmation.planAdjustment
461
+ : '用户要求修改计划';
462
+
463
+ // 返回调整信息而不是抛出错误,避免MCP服务崩溃
464
+ return `⚠️ **用户要求调整计划**: ${adjustmentMessage}
465
+
466
+ 请根据用户的要求调整当前计划后重新执行。
467
+
468
+ ---
469
+
470
+ 如需重新开始,请再次调用此工具。`;
471
+ }
472
+ }
473
+
474
+ let content = await getPrompt(fileName);
475
+
476
+ // Use enhanced template processing
477
+ const context = {
478
+ source: sourceText,
479
+ projectInfo: getProjectContext(),
480
+ stepMode: !automatedMode
481
+ };
482
+
483
+ content = processPromptTemplate(content, context);
484
+
485
+ // 🎯 CRITICAL: Inject current date into AI context at the very beginning
486
+ const currentDate = getCurrentDateString();
487
+
488
+ const dateContextHeader = `
489
+ 🗓️ **CURRENT DATE CONTEXT**: Today is ${currentDate} (YYYYMMDD format).
490
+
491
+ **CRITICAL**: Use ONLY this date (${currentDate}) for all directory naming, file paths, and timestamps.
492
+ - ✅ Correct: \`features/${currentDate}-my-feature/\`
493
+ - ❌ Wrong: Any other date like 20250103, 20250104, 20250105, etc.
494
+
495
+ When creating directories or referencing dates, always use ${currentDate}.
496
+
497
+ ---
498
+
499
+ `;
500
+
501
+ // Prepend date context to the beginning of the content
502
+ content = dateContextHeader + content;
503
+
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
+ // 版本信息现在在弹窗中显示,不再添加到response中
579
+ return content;
580
+ }
581
+
582
+ export async function handleDevManual() {
583
+ // Use enhanced dev-manual with better UI and validation
584
+ return await enhancedDevManual();
585
+ }
586
+
587
+ export async function handleDevFeedback(args) {
588
+ // Support both old simple format and new enhanced format
589
+ if (args.phase || args.context || args.allowPlanAdjustment) {
590
+ // Use enhanced feedback for new format
591
+ return await enhancedDevFeedback(args);
592
+ }
593
+
594
+ // Legacy support for old format
595
+ const { title, message, options = [] } = args;
596
+ if (process.env.AUTOMATED_MODE === 'true') {
597
+ // Return first option or default for automated testing
598
+ console.log('🤖 [AUTOMATED_MODE] Returning:', options.length ? options[0] : '继续');
599
+ return options.length ? options[0] : '继续';
600
+ }
601
+
602
+ // 简化逻辑:直接传入options,函数内部自动判断场景
603
+ const finalOptions = getStandardButtons(options.length > 0 ? options : null);
604
+
605
+ console.log('🔧 [BUTTON-MANAGEMENT] Applied unified standard buttons:', finalOptions);
606
+
607
+ console.log('📞 [DEV-FEEDBACK] Showing dialog:', { title, message, options: finalOptions });
608
+
609
+ try {
610
+ const result = await showConfirmDialog({
611
+ title,
612
+ message,
613
+ buttons: finalOptions
614
+ });
615
+
616
+ // If user selects a "modify" option, automatically show input dialog
617
+ if (result && (result.includes('修改') || result.includes('调整') || result.includes('建议'))) {
618
+ console.log('📝 [INPUT REQUEST] User wants to provide input, showing input dialog...');
619
+
620
+ const userInput = await showInputDialog({
621
+ title: '输入修改建议',
622
+ message: '请输入您的具体修改建议或调整要求:',
623
+ defaultValue: '',
624
+ rows: 5 // Use 5-row input for modification suggestions
625
+ });
626
+
627
+ console.log('✅ [USER INPUT]:', userInput);
628
+
629
+ // Return structured feedback with clear indication for AI processing
630
+ return {
631
+ action: result,
632
+ input: userInput.trim(),
633
+ hasUserInput: true,
634
+ timestamp: new Date().toISOString(),
635
+ requiresAdjustment: true // Flag to indicate AI should adjust execution
636
+ };
637
+ }
638
+ console.log('✅ [USER RESPONSE]:', result);
639
+ return result;
640
+ } catch (error) {
641
+ console.error('❌ [FEEDBACK ERROR]:', error.message);
642
+
643
+ // Check if this is a dialog system failure
644
+ if (error.message.includes('DIALOG_SYSTEM_FAILURE')) {
645
+ // Critical failure - inform user and stop AI conversation
646
+ const failureMessage = `
647
+ 🚨 **系统对话框执行失败**
648
+
649
+ **错误详情:** ${error.message.replace('DIALOG_SYSTEM_FAILURE: ', '')}
650
+
651
+ **当前步骤已中断。** 请检查系统权限或重启应用后再试。
652
+
653
+ **需要您确认:** 请输入 "confirmed" 确认已了解此错误,AI将停止当前对话。`;
654
+
655
+ console.log('🚨 [CRITICAL] Dialog system failure - stopping AI conversation');
656
+ console.log(failureMessage);
657
+
658
+ // This will be returned to the AI, causing it to stop and wait for user input
659
+ throw new Error(`CRITICAL_DIALOG_FAILURE: ${failureMessage}`);
660
+ }
661
+
662
+ // For other errors, try browser fallback
663
+ console.log('🔄 [FALLBACK] Trying browser dialog...');
664
+ const { showConfirmDialog: browserConfirm } = await import('./dialog/browser.js');
665
+
666
+ return await browserConfirm({
667
+ title,
668
+ message: message + '\n\n⚠️ 原生对话框无法显示,使用浏览器模式',
669
+ buttons: getSafeButtons(options.length ? options : null)
670
+ });
671
+ }
672
+ }
673
+
674
+ // 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
+ }