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