mcp-adr-analysis-server 2.0.13 → 2.0.15
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/README.md +87 -2
- package/dist/.tsbuildinfo +1 -0
- package/dist/src/index.d.ts +18 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +555 -26
- package/dist/src/index.js.map +1 -1
- package/dist/src/tools/mcp-planning-tool.d.ts +26 -0
- package/dist/src/tools/mcp-planning-tool.d.ts.map +1 -0
- package/dist/src/tools/mcp-planning-tool.js +1096 -0
- package/dist/src/tools/mcp-planning-tool.js.map +1 -0
- package/dist/src/tools/todo-management-tool-v2.d.ts.map +1 -1
- package/dist/src/tools/todo-management-tool-v2.js +69 -15
- package/dist/src/tools/todo-management-tool-v2.js.map +1 -1
- package/dist/src/utils/directory-compat.d.ts +8 -0
- package/dist/src/utils/directory-compat.d.ts.map +1 -0
- package/dist/src/utils/directory-compat.js +27 -0
- package/dist/src/utils/directory-compat.js.map +1 -0
- package/dist/src/utils/todo-json-manager.d.ts.map +1 -1
- package/dist/src/utils/todo-json-manager.js +5 -3
- package/dist/src/utils/todo-json-manager.js.map +1 -1
- package/package.json +13 -12
package/dist/src/index.js
CHANGED
|
@@ -10,8 +10,8 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
|
10
10
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
11
11
|
import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
12
12
|
import { readFileSync } from 'fs';
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
13
|
+
import { join } from 'path';
|
|
14
|
+
import { getCurrentDirCompat } from './utils/directory-compat.js';
|
|
15
15
|
import { McpAdrError } from './types/index.js';
|
|
16
16
|
import { CONVERSATION_CONTEXT_SCHEMA } from './types/conversation-context.js';
|
|
17
17
|
import { maskMcpResponse, createMaskingConfig } from './utils/output-masking.js';
|
|
@@ -23,18 +23,8 @@ import { KnowledgeGraphManager } from './utils/knowledge-graph-manager.js';
|
|
|
23
23
|
function getPackageVersion() {
|
|
24
24
|
try {
|
|
25
25
|
// Handle both Jest environment and normal execution
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
// Normal ESM execution
|
|
29
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
30
|
-
currentDir = dirname(__filename);
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
// Jest or other environments without import.meta support
|
|
34
|
-
// Use process.cwd() as fallback
|
|
35
|
-
currentDir = process.cwd();
|
|
36
|
-
}
|
|
37
|
-
// Try multiple possible locations for package.json
|
|
26
|
+
const currentDir = getCurrentDirCompat();
|
|
27
|
+
// Strategy 1: Try multiple possible locations for package.json
|
|
38
28
|
const possiblePaths = [
|
|
39
29
|
join(currentDir, 'package.json'),
|
|
40
30
|
join(currentDir, '..', 'package.json'),
|
|
@@ -52,11 +42,17 @@ function getPackageVersion() {
|
|
|
52
42
|
// Try next path
|
|
53
43
|
}
|
|
54
44
|
}
|
|
55
|
-
|
|
45
|
+
// Strategy 2: Use process.env.npm_package_version if available (during npm scripts)
|
|
46
|
+
if (process.env['npm_package_version']) {
|
|
47
|
+
return process.env['npm_package_version'];
|
|
48
|
+
}
|
|
49
|
+
// Final fallback: Use generic version instead of hardcoded specific version
|
|
50
|
+
// This prevents the need to update this code when version changes
|
|
51
|
+
return 'unknown'; // Generic fallback - no longer tied to specific version
|
|
56
52
|
}
|
|
57
53
|
catch (error) {
|
|
58
54
|
console.error('Error reading package.json:', error);
|
|
59
|
-
return '
|
|
55
|
+
return 'unknown'; // Generic fallback - no longer tied to specific version
|
|
60
56
|
}
|
|
61
57
|
}
|
|
62
58
|
/**
|
|
@@ -330,6 +326,37 @@ export class McpAdrAnalysisServer {
|
|
|
330
326
|
description: 'Path to project root for environment analysis',
|
|
331
327
|
default: '.'
|
|
332
328
|
},
|
|
329
|
+
environment: {
|
|
330
|
+
type: 'string',
|
|
331
|
+
enum: ['development', 'staging', 'production', 'testing', 'auto-detect'],
|
|
332
|
+
description: 'Target environment context for validation (auto-detect will infer from project structure)',
|
|
333
|
+
default: 'auto-detect'
|
|
334
|
+
},
|
|
335
|
+
environmentConfig: {
|
|
336
|
+
type: 'object',
|
|
337
|
+
description: 'Environment-specific configuration and requirements',
|
|
338
|
+
properties: {
|
|
339
|
+
requiredFiles: {
|
|
340
|
+
type: 'array',
|
|
341
|
+
items: { type: 'string' },
|
|
342
|
+
description: 'Files required for this environment'
|
|
343
|
+
},
|
|
344
|
+
requiredServices: {
|
|
345
|
+
type: 'array',
|
|
346
|
+
items: { type: 'string' },
|
|
347
|
+
description: 'Services that must be implemented for this environment'
|
|
348
|
+
},
|
|
349
|
+
securityLevel: {
|
|
350
|
+
type: 'string',
|
|
351
|
+
enum: ['low', 'medium', 'high', 'critical'],
|
|
352
|
+
description: 'Required security level for this environment'
|
|
353
|
+
},
|
|
354
|
+
performanceRequirements: {
|
|
355
|
+
type: 'object',
|
|
356
|
+
description: 'Performance requirements for this environment'
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
},
|
|
333
360
|
validationType: {
|
|
334
361
|
type: 'string',
|
|
335
362
|
enum: ['full', 'todo-only', 'adr-only', 'environment-only'],
|
|
@@ -360,6 +387,11 @@ export class McpAdrAnalysisServer {
|
|
|
360
387
|
type: 'boolean',
|
|
361
388
|
description: 'Enable strict validation mode with reality-check mechanisms against overconfident assessments',
|
|
362
389
|
default: true
|
|
390
|
+
},
|
|
391
|
+
environmentValidation: {
|
|
392
|
+
type: 'boolean',
|
|
393
|
+
description: 'Enable environment-specific validation rules and checks',
|
|
394
|
+
default: true
|
|
363
395
|
}
|
|
364
396
|
}
|
|
365
397
|
}
|
|
@@ -1935,6 +1967,208 @@ export class McpAdrAnalysisServer {
|
|
|
1935
1967
|
},
|
|
1936
1968
|
required: ['operation', 'projectPath']
|
|
1937
1969
|
}
|
|
1970
|
+
},
|
|
1971
|
+
{
|
|
1972
|
+
name: 'mcp_planning',
|
|
1973
|
+
description: 'Enhanced project planning and workflow management tool - phase-based project management, team resource allocation, progress tracking, risk analysis, and executive reporting',
|
|
1974
|
+
inputSchema: {
|
|
1975
|
+
type: 'object',
|
|
1976
|
+
properties: {
|
|
1977
|
+
operation: {
|
|
1978
|
+
type: 'string',
|
|
1979
|
+
enum: ['create_project', 'manage_phases', 'track_progress', 'manage_resources', 'risk_analysis', 'generate_reports'],
|
|
1980
|
+
description: 'Project planning operation to perform'
|
|
1981
|
+
},
|
|
1982
|
+
projectPath: {
|
|
1983
|
+
type: 'string',
|
|
1984
|
+
description: 'Project root path'
|
|
1985
|
+
},
|
|
1986
|
+
projectName: {
|
|
1987
|
+
type: 'string',
|
|
1988
|
+
description: 'Project name (for create_project operation)'
|
|
1989
|
+
},
|
|
1990
|
+
description: {
|
|
1991
|
+
type: 'string',
|
|
1992
|
+
description: 'Project description (for create_project operation)'
|
|
1993
|
+
},
|
|
1994
|
+
phases: {
|
|
1995
|
+
type: 'array',
|
|
1996
|
+
items: {
|
|
1997
|
+
type: 'object',
|
|
1998
|
+
properties: {
|
|
1999
|
+
name: { type: 'string' },
|
|
2000
|
+
duration: { type: 'string' },
|
|
2001
|
+
dependencies: {
|
|
2002
|
+
type: 'array',
|
|
2003
|
+
items: { type: 'string' },
|
|
2004
|
+
default: []
|
|
2005
|
+
},
|
|
2006
|
+
milestones: {
|
|
2007
|
+
type: 'array',
|
|
2008
|
+
items: { type: 'string' },
|
|
2009
|
+
default: []
|
|
2010
|
+
}
|
|
2011
|
+
},
|
|
2012
|
+
required: ['name', 'duration']
|
|
2013
|
+
},
|
|
2014
|
+
description: 'Initial project phases (for create_project operation)'
|
|
2015
|
+
},
|
|
2016
|
+
team: {
|
|
2017
|
+
type: 'array',
|
|
2018
|
+
items: {
|
|
2019
|
+
type: 'object',
|
|
2020
|
+
properties: {
|
|
2021
|
+
name: { type: 'string' },
|
|
2022
|
+
role: { type: 'string' },
|
|
2023
|
+
skills: {
|
|
2024
|
+
type: 'array',
|
|
2025
|
+
items: { type: 'string' },
|
|
2026
|
+
default: []
|
|
2027
|
+
},
|
|
2028
|
+
capacity: { type: 'string' }
|
|
2029
|
+
},
|
|
2030
|
+
required: ['name', 'role', 'capacity']
|
|
2031
|
+
},
|
|
2032
|
+
default: [],
|
|
2033
|
+
description: 'Team structure (for create_project operation)'
|
|
2034
|
+
},
|
|
2035
|
+
importFromAdrs: {
|
|
2036
|
+
type: 'boolean',
|
|
2037
|
+
default: true,
|
|
2038
|
+
description: 'Import phases from existing ADRs (for create_project operation)'
|
|
2039
|
+
},
|
|
2040
|
+
importFromTodos: {
|
|
2041
|
+
type: 'boolean',
|
|
2042
|
+
default: true,
|
|
2043
|
+
description: 'Import tasks from TODO system (for create_project operation)'
|
|
2044
|
+
},
|
|
2045
|
+
action: {
|
|
2046
|
+
type: 'string',
|
|
2047
|
+
enum: ['list', 'create', 'update', 'delete', 'transition', 'add', 'remove', 'allocate', 'optimize'],
|
|
2048
|
+
description: 'Management action (for manage_phases/manage_resources operations)'
|
|
2049
|
+
},
|
|
2050
|
+
phaseId: {
|
|
2051
|
+
type: 'string',
|
|
2052
|
+
description: 'Phase ID for phase operations'
|
|
2053
|
+
},
|
|
2054
|
+
phaseData: {
|
|
2055
|
+
type: 'object',
|
|
2056
|
+
properties: {
|
|
2057
|
+
name: { type: 'string' },
|
|
2058
|
+
description: { type: 'string' },
|
|
2059
|
+
estimatedDuration: { type: 'string' },
|
|
2060
|
+
dependencies: {
|
|
2061
|
+
type: 'array',
|
|
2062
|
+
items: { type: 'string' }
|
|
2063
|
+
},
|
|
2064
|
+
milestones: {
|
|
2065
|
+
type: 'array',
|
|
2066
|
+
items: { type: 'string' }
|
|
2067
|
+
},
|
|
2068
|
+
linkedAdrs: {
|
|
2069
|
+
type: 'array',
|
|
2070
|
+
items: { type: 'string' }
|
|
2071
|
+
}
|
|
2072
|
+
},
|
|
2073
|
+
description: 'Phase data for create/update operations'
|
|
2074
|
+
},
|
|
2075
|
+
targetStatus: {
|
|
2076
|
+
type: 'string',
|
|
2077
|
+
enum: ['planning', 'active', 'completed', 'blocked', 'cancelled'],
|
|
2078
|
+
description: 'Target status for phase transition'
|
|
2079
|
+
},
|
|
2080
|
+
reportType: {
|
|
2081
|
+
type: 'string',
|
|
2082
|
+
enum: ['summary', 'detailed', 'gantt', 'milestones', 'risks', 'executive', 'status', 'health', 'team_performance', 'milestone_tracking'],
|
|
2083
|
+
default: 'summary',
|
|
2084
|
+
description: 'Type of progress report or generated report'
|
|
2085
|
+
},
|
|
2086
|
+
timeframe: {
|
|
2087
|
+
type: 'string',
|
|
2088
|
+
enum: ['current', 'weekly', 'monthly', 'quarterly', 'week', 'month', 'quarter', 'project'],
|
|
2089
|
+
default: 'current',
|
|
2090
|
+
description: 'Time frame for reports and tracking'
|
|
2091
|
+
},
|
|
2092
|
+
includeVisuals: {
|
|
2093
|
+
type: 'boolean',
|
|
2094
|
+
default: true,
|
|
2095
|
+
description: 'Include visual progress indicators'
|
|
2096
|
+
},
|
|
2097
|
+
updateTaskProgress: {
|
|
2098
|
+
type: 'boolean',
|
|
2099
|
+
default: true,
|
|
2100
|
+
description: 'Sync progress from TODO system'
|
|
2101
|
+
},
|
|
2102
|
+
memberId: {
|
|
2103
|
+
type: 'string',
|
|
2104
|
+
description: 'Team member ID for resource operations'
|
|
2105
|
+
},
|
|
2106
|
+
memberData: {
|
|
2107
|
+
type: 'object',
|
|
2108
|
+
properties: {
|
|
2109
|
+
name: { type: 'string' },
|
|
2110
|
+
role: { type: 'string' },
|
|
2111
|
+
skills: {
|
|
2112
|
+
type: 'array',
|
|
2113
|
+
items: { type: 'string' }
|
|
2114
|
+
},
|
|
2115
|
+
capacity: { type: 'string' }
|
|
2116
|
+
},
|
|
2117
|
+
description: 'Team member data for resource operations'
|
|
2118
|
+
},
|
|
2119
|
+
allocationData: {
|
|
2120
|
+
type: 'object',
|
|
2121
|
+
properties: {
|
|
2122
|
+
phaseId: { type: 'string' },
|
|
2123
|
+
allocation: {
|
|
2124
|
+
type: 'number',
|
|
2125
|
+
minimum: 0,
|
|
2126
|
+
maximum: 100
|
|
2127
|
+
}
|
|
2128
|
+
},
|
|
2129
|
+
required: ['phaseId', 'allocation'],
|
|
2130
|
+
description: 'Resource allocation data'
|
|
2131
|
+
},
|
|
2132
|
+
analysisType: {
|
|
2133
|
+
type: 'string',
|
|
2134
|
+
enum: ['automated', 'manual', 'comprehensive'],
|
|
2135
|
+
default: 'comprehensive',
|
|
2136
|
+
description: 'Type of risk analysis'
|
|
2137
|
+
},
|
|
2138
|
+
includeAdrRisks: {
|
|
2139
|
+
type: 'boolean',
|
|
2140
|
+
default: true,
|
|
2141
|
+
description: 'Analyze risks from ADR complexity'
|
|
2142
|
+
},
|
|
2143
|
+
includeDependencyRisks: {
|
|
2144
|
+
type: 'boolean',
|
|
2145
|
+
default: true,
|
|
2146
|
+
description: 'Analyze dependency chain risks'
|
|
2147
|
+
},
|
|
2148
|
+
includeResourceRisks: {
|
|
2149
|
+
type: 'boolean',
|
|
2150
|
+
default: true,
|
|
2151
|
+
description: 'Analyze resource allocation risks'
|
|
2152
|
+
},
|
|
2153
|
+
generateMitigation: {
|
|
2154
|
+
type: 'boolean',
|
|
2155
|
+
default: true,
|
|
2156
|
+
description: 'Generate mitigation strategies'
|
|
2157
|
+
},
|
|
2158
|
+
format: {
|
|
2159
|
+
type: 'string',
|
|
2160
|
+
enum: ['markdown', 'json', 'html'],
|
|
2161
|
+
default: 'markdown',
|
|
2162
|
+
description: 'Report output format'
|
|
2163
|
+
},
|
|
2164
|
+
includeCharts: {
|
|
2165
|
+
type: 'boolean',
|
|
2166
|
+
default: true,
|
|
2167
|
+
description: 'Include progress charts and graphs'
|
|
2168
|
+
}
|
|
2169
|
+
},
|
|
2170
|
+
required: ['operation', 'projectPath']
|
|
2171
|
+
}
|
|
1938
2172
|
}
|
|
1939
2173
|
]
|
|
1940
2174
|
};
|
|
@@ -2053,6 +2287,9 @@ export class McpAdrAnalysisServer {
|
|
|
2053
2287
|
case 'smart_score':
|
|
2054
2288
|
response = await this.smartScore(args);
|
|
2055
2289
|
break;
|
|
2290
|
+
case 'mcp_planning':
|
|
2291
|
+
response = await this.mcpPlanning(args);
|
|
2292
|
+
break;
|
|
2056
2293
|
default:
|
|
2057
2294
|
throw new McpAdrError(`Unknown tool: ${name}`, 'UNKNOWN_TOOL');
|
|
2058
2295
|
}
|
|
@@ -3588,7 +3825,7 @@ ${importResult.content[0].text}
|
|
|
3588
3825
|
}
|
|
3589
3826
|
}
|
|
3590
3827
|
async compareAdrProgress(args) {
|
|
3591
|
-
const { todoPath = 'TODO.md', adrDirectory = this.config.adrDirectory, projectPath = this.config.projectPath, validationType = 'full', includeFileChecks = true, includeRuleValidation = true, deepCodeAnalysis = true, functionalValidation = true, strictMode = true } = args;
|
|
3828
|
+
const { todoPath = 'TODO.md', adrDirectory = this.config.adrDirectory, projectPath = this.config.projectPath, environment = 'auto-detect', environmentConfig = {}, validationType = 'full', includeFileChecks = true, includeRuleValidation = true, deepCodeAnalysis = true, functionalValidation = true, strictMode = true, environmentValidation = true } = args;
|
|
3592
3829
|
const { getAdrDirectoryPath } = await import('./utils/config.js');
|
|
3593
3830
|
const path = await import('path');
|
|
3594
3831
|
// Resolve paths
|
|
@@ -3596,7 +3833,21 @@ ${importResult.content[0].text}
|
|
|
3596
3833
|
const absoluteAdrPath = adrDirectory ?
|
|
3597
3834
|
path.resolve(projectPath, adrDirectory) :
|
|
3598
3835
|
getAdrDirectoryPath(this.config);
|
|
3599
|
-
this.logger.info(`Comparing ADR progress: TODO(${absoluteTodoPath}) vs ADRs(${absoluteAdrPath}) vs Environment(${projectPath})`);
|
|
3836
|
+
this.logger.info(`Comparing ADR progress: TODO(${absoluteTodoPath}) vs ADRs(${absoluteAdrPath}) vs Environment(${projectPath}) [env: ${environment}]`);
|
|
3837
|
+
// Environment validation and auto-detection
|
|
3838
|
+
let detectedEnvironment = environment;
|
|
3839
|
+
let finalEnvironmentConfig = { ...environmentConfig };
|
|
3840
|
+
if (environmentValidation && (validationType === 'full' || validationType === 'environment-only')) {
|
|
3841
|
+
try {
|
|
3842
|
+
const envResult = await this.detectAndValidateEnvironment(projectPath, environment, environmentConfig);
|
|
3843
|
+
detectedEnvironment = envResult.detectedEnvironment;
|
|
3844
|
+
finalEnvironmentConfig = { ...finalEnvironmentConfig, ...envResult.environmentConfig };
|
|
3845
|
+
this.logger.info(`Environment detection result: ${detectedEnvironment}`);
|
|
3846
|
+
}
|
|
3847
|
+
catch (error) {
|
|
3848
|
+
this.logger.warn(`Environment detection failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
3849
|
+
}
|
|
3850
|
+
}
|
|
3600
3851
|
try {
|
|
3601
3852
|
// Step 1: Read TODO.md file directly
|
|
3602
3853
|
let todoContent = '';
|
|
@@ -3642,7 +3893,10 @@ ${importResult.content[0].text}
|
|
|
3642
3893
|
includeRuleValidation,
|
|
3643
3894
|
deepCodeAnalysis,
|
|
3644
3895
|
functionalValidation,
|
|
3645
|
-
strictMode
|
|
3896
|
+
strictMode,
|
|
3897
|
+
environment: detectedEnvironment,
|
|
3898
|
+
environmentConfig: finalEnvironmentConfig,
|
|
3899
|
+
environmentValidation
|
|
3646
3900
|
});
|
|
3647
3901
|
return {
|
|
3648
3902
|
content: [
|
|
@@ -3657,11 +3911,101 @@ ${importResult.content[0].text}
|
|
|
3657
3911
|
throw new McpAdrError(`Failed to compare ADR progress: ${error instanceof Error ? error.message : String(error)}`, 'VALIDATION_ERROR');
|
|
3658
3912
|
}
|
|
3659
3913
|
}
|
|
3914
|
+
/**
|
|
3915
|
+
* Detect and validate environment context
|
|
3916
|
+
*/
|
|
3917
|
+
async detectAndValidateEnvironment(projectPath, environment, environmentConfig) {
|
|
3918
|
+
const path = await import('path');
|
|
3919
|
+
const fs = await import('fs/promises');
|
|
3920
|
+
let detectedEnvironment = environment;
|
|
3921
|
+
let finalConfig = { ...environmentConfig };
|
|
3922
|
+
if (environment === 'auto-detect') {
|
|
3923
|
+
// Auto-detect environment based on project structure
|
|
3924
|
+
try {
|
|
3925
|
+
// Check for environment indicator files
|
|
3926
|
+
const envFiles = [
|
|
3927
|
+
'.env.development',
|
|
3928
|
+
'.env.staging',
|
|
3929
|
+
'.env.production',
|
|
3930
|
+
'.env.test',
|
|
3931
|
+
'package.json',
|
|
3932
|
+
'docker-compose.yml',
|
|
3933
|
+
'Dockerfile'
|
|
3934
|
+
];
|
|
3935
|
+
const existingFiles = [];
|
|
3936
|
+
for (const file of envFiles) {
|
|
3937
|
+
try {
|
|
3938
|
+
await fs.access(path.join(projectPath, file));
|
|
3939
|
+
existingFiles.push(file);
|
|
3940
|
+
}
|
|
3941
|
+
catch {
|
|
3942
|
+
// File doesn't exist, continue
|
|
3943
|
+
}
|
|
3944
|
+
}
|
|
3945
|
+
// Environment detection logic
|
|
3946
|
+
if (existingFiles.includes('.env.production') || existingFiles.includes('Dockerfile')) {
|
|
3947
|
+
detectedEnvironment = 'production';
|
|
3948
|
+
}
|
|
3949
|
+
else if (existingFiles.includes('.env.staging')) {
|
|
3950
|
+
detectedEnvironment = 'staging';
|
|
3951
|
+
}
|
|
3952
|
+
else if (existingFiles.includes('.env.test')) {
|
|
3953
|
+
detectedEnvironment = 'testing';
|
|
3954
|
+
}
|
|
3955
|
+
else {
|
|
3956
|
+
detectedEnvironment = 'development';
|
|
3957
|
+
}
|
|
3958
|
+
// Set environment-specific default configurations
|
|
3959
|
+
switch (detectedEnvironment) {
|
|
3960
|
+
case 'production':
|
|
3961
|
+
finalConfig = {
|
|
3962
|
+
securityLevel: 'critical',
|
|
3963
|
+
requiredFiles: ['package.json', 'README.md'],
|
|
3964
|
+
requiredServices: ['monitoring', 'logging'],
|
|
3965
|
+
performanceRequirements: { minUptime: 99.9 },
|
|
3966
|
+
...finalConfig
|
|
3967
|
+
};
|
|
3968
|
+
break;
|
|
3969
|
+
case 'staging':
|
|
3970
|
+
finalConfig = {
|
|
3971
|
+
securityLevel: 'high',
|
|
3972
|
+
requiredFiles: ['package.json'],
|
|
3973
|
+
requiredServices: ['testing', 'monitoring'],
|
|
3974
|
+
performanceRequirements: { minUptime: 95 },
|
|
3975
|
+
...finalConfig
|
|
3976
|
+
};
|
|
3977
|
+
break;
|
|
3978
|
+
case 'testing':
|
|
3979
|
+
finalConfig = {
|
|
3980
|
+
securityLevel: 'medium',
|
|
3981
|
+
requiredFiles: ['package.json'],
|
|
3982
|
+
requiredServices: ['testing'],
|
|
3983
|
+
performanceRequirements: {},
|
|
3984
|
+
...finalConfig
|
|
3985
|
+
};
|
|
3986
|
+
break;
|
|
3987
|
+
default: // development
|
|
3988
|
+
finalConfig = {
|
|
3989
|
+
securityLevel: 'medium',
|
|
3990
|
+
requiredFiles: ['package.json'],
|
|
3991
|
+
requiredServices: [],
|
|
3992
|
+
performanceRequirements: {},
|
|
3993
|
+
...finalConfig
|
|
3994
|
+
};
|
|
3995
|
+
}
|
|
3996
|
+
}
|
|
3997
|
+
catch (error) {
|
|
3998
|
+
this.logger.warn(`Environment auto-detection failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
3999
|
+
detectedEnvironment = 'development'; // fallback
|
|
4000
|
+
}
|
|
4001
|
+
}
|
|
4002
|
+
return { detectedEnvironment, environmentConfig: finalConfig };
|
|
4003
|
+
}
|
|
3660
4004
|
/**
|
|
3661
4005
|
* Perform local ADR progress analysis without relying on AI execution
|
|
3662
4006
|
*/
|
|
3663
4007
|
async performLocalAdrProgressAnalysis(params) {
|
|
3664
|
-
const { todoContent, todoPath, discoveredAdrs, adrDirectory, projectStructure, projectPath, validationType, includeFileChecks, includeRuleValidation, deepCodeAnalysis, functionalValidation, strictMode } = params;
|
|
4008
|
+
const { todoContent, todoPath, discoveredAdrs, adrDirectory, projectStructure, projectPath, validationType, includeFileChecks, includeRuleValidation, deepCodeAnalysis, functionalValidation, strictMode, environment, environmentConfig, environmentValidation } = params;
|
|
3665
4009
|
const currentDate = new Date().toISOString().split('T')[0];
|
|
3666
4010
|
// Parse TODO content to extract tasks
|
|
3667
4011
|
const todoTasks = this.parseTodoTasks(todoContent);
|
|
@@ -3669,15 +4013,25 @@ ${importResult.content[0].text}
|
|
|
3669
4013
|
const totalAdrs = discoveredAdrs.length;
|
|
3670
4014
|
const totalTasks = todoTasks.length;
|
|
3671
4015
|
const completedTasks = todoTasks.filter(task => task.completed).length;
|
|
3672
|
-
// Calculate alignment score (simplified)
|
|
3673
|
-
const adrTaskMapping = this.mapTasksToAdrs(todoTasks, discoveredAdrs);
|
|
4016
|
+
// Calculate alignment score (simplified, now environment-aware)
|
|
4017
|
+
const adrTaskMapping = this.mapTasksToAdrs(todoTasks, discoveredAdrs, environment, environmentConfig);
|
|
3674
4018
|
const alignedTasks = adrTaskMapping.aligned.length;
|
|
3675
|
-
|
|
4019
|
+
let alignmentScore = totalTasks > 0 ? Math.round((alignedTasks / totalTasks) * 100) : 0;
|
|
4020
|
+
// Environment-aware scoring adjustments
|
|
4021
|
+
if (environmentValidation && environmentConfig) {
|
|
4022
|
+
const envScore = this.calculateEnvironmentScore(projectStructure, environment, environmentConfig);
|
|
4023
|
+
alignmentScore = Math.round((alignmentScore + envScore) / 2); // Blend scores
|
|
4024
|
+
}
|
|
3676
4025
|
// File existence checks
|
|
3677
4026
|
let fileCheckResults = '';
|
|
3678
4027
|
if (includeFileChecks && projectStructure) {
|
|
3679
4028
|
fileCheckResults = this.performFileExistenceChecks(todoTasks, projectStructure);
|
|
3680
4029
|
}
|
|
4030
|
+
// Environment compliance checks
|
|
4031
|
+
let environmentAnalysisResults = '';
|
|
4032
|
+
if (environmentValidation && environmentConfig) {
|
|
4033
|
+
environmentAnalysisResults = this.performEnvironmentComplianceAnalysis(projectStructure, environment, environmentConfig, strictMode);
|
|
4034
|
+
}
|
|
3681
4035
|
// Mock vs Production analysis
|
|
3682
4036
|
let mockAnalysisResults = '';
|
|
3683
4037
|
if (deepCodeAnalysis && projectStructure) {
|
|
@@ -3690,6 +4044,7 @@ ${importResult.content[0].text}
|
|
|
3690
4044
|
**Project Path**: ${projectPath}
|
|
3691
4045
|
**TODO Path**: ${todoPath}
|
|
3692
4046
|
**ADR Directory**: ${adrDirectory}
|
|
4047
|
+
**Environment**: ${environment}${environmentValidation ? ` (validation enabled)` : ''}
|
|
3693
4048
|
|
|
3694
4049
|
## Summary
|
|
3695
4050
|
- **Total ADRs**: ${totalAdrs}
|
|
@@ -3697,6 +4052,7 @@ ${importResult.content[0].text}
|
|
|
3697
4052
|
- **Completed Tasks**: ${completedTasks}
|
|
3698
4053
|
- **Alignment Score**: ${alignmentScore}%
|
|
3699
4054
|
- **Compliance Score**: ${Math.max(alignmentScore - 10, 0)}%
|
|
4055
|
+
- **Environment**: ${environment}
|
|
3700
4056
|
|
|
3701
4057
|
## Configuration
|
|
3702
4058
|
- **File Checks**: ${includeFileChecks ? 'Enabled' : 'Disabled'}
|
|
@@ -3704,6 +4060,13 @@ ${importResult.content[0].text}
|
|
|
3704
4060
|
- **Deep Code Analysis**: ${deepCodeAnalysis ? 'Enabled' : 'Disabled'}
|
|
3705
4061
|
- **Functional Validation**: ${functionalValidation ? 'Enabled' : 'Disabled'}
|
|
3706
4062
|
- **Strict Mode**: ${strictMode ? 'Enabled - High scrutiny for mock vs production' : 'Disabled'}
|
|
4063
|
+
- **Environment Validation**: ${environmentValidation ? 'Enabled' : 'Disabled'}
|
|
4064
|
+
|
|
4065
|
+
## Environment Context
|
|
4066
|
+
- **Target Environment**: ${environment}
|
|
4067
|
+
- **Security Level**: ${environmentConfig.securityLevel || 'Not specified'}
|
|
4068
|
+
- **Required Files**: ${environmentConfig.requiredFiles?.length || 0} files
|
|
4069
|
+
- **Required Services**: ${environmentConfig.requiredServices?.length || 0} services
|
|
3707
4070
|
|
|
3708
4071
|
## ADR Discovery Results
|
|
3709
4072
|
${totalAdrs > 0 ?
|
|
@@ -3736,6 +4099,8 @@ ${adrTaskMapping.missing.length > 0 ?
|
|
|
3736
4099
|
|
|
3737
4100
|
${fileCheckResults || '### File Existence Validation\n- File checks disabled or no project structure available'}
|
|
3738
4101
|
|
|
4102
|
+
${environmentAnalysisResults || ''}
|
|
4103
|
+
|
|
3739
4104
|
${mockAnalysisResults || ''}
|
|
3740
4105
|
|
|
3741
4106
|
## Recommendations
|
|
@@ -3746,10 +4111,14 @@ ${alignmentScore < 70 ?
|
|
|
3746
4111
|
'1. **Maintain Current Alignment**: Continue following ADR specifications'}
|
|
3747
4112
|
${completedTasks < totalTasks * 0.5 ?
|
|
3748
4113
|
'\n3. **Accelerate Implementation**: Focus on completing pending tasks' : ''}
|
|
4114
|
+
${environmentValidation && environment === 'production' && alignmentScore < 90 ?
|
|
4115
|
+
'\n4. **⚠️ Production Environment Warning**: Current alignment may not meet production requirements' : ''}
|
|
3749
4116
|
|
|
3750
4117
|
### Medium Priority Actions
|
|
3751
4118
|
1. **Review Implementation Quality**: ${strictMode ? 'Strict mode analysis above shows' : 'Consider enabling strict mode for'} detailed quality assessment
|
|
3752
4119
|
2. **Update Documentation**: Ensure TODO.md reflects current project state
|
|
4120
|
+
${environmentValidation ?
|
|
4121
|
+
`3. **Environment Compliance**: Ensure ${environment} environment requirements are met` : ''}
|
|
3753
4122
|
|
|
3754
4123
|
### Low Priority Actions
|
|
3755
4124
|
1. **Optimize Workflow**: Consider tools for automated ADR-TODO synchronization
|
|
@@ -3825,9 +4194,9 @@ To re-run this validation with strict mode:
|
|
|
3825
4194
|
return tasks;
|
|
3826
4195
|
}
|
|
3827
4196
|
/**
|
|
3828
|
-
* Map TODO tasks to ADRs to identify alignment
|
|
4197
|
+
* Map TODO tasks to ADRs to identify alignment (now environment-aware)
|
|
3829
4198
|
*/
|
|
3830
|
-
mapTasksToAdrs(tasks, adrs) {
|
|
4199
|
+
mapTasksToAdrs(tasks, adrs, environment, environmentConfig) {
|
|
3831
4200
|
const aligned = [];
|
|
3832
4201
|
const misaligned = [];
|
|
3833
4202
|
const missing = [];
|
|
@@ -3837,10 +4206,25 @@ To re-run this validation with strict mode:
|
|
|
3837
4206
|
...(adr.decision || '').toLowerCase().split(/\s+/).filter((w) => w.length > 4),
|
|
3838
4207
|
...(adr.context || '').toLowerCase().split(/\s+/).filter((w) => w.length > 4)
|
|
3839
4208
|
]);
|
|
4209
|
+
// Environment-specific keywords that should be prioritized
|
|
4210
|
+
const envKeywords = [];
|
|
4211
|
+
if (environment && environmentConfig) {
|
|
4212
|
+
if (environment === 'production') {
|
|
4213
|
+
envKeywords.push('deploy', 'production', 'monitoring', 'security', 'performance');
|
|
4214
|
+
}
|
|
4215
|
+
else if (environment === 'staging') {
|
|
4216
|
+
envKeywords.push('test', 'staging', 'integration', 'validation');
|
|
4217
|
+
}
|
|
4218
|
+
else if (environment === 'development') {
|
|
4219
|
+
envKeywords.push('setup', 'development', 'local', 'debug');
|
|
4220
|
+
}
|
|
4221
|
+
}
|
|
3840
4222
|
for (const task of tasks) {
|
|
3841
4223
|
const taskLower = task.title.toLowerCase();
|
|
3842
4224
|
const hasKeywordMatch = adrKeywords.some(keyword => taskLower.includes(keyword) || keyword.includes(taskLower.split(' ')[0]));
|
|
3843
|
-
|
|
4225
|
+
// Environment-aware alignment scoring
|
|
4226
|
+
const hasEnvKeywordMatch = envKeywords.some(keyword => taskLower.includes(keyword));
|
|
4227
|
+
if (hasKeywordMatch || hasEnvKeywordMatch) {
|
|
3844
4228
|
aligned.push(task);
|
|
3845
4229
|
}
|
|
3846
4230
|
else {
|
|
@@ -3860,6 +4244,25 @@ To re-run this validation with strict mode:
|
|
|
3860
4244
|
}
|
|
3861
4245
|
}
|
|
3862
4246
|
}
|
|
4247
|
+
// Environment-specific missing tasks
|
|
4248
|
+
if (environment && environmentConfig) {
|
|
4249
|
+
if (environmentConfig.requiredFiles) {
|
|
4250
|
+
for (const file of environmentConfig.requiredFiles) {
|
|
4251
|
+
const hasFileTask = tasks.some(task => task.title.toLowerCase().includes(file.toLowerCase()));
|
|
4252
|
+
if (!hasFileTask) {
|
|
4253
|
+
missing.push(`Create ${file} for ${environment} environment`);
|
|
4254
|
+
}
|
|
4255
|
+
}
|
|
4256
|
+
}
|
|
4257
|
+
if (environmentConfig.requiredServices) {
|
|
4258
|
+
for (const service of environmentConfig.requiredServices) {
|
|
4259
|
+
const hasServiceTask = tasks.some(task => task.title.toLowerCase().includes(service.toLowerCase()));
|
|
4260
|
+
if (!hasServiceTask) {
|
|
4261
|
+
missing.push(`Setup ${service} service for ${environment}`);
|
|
4262
|
+
}
|
|
4263
|
+
}
|
|
4264
|
+
}
|
|
4265
|
+
}
|
|
3863
4266
|
return { aligned, misaligned, missing };
|
|
3864
4267
|
}
|
|
3865
4268
|
/**
|
|
@@ -3971,6 +4374,122 @@ To re-run this validation with strict mode:
|
|
|
3971
4374
|
}
|
|
3972
4375
|
return results;
|
|
3973
4376
|
}
|
|
4377
|
+
/**
|
|
4378
|
+
* Calculate environment-specific compliance score
|
|
4379
|
+
*/
|
|
4380
|
+
calculateEnvironmentScore(projectStructure, environment, environmentConfig) {
|
|
4381
|
+
if (!projectStructure || !environmentConfig)
|
|
4382
|
+
return 0;
|
|
4383
|
+
let score = 100; // Start with perfect score
|
|
4384
|
+
// Check required files
|
|
4385
|
+
if (environmentConfig.requiredFiles) {
|
|
4386
|
+
const allFiles = [
|
|
4387
|
+
...projectStructure.packageFiles || [],
|
|
4388
|
+
...projectStructure.configFiles || [],
|
|
4389
|
+
...projectStructure.buildFiles || [],
|
|
4390
|
+
...projectStructure.dockerFiles || [],
|
|
4391
|
+
...projectStructure.ciFiles || [],
|
|
4392
|
+
...projectStructure.scriptFiles || []
|
|
4393
|
+
];
|
|
4394
|
+
const existingFiles = allFiles.map(f => f.filename);
|
|
4395
|
+
const missingFiles = environmentConfig.requiredFiles.filter((file) => !existingFiles.includes(file));
|
|
4396
|
+
// Deduct 10 points per missing required file
|
|
4397
|
+
score -= missingFiles.length * 10;
|
|
4398
|
+
}
|
|
4399
|
+
// Environment-specific penalties
|
|
4400
|
+
if (environment === 'production') {
|
|
4401
|
+
// Production requires higher standards
|
|
4402
|
+
if (!projectStructure.dockerFiles?.length)
|
|
4403
|
+
score -= 15;
|
|
4404
|
+
if (!projectStructure.ciFiles?.length)
|
|
4405
|
+
score -= 10;
|
|
4406
|
+
}
|
|
4407
|
+
return Math.max(score, 0);
|
|
4408
|
+
}
|
|
4409
|
+
/**
|
|
4410
|
+
* Perform environment compliance analysis
|
|
4411
|
+
*/
|
|
4412
|
+
performEnvironmentComplianceAnalysis(projectStructure, environment, environmentConfig, strictMode) {
|
|
4413
|
+
if (!projectStructure || !environmentConfig) {
|
|
4414
|
+
return '\n### Environment Compliance Analysis\n- Environment analysis disabled or no project structure available\n';
|
|
4415
|
+
}
|
|
4416
|
+
let results = '\n### Environment Compliance Analysis\n';
|
|
4417
|
+
// Required files analysis
|
|
4418
|
+
if (environmentConfig.requiredFiles) {
|
|
4419
|
+
results += `#### Required Files for ${environment} Environment\n`;
|
|
4420
|
+
const allFiles = [
|
|
4421
|
+
...projectStructure.packageFiles || [],
|
|
4422
|
+
...projectStructure.configFiles || [],
|
|
4423
|
+
...projectStructure.buildFiles || [],
|
|
4424
|
+
...projectStructure.dockerFiles || [],
|
|
4425
|
+
...projectStructure.ciFiles || [],
|
|
4426
|
+
...projectStructure.scriptFiles || []
|
|
4427
|
+
];
|
|
4428
|
+
const existingFiles = allFiles.map(f => f.filename);
|
|
4429
|
+
for (const requiredFile of environmentConfig.requiredFiles) {
|
|
4430
|
+
const exists = existingFiles.includes(requiredFile);
|
|
4431
|
+
results += `- ${exists ? '✅' : '❌'} **${requiredFile}**: ${exists ? 'Found' : 'Missing'}\n`;
|
|
4432
|
+
}
|
|
4433
|
+
}
|
|
4434
|
+
// Security level compliance
|
|
4435
|
+
if (environmentConfig.securityLevel) {
|
|
4436
|
+
results += `\n#### Security Level: ${environmentConfig.securityLevel}\n`;
|
|
4437
|
+
const securityIndicators = this.analyzeSecurityCompliance(projectStructure, environmentConfig.securityLevel);
|
|
4438
|
+
results += securityIndicators;
|
|
4439
|
+
}
|
|
4440
|
+
// Environment-specific recommendations
|
|
4441
|
+
results += `\n#### ${environment} Environment Recommendations\n`;
|
|
4442
|
+
switch (environment) {
|
|
4443
|
+
case 'production':
|
|
4444
|
+
results += '- ⚠️ **Production Critical**: Ensure monitoring, logging, and backup strategies are implemented\n';
|
|
4445
|
+
results += '- 🔒 **Security**: Implement comprehensive security measures\n';
|
|
4446
|
+
results += '- 📊 **Performance**: Monitor and optimize for production workloads\n';
|
|
4447
|
+
if (strictMode) {
|
|
4448
|
+
results += '- 🔍 **Strict Mode**: Enhanced validation enabled for production environment\n';
|
|
4449
|
+
}
|
|
4450
|
+
break;
|
|
4451
|
+
case 'staging':
|
|
4452
|
+
results += '- 🧪 **Testing**: Ensure comprehensive test coverage and validation\n';
|
|
4453
|
+
results += '- 📋 **Validation**: Implement environment parity checks\n';
|
|
4454
|
+
break;
|
|
4455
|
+
case 'development':
|
|
4456
|
+
results += '- 🛠️ **Development**: Focus on developer experience and debugging tools\n';
|
|
4457
|
+
results += '- 🔄 **Iteration**: Ensure fast feedback loops\n';
|
|
4458
|
+
break;
|
|
4459
|
+
}
|
|
4460
|
+
return results;
|
|
4461
|
+
}
|
|
4462
|
+
/**
|
|
4463
|
+
* Analyze security compliance based on security level
|
|
4464
|
+
*/
|
|
4465
|
+
analyzeSecurityCompliance(projectStructure, securityLevel) {
|
|
4466
|
+
let results = '';
|
|
4467
|
+
const securityFiles = [
|
|
4468
|
+
...projectStructure.configFiles || [],
|
|
4469
|
+
...projectStructure.dockerFiles || []
|
|
4470
|
+
].filter(file => file.filename.includes('security') ||
|
|
4471
|
+
file.filename.includes('auth') ||
|
|
4472
|
+
file.filename.includes('.env') ||
|
|
4473
|
+
file.filename === 'Dockerfile');
|
|
4474
|
+
const hasSecurityConfig = securityFiles.length > 0;
|
|
4475
|
+
switch (securityLevel) {
|
|
4476
|
+
case 'critical':
|
|
4477
|
+
results += `- ${hasSecurityConfig ? '✅' : '❌'} **Critical Security**: ${hasSecurityConfig ? 'Security configuration found' : 'No security configuration detected'}\n`;
|
|
4478
|
+
if (!hasSecurityConfig) {
|
|
4479
|
+
results += ' - **Action Required**: Implement comprehensive security measures\n';
|
|
4480
|
+
}
|
|
4481
|
+
break;
|
|
4482
|
+
case 'high':
|
|
4483
|
+
results += `- ${hasSecurityConfig ? '✅' : '⚠️'} **High Security**: ${hasSecurityConfig ? 'Some security configuration found' : 'Limited security configuration'}\n`;
|
|
4484
|
+
break;
|
|
4485
|
+
case 'medium':
|
|
4486
|
+
results += `- ℹ️ **Medium Security**: Basic security measures recommended\n`;
|
|
4487
|
+
break;
|
|
4488
|
+
default:
|
|
4489
|
+
results += `- ℹ️ **Security Level**: ${securityLevel} (consider increasing for production)\n`;
|
|
4490
|
+
}
|
|
4491
|
+
return results;
|
|
4492
|
+
}
|
|
3974
4493
|
/**
|
|
3975
4494
|
* Content masking tool implementations
|
|
3976
4495
|
*/
|
|
@@ -4765,6 +5284,15 @@ Please provide:
|
|
|
4765
5284
|
throw new McpAdrError(`Smart score analysis failed: ${error instanceof Error ? error.message : String(error)}`, 'SMART_SCORE_ERROR');
|
|
4766
5285
|
}
|
|
4767
5286
|
}
|
|
5287
|
+
async mcpPlanning(args) {
|
|
5288
|
+
try {
|
|
5289
|
+
const { mcpPlanning } = await import('./tools/mcp-planning-tool.js');
|
|
5290
|
+
return await mcpPlanning(args);
|
|
5291
|
+
}
|
|
5292
|
+
catch (error) {
|
|
5293
|
+
throw new McpAdrError(`MCP planning failed: ${error instanceof Error ? error.message : String(error)}`, 'MCP_PLANNING_ERROR');
|
|
5294
|
+
}
|
|
5295
|
+
}
|
|
4768
5296
|
}
|
|
4769
5297
|
/**
|
|
4770
5298
|
* Main execution
|
|
@@ -4833,4 +5361,5 @@ if (process.argv[1] && (process.argv[1].endsWith('index.js') ||
|
|
|
4833
5361
|
process.exit(1);
|
|
4834
5362
|
});
|
|
4835
5363
|
}
|
|
5364
|
+
// Test comment for pre-commit hook
|
|
4836
5365
|
//# sourceMappingURL=index.js.map
|