mcp-adr-analysis-server 2.0.9 → 2.0.10

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 (60) hide show
  1. package/dist/src/index.d.ts +8 -0
  2. package/dist/src/index.d.ts.map +1 -1
  3. package/dist/src/index.js +434 -5
  4. package/dist/src/index.js.map +1 -1
  5. package/dist/src/resources/index.d.ts.map +1 -1
  6. package/dist/src/resources/index.js +71 -1
  7. package/dist/src/resources/index.js.map +1 -1
  8. package/dist/src/tools/human-override-tool.d.ts +42 -0
  9. package/dist/src/tools/human-override-tool.d.ts.map +1 -0
  10. package/dist/src/tools/human-override-tool.js +431 -0
  11. package/dist/src/tools/human-override-tool.js.map +1 -0
  12. package/dist/src/tools/smart-git-push-tool.d.ts +5 -1
  13. package/dist/src/tools/smart-git-push-tool.d.ts.map +1 -1
  14. package/dist/src/tools/smart-git-push-tool.js +70 -25
  15. package/dist/src/tools/smart-git-push-tool.js.map +1 -1
  16. package/dist/src/tools/smart-score-tool.d.ts +138 -0
  17. package/dist/src/tools/smart-score-tool.d.ts.map +1 -0
  18. package/dist/src/tools/smart-score-tool.js +602 -0
  19. package/dist/src/tools/smart-score-tool.js.map +1 -0
  20. package/dist/src/tools/todo-management-tool.d.ts +184 -6
  21. package/dist/src/tools/todo-management-tool.d.ts.map +1 -1
  22. package/dist/src/tools/todo-management-tool.js +819 -42
  23. package/dist/src/tools/todo-management-tool.js.map +1 -1
  24. package/dist/src/tools/tool-chain-orchestrator.d.ts +164 -0
  25. package/dist/src/tools/tool-chain-orchestrator.d.ts.map +1 -0
  26. package/dist/src/tools/tool-chain-orchestrator.js +738 -0
  27. package/dist/src/tools/tool-chain-orchestrator.js.map +1 -0
  28. package/dist/src/tools/troubleshoot-guided-workflow-tool.d.ts +150 -0
  29. package/dist/src/tools/troubleshoot-guided-workflow-tool.d.ts.map +1 -0
  30. package/dist/src/tools/troubleshoot-guided-workflow-tool.js +520 -0
  31. package/dist/src/tools/troubleshoot-guided-workflow-tool.js.map +1 -0
  32. package/dist/src/types/knowledge-graph-schemas.d.ts +481 -0
  33. package/dist/src/types/knowledge-graph-schemas.d.ts.map +1 -0
  34. package/dist/src/types/knowledge-graph-schemas.js +59 -0
  35. package/dist/src/types/knowledge-graph-schemas.js.map +1 -0
  36. package/dist/src/utils/json-safe.d.ts +38 -0
  37. package/dist/src/utils/json-safe.d.ts.map +1 -0
  38. package/dist/src/utils/json-safe.js +86 -0
  39. package/dist/src/utils/json-safe.js.map +1 -0
  40. package/dist/src/utils/knowledge-graph-manager.d.ts +28 -0
  41. package/dist/src/utils/knowledge-graph-manager.d.ts.map +1 -0
  42. package/dist/src/utils/knowledge-graph-manager.js +192 -0
  43. package/dist/src/utils/knowledge-graph-manager.js.map +1 -0
  44. package/dist/src/utils/mcp-response-validator.d.ts +30 -0
  45. package/dist/src/utils/mcp-response-validator.d.ts.map +1 -0
  46. package/dist/src/utils/mcp-response-validator.js +197 -0
  47. package/dist/src/utils/mcp-response-validator.js.map +1 -0
  48. package/dist/src/utils/project-health-scoring.d.ts +177 -0
  49. package/dist/src/utils/project-health-scoring.d.ts.map +1 -0
  50. package/dist/src/utils/project-health-scoring.js +370 -0
  51. package/dist/src/utils/project-health-scoring.js.map +1 -0
  52. package/dist/src/utils/release-readiness-detector.d.ts +2 -0
  53. package/dist/src/utils/release-readiness-detector.d.ts.map +1 -1
  54. package/dist/src/utils/release-readiness-detector.js +2 -0
  55. package/dist/src/utils/release-readiness-detector.js.map +1 -1
  56. package/dist/src/utils/todo-file-watcher.d.ts +26 -0
  57. package/dist/src/utils/todo-file-watcher.d.ts.map +1 -0
  58. package/dist/src/utils/todo-file-watcher.js +163 -0
  59. package/dist/src/utils/todo-file-watcher.js.map +1 -0
  60. package/package.json +1 -1
@@ -0,0 +1,738 @@
1
+ /**
2
+ * Tool Chain Orchestrator - AI-Powered Dynamic Tool Sequencing
3
+ *
4
+ * Uses OpenRouter.ai to intelligently analyze user requests and generate
5
+ * structured tool execution plans for the calling LLM to execute.
6
+ */
7
+ import { z } from 'zod';
8
+ import { McpAdrError } from '../types/index.js';
9
+ import { loadAIConfig, isAIExecutionEnabled, getRecommendedModel } from '../config/ai-config.js';
10
+ import { KnowledgeGraphManager } from '../utils/knowledge-graph-manager.js';
11
+ // Tool chain step schema
12
+ const ToolChainStepSchema = z.object({
13
+ toolName: z.string().describe('MCP tool name to execute'),
14
+ parameters: z.record(z.any()).describe('Parameters to pass to the tool'),
15
+ description: z.string().describe('What this step accomplishes'),
16
+ dependsOn: z.array(z.string()).optional().describe('Previous step IDs this depends on'),
17
+ stepId: z.string().describe('Unique identifier for this step'),
18
+ conditional: z.boolean().default(false).describe('Whether this step should only run if previous steps succeed'),
19
+ retryable: z.boolean().default(true).describe('Whether this step can be retried on failure')
20
+ });
21
+ // Tool chain plan schema
22
+ const ToolChainPlanSchema = z.object({
23
+ planId: z.string().describe('Unique plan identifier'),
24
+ userIntent: z.string().describe('Interpreted user intent'),
25
+ confidence: z.number().min(0).max(1).describe('Confidence in the plan (0-1)'),
26
+ estimatedDuration: z.string().describe('Estimated execution time'),
27
+ steps: z.array(ToolChainStepSchema).describe('Ordered sequence of tool executions'),
28
+ fallbackSteps: z.array(ToolChainStepSchema).optional().describe('Alternative steps if main plan fails'),
29
+ prerequisites: z.array(z.string()).optional().describe('Required conditions before execution'),
30
+ expectedOutputs: z.array(z.string()).describe('What outputs the plan will generate')
31
+ });
32
+ // Available MCP tools registry
33
+ const AVAILABLE_TOOLS = [
34
+ 'analyze_project_ecosystem',
35
+ 'generate_adrs_from_prd',
36
+ 'suggest_adrs',
37
+ 'analyze_content_security',
38
+ 'generate_rules',
39
+ 'generate_adr_todo',
40
+ 'compare_adr_progress',
41
+ 'manage_todo',
42
+ 'generate_deployment_guidance',
43
+ 'smart_score',
44
+ 'troubleshoot_guided_workflow',
45
+ 'smart_git_push',
46
+ 'generate_research_questions',
47
+ 'validate_rules',
48
+ 'analyze_code_patterns',
49
+ 'suggest_improvements',
50
+ 'generate_test_scenarios',
51
+ 'create_documentation',
52
+ 'security_audit',
53
+ 'performance_analysis',
54
+ 'dependency_analysis',
55
+ 'refactoring_suggestions',
56
+ 'api_documentation',
57
+ 'deployment_checklist',
58
+ 'release_notes'
59
+ ];
60
+ // Tool capabilities mapping for AI context
61
+ const TOOL_CAPABILITIES = {
62
+ 'analyze_project_ecosystem': 'Analyze technology stack, dependencies, and architectural patterns',
63
+ 'generate_adrs_from_prd': 'Convert Product Requirements Documents to Architectural Decision Records',
64
+ 'suggest_adrs': 'Auto-suggest ADRs based on code analysis and project patterns',
65
+ 'analyze_content_security': 'Detect and mask sensitive information in project content',
66
+ 'generate_rules': 'Extract architectural rules and constraints from project analysis',
67
+ 'generate_adr_todo': 'Generate TODO.md from ADRs with comprehensive task breakdown',
68
+ 'compare_adr_progress': 'Validate TODO vs ADRs vs actual environment state',
69
+ 'manage_todo': 'Comprehensive TODO.md lifecycle management and progress tracking',
70
+ 'generate_deployment_guidance': 'AI-driven deployment procedures from architectural decisions',
71
+ 'smart_score': 'Project health scoring with cross-tool synchronization',
72
+ 'troubleshoot_guided_workflow': 'Systematic troubleshooting with ADR/TODO alignment',
73
+ 'smart_git_push': 'Intelligent release readiness analysis and git operations',
74
+ 'generate_research_questions': 'Generate targeted research questions for project analysis',
75
+ 'validate_rules': 'Validate architectural rule compliance across the project',
76
+ 'analyze_code_patterns': 'Identify code patterns and architectural consistency',
77
+ 'suggest_improvements': 'Provide targeted improvement recommendations',
78
+ 'generate_test_scenarios': 'Create comprehensive test scenarios and strategies',
79
+ 'create_documentation': 'Generate project documentation from code and ADRs',
80
+ 'security_audit': 'Comprehensive security analysis and vulnerability detection',
81
+ 'performance_analysis': 'Analyze performance bottlenecks and optimization opportunities',
82
+ 'dependency_analysis': 'Analyze project dependencies and potential issues',
83
+ 'refactoring_suggestions': 'Suggest code refactoring based on architectural principles',
84
+ 'api_documentation': 'Generate API documentation from code analysis',
85
+ 'deployment_checklist': 'Create deployment checklists based on ADRs and project state',
86
+ 'release_notes': 'Generate release notes from commits, ADRs, and TODO completion'
87
+ };
88
+ // Operation schema
89
+ const ToolChainOrchestratorSchema = z.object({
90
+ operation: z.enum(['generate_plan', 'analyze_intent', 'suggest_tools', 'validate_plan', 'reality_check', 'session_guidance', 'human_override']).describe('Orchestrator operation'),
91
+ userRequest: z.string().describe('Natural language user request'),
92
+ projectContext: z.object({
93
+ projectPath: z.string().describe('Path to project directory'),
94
+ adrDirectory: z.string().default('docs/adrs').describe('ADR directory path'),
95
+ todoPath: z.string().default('TODO.md').describe('TODO.md file path'),
96
+ hasADRs: z.boolean().optional().describe('Whether project has existing ADRs'),
97
+ hasTODO: z.boolean().optional().describe('Whether project has TODO.md'),
98
+ projectType: z.string().optional().describe('Project type (e.g., web-app, library, api)')
99
+ }).describe('Project context information'),
100
+ constraints: z.object({
101
+ maxSteps: z.number().default(10).describe('Maximum number of steps in plan'),
102
+ timeLimit: z.string().optional().describe('Time limit for execution'),
103
+ excludeTools: z.array(z.string()).optional().describe('Tools to exclude from plan'),
104
+ prioritizeSpeed: z.boolean().default(false).describe('Prioritize fast execution over thoroughness')
105
+ }).optional().describe('Execution constraints'),
106
+ customInstructions: z.string().optional().describe('Additional context or specific requirements'),
107
+ sessionContext: z.object({
108
+ conversationLength: z.number().optional().describe('Number of messages in current session'),
109
+ previousActions: z.array(z.string()).optional().describe('Tools/actions already executed this session'),
110
+ confusionIndicators: z.array(z.string()).optional().describe('Signs that LLM might be confused or hallucinating'),
111
+ lastSuccessfulAction: z.string().optional().describe('Last action that produced good results'),
112
+ stuckOnTask: z.string().optional().describe('Task the LLM seems stuck on')
113
+ }).optional().describe('Session context for hallucination prevention'),
114
+ humanOverride: z.object({
115
+ taskType: z.enum(['analyze_project', 'generate_docs', 'fix_security', 'deploy_ready', 'troubleshoot_issue', 'update_todos', 'custom']).describe('Predefined task type or custom'),
116
+ forceExecution: z.boolean().default(true).describe('Skip all AI analysis and force direct execution'),
117
+ priority: z.enum(['low', 'medium', 'high', 'critical']).default('high').describe('Task priority level'),
118
+ deadline: z.string().optional().describe('When this must be completed'),
119
+ specificRequirement: z.string().optional().describe('Exact requirement that must be fulfilled'),
120
+ bypassSafety: z.boolean().default(false).describe('Bypass safety checks (use with caution)')
121
+ }).optional().describe('Human override settings for forced execution')
122
+ });
123
+ // Predefined task patterns for human override
124
+ const PREDEFINED_TASK_PATTERNS = {
125
+ 'analyze_project': {
126
+ description: 'Complete project analysis including ecosystem, security, and health scoring',
127
+ steps: [
128
+ { tool: 'analyze_project_ecosystem', params: {} },
129
+ { tool: 'analyze_content_security', params: {} },
130
+ { tool: 'smart_score', params: { operation: 'recalculate_scores' } }
131
+ ]
132
+ },
133
+ 'generate_docs': {
134
+ description: 'Generate comprehensive project documentation',
135
+ steps: [
136
+ { tool: 'suggest_adrs', params: {} },
137
+ { tool: 'generate_adr_todo', params: {} },
138
+ { tool: 'generate_deployment_guidance', params: {} }
139
+ ]
140
+ },
141
+ 'fix_security': {
142
+ description: 'Security audit and remediation workflow',
143
+ steps: [
144
+ { tool: 'analyze_content_security', params: {} },
145
+ { tool: 'security_audit', params: {} },
146
+ { tool: 'suggest_improvements', params: { focusArea: 'security' } }
147
+ ]
148
+ },
149
+ 'deploy_ready': {
150
+ description: 'Full deployment readiness check and preparation',
151
+ steps: [
152
+ { tool: 'compare_adr_progress', params: {} },
153
+ { tool: 'smart_git_push', params: { checkReleaseReadiness: true } },
154
+ { tool: 'generate_deployment_guidance', params: {} },
155
+ { tool: 'deployment_checklist', params: {} }
156
+ ]
157
+ },
158
+ 'troubleshoot_issue': {
159
+ description: 'Systematic troubleshooting workflow',
160
+ steps: [
161
+ { tool: 'troubleshoot_guided_workflow', params: { operation: 'analyze_with_tools' } },
162
+ { tool: 'compare_adr_progress', params: {} },
163
+ { tool: 'manage_todo', params: { operation: 'analyze_progress' } }
164
+ ]
165
+ },
166
+ 'update_todos': {
167
+ description: 'Complete TODO management and synchronization',
168
+ steps: [
169
+ { tool: 'generate_adr_todo', params: {} },
170
+ { tool: 'manage_todo', params: { operation: 'sync_progress' } },
171
+ { tool: 'smart_score', params: { operation: 'sync_scores' } }
172
+ ]
173
+ }
174
+ };
175
+ /**
176
+ * Generate AI-powered tool execution plan
177
+ */
178
+ async function generateToolChainPlan(args) {
179
+ const aiConfig = loadAIConfig();
180
+ if (!isAIExecutionEnabled(aiConfig)) {
181
+ throw new McpAdrError('AI execution not enabled. Set OPENROUTER_API_KEY and execution mode to "full"', 'AI_NOT_ENABLED');
182
+ }
183
+ // Build context for AI analysis
184
+ const systemPrompt = `You are an expert software architect and MCP tool orchestrator. Your job is to analyze user requests and generate intelligent tool execution plans.
185
+
186
+ Available MCP Tools:
187
+ ${Object.entries(TOOL_CAPABILITIES).map(([tool, desc]) => `- ${tool}: ${desc}`).join('\n')}
188
+
189
+ Project Context:
190
+ - Project Path: ${args.projectContext.projectPath}
191
+ - ADR Directory: ${args.projectContext.adrDirectory}
192
+ - TODO Path: ${args.projectContext.todoPath}
193
+ - Has ADRs: ${args.projectContext.hasADRs ? 'Yes' : 'No'}
194
+ - Has TODO: ${args.projectContext.hasTODO ? 'Yes' : 'No'}
195
+ - Project Type: ${args.projectContext.projectType || 'Unknown'}
196
+
197
+ Generate a structured tool execution plan that:
198
+ 1. Interprets the user's intent accurately
199
+ 2. Selects the optimal sequence of MCP tools
200
+ 3. Provides clear parameters for each tool
201
+ 4. Handles dependencies between steps
202
+ 5. Includes fallback options for robustness
203
+
204
+ Return a JSON object matching this schema:
205
+ {
206
+ "planId": "unique-plan-id",
207
+ "userIntent": "interpreted intent",
208
+ "confidence": 0.95,
209
+ "estimatedDuration": "2-5 minutes",
210
+ "steps": [
211
+ {
212
+ "stepId": "step1",
213
+ "toolName": "tool_name",
214
+ "parameters": { "param": "value" },
215
+ "description": "what this accomplishes",
216
+ "dependsOn": [],
217
+ "conditional": false,
218
+ "retryable": true
219
+ }
220
+ ],
221
+ "fallbackSteps": [],
222
+ "prerequisites": [],
223
+ "expectedOutputs": ["output1", "output2"]
224
+ }`;
225
+ const userPrompt = `User Request: "${args.userRequest}"
226
+
227
+ ${args.customInstructions ? `Additional Instructions: ${args.customInstructions}` : ''}
228
+
229
+ ${args.constraints ? `Constraints:
230
+ - Max Steps: ${args.constraints.maxSteps}
231
+ - Time Limit: ${args.constraints.timeLimit || 'None'}
232
+ - Exclude Tools: ${args.constraints.excludeTools?.join(', ') || 'None'}
233
+ - Prioritize Speed: ${args.constraints.prioritizeSpeed ? 'Yes' : 'No'}` : ''}
234
+
235
+ Generate the optimal tool execution plan.`;
236
+ try {
237
+ // Call OpenRouter.ai for intelligent planning
238
+ const response = await fetch(aiConfig.baseURL + '/chat/completions', {
239
+ method: 'POST',
240
+ headers: {
241
+ 'Authorization': `Bearer ${aiConfig.apiKey}`,
242
+ 'Content-Type': 'application/json',
243
+ 'HTTP-Referer': aiConfig.siteUrl || '',
244
+ 'X-Title': aiConfig.siteName || ''
245
+ },
246
+ body: JSON.stringify({
247
+ model: getRecommendedModel('analysis'),
248
+ messages: [
249
+ { role: 'system', content: systemPrompt },
250
+ { role: 'user', content: userPrompt }
251
+ ],
252
+ temperature: 0.1, // Low temperature for consistent planning
253
+ max_tokens: aiConfig.maxTokens,
254
+ response_format: { type: 'json_object' }
255
+ })
256
+ });
257
+ if (!response.ok) {
258
+ throw new Error(`OpenRouter API error: ${response.status} ${response.statusText}`);
259
+ }
260
+ const result = await response.json();
261
+ const planContent = result.choices?.[0]?.message?.content;
262
+ if (!planContent) {
263
+ throw new Error('No plan generated from AI response');
264
+ }
265
+ // Parse and validate the AI-generated plan
266
+ const rawPlan = JSON.parse(planContent);
267
+ const validatedPlan = ToolChainPlanSchema.parse(rawPlan);
268
+ // Add safety checks
269
+ validatePlanSafety(validatedPlan, args.constraints);
270
+ return validatedPlan;
271
+ }
272
+ catch (error) {
273
+ throw new McpAdrError(`Tool chain planning failed: ${error instanceof Error ? error.message : String(error)}`, 'PLANNING_FAILED');
274
+ }
275
+ }
276
+ /**
277
+ * Validate plan safety and constraints
278
+ */
279
+ function validatePlanSafety(plan, constraints) {
280
+ // Check step count
281
+ if (constraints?.maxSteps && plan.steps.length > constraints.maxSteps) {
282
+ throw new McpAdrError(`Plan exceeds maximum steps: ${plan.steps.length} > ${constraints.maxSteps}`, 'PLAN_TOO_COMPLEX');
283
+ }
284
+ // Check for excluded tools
285
+ if (constraints?.excludeTools) {
286
+ const usedExcludedTools = plan.steps.filter(step => constraints.excludeTools.includes(step.toolName));
287
+ if (usedExcludedTools.length > 0) {
288
+ throw new McpAdrError(`Plan uses excluded tools: ${usedExcludedTools.map(s => s.toolName).join(', ')}`, 'EXCLUDED_TOOLS_USED');
289
+ }
290
+ }
291
+ // Validate tool names
292
+ const invalidTools = plan.steps.filter(step => !AVAILABLE_TOOLS.includes(step.toolName));
293
+ if (invalidTools.length > 0) {
294
+ throw new McpAdrError(`Plan uses unknown tools: ${invalidTools.map(s => s.toolName).join(', ')}`, 'UNKNOWN_TOOLS');
295
+ }
296
+ // Check for circular dependencies
297
+ const stepIds = new Set(plan.steps.map(s => s.stepId));
298
+ for (const step of plan.steps) {
299
+ if (step.dependsOn) {
300
+ for (const depId of step.dependsOn) {
301
+ if (!stepIds.has(depId)) {
302
+ throw new McpAdrError(`Step ${step.stepId} depends on non-existent step: ${depId}`, 'INVALID_DEPENDENCY');
303
+ }
304
+ }
305
+ }
306
+ }
307
+ // Validate confidence threshold
308
+ if (plan.confidence < 0.6) {
309
+ throw new McpAdrError(`Plan confidence too low: ${plan.confidence}`, 'LOW_CONFIDENCE_PLAN');
310
+ }
311
+ }
312
+ /**
313
+ * Analyze user intent without generating full plan
314
+ */
315
+ async function analyzeUserIntent(args) {
316
+ const aiConfig = loadAIConfig();
317
+ if (!isAIExecutionEnabled(aiConfig)) {
318
+ // Fallback to basic keyword analysis
319
+ return fallbackIntentAnalysis(args.userRequest);
320
+ }
321
+ const systemPrompt = `Analyze the user's intent and suggest relevant MCP tools.
322
+
323
+ Available Tools: ${AVAILABLE_TOOLS.join(', ')}
324
+
325
+ Return JSON with:
326
+ {
327
+ "intent": "clear description of what user wants to accomplish",
328
+ "category": "analysis|generation|management|troubleshooting|deployment",
329
+ "complexity": "simple|moderate|complex",
330
+ "suggestedTools": ["tool1", "tool2"],
331
+ "confidence": 0.85
332
+ }`;
333
+ try {
334
+ const response = await fetch(aiConfig.baseURL + '/chat/completions', {
335
+ method: 'POST',
336
+ headers: {
337
+ 'Authorization': `Bearer ${aiConfig.apiKey}`,
338
+ 'Content-Type': 'application/json',
339
+ 'HTTP-Referer': aiConfig.siteUrl || '',
340
+ 'X-Title': aiConfig.siteName || ''
341
+ },
342
+ body: JSON.stringify({
343
+ model: getRecommendedModel('quick-analysis', true), // Use cost-effective model
344
+ messages: [
345
+ { role: 'system', content: systemPrompt },
346
+ { role: 'user', content: `Analyze this request: "${args.userRequest}"` }
347
+ ],
348
+ temperature: 0.1,
349
+ max_tokens: 500,
350
+ response_format: { type: 'json_object' }
351
+ })
352
+ });
353
+ const result = await response.json();
354
+ const analysisContent = result.choices?.[0]?.message?.content;
355
+ if (analysisContent) {
356
+ return JSON.parse(analysisContent);
357
+ }
358
+ }
359
+ catch (error) {
360
+ // Fall back to keyword analysis
361
+ }
362
+ return fallbackIntentAnalysis(args.userRequest);
363
+ }
364
+ /**
365
+ * Human override - Generate tool chain based on predefined patterns
366
+ */
367
+ function generateHumanOverridePlan(args) {
368
+ if (!args.humanOverride) {
369
+ throw new McpAdrError('Human override settings required for this operation', 'MISSING_OVERRIDE');
370
+ }
371
+ const override = args.humanOverride;
372
+ const planId = `human-override-${Date.now()}`;
373
+ // Handle predefined task types
374
+ if (override.taskType !== 'custom' && PREDEFINED_TASK_PATTERNS[override.taskType]) {
375
+ const pattern = PREDEFINED_TASK_PATTERNS[override.taskType];
376
+ const steps = pattern.steps.map((step, index) => ({
377
+ stepId: `override-step-${index + 1}`,
378
+ toolName: step.tool,
379
+ parameters: {
380
+ ...step.params,
381
+ projectPath: args.projectContext.projectPath,
382
+ adrDirectory: args.projectContext.adrDirectory,
383
+ todoPath: args.projectContext.todoPath
384
+ },
385
+ description: `Execute ${step.tool} as part of ${override.taskType} workflow`,
386
+ dependsOn: index > 0 ? [`override-step-${index}`] : [],
387
+ conditional: false,
388
+ retryable: !override.bypassSafety
389
+ }));
390
+ return {
391
+ planId,
392
+ userIntent: `HUMAN OVERRIDE: ${pattern.description}${override.specificRequirement ? ` - ${override.specificRequirement}` : ''}`,
393
+ confidence: 1.0, // Human override = 100% confidence
394
+ estimatedDuration: override.priority === 'critical' ? '1-3 minutes' : '3-10 minutes',
395
+ steps,
396
+ fallbackSteps: override.bypassSafety ? [] : [{
397
+ stepId: 'fallback-manual',
398
+ toolName: 'troubleshoot_guided_workflow',
399
+ parameters: { operation: 'full_workflow' },
400
+ description: 'Manual troubleshooting if automated workflow fails',
401
+ dependsOn: [],
402
+ conditional: true,
403
+ retryable: true
404
+ }],
405
+ prerequisites: override.bypassSafety ? [] : ['Human has confirmed this action is necessary'],
406
+ expectedOutputs: [
407
+ `${pattern.description} completed`,
408
+ 'Structured results for each tool execution',
409
+ override.deadline ? `Completion by ${override.deadline}` : 'Task completion confirmation'
410
+ ]
411
+ };
412
+ }
413
+ // Handle custom task type
414
+ if (override.taskType === 'custom') {
415
+ if (!override.specificRequirement) {
416
+ throw new McpAdrError('Specific requirement must be provided for custom human override', 'MISSING_REQUIREMENT');
417
+ }
418
+ // Use simple keyword matching for custom tasks
419
+ const request = override.specificRequirement.toLowerCase();
420
+ const suggestedTools = [];
421
+ // Map common keywords to tools
422
+ if (request.includes('analyze') || request.includes('analysis')) {
423
+ suggestedTools.push('analyze_project_ecosystem', 'analyze_content_security');
424
+ }
425
+ if (request.includes('todo') || request.includes('task')) {
426
+ suggestedTools.push('manage_todo', 'generate_adr_todo');
427
+ }
428
+ if (request.includes('adr') || request.includes('decision')) {
429
+ suggestedTools.push('suggest_adrs', 'compare_adr_progress');
430
+ }
431
+ if (request.includes('deploy') || request.includes('release')) {
432
+ suggestedTools.push('smart_git_push', 'generate_deployment_guidance');
433
+ }
434
+ if (request.includes('score') || request.includes('health')) {
435
+ suggestedTools.push('smart_score');
436
+ }
437
+ // If no tools matched, default to analysis
438
+ if (suggestedTools.length === 0) {
439
+ suggestedTools.push('analyze_project_ecosystem', 'troubleshoot_guided_workflow');
440
+ }
441
+ const steps = suggestedTools.map((tool, index) => ({
442
+ stepId: `custom-step-${index + 1}`,
443
+ toolName: tool,
444
+ parameters: {
445
+ projectPath: args.projectContext.projectPath,
446
+ adrDirectory: args.projectContext.adrDirectory,
447
+ todoPath: args.projectContext.todoPath
448
+ },
449
+ description: `Execute ${tool} for custom requirement: ${override.specificRequirement}`,
450
+ dependsOn: index > 0 ? [`custom-step-${index}`] : [],
451
+ conditional: false,
452
+ retryable: !override.bypassSafety
453
+ }));
454
+ return {
455
+ planId,
456
+ userIntent: `HUMAN OVERRIDE (CUSTOM): ${override.specificRequirement}`,
457
+ confidence: 0.8, // Slightly lower for custom tasks
458
+ estimatedDuration: override.priority === 'critical' ? '2-5 minutes' : '5-15 minutes',
459
+ steps,
460
+ fallbackSteps: [],
461
+ prerequisites: override.bypassSafety ? [] : ['Human has specified exact requirement'],
462
+ expectedOutputs: [
463
+ 'Custom requirement fulfilled',
464
+ 'Tool execution results',
465
+ 'Confirmation of task completion'
466
+ ]
467
+ };
468
+ }
469
+ throw new McpAdrError(`Unknown task type: ${override.taskType}`, 'UNKNOWN_TASK_TYPE');
470
+ }
471
+ /**
472
+ * Reality check - Detect if LLM is hallucinating or confused
473
+ */
474
+ function performRealityCheck(args) {
475
+ const confusionIndicators = [];
476
+ const recommendations = [];
477
+ const suggestedActions = [];
478
+ const sessionCtx = args.sessionContext;
479
+ const request = args.userRequest.toLowerCase();
480
+ // Check for hallucination indicators
481
+ let riskScore = 0;
482
+ // Long conversation without progress
483
+ if (sessionCtx?.conversationLength && sessionCtx.conversationLength > 20) {
484
+ riskScore += 2;
485
+ confusionIndicators.push('Very long conversation - potential confusion accumulation');
486
+ recommendations.push('Consider starting fresh with human override');
487
+ }
488
+ // Repetitive tool usage
489
+ if (sessionCtx?.previousActions) {
490
+ const toolCounts = sessionCtx.previousActions.reduce((acc, tool) => {
491
+ acc[tool] = (acc[tool] || 0) + 1;
492
+ return acc;
493
+ }, {});
494
+ const repeatedTools = Object.entries(toolCounts).filter(([_, count]) => count > 3);
495
+ if (repeatedTools.length > 0) {
496
+ riskScore += repeatedTools.length;
497
+ confusionIndicators.push(`Excessive repetition of tools: ${repeatedTools.map(([tool, count]) => `${tool}(${count}x)`).join(', ')}`);
498
+ recommendations.push('Break the repetition cycle with human override or different approach');
499
+ }
500
+ }
501
+ // Confusion indicators in the request
502
+ const confusionKeywords = ['confused', 'not working', 'stuck', 'help', 'what should', 'don\'t know', 'error', 'failed'];
503
+ const foundKeywords = confusionKeywords.filter(keyword => request.includes(keyword));
504
+ if (foundKeywords.length > 0) {
505
+ riskScore += foundKeywords.length;
506
+ confusionIndicators.push(`Confusion keywords detected: ${foundKeywords.join(', ')}`);
507
+ recommendations.push('LLM expressing uncertainty - human override recommended');
508
+ }
509
+ // Stuck on same task
510
+ if (sessionCtx?.stuckOnTask) {
511
+ riskScore += 3;
512
+ confusionIndicators.push(`Stuck on task: ${sessionCtx.stuckOnTask}`);
513
+ recommendations.push('Use human override to force progress on stuck task');
514
+ }
515
+ // Suggest actions based on risk level
516
+ const hallucinationRisk = riskScore >= 5 ? 'high' :
517
+ riskScore >= 2 ? 'medium' : 'low';
518
+ if (hallucinationRisk === 'high') {
519
+ suggestedActions.push('IMMEDIATE: Use human_override operation to force structured execution', 'Avoid further AI planning - use predefined task patterns', 'Consider resetting the conversation context');
520
+ }
521
+ else if (hallucinationRisk === 'medium') {
522
+ suggestedActions.push('Use human_override for critical tasks', 'Limit AI planning to simple operations', 'Monitor for increasing confusion indicators');
523
+ }
524
+ else {
525
+ suggestedActions.push('Continue with AI-assisted planning', 'Monitor session for confusion indicators', 'Keep human override available as backup');
526
+ }
527
+ return {
528
+ hallucinationRisk,
529
+ confusionIndicators,
530
+ recommendations,
531
+ suggestedActions
532
+ };
533
+ }
534
+ /**
535
+ * Session guidance - Provide structured guidance for long sessions
536
+ */
537
+ function generateSessionGuidance(args) {
538
+ const realityCheck = performRealityCheck(args);
539
+ const sessionCtx = args.sessionContext;
540
+ const guidance = [];
541
+ let sessionStatus = 'healthy';
542
+ let humanInterventionNeeded = false;
543
+ let recommendedNextStep = 'Continue with current approach';
544
+ // Assess session health
545
+ if (realityCheck.hallucinationRisk === 'high') {
546
+ sessionStatus = 'critical';
547
+ humanInterventionNeeded = true;
548
+ recommendedNextStep = 'Use human_override immediately';
549
+ guidance.push('🚨 CRITICAL: High hallucination risk detected');
550
+ guidance.push('LLM appears confused or stuck in loops');
551
+ guidance.push('Human override strongly recommended to restore focus');
552
+ }
553
+ else if (realityCheck.hallucinationRisk === 'medium') {
554
+ sessionStatus = 'concerning';
555
+ recommendedNextStep = 'Consider human_override for next critical task';
556
+ guidance.push('āš ļø WARNING: Session showing signs of confusion');
557
+ guidance.push('Monitor closely and be ready to intervene');
558
+ }
559
+ else {
560
+ guidance.push('āœ… Session appears healthy');
561
+ guidance.push('AI planning can continue safely');
562
+ }
563
+ // Add specific guidance based on context
564
+ if (sessionCtx?.conversationLength && sessionCtx.conversationLength > 15) {
565
+ guidance.push(`šŸ“ Long session (${sessionCtx.conversationLength} messages) - consider summarizing progress`);
566
+ }
567
+ if (sessionCtx?.lastSuccessfulAction) {
568
+ guidance.push(`āœ… Last successful action: ${sessionCtx.lastSuccessfulAction}`);
569
+ guidance.push('Consider building on this success rather than trying new approaches');
570
+ }
571
+ // Add actionable next steps
572
+ guidance.push('', 'šŸŽÆ Recommended Actions:');
573
+ guidance.push(...realityCheck.suggestedActions.map(action => `• ${action}`));
574
+ return {
575
+ sessionStatus,
576
+ guidance,
577
+ recommendedNextStep,
578
+ humanInterventionNeeded
579
+ };
580
+ }
581
+ /**
582
+ * Fallback intent analysis using keywords
583
+ */
584
+ function fallbackIntentAnalysis(userRequest) {
585
+ const request = userRequest.toLowerCase();
586
+ // Simple keyword matching
587
+ const keywordMap = {
588
+ 'analyze': ['analyze_project_ecosystem', 'analyze_content_security'],
589
+ 'generate': ['generate_adrs_from_prd', 'generate_adr_todo', 'generate_deployment_guidance'],
590
+ 'todo': ['manage_todo', 'generate_adr_todo'],
591
+ 'adr': ['suggest_adrs', 'generate_adrs_from_prd', 'compare_adr_progress'],
592
+ 'deploy': ['generate_deployment_guidance', 'smart_git_push'],
593
+ 'score': ['smart_score'],
594
+ 'troubleshoot': ['troubleshoot_guided_workflow'],
595
+ 'security': ['analyze_content_security', 'security_audit']
596
+ };
597
+ const suggestedTools = [];
598
+ let category = 'analysis';
599
+ let complexity = 'simple';
600
+ for (const [keyword, tools] of Object.entries(keywordMap)) {
601
+ if (request.includes(keyword)) {
602
+ suggestedTools.push(...tools);
603
+ }
604
+ }
605
+ // Determine category and complexity
606
+ if (request.includes('generate') || request.includes('create')) {
607
+ category = 'generation';
608
+ complexity = 'moderate';
609
+ }
610
+ else if (request.includes('troubleshoot') || request.includes('debug')) {
611
+ category = 'troubleshooting';
612
+ complexity = 'complex';
613
+ }
614
+ else if (request.includes('deploy') || request.includes('release')) {
615
+ category = 'deployment';
616
+ complexity = 'complex';
617
+ }
618
+ return {
619
+ intent: `User wants to ${request.includes('analyze') ? 'analyze' : request.includes('generate') ? 'generate' : 'manage'} project elements`,
620
+ category,
621
+ complexity,
622
+ suggestedTools: [...new Set(suggestedTools)].slice(0, 5),
623
+ confidence: suggestedTools.length > 0 ? 0.7 : 0.3
624
+ };
625
+ }
626
+ /**
627
+ * Main orchestrator function
628
+ */
629
+ export async function toolChainOrchestrator(args) {
630
+ try {
631
+ const validatedArgs = ToolChainOrchestratorSchema.parse(args);
632
+ // Initialize knowledge graph manager
633
+ const kgManager = new KnowledgeGraphManager();
634
+ let intentId;
635
+ switch (validatedArgs.operation) {
636
+ case 'generate_plan': {
637
+ // Create intent for plan generation
638
+ intentId = await kgManager.createIntent(validatedArgs.userRequest, ['Generate tool execution plan', 'Plan tool chain sequence'], 'medium');
639
+ const plan = await generateToolChainPlan(validatedArgs);
640
+ // Store plan generation in knowledge graph
641
+ await kgManager.addToolExecution(intentId, 'tool_chain_orchestrator_generate_plan', validatedArgs, { plan }, true, [], [], undefined);
642
+ return {
643
+ content: [{
644
+ type: 'text',
645
+ text: `# šŸŽÆ AI-Generated Tool Execution Plan\n\n## Intent Analysis\n**User Intent**: ${plan.userIntent}\n**Confidence**: ${(plan.confidence * 100).toFixed(1)}%\n**Estimated Duration**: ${plan.estimatedDuration}\n\n## Execution Steps\n\n${plan.steps.map((step, i) => `### Step ${i + 1}: ${step.description}\n- **Tool**: \`${step.toolName}\`\n- **Step ID**: \`${step.stepId}\`\n${step.dependsOn && step.dependsOn.length > 0 ? `- **Depends On**: ${step.dependsOn.join(', ')}\n` : ''}- **Parameters**: \`\`\`json\n${JSON.stringify(step.parameters, null, 2)}\n\`\`\`\n${step.conditional ? '- **Conditional**: Only runs if previous steps succeed\n' : ''}${step.retryable ? '- **Retryable**: Can be retried on failure\n' : ''}`).join('\n\n')}\n\n## Expected Outputs\n${plan.expectedOutputs.map(output => `- ${output}`).join('\n')}\n\n${plan.fallbackSteps && plan.fallbackSteps.length > 0 ? `## Fallback Steps\n${plan.fallbackSteps.map(step => `- **${step.toolName}**: ${step.description}`).join('\n')}\n\n` : ''}${plan.prerequisites && plan.prerequisites.length > 0 ? `## Prerequisites\n${plan.prerequisites.map(req => `- ${req}`).join('\n')}\n\n` : ''}## Usage Instructions\n\n1. Execute steps in order, respecting dependencies\n2. Pass the provided parameters to each tool\n3. Handle conditional steps based on previous results\n4. Use fallback steps if main plan encounters issues\n\n*This plan was generated by AI analysis of your request and project context.*`
646
+ }],
647
+ metadata: {
648
+ intentId,
649
+ planId: plan.planId,
650
+ confidence: plan.confidence,
651
+ stepCount: plan.steps.length,
652
+ toolChain: plan.steps.map(s => s.toolName)
653
+ }
654
+ };
655
+ }
656
+ case 'analyze_intent': {
657
+ const analysis = await analyzeUserIntent(validatedArgs);
658
+ return {
659
+ content: [{
660
+ type: 'text',
661
+ text: `# šŸŽÆ Intent Analysis\n\n**Intent**: ${analysis.intent}\n**Category**: ${analysis.category}\n**Complexity**: ${analysis.complexity}\n**Confidence**: ${(analysis.confidence * 100).toFixed(1)}%\n\n## Suggested Tools\n${analysis.suggestedTools.map(tool => `- **${tool}**: ${TOOL_CAPABILITIES[tool] || 'Tool capability description'}`).join('\n')}\n\n*Use 'generate_plan' operation to create a full execution plan.*`
662
+ }]
663
+ };
664
+ }
665
+ case 'suggest_tools': {
666
+ const analysis = await analyzeUserIntent(validatedArgs);
667
+ return {
668
+ content: [{
669
+ type: 'text',
670
+ text: `# šŸ› ļø Tool Suggestions\n\n${analysis.suggestedTools.map(tool => `## ${tool}\n${TOOL_CAPABILITIES[tool] || 'Tool capability description'}\n`).join('\n')}`
671
+ }]
672
+ };
673
+ }
674
+ case 'validate_plan': {
675
+ // This would validate a provided plan structure
676
+ return {
677
+ content: [{
678
+ type: 'text',
679
+ text: `# āœ… Plan Validation\n\nPlan validation functionality would analyze a provided plan structure for safety, dependencies, and feasibility.`
680
+ }]
681
+ };
682
+ }
683
+ case 'human_override': {
684
+ // Create intent for human override
685
+ intentId = await kgManager.createIntent(validatedArgs.userRequest, ['Execute human override plan', 'Force structured execution'], validatedArgs.humanOverride?.priority === 'critical' ? 'high' : (validatedArgs.humanOverride?.priority || 'high'));
686
+ const plan = generateHumanOverridePlan(validatedArgs);
687
+ // Store human override plan in knowledge graph
688
+ await kgManager.addToolExecution(intentId, 'tool_chain_orchestrator_human_override', validatedArgs, { plan }, true, [], [], undefined);
689
+ return {
690
+ content: [{
691
+ type: 'text',
692
+ text: `# 🚨 HUMAN OVERRIDE ACTIVATED\n\n## Override Details\n**Task Type**: ${validatedArgs.humanOverride?.taskType}\n**Priority**: ${validatedArgs.humanOverride?.priority}\n**Force Execution**: ${validatedArgs.humanOverride?.forceExecution ? 'YES' : 'NO'}\n**Bypass Safety**: ${validatedArgs.humanOverride?.bypassSafety ? 'YES - USE CAUTION' : 'NO'}\n\n## Generated Plan\n**Intent**: ${plan.userIntent}\n**Confidence**: ${(plan.confidence * 100).toFixed(0)}% (Human Override)\n**Estimated Duration**: ${plan.estimatedDuration}\n\n## Execution Steps (MANDATORY)\n\n${plan.steps.map((step, i) => `### Step ${i + 1}: ${step.description}\n\`\`\`\nTool: ${step.toolName}\nParameters: ${JSON.stringify(step.parameters, null, 2)}\n\`\`\`\n${step.dependsOn && step.dependsOn.length > 0 ? `**Depends On**: ${step.dependsOn.join(', ')}\n` : ''}**Retryable**: ${step.retryable ? 'Yes' : 'No'}\n`).join('\n')}\n\n## Expected Outputs\n${plan.expectedOutputs.map(output => `āœ… ${output}`).join('\n')}\n\n${plan.prerequisites && plan.prerequisites.length > 0 ? `## Prerequisites\n${plan.prerequisites.map(req => `āš ļø ${req}`).join('\n')}\n\n` : ''}## āš ļø IMPORTANT NOTES\n\n- **This is a HUMAN OVERRIDE** - execute all steps as specified\n- **No deviation** from the plan unless critical errors occur\n- **Report results** for each step before proceeding\n- ${validatedArgs.humanOverride?.deadline ? `**DEADLINE**: ${validatedArgs.humanOverride.deadline}` : 'Execute promptly'}\n\n*Human override bypasses AI planning to ensure task completion.*`
693
+ }],
694
+ metadata: {
695
+ intentId,
696
+ planId: plan.planId,
697
+ isHumanOverride: true,
698
+ bypassSafety: validatedArgs.humanOverride?.bypassSafety || false,
699
+ priority: validatedArgs.humanOverride?.priority,
700
+ stepCount: plan.steps.length
701
+ }
702
+ };
703
+ }
704
+ case 'reality_check': {
705
+ const realityCheck = performRealityCheck(validatedArgs);
706
+ return {
707
+ content: [{
708
+ type: 'text',
709
+ text: `# šŸ” Reality Check Results\n\n## Hallucination Risk Assessment\n**Risk Level**: ${realityCheck.hallucinationRisk.toUpperCase()} ${realityCheck.hallucinationRisk === 'high' ? '🚨' : realityCheck.hallucinationRisk === 'medium' ? 'āš ļø' : 'āœ…'}\n\n## Confusion Indicators\n${realityCheck.confusionIndicators.length > 0 ? realityCheck.confusionIndicators.map(indicator => `āš ļø ${indicator}`).join('\n') : 'āœ… No confusion indicators detected'}\n\n## Recommendations\n${realityCheck.recommendations.map(rec => `šŸ’” ${rec}`).join('\n')}\n\n## Suggested Actions\n${realityCheck.suggestedActions.map(action => `šŸŽÆ ${action}`).join('\n')}\n\n${realityCheck.hallucinationRisk === 'high' ? '## 🚨 IMMEDIATE ACTION REQUIRED\n\nHigh hallucination risk detected. Use `human_override` operation immediately to restore control and prevent further confusion.\n\n' : ''}*Reality check helps maintain accuracy during long LLM sessions.*`
710
+ }]
711
+ };
712
+ }
713
+ case 'session_guidance': {
714
+ const guidance = generateSessionGuidance(validatedArgs);
715
+ return {
716
+ content: [{
717
+ type: 'text',
718
+ text: `# 🧭 Session Guidance\n\n## Session Status: ${guidance.sessionStatus.toUpperCase()} ${guidance.sessionStatus === 'critical' ? '🚨' : guidance.sessionStatus === 'concerning' ? 'āš ļø' : 'āœ…'}\n\n## Guidance\n${guidance.guidance.join('\n')}\n\n## Recommended Next Step\nšŸŽÆ **${guidance.recommendedNextStep}**\n\n${guidance.humanInterventionNeeded ? '## 🚨 HUMAN INTERVENTION NEEDED\n\nThe session has reached a state where human override is strongly recommended to maintain progress and accuracy.\n\n**Use the `human_override` operation to:**\n- Force structured execution\n- Break confusion cycles\n- Ensure task completion\n\n' : ''}*Session guidance helps maintain productive long conversations.*`
719
+ }],
720
+ metadata: {
721
+ sessionStatus: guidance.sessionStatus,
722
+ humanInterventionNeeded: guidance.humanInterventionNeeded,
723
+ recommendedNextStep: guidance.recommendedNextStep
724
+ }
725
+ };
726
+ }
727
+ default:
728
+ throw new McpAdrError(`Unknown operation: ${validatedArgs.operation}`, 'INVALID_OPERATION');
729
+ }
730
+ }
731
+ catch (error) {
732
+ if (error instanceof z.ZodError) {
733
+ throw new McpAdrError(`Invalid input: ${error.errors.map(e => e.message).join(', ')}`, 'INVALID_INPUT');
734
+ }
735
+ throw new McpAdrError(`Tool chain orchestration failed: ${error instanceof Error ? error.message : String(error)}`, 'ORCHESTRATION_ERROR');
736
+ }
737
+ }
738
+ //# sourceMappingURL=tool-chain-orchestrator.js.map