mcp-adr-analysis-server 2.0.21 → 2.0.24

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 (119) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/src/index.d.ts +9 -0
  3. package/dist/src/index.d.ts.map +1 -1
  4. package/dist/src/index.js +1380 -781
  5. package/dist/src/index.js.map +1 -1
  6. package/dist/src/tools/adr-suggestion-tool.d.ts.map +1 -1
  7. package/dist/src/tools/adr-suggestion-tool.js +32 -30
  8. package/dist/src/tools/adr-suggestion-tool.js.map +1 -1
  9. package/dist/src/tools/content-masking-tool.d.ts +4 -0
  10. package/dist/src/tools/content-masking-tool.d.ts.map +1 -1
  11. package/dist/src/tools/content-masking-tool.js +531 -28
  12. package/dist/src/tools/content-masking-tool.js.map +1 -1
  13. package/dist/src/tools/deployment-readiness-tool.d.ts +8 -5
  14. package/dist/src/tools/deployment-readiness-tool.d.ts.map +1 -1
  15. package/dist/src/tools/deployment-readiness-tool.js +741 -79
  16. package/dist/src/tools/deployment-readiness-tool.js.map +1 -1
  17. package/dist/src/tools/environment-analysis-tool.d.ts +4 -0
  18. package/dist/src/tools/environment-analysis-tool.d.ts.map +1 -1
  19. package/dist/src/tools/environment-analysis-tool.js +568 -24
  20. package/dist/src/tools/environment-analysis-tool.js.map +1 -1
  21. package/dist/src/tools/mcp-planning-tool.d.ts.map +1 -1
  22. package/dist/src/tools/mcp-planning-tool.js +298 -173
  23. package/dist/src/tools/mcp-planning-tool.js.map +1 -1
  24. package/dist/src/tools/memory-loading-tool.d.ts +60 -0
  25. package/dist/src/tools/memory-loading-tool.d.ts.map +1 -0
  26. package/dist/src/tools/memory-loading-tool.js +457 -0
  27. package/dist/src/tools/memory-loading-tool.js.map +1 -0
  28. package/dist/src/tools/smart-git-push-tool.d.ts +3 -0
  29. package/dist/src/tools/smart-git-push-tool.d.ts.map +1 -1
  30. package/dist/src/tools/smart-git-push-tool.js +177 -223
  31. package/dist/src/tools/smart-git-push-tool.js.map +1 -1
  32. package/dist/src/tools/troubleshoot-guided-workflow-tool.d.ts +20 -11
  33. package/dist/src/tools/troubleshoot-guided-workflow-tool.d.ts.map +1 -1
  34. package/dist/src/tools/troubleshoot-guided-workflow-tool.js +506 -22
  35. package/dist/src/tools/troubleshoot-guided-workflow-tool.js.map +1 -1
  36. package/dist/src/types/enhanced-errors.d.ts +173 -0
  37. package/dist/src/types/enhanced-errors.d.ts.map +1 -0
  38. package/dist/src/types/enhanced-errors.js +668 -0
  39. package/dist/src/types/enhanced-errors.js.map +1 -0
  40. package/dist/src/types/knowledge-graph-schemas.d.ts +92 -0
  41. package/dist/src/types/knowledge-graph-schemas.d.ts.map +1 -1
  42. package/dist/src/types/knowledge-graph-schemas.js +45 -17
  43. package/dist/src/types/knowledge-graph-schemas.js.map +1 -1
  44. package/dist/src/types/memory-entities.d.ts +7209 -0
  45. package/dist/src/types/memory-entities.d.ts.map +1 -0
  46. package/dist/src/types/memory-entities.js +395 -0
  47. package/dist/src/types/memory-entities.js.map +1 -0
  48. package/dist/src/types/todo-json-schemas.d.ts +7 -653
  49. package/dist/src/types/todo-json-schemas.d.ts.map +1 -1
  50. package/dist/src/types/todo-json-schemas.js +6 -110
  51. package/dist/src/types/todo-json-schemas.js.map +1 -1
  52. package/dist/src/utils/enhanced-logging.d.ts +195 -0
  53. package/dist/src/utils/enhanced-logging.d.ts.map +1 -0
  54. package/dist/src/utils/enhanced-logging.js +449 -0
  55. package/dist/src/utils/enhanced-logging.js.map +1 -0
  56. package/dist/src/utils/interactive-approval.d.ts +1 -1
  57. package/dist/src/utils/interactive-approval.d.ts.map +1 -1
  58. package/dist/src/utils/interactive-approval.js +20 -16
  59. package/dist/src/utils/interactive-approval.js.map +1 -1
  60. package/dist/src/utils/knowledge-graph-manager.d.ts +23 -1
  61. package/dist/src/utils/knowledge-graph-manager.d.ts.map +1 -1
  62. package/dist/src/utils/knowledge-graph-manager.js +297 -69
  63. package/dist/src/utils/knowledge-graph-manager.js.map +1 -1
  64. package/dist/src/utils/memory-entity-manager.d.ts +134 -0
  65. package/dist/src/utils/memory-entity-manager.d.ts.map +1 -0
  66. package/dist/src/utils/memory-entity-manager.js +848 -0
  67. package/dist/src/utils/memory-entity-manager.js.map +1 -0
  68. package/dist/src/utils/memory-health-scoring.d.ts +125 -0
  69. package/dist/src/utils/memory-health-scoring.d.ts.map +1 -0
  70. package/dist/src/utils/memory-health-scoring.js +277 -0
  71. package/dist/src/utils/memory-health-scoring.js.map +1 -0
  72. package/dist/src/utils/memory-migration-manager.d.ts +93 -0
  73. package/dist/src/utils/memory-migration-manager.d.ts.map +1 -0
  74. package/dist/src/utils/memory-migration-manager.js +834 -0
  75. package/dist/src/utils/memory-migration-manager.js.map +1 -0
  76. package/dist/src/utils/memory-relationship-mapper.d.ts +87 -0
  77. package/dist/src/utils/memory-relationship-mapper.d.ts.map +1 -0
  78. package/dist/src/utils/memory-relationship-mapper.js +481 -0
  79. package/dist/src/utils/memory-relationship-mapper.js.map +1 -0
  80. package/dist/src/utils/memory-rollback-manager.d.ts +93 -0
  81. package/dist/src/utils/memory-rollback-manager.d.ts.map +1 -0
  82. package/dist/src/utils/memory-rollback-manager.js +542 -0
  83. package/dist/src/utils/memory-rollback-manager.js.map +1 -0
  84. package/dist/src/utils/memory-transformation.d.ts +59 -0
  85. package/dist/src/utils/memory-transformation.d.ts.map +1 -0
  86. package/dist/src/utils/memory-transformation.js +742 -0
  87. package/dist/src/utils/memory-transformation.js.map +1 -0
  88. package/dist/src/utils/prompt-execution.d.ts.map +1 -1
  89. package/dist/src/utils/prompt-execution.js +72 -51
  90. package/dist/src/utils/prompt-execution.js.map +1 -1
  91. package/dist/src/utils/todo-file-watcher.d.ts +11 -23
  92. package/dist/src/utils/todo-file-watcher.d.ts.map +1 -1
  93. package/dist/src/utils/todo-file-watcher.js +18 -156
  94. package/dist/src/utils/todo-file-watcher.js.map +1 -1
  95. package/package.json +22 -6
  96. package/dist/src/tools/smart-score-tool.d.ts +0 -173
  97. package/dist/src/tools/smart-score-tool.d.ts.map +0 -1
  98. package/dist/src/tools/smart-score-tool.js +0 -681
  99. package/dist/src/tools/smart-score-tool.js.map +0 -1
  100. package/dist/src/tools/todo-management-tool-v2.d.ts +0 -368
  101. package/dist/src/tools/todo-management-tool-v2.d.ts.map +0 -1
  102. package/dist/src/tools/todo-management-tool-v2.js +0 -922
  103. package/dist/src/tools/todo-management-tool-v2.js.map +0 -1
  104. package/dist/src/utils/project-health-scoring.d.ts +0 -177
  105. package/dist/src/utils/project-health-scoring.d.ts.map +0 -1
  106. package/dist/src/utils/project-health-scoring.js +0 -370
  107. package/dist/src/utils/project-health-scoring.js.map +0 -1
  108. package/dist/src/utils/todo-json-manager.d.ts +0 -71
  109. package/dist/src/utils/todo-json-manager.d.ts.map +0 -1
  110. package/dist/src/utils/todo-json-manager.js +0 -396
  111. package/dist/src/utils/todo-json-manager.js.map +0 -1
  112. package/dist/src/utils/todo-markdown-converter.d.ts +0 -16
  113. package/dist/src/utils/todo-markdown-converter.d.ts.map +0 -1
  114. package/dist/src/utils/todo-markdown-converter.js +0 -362
  115. package/dist/src/utils/todo-markdown-converter.js.map +0 -1
  116. package/dist/src/utils/todo-migration.d.ts +0 -47
  117. package/dist/src/utils/todo-migration.d.ts.map +0 -1
  118. package/dist/src/utils/todo-migration.js +0 -261
  119. package/dist/src/utils/todo-migration.js.map +0 -1
@@ -0,0 +1,834 @@
1
+ /**
2
+ * Memory Migration Manager
3
+ *
4
+ * Comprehensive migration strategy for transitioning existing data to memory entities.
5
+ * Handles deployment history, troubleshooting data, knowledge graphs, and other legacy
6
+ * systems with zero data loss and rollback capabilities.
7
+ */
8
+ import * as fs from 'fs/promises';
9
+ import * as path from 'path';
10
+ import { existsSync } from 'fs';
11
+ import crypto from 'crypto';
12
+ import { EnhancedLogger } from './enhanced-logging.js';
13
+ import { loadConfig } from './config.js';
14
+ import { McpAdrError } from '../types/index.js';
15
+ export class MemoryMigrationManager {
16
+ memoryManager;
17
+ logger;
18
+ config;
19
+ projectConfig;
20
+ migrationBackupDir;
21
+ constructor(memoryManager, config) {
22
+ this.memoryManager = memoryManager;
23
+ this.logger = new EnhancedLogger();
24
+ this.projectConfig = loadConfig();
25
+ this.config = {
26
+ enableBackup: true,
27
+ backupDirectory: path.join(this.projectConfig.projectPath, '.mcp-migration-backups'),
28
+ migrationBatchSize: 50,
29
+ validateIntegrity: true,
30
+ enableRollback: true,
31
+ logLevel: 'standard',
32
+ ...config,
33
+ };
34
+ this.migrationBackupDir = path.join(this.config.backupDirectory, `migration-${new Date().toISOString().replace(/[:.]/g, '-')}`);
35
+ }
36
+ /**
37
+ * Migrate all existing data to memory entities
38
+ */
39
+ async migrateAllExistingData() {
40
+ const startTime = new Date();
41
+ this.logger.info('Starting comprehensive data migration to memory entities', 'MemoryMigrationManager');
42
+ const result = {
43
+ success: true,
44
+ migratedCount: 0,
45
+ failedCount: 0,
46
+ errors: [],
47
+ performance: {
48
+ startTime: startTime.toISOString(),
49
+ endTime: '',
50
+ durationMs: 0,
51
+ throughputPerSecond: 0,
52
+ },
53
+ };
54
+ try {
55
+ // Create backup if enabled
56
+ if (this.config.enableBackup) {
57
+ result.backupPath = await this.createMigrationBackup();
58
+ this.logger.info('Migration backup created', 'MemoryMigrationManager', {
59
+ backupPath: result.backupPath,
60
+ });
61
+ }
62
+ // Define migration sources
63
+ const deploymentHistoryPath = path.join(this.projectConfig.projectPath, '.mcp-adr-cache', 'deployment-history.json');
64
+ const migrationSources = [
65
+ {
66
+ path: deploymentHistoryPath,
67
+ type: 'deployment_history',
68
+ format: 'json',
69
+ migrationStrategy: 'full',
70
+ },
71
+ {
72
+ path: path.join(this.projectConfig.projectPath, '.mcp-adr-cache', 'knowledge-graph-snapshots.json'),
73
+ type: 'knowledge_graph',
74
+ format: 'json',
75
+ migrationStrategy: 'selective',
76
+ },
77
+ {
78
+ path: path.join(this.projectConfig.projectPath, 'docs', 'adrs'),
79
+ type: 'adr_collection',
80
+ format: 'markdown',
81
+ migrationStrategy: 'full',
82
+ },
83
+ {
84
+ path: path.join(this.projectConfig.projectPath, '.mcp-adr-cache'),
85
+ type: 'troubleshooting_sessions',
86
+ format: 'json',
87
+ migrationStrategy: 'incremental',
88
+ },
89
+ ];
90
+ // Migrate each data source
91
+ for (const source of migrationSources) {
92
+ try {
93
+ const sourceResult = await this.migrateDataSource(source);
94
+ result.migratedCount += sourceResult.migratedCount;
95
+ result.failedCount += sourceResult.failedCount;
96
+ result.errors.push(...sourceResult.errors);
97
+ }
98
+ catch (error) {
99
+ result.failedCount++;
100
+ result.errors.push({
101
+ source: source.path,
102
+ error: error instanceof Error ? error.message : String(error),
103
+ data: undefined,
104
+ });
105
+ this.logger.error('Failed to migrate data source', 'MemoryMigrationManager');
106
+ }
107
+ }
108
+ // Create cross-tool relationships after migration
109
+ if (result.migratedCount > 0) {
110
+ try {
111
+ const relationshipResult = await this.memoryManager.createCrossToolRelationships();
112
+ this.logger.info('Cross-tool relationships created post-migration', 'MemoryMigrationManager', {
113
+ suggestedRelationships: relationshipResult.suggestedRelationships.length,
114
+ autoCreated: relationshipResult.autoCreatedCount,
115
+ });
116
+ }
117
+ catch (error) {
118
+ this.logger.warn('Failed to create cross-tool relationships', 'MemoryMigrationManager', {
119
+ error,
120
+ });
121
+ }
122
+ }
123
+ // Validate migration if enabled
124
+ if (this.config.validateIntegrity) {
125
+ const validationResult = await this.validateMigrationIntegrity(result.migratedCount);
126
+ if (!validationResult.isValid) {
127
+ result.success = false;
128
+ result.errors.push({
129
+ source: 'validation',
130
+ error: 'Migration integrity validation failed',
131
+ data: validationResult,
132
+ });
133
+ }
134
+ }
135
+ // Generate rollback plan if enabled
136
+ if (this.config.enableRollback) {
137
+ result.rollbackPlan = await this.generateRollbackPlan(result);
138
+ }
139
+ }
140
+ catch (error) {
141
+ result.success = false;
142
+ result.errors.push({
143
+ source: 'migration_manager',
144
+ error: error instanceof Error ? error.message : String(error),
145
+ });
146
+ this.logger.error('Migration failed with critical error', 'MemoryMigrationManager');
147
+ }
148
+ // Calculate performance metrics
149
+ const endTime = new Date();
150
+ result.performance.endTime = endTime.toISOString();
151
+ result.performance.durationMs = endTime.getTime() - startTime.getTime();
152
+ result.performance.throughputPerSecond =
153
+ result.migratedCount / (result.performance.durationMs / 1000);
154
+ // Log final results
155
+ this.logger.info('Migration completed', 'MemoryMigrationManager', {
156
+ success: result.success,
157
+ migratedCount: result.migratedCount,
158
+ failedCount: result.failedCount,
159
+ durationMs: result.performance.durationMs,
160
+ throughputPerSecond: result.performance.throughputPerSecond.toFixed(2),
161
+ });
162
+ return result;
163
+ }
164
+ /**
165
+ * Migrate a specific data source to memory entities
166
+ */
167
+ async migrateDataSource(source) {
168
+ this.logger.info('Starting data source migration', 'MemoryMigrationManager', {
169
+ path: source.path,
170
+ type: source.type,
171
+ });
172
+ const result = {
173
+ success: true,
174
+ migratedCount: 0,
175
+ failedCount: 0,
176
+ errors: [],
177
+ performance: {
178
+ startTime: new Date().toISOString(),
179
+ endTime: '',
180
+ durationMs: 0,
181
+ throughputPerSecond: 0,
182
+ },
183
+ };
184
+ if (!existsSync(source.path)) {
185
+ this.logger.info('Data source does not exist, skipping', 'MemoryMigrationManager', {
186
+ path: source.path,
187
+ });
188
+ return result;
189
+ }
190
+ try {
191
+ switch (source.type) {
192
+ case 'deployment_history':
193
+ const deploymentResult = await this.migrateDeploymentHistory(source.path);
194
+ Object.assign(result, deploymentResult);
195
+ break;
196
+ case 'knowledge_graph':
197
+ const knowledgeResult = await this.migrateKnowledgeGraph(source.path);
198
+ Object.assign(result, knowledgeResult);
199
+ break;
200
+ case 'adr_collection':
201
+ const adrResult = await this.migrateAdrCollection(source.path);
202
+ Object.assign(result, adrResult);
203
+ break;
204
+ case 'troubleshooting_sessions':
205
+ const troubleshootingResult = await this.migrateTroubleshootingSessions(source.path);
206
+ Object.assign(result, troubleshootingResult);
207
+ break;
208
+ default:
209
+ this.logger.warn('Unknown data source type', 'MemoryMigrationManager', {
210
+ type: source.type,
211
+ });
212
+ }
213
+ }
214
+ catch (error) {
215
+ result.success = false;
216
+ result.errors.push({
217
+ source: source.path,
218
+ error: error instanceof Error ? error.message : String(error),
219
+ });
220
+ }
221
+ return result;
222
+ }
223
+ /**
224
+ * Migrate deployment history JSON files to deployment assessment memory entities
225
+ */
226
+ async migrateDeploymentHistory(historyPath) {
227
+ try {
228
+ const historyData = JSON.parse(await fs.readFile(historyPath, 'utf-8'));
229
+ const deployments = Array.isArray(historyData) ? historyData : historyData.deployments || [];
230
+ let migratedCount = 0;
231
+ const errors = [];
232
+ for (const deployment of deployments) {
233
+ try {
234
+ const memoryEntity = {
235
+ id: crypto.randomUUID(),
236
+ type: 'deployment_assessment',
237
+ title: `Migrated Deployment Assessment - ${deployment.environment || 'Unknown'}`,
238
+ description: `Deployment assessment migrated from legacy JSON data: ${deployment.timestamp || 'Unknown date'}`,
239
+ confidence: 0.8,
240
+ relevance: 0.7,
241
+ tags: ['migrated', 'deployment', deployment.environment || 'unknown'],
242
+ created: deployment.timestamp || new Date().toISOString(),
243
+ lastModified: new Date().toISOString(),
244
+ version: 1,
245
+ context: {
246
+ technicalStack: deployment.technicalStack || [],
247
+ environmentalFactors: [deployment.environment || 'unknown'],
248
+ stakeholders: ['migration-tool'],
249
+ },
250
+ relationships: [],
251
+ accessPattern: {
252
+ accessCount: 1,
253
+ lastAccessed: new Date().toISOString(),
254
+ accessContext: ['migration'],
255
+ },
256
+ evolution: {
257
+ origin: 'imported',
258
+ transformations: [
259
+ {
260
+ timestamp: new Date().toISOString(),
261
+ type: 'migration',
262
+ description: `Migrated from deployment-history.json`,
263
+ agent: 'MemoryMigrationManager',
264
+ },
265
+ ],
266
+ },
267
+ validation: {
268
+ isVerified: false,
269
+ verificationMethod: 'automatic-migration',
270
+ verificationTimestamp: new Date().toISOString(),
271
+ },
272
+ assessmentData: {
273
+ environment: this.mapEnvironmentType(deployment.environment),
274
+ readinessScore: deployment.readinessScore || 0.5,
275
+ validationResults: {
276
+ testResults: {
277
+ passed: deployment.testsPassed || 0,
278
+ failed: deployment.testsFailed || 0,
279
+ coverage: deployment.testCoverage || 0.0,
280
+ criticalFailures: deployment.criticalFailures || [],
281
+ },
282
+ securityValidation: {
283
+ vulnerabilities: deployment.securityIssues || 0,
284
+ securityScore: deployment.securityScore || 0.5,
285
+ criticalIssues: deployment.securityCriticalIssues || [],
286
+ },
287
+ performanceValidation: {
288
+ performanceScore: deployment.performanceScore || 0.5,
289
+ bottlenecks: deployment.performanceBottlenecks || [],
290
+ resourceUtilization: deployment.resourceUtilization || {},
291
+ },
292
+ },
293
+ blockingIssues: (deployment.blockers || []).map((blocker) => ({
294
+ issue: blocker.issue || blocker,
295
+ severity: blocker.severity || 'medium',
296
+ category: blocker.category || 'configuration',
297
+ resolution: blocker.resolution,
298
+ estimatedEffort: blocker.effort,
299
+ })),
300
+ deploymentStrategy: {
301
+ type: deployment.strategy || 'rolling',
302
+ rollbackPlan: deployment.rollbackPlan || 'Standard rollback procedure',
303
+ monitoringPlan: deployment.monitoringPlan || 'Standard monitoring',
304
+ estimatedDowntime: deployment.estimatedDowntime,
305
+ },
306
+ complianceChecks: {
307
+ adrCompliance: deployment.adrCompliance || 0.5,
308
+ regulatoryCompliance: deployment.complianceChecks || [],
309
+ auditTrail: deployment.auditTrail || [`Migrated from ${historyPath}`],
310
+ },
311
+ },
312
+ };
313
+ await this.memoryManager.upsertEntity(memoryEntity);
314
+ migratedCount++;
315
+ }
316
+ catch (error) {
317
+ this.logger.error('Failed to migrate deployment', 'MemoryMigrationManager', error instanceof Error ? error : new Error(String(error)));
318
+ errors.push({
319
+ source: 'deployment',
320
+ error: error instanceof Error ? error.message : String(error),
321
+ data: deployment,
322
+ });
323
+ }
324
+ }
325
+ return { migratedCount, failedCount: errors.length, errors };
326
+ }
327
+ catch (error) {
328
+ this.logger.error('Critical error in deployment history migration', 'MemoryMigrationManager', error instanceof Error ? error : new Error(String(error)));
329
+ throw new McpAdrError(`Failed to migrate deployment history: ${error instanceof Error ? error.message : String(error)}`, 'MIGRATION_ERROR');
330
+ }
331
+ }
332
+ /**
333
+ * Migrate knowledge graph snapshots to architectural decision memory entities
334
+ */
335
+ async migrateKnowledgeGraph(snapshotsPath) {
336
+ try {
337
+ const snapshotsData = JSON.parse(await fs.readFile(snapshotsPath, 'utf-8'));
338
+ const snapshots = Array.isArray(snapshotsData) ? snapshotsData : [snapshotsData];
339
+ let migratedCount = 0;
340
+ const errors = [];
341
+ for (const snapshot of snapshots) {
342
+ if (snapshot.adrs) {
343
+ for (const adr of snapshot.adrs) {
344
+ try {
345
+ const memoryEntity = {
346
+ id: crypto.randomUUID(),
347
+ type: 'architectural_decision',
348
+ title: adr.title || `Migrated ADR - ${adr.number || 'Unknown'}`,
349
+ description: adr.content || 'Architectural decision migrated from knowledge graph',
350
+ confidence: 0.9,
351
+ relevance: adr.importance || 0.8,
352
+ tags: ['migrated', 'adr', ...(adr.tags || [])],
353
+ created: adr.created || new Date().toISOString(),
354
+ lastModified: adr.lastModified || new Date().toISOString(),
355
+ version: adr.version || 1,
356
+ context: {
357
+ technicalStack: adr.technicalStack || [],
358
+ environmentalFactors: adr.environmentalFactors || [],
359
+ stakeholders: adr.stakeholders || ['migration-tool'],
360
+ },
361
+ relationships: [],
362
+ accessPattern: {
363
+ accessCount: 1,
364
+ lastAccessed: new Date().toISOString(),
365
+ accessContext: ['migration'],
366
+ },
367
+ evolution: {
368
+ origin: 'imported',
369
+ transformations: [
370
+ {
371
+ timestamp: new Date().toISOString(),
372
+ type: 'migration',
373
+ description: `Migrated from knowledge graph snapshot`,
374
+ agent: 'MemoryMigrationManager',
375
+ },
376
+ ],
377
+ },
378
+ validation: {
379
+ isVerified: true,
380
+ verificationMethod: 'knowledge-graph-import',
381
+ verificationTimestamp: new Date().toISOString(),
382
+ },
383
+ decisionData: {
384
+ status: adr.status || 'accepted',
385
+ context: adr.context || 'Migrated from knowledge graph',
386
+ decision: adr.decision || adr.title || 'Decision details not available',
387
+ consequences: {
388
+ positive: adr.positiveConsequences || [],
389
+ negative: adr.negativeConsequences || [],
390
+ risks: adr.risks || [],
391
+ },
392
+ alternatives: (adr.alternatives || []).map((alt) => ({
393
+ name: alt.name || alt,
394
+ description: alt.description || '',
395
+ tradeoffs: alt.tradeoffs || '',
396
+ })),
397
+ implementationStatus: adr.implementationStatus || 'unknown',
398
+ implementationTasks: adr.implementationTasks || [],
399
+ reviewHistory: adr.reviewHistory || [],
400
+ },
401
+ };
402
+ await this.memoryManager.upsertEntity(memoryEntity);
403
+ migratedCount++;
404
+ if (this.config.logLevel === 'verbose') {
405
+ this.logger.debug('Migrated ADR from knowledge graph', 'MemoryMigrationManager', {
406
+ id: memoryEntity.id,
407
+ title: adr.title,
408
+ });
409
+ }
410
+ }
411
+ catch (error) {
412
+ errors.push({
413
+ source: 'knowledge_graph_adr',
414
+ error: error instanceof Error ? error.message : String(error),
415
+ data: adr,
416
+ });
417
+ }
418
+ }
419
+ }
420
+ }
421
+ return { migratedCount, failedCount: errors.length, errors };
422
+ }
423
+ catch (error) {
424
+ throw new McpAdrError(`Failed to migrate knowledge graph: ${error instanceof Error ? error.message : String(error)}`, 'MIGRATION_ERROR');
425
+ }
426
+ }
427
+ /**
428
+ * Migrate ADR markdown files to architectural decision memory entities
429
+ */
430
+ async migrateAdrCollection(adrDirectory) {
431
+ try {
432
+ const files = await fs.readdir(adrDirectory);
433
+ const adrFiles = files.filter(file => file.endsWith('.md') && file.match(/^\d+/));
434
+ let migratedCount = 0;
435
+ const errors = [];
436
+ for (const file of adrFiles) {
437
+ try {
438
+ const filePath = path.join(adrDirectory, file);
439
+ const content = await fs.readFile(filePath, 'utf-8');
440
+ const adrData = this.parseAdrMarkdown(content, file);
441
+ const memoryEntity = {
442
+ id: crypto.randomUUID(),
443
+ type: 'architectural_decision',
444
+ title: adrData.title,
445
+ description: adrData.description,
446
+ confidence: 0.95, // High confidence for formal ADR documents
447
+ relevance: 0.9,
448
+ tags: ['migrated', 'adr', 'formal', ...adrData.tags],
449
+ created: adrData.created || new Date().toISOString(),
450
+ lastModified: new Date().toISOString(),
451
+ version: 1,
452
+ context: {
453
+ technicalStack: adrData.technicalStack || [],
454
+ environmentalFactors: adrData.environmentalFactors || [],
455
+ stakeholders: adrData.stakeholders || ['architecture-team'],
456
+ },
457
+ relationships: [],
458
+ accessPattern: {
459
+ accessCount: 1,
460
+ lastAccessed: new Date().toISOString(),
461
+ accessContext: ['migration'],
462
+ },
463
+ evolution: {
464
+ origin: 'imported',
465
+ transformations: [
466
+ {
467
+ timestamp: new Date().toISOString(),
468
+ type: 'migration',
469
+ description: `Migrated from ADR markdown file: ${file}`,
470
+ agent: 'MemoryMigrationManager',
471
+ },
472
+ ],
473
+ },
474
+ validation: {
475
+ isVerified: true,
476
+ verificationMethod: 'adr-markdown-import',
477
+ verificationTimestamp: new Date().toISOString(),
478
+ },
479
+ decisionData: {
480
+ status: adrData.status,
481
+ context: adrData.context,
482
+ decision: adrData.decision,
483
+ consequences: adrData.consequences,
484
+ alternatives: adrData.alternatives,
485
+ implementationStatus: adrData.implementationStatus || 'unknown',
486
+ implementationTasks: adrData.implementationTasks || [],
487
+ reviewHistory: [],
488
+ },
489
+ };
490
+ await this.memoryManager.upsertEntity(memoryEntity);
491
+ migratedCount++;
492
+ if (this.config.logLevel === 'verbose') {
493
+ this.logger.debug('Migrated ADR markdown file', 'MemoryMigrationManager', {
494
+ id: memoryEntity.id,
495
+ file,
496
+ title: adrData.title,
497
+ });
498
+ }
499
+ }
500
+ catch (error) {
501
+ errors.push({
502
+ source: file,
503
+ error: error instanceof Error ? error.message : String(error),
504
+ });
505
+ }
506
+ }
507
+ return { migratedCount, failedCount: errors.length, errors };
508
+ }
509
+ catch (error) {
510
+ throw new McpAdrError(`Failed to migrate ADR collection: ${error instanceof Error ? error.message : String(error)}`, 'MIGRATION_ERROR');
511
+ }
512
+ }
513
+ /**
514
+ * Migrate troubleshooting session data
515
+ */
516
+ async migrateTroubleshootingSessions(cacheDirectory) {
517
+ try {
518
+ const files = await fs.readdir(cacheDirectory);
519
+ const sessionFiles = files.filter(file => file.includes('troubleshoot') || file.includes('session') || file.includes('debug'));
520
+ let migratedCount = 0;
521
+ const errors = [];
522
+ for (const file of sessionFiles) {
523
+ try {
524
+ if (file.endsWith('.json')) {
525
+ const filePath = path.join(cacheDirectory, file);
526
+ const sessionData = JSON.parse(await fs.readFile(filePath, 'utf-8'));
527
+ const memoryEntity = {
528
+ id: crypto.randomUUID(),
529
+ type: 'troubleshooting_session',
530
+ title: `Migrated Troubleshooting Session - ${file}`,
531
+ description: sessionData.description || 'Troubleshooting session migrated from cache',
532
+ confidence: 0.7,
533
+ relevance: 0.8,
534
+ tags: ['migrated', 'troubleshooting', ...(sessionData.tags || [])],
535
+ created: sessionData.timestamp || new Date().toISOString(),
536
+ lastModified: new Date().toISOString(),
537
+ version: 1,
538
+ context: {
539
+ technicalStack: sessionData.technicalStack || [],
540
+ environmentalFactors: sessionData.environment ? [sessionData.environment] : [],
541
+ stakeholders: ['migration-tool'],
542
+ },
543
+ relationships: [],
544
+ accessPattern: {
545
+ accessCount: 1,
546
+ lastAccessed: new Date().toISOString(),
547
+ accessContext: ['migration'],
548
+ },
549
+ evolution: {
550
+ origin: 'imported',
551
+ transformations: [
552
+ {
553
+ timestamp: new Date().toISOString(),
554
+ type: 'migration',
555
+ description: `Migrated from troubleshooting cache file: ${file}`,
556
+ agent: 'MemoryMigrationManager',
557
+ },
558
+ ],
559
+ },
560
+ validation: {
561
+ isVerified: false,
562
+ verificationMethod: 'cache-import',
563
+ verificationTimestamp: new Date().toISOString(),
564
+ },
565
+ sessionData: {
566
+ failurePattern: {
567
+ failureType: sessionData.failureType || 'unknown',
568
+ errorSignature: sessionData.errorSignature || sessionData.error || 'Unknown error',
569
+ frequency: sessionData.frequency || 1,
570
+ environments: sessionData.environments || [sessionData.environment || 'unknown'],
571
+ },
572
+ failureDetails: {
573
+ errorMessage: sessionData.errorMessage || sessionData.error || 'No error message available',
574
+ environment: sessionData.environment || 'unknown',
575
+ },
576
+ analysisSteps: sessionData.steps || sessionData.analysisSteps || [],
577
+ solutionEffectiveness: sessionData.effectiveness || 0.5,
578
+ preventionMeasures: sessionData.prevention || [],
579
+ relatedADRs: sessionData.relatedADRs || [],
580
+ environmentContext: {
581
+ environment: sessionData.environment || 'unknown',
582
+ },
583
+ followUpActions: sessionData.followUpActions || [],
584
+ },
585
+ };
586
+ await this.memoryManager.upsertEntity(memoryEntity);
587
+ migratedCount++;
588
+ }
589
+ }
590
+ catch (error) {
591
+ errors.push({
592
+ source: file,
593
+ error: error instanceof Error ? error.message : String(error),
594
+ });
595
+ }
596
+ }
597
+ return { migratedCount, failedCount: errors.length, errors };
598
+ }
599
+ catch (error) {
600
+ throw new McpAdrError(`Failed to migrate troubleshooting sessions: ${error instanceof Error ? error.message : String(error)}`, 'MIGRATION_ERROR');
601
+ }
602
+ }
603
+ /**
604
+ * Create backup of existing data before migration
605
+ */
606
+ async createMigrationBackup() {
607
+ await fs.mkdir(this.migrationBackupDir, { recursive: true });
608
+ const cacheDir = path.join(this.projectConfig.projectPath, '.mcp-adr-cache');
609
+ const docsDir = path.join(this.projectConfig.projectPath, 'docs');
610
+ // Backup cache directory
611
+ if (existsSync(cacheDir)) {
612
+ await this.copyDirectory(cacheDir, path.join(this.migrationBackupDir, 'cache'));
613
+ }
614
+ // Backup docs directory
615
+ if (existsSync(docsDir)) {
616
+ await this.copyDirectory(docsDir, path.join(this.migrationBackupDir, 'docs'));
617
+ }
618
+ // Create backup manifest
619
+ const manifest = {
620
+ timestamp: new Date().toISOString(),
621
+ migrationVersion: '1.0.0',
622
+ projectPath: this.projectConfig.projectPath,
623
+ backupContents: {
624
+ cache: existsSync(cacheDir),
625
+ docs: existsSync(docsDir),
626
+ },
627
+ };
628
+ await fs.writeFile(path.join(this.migrationBackupDir, 'backup-manifest.json'), JSON.stringify(manifest, null, 2));
629
+ return this.migrationBackupDir;
630
+ }
631
+ /**
632
+ * Validate migration integrity
633
+ */
634
+ async validateMigrationIntegrity(expectedCount) {
635
+ const queryResult = await this.memoryManager.queryEntities({});
636
+ const issues = [];
637
+ const actualCount = queryResult.entities.length;
638
+ // Check entity count expectations
639
+ if (actualCount === 0 && expectedCount > 0) {
640
+ issues.push('No entities found after migration');
641
+ }
642
+ // Validate entity structure
643
+ for (const entity of queryResult.entities.slice(0, 10)) {
644
+ // Sample first 10
645
+ if (!entity.id || !entity.type || !entity.title) {
646
+ issues.push(`Invalid entity structure: ${entity.id}`);
647
+ }
648
+ }
649
+ return {
650
+ isValid: issues.length === 0,
651
+ actualCount,
652
+ issues,
653
+ };
654
+ }
655
+ /**
656
+ * Generate rollback plan
657
+ */
658
+ async generateRollbackPlan(migrationResult) {
659
+ const rollbackSteps = [
660
+ '# Migration Rollback Plan',
661
+ '',
662
+ `Generated: ${new Date().toISOString()}`,
663
+ `Migration ID: ${path.basename(this.migrationBackupDir)}`,
664
+ '',
665
+ '## Steps to Rollback:',
666
+ '',
667
+ '1. Stop the MCP ADR Analysis Server',
668
+ '2. Clear memory entities:',
669
+ ' ```bash',
670
+ ` rm -rf "${path.join(this.projectConfig.projectPath, '.mcp-adr-memory')}"`,
671
+ ' ```',
672
+ '',
673
+ '3. Restore backup data:',
674
+ ' ```bash',
675
+ ];
676
+ if (migrationResult.backupPath) {
677
+ rollbackSteps.push(` cp -r "${path.join(migrationResult.backupPath, 'cache')}" "${path.join(this.projectConfig.projectPath, '.mcp-adr-cache')}"`, ` cp -r "${path.join(migrationResult.backupPath, 'docs')}" "${path.join(this.projectConfig.projectPath, 'docs')}"`);
678
+ }
679
+ rollbackSteps.push(' ```', '', '4. Restart the server', '', '## Verification:', '- Check that legacy cache files are restored', '- Verify ADR documents are accessible', '- Confirm troubleshooting history is available');
680
+ const rollbackContent = rollbackSteps.join('\n');
681
+ // Save rollback plan
682
+ const rollbackPath = path.join(this.migrationBackupDir, 'rollback-plan.md');
683
+ await fs.writeFile(rollbackPath, rollbackContent);
684
+ return rollbackPath;
685
+ }
686
+ /**
687
+ * Helper methods
688
+ */
689
+ async copyDirectory(src, dest) {
690
+ await fs.mkdir(dest, { recursive: true });
691
+ const entries = await fs.readdir(src, { withFileTypes: true });
692
+ for (const entry of entries) {
693
+ const srcPath = path.join(src, entry.name);
694
+ const destPath = path.join(dest, entry.name);
695
+ if (entry.isDirectory()) {
696
+ await this.copyDirectory(srcPath, destPath);
697
+ }
698
+ else {
699
+ await fs.copyFile(srcPath, destPath);
700
+ }
701
+ }
702
+ }
703
+ mapEnvironmentType(env) {
704
+ const envLower = (env || '').toLowerCase();
705
+ if (envLower.includes('prod'))
706
+ return 'production';
707
+ if (envLower.includes('stag'))
708
+ return 'staging';
709
+ if (envLower.includes('test'))
710
+ return 'testing';
711
+ return 'development';
712
+ }
713
+ parseAdrMarkdown(content, filename) {
714
+ const lines = content.split('\n');
715
+ const result = {
716
+ title: filename.replace(/^\d+[-_]/, '').replace(/\.md$/, ''),
717
+ status: 'accepted',
718
+ context: '',
719
+ decision: '',
720
+ consequences: { positive: [], negative: [], risks: [] },
721
+ alternatives: [],
722
+ tags: [],
723
+ technicalStack: [],
724
+ environmentalFactors: [],
725
+ stakeholders: [],
726
+ };
727
+ let currentSection = '';
728
+ let currentContent = [];
729
+ for (const line of lines) {
730
+ const trimmed = line.trim();
731
+ // Extract title
732
+ if (trimmed.startsWith('# ')) {
733
+ result.title = trimmed.substring(2);
734
+ continue;
735
+ }
736
+ // Extract status
737
+ if (trimmed.toLowerCase().includes('status')) {
738
+ const statusMatch = trimmed.match(/status[:\s]*(\w+)/i);
739
+ if (statusMatch && statusMatch[1]) {
740
+ result.status = statusMatch[1].toLowerCase();
741
+ }
742
+ continue;
743
+ }
744
+ // Extract sections
745
+ if (trimmed.startsWith('## ')) {
746
+ // Process previous section
747
+ if (currentSection && currentContent.length > 0) {
748
+ const sectionContent = currentContent.join('\n').trim();
749
+ switch (currentSection.toLowerCase()) {
750
+ case 'context':
751
+ result.context = sectionContent;
752
+ break;
753
+ case 'decision':
754
+ result.decision = sectionContent;
755
+ break;
756
+ case 'consequences':
757
+ result.consequences = this.parseConsequences(sectionContent);
758
+ break;
759
+ case 'alternatives':
760
+ result.alternatives = this.parseAlternatives(sectionContent);
761
+ break;
762
+ }
763
+ }
764
+ currentSection = trimmed.substring(3);
765
+ currentContent = [];
766
+ }
767
+ else if (currentSection) {
768
+ currentContent.push(line);
769
+ }
770
+ }
771
+ // Process last section
772
+ if (currentSection && currentContent.length > 0) {
773
+ const sectionContent = currentContent.join('\n').trim();
774
+ switch (currentSection.toLowerCase()) {
775
+ case 'context':
776
+ result.context = sectionContent;
777
+ break;
778
+ case 'decision':
779
+ result.decision = sectionContent;
780
+ break;
781
+ case 'consequences':
782
+ result.consequences = this.parseConsequences(sectionContent);
783
+ break;
784
+ case 'alternatives':
785
+ result.alternatives = this.parseAlternatives(sectionContent);
786
+ break;
787
+ }
788
+ }
789
+ return result;
790
+ }
791
+ parseConsequences(content) {
792
+ const result = { positive: [], negative: [], risks: [] };
793
+ const lines = content.split('\n');
794
+ let currentType = '';
795
+ for (const line of lines) {
796
+ const trimmed = line.trim();
797
+ if (trimmed.toLowerCase().includes('positive')) {
798
+ currentType = 'positive';
799
+ }
800
+ else if (trimmed.toLowerCase().includes('negative')) {
801
+ currentType = 'negative';
802
+ }
803
+ else if (trimmed.toLowerCase().includes('risk')) {
804
+ currentType = 'risks';
805
+ }
806
+ else if (trimmed.startsWith('-') || trimmed.startsWith('*')) {
807
+ const item = trimmed.substring(1).trim();
808
+ if (currentType && item) {
809
+ result[currentType].push(item);
810
+ }
811
+ }
812
+ }
813
+ return result;
814
+ }
815
+ parseAlternatives(content) {
816
+ const alternatives = [];
817
+ const sections = content.split(/(?=^[#]+\s)/m);
818
+ for (const section of sections) {
819
+ const lines = section.split('\n');
820
+ const titleLine = lines.find(line => line.trim().startsWith('#'));
821
+ if (titleLine) {
822
+ const name = titleLine.replace(/^#+\s*/, '');
823
+ const description = lines.slice(1).join('\n').trim();
824
+ alternatives.push({
825
+ name,
826
+ description,
827
+ tradeoffs: '', // Extract if pattern found
828
+ });
829
+ }
830
+ }
831
+ return alternatives;
832
+ }
833
+ }
834
+ //# sourceMappingURL=memory-migration-manager.js.map