mcp-adr-analysis-server 1.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.
Files changed (131) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +608 -0
  3. package/dist/src/index.d.ts +10 -0
  4. package/dist/src/index.d.ts.map +1 -0
  5. package/dist/src/index.js +1722 -0
  6. package/dist/src/index.js.map +1 -0
  7. package/dist/src/prompts/adr-suggestion-prompts.d.ts +24 -0
  8. package/dist/src/prompts/adr-suggestion-prompts.d.ts.map +1 -0
  9. package/dist/src/prompts/adr-suggestion-prompts.js +383 -0
  10. package/dist/src/prompts/adr-suggestion-prompts.js.map +1 -0
  11. package/dist/src/prompts/analysis-prompts.d.ts +24 -0
  12. package/dist/src/prompts/analysis-prompts.d.ts.map +1 -0
  13. package/dist/src/prompts/analysis-prompts.js +489 -0
  14. package/dist/src/prompts/analysis-prompts.js.map +1 -0
  15. package/dist/src/prompts/deployment-analysis-prompts.d.ts +54 -0
  16. package/dist/src/prompts/deployment-analysis-prompts.d.ts.map +1 -0
  17. package/dist/src/prompts/deployment-analysis-prompts.js +712 -0
  18. package/dist/src/prompts/deployment-analysis-prompts.js.map +1 -0
  19. package/dist/src/prompts/environment-analysis-prompts.d.ts +34 -0
  20. package/dist/src/prompts/environment-analysis-prompts.d.ts.map +1 -0
  21. package/dist/src/prompts/environment-analysis-prompts.js +724 -0
  22. package/dist/src/prompts/environment-analysis-prompts.js.map +1 -0
  23. package/dist/src/prompts/index.d.ts +43 -0
  24. package/dist/src/prompts/index.d.ts.map +1 -0
  25. package/dist/src/prompts/index.js +384 -0
  26. package/dist/src/prompts/index.js.map +1 -0
  27. package/dist/src/prompts/research-integration-prompts.d.ts +43 -0
  28. package/dist/src/prompts/research-integration-prompts.d.ts.map +1 -0
  29. package/dist/src/prompts/research-integration-prompts.js +398 -0
  30. package/dist/src/prompts/research-integration-prompts.js.map +1 -0
  31. package/dist/src/prompts/research-question-prompts.d.ts +75 -0
  32. package/dist/src/prompts/research-question-prompts.d.ts.map +1 -0
  33. package/dist/src/prompts/research-question-prompts.js +695 -0
  34. package/dist/src/prompts/research-question-prompts.js.map +1 -0
  35. package/dist/src/prompts/rule-generation-prompts.d.ts +63 -0
  36. package/dist/src/prompts/rule-generation-prompts.d.ts.map +1 -0
  37. package/dist/src/prompts/rule-generation-prompts.js +630 -0
  38. package/dist/src/prompts/rule-generation-prompts.js.map +1 -0
  39. package/dist/src/prompts/security-prompts.d.ts +23 -0
  40. package/dist/src/prompts/security-prompts.d.ts.map +1 -0
  41. package/dist/src/prompts/security-prompts.js +287 -0
  42. package/dist/src/prompts/security-prompts.js.map +1 -0
  43. package/dist/src/resources/index.d.ts +24 -0
  44. package/dist/src/resources/index.d.ts.map +1 -0
  45. package/dist/src/resources/index.js +458 -0
  46. package/dist/src/resources/index.js.map +1 -0
  47. package/dist/src/tools/adr-suggestion-tool.d.ts +40 -0
  48. package/dist/src/tools/adr-suggestion-tool.d.ts.map +1 -0
  49. package/dist/src/tools/adr-suggestion-tool.js +338 -0
  50. package/dist/src/tools/adr-suggestion-tool.js.map +1 -0
  51. package/dist/src/tools/content-masking-tool.d.ts +52 -0
  52. package/dist/src/tools/content-masking-tool.d.ts.map +1 -0
  53. package/dist/src/tools/content-masking-tool.js +206 -0
  54. package/dist/src/tools/content-masking-tool.js.map +1 -0
  55. package/dist/src/tools/deployment-analysis-tool.d.ts +39 -0
  56. package/dist/src/tools/deployment-analysis-tool.d.ts.map +1 -0
  57. package/dist/src/tools/deployment-analysis-tool.js +310 -0
  58. package/dist/src/tools/deployment-analysis-tool.js.map +1 -0
  59. package/dist/src/tools/environment-analysis-tool.d.ts +16 -0
  60. package/dist/src/tools/environment-analysis-tool.d.ts.map +1 -0
  61. package/dist/src/tools/environment-analysis-tool.js +298 -0
  62. package/dist/src/tools/environment-analysis-tool.js.map +1 -0
  63. package/dist/src/tools/research-integration-tool.d.ts +44 -0
  64. package/dist/src/tools/research-integration-tool.d.ts.map +1 -0
  65. package/dist/src/tools/research-integration-tool.js +429 -0
  66. package/dist/src/tools/research-integration-tool.js.map +1 -0
  67. package/dist/src/tools/research-question-tool.d.ts +55 -0
  68. package/dist/src/tools/research-question-tool.d.ts.map +1 -0
  69. package/dist/src/tools/research-question-tool.js +333 -0
  70. package/dist/src/tools/research-question-tool.js.map +1 -0
  71. package/dist/src/tools/rule-generation-tool.d.ts +49 -0
  72. package/dist/src/tools/rule-generation-tool.d.ts.map +1 -0
  73. package/dist/src/tools/rule-generation-tool.js +432 -0
  74. package/dist/src/tools/rule-generation-tool.js.map +1 -0
  75. package/dist/src/types/index.d.ts +531 -0
  76. package/dist/src/types/index.d.ts.map +1 -0
  77. package/dist/src/types/index.js +129 -0
  78. package/dist/src/types/index.js.map +1 -0
  79. package/dist/src/utils/adr-suggestions.d.ts +104 -0
  80. package/dist/src/utils/adr-suggestions.d.ts.map +1 -0
  81. package/dist/src/utils/adr-suggestions.js +228 -0
  82. package/dist/src/utils/adr-suggestions.js.map +1 -0
  83. package/dist/src/utils/cache.d.ts +51 -0
  84. package/dist/src/utils/cache.d.ts.map +1 -0
  85. package/dist/src/utils/cache.js +243 -0
  86. package/dist/src/utils/cache.js.map +1 -0
  87. package/dist/src/utils/config.d.ts +65 -0
  88. package/dist/src/utils/config.d.ts.map +1 -0
  89. package/dist/src/utils/config.js +118 -0
  90. package/dist/src/utils/config.js.map +1 -0
  91. package/dist/src/utils/content-masking.d.ts +79 -0
  92. package/dist/src/utils/content-masking.d.ts.map +1 -0
  93. package/dist/src/utils/content-masking.js +203 -0
  94. package/dist/src/utils/content-masking.js.map +1 -0
  95. package/dist/src/utils/deployment-analysis.d.ts +67 -0
  96. package/dist/src/utils/deployment-analysis.d.ts.map +1 -0
  97. package/dist/src/utils/deployment-analysis.js +263 -0
  98. package/dist/src/utils/deployment-analysis.js.map +1 -0
  99. package/dist/src/utils/environment-analysis.d.ts +76 -0
  100. package/dist/src/utils/environment-analysis.d.ts.map +1 -0
  101. package/dist/src/utils/environment-analysis.js +329 -0
  102. package/dist/src/utils/environment-analysis.js.map +1 -0
  103. package/dist/src/utils/file-system.d.ts +63 -0
  104. package/dist/src/utils/file-system.d.ts.map +1 -0
  105. package/dist/src/utils/file-system.js +189 -0
  106. package/dist/src/utils/file-system.js.map +1 -0
  107. package/dist/src/utils/output-masking.d.ts +45 -0
  108. package/dist/src/utils/output-masking.d.ts.map +1 -0
  109. package/dist/src/utils/output-masking.js +200 -0
  110. package/dist/src/utils/output-masking.js.map +1 -0
  111. package/dist/src/utils/research-documentation.d.ts +58 -0
  112. package/dist/src/utils/research-documentation.d.ts.map +1 -0
  113. package/dist/src/utils/research-documentation.js +438 -0
  114. package/dist/src/utils/research-documentation.js.map +1 -0
  115. package/dist/src/utils/research-integration.d.ts +89 -0
  116. package/dist/src/utils/research-integration.d.ts.map +1 -0
  117. package/dist/src/utils/research-integration.js +432 -0
  118. package/dist/src/utils/research-integration.js.map +1 -0
  119. package/dist/src/utils/research-questions.d.ts +97 -0
  120. package/dist/src/utils/research-questions.d.ts.map +1 -0
  121. package/dist/src/utils/research-questions.js +319 -0
  122. package/dist/src/utils/research-questions.js.map +1 -0
  123. package/dist/src/utils/rule-format.d.ts +76 -0
  124. package/dist/src/utils/rule-format.d.ts.map +1 -0
  125. package/dist/src/utils/rule-format.js +257 -0
  126. package/dist/src/utils/rule-format.js.map +1 -0
  127. package/dist/src/utils/rule-generation.d.ts +86 -0
  128. package/dist/src/utils/rule-generation.d.ts.map +1 -0
  129. package/dist/src/utils/rule-generation.js +330 -0
  130. package/dist/src/utils/rule-generation.js.map +1 -0
  131. package/package.json +71 -0
@@ -0,0 +1,104 @@
1
+ /**
2
+ * ADR suggestion utilities using prompt-driven AI analysis
3
+ * Implements intelligent ADR recommendations based on code analysis
4
+ */
5
+ export interface ImplicitDecision {
6
+ id: string;
7
+ title: string;
8
+ category: string;
9
+ confidence: number;
10
+ evidence: string[];
11
+ filePaths: string[];
12
+ description: string;
13
+ context: string;
14
+ consequences: string;
15
+ alternatives: string[];
16
+ priority: 'low' | 'medium' | 'high' | 'critical';
17
+ complexity: 'low' | 'medium' | 'high';
18
+ riskLevel: 'low' | 'medium' | 'high' | 'critical';
19
+ suggestedAdrTitle: string;
20
+ relatedPatterns: string[];
21
+ }
22
+ export interface DecisionCluster {
23
+ theme: string;
24
+ decisions: string[];
25
+ suggestedCombinedAdr: string;
26
+ }
27
+ export interface ImplicitDecisionAnalysis {
28
+ implicitDecisions: ImplicitDecision[];
29
+ decisionClusters: DecisionCluster[];
30
+ recommendations: string[];
31
+ gaps: Array<{
32
+ area: string;
33
+ description: string;
34
+ suggestedInvestigation: string;
35
+ }>;
36
+ }
37
+ export interface CodeChangeDecision {
38
+ id: string;
39
+ title: string;
40
+ category: string;
41
+ confidence: number;
42
+ evidence: string[];
43
+ context: string;
44
+ decision: string;
45
+ consequences: string;
46
+ alternatives: string[];
47
+ changeMotivation: string;
48
+ futureImplications: string;
49
+ suggestedAdrTitle: string;
50
+ priority: 'low' | 'medium' | 'high' | 'critical';
51
+ }
52
+ export interface GeneratedAdr {
53
+ id: string;
54
+ title: string;
55
+ status: string;
56
+ date: string;
57
+ format: string;
58
+ content: string;
59
+ filename: string;
60
+ metadata: {
61
+ category: string;
62
+ tags: string[];
63
+ complexity: string;
64
+ impact: string;
65
+ stakeholders: string[];
66
+ };
67
+ }
68
+ /**
69
+ * Analyze project for implicit architectural decisions
70
+ */
71
+ export declare function analyzeImplicitDecisions(projectPath: string, existingAdrs?: string[]): Promise<{
72
+ analysisPrompt: string;
73
+ instructions: string;
74
+ }>;
75
+ /**
76
+ * Analyze code changes for architectural decisions
77
+ */
78
+ export declare function analyzeCodeChanges(beforeCode: string, afterCode: string, changeDescription: string, commitMessages?: string[]): Promise<{
79
+ analysisPrompt: string;
80
+ instructions: string;
81
+ }>;
82
+ /**
83
+ * Generate ADR from decision data
84
+ */
85
+ export declare function generateAdrFromDecision(decisionData: {
86
+ title: string;
87
+ context: string;
88
+ decision: string;
89
+ consequences: string;
90
+ alternatives?: string[];
91
+ evidence?: string[];
92
+ }, templateFormat?: 'nygard' | 'madr' | 'custom', existingAdrs?: string[]): Promise<{
93
+ generationPrompt: string;
94
+ instructions: string;
95
+ }>;
96
+ /**
97
+ * Generate next ADR number based on existing ADRs
98
+ */
99
+ export declare function generateNextAdrNumber(existingAdrs: string[]): string;
100
+ /**
101
+ * Suggest ADR filename based on title and number
102
+ */
103
+ export declare function suggestAdrFilename(title: string, adrNumber?: string): string;
104
+ //# sourceMappingURL=adr-suggestions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adr-suggestions.d.ts","sourceRoot":"","sources":["../../../src/utils/adr-suggestions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,228 @@
1
+ /**
2
+ * ADR suggestion utilities using prompt-driven AI analysis
3
+ * Implements intelligent ADR recommendations based on code analysis
4
+ */
5
+ import { McpAdrError } from '../types/index.js';
6
+ /**
7
+ * Analyze project for implicit architectural decisions
8
+ */
9
+ export async function analyzeImplicitDecisions(projectPath, existingAdrs) {
10
+ try {
11
+ const { analyzeProjectStructure } = await import('./file-system.js');
12
+ const { generateAnalysisContext } = await import('../prompts/analysis-prompts.js');
13
+ const { generateImplicitDecisionDetectionPrompt } = await import('../prompts/adr-suggestion-prompts.js');
14
+ // Analyze project structure
15
+ const projectStructure = await analyzeProjectStructure(projectPath);
16
+ const analysisContext = generateAnalysisContext(projectStructure);
17
+ // Extract code patterns from project structure
18
+ const codePatterns = extractCodePatterns(projectStructure);
19
+ const analysisPrompt = generateImplicitDecisionDetectionPrompt(analysisContext, codePatterns, existingAdrs);
20
+ const instructions = `
21
+ # Implicit Decision Analysis Instructions
22
+
23
+ This analysis will identify architectural decisions that are implicit in the codebase but not formally documented.
24
+
25
+ ## Analysis Scope
26
+ - **Project Path**: ${projectPath}
27
+ - **Files Analyzed**: ${projectStructure.totalFiles} files
28
+ - **Directories**: ${projectStructure.totalDirectories} directories
29
+ - **Existing ADRs**: ${existingAdrs?.length || 0} ADRs
30
+
31
+ ## Next Steps
32
+ 1. **Submit the analysis prompt** to an AI agent for decision detection
33
+ 2. **Parse the JSON response** as ImplicitDecisionAnalysis
34
+ 3. **Review suggested decisions** and prioritize for documentation
35
+ 4. **Generate ADRs** for high-priority decisions using the ADR generation tool
36
+
37
+ ## Expected AI Response Format
38
+ The AI will return a JSON object with:
39
+ - \`implicitDecisions\`: Array of detected implicit decisions
40
+ - \`decisionClusters\`: Related decisions that could be combined
41
+ - \`recommendations\`: Specific recommendations for documentation
42
+ - \`gaps\`: Areas where more investigation is needed
43
+
44
+ ## Usage Example
45
+ \`\`\`typescript
46
+ const result = await analyzeImplicitDecisions(projectPath, existingAdrs);
47
+ // Submit result.analysisPrompt to AI agent
48
+ // Parse AI response as ImplicitDecisionAnalysis
49
+ \`\`\`
50
+ `;
51
+ return {
52
+ analysisPrompt,
53
+ instructions,
54
+ };
55
+ }
56
+ catch (error) {
57
+ throw new McpAdrError(`Failed to analyze implicit decisions: ${error instanceof Error ? error.message : String(error)}`, 'ANALYSIS_ERROR');
58
+ }
59
+ }
60
+ /**
61
+ * Analyze code changes for architectural decisions
62
+ */
63
+ export async function analyzeCodeChanges(beforeCode, afterCode, changeDescription, commitMessages) {
64
+ try {
65
+ const { generateCodeChangeAnalysisPrompt } = await import('../prompts/adr-suggestion-prompts.js');
66
+ const analysisPrompt = generateCodeChangeAnalysisPrompt(beforeCode, afterCode, changeDescription, commitMessages);
67
+ const instructions = `
68
+ # Code Change Analysis Instructions
69
+
70
+ This analysis will identify architectural decisions reflected in code changes.
71
+
72
+ ## Change Analysis
73
+ - **Change Description**: ${changeDescription}
74
+ - **Before Code Length**: ${beforeCode.length} characters
75
+ - **After Code Length**: ${afterCode.length} characters
76
+ - **Commit Messages**: ${commitMessages?.length || 0} messages
77
+
78
+ ## Next Steps
79
+ 1. **Submit the analysis prompt** to an AI agent for decision detection
80
+ 2. **Parse the JSON response** to get identified decisions
81
+ 3. **Review change motivations** and architectural implications
82
+ 4. **Document significant decisions** as ADRs
83
+
84
+ ## Expected AI Response Format
85
+ The AI will return a JSON object with:
86
+ - \`changeAnalysis\`: Overall analysis of the change
87
+ - \`identifiedDecisions\`: Specific decisions reflected in changes
88
+ - \`recommendations\`: Documentation recommendations
89
+ - \`followUpQuestions\`: Questions for the development team
90
+
91
+ ## Usage Example
92
+ \`\`\`typescript
93
+ const result = await analyzeCodeChanges(before, after, description, commits);
94
+ // Submit result.analysisPrompt to AI agent
95
+ // Parse AI response for architectural decisions
96
+ \`\`\`
97
+ `;
98
+ return {
99
+ analysisPrompt,
100
+ instructions,
101
+ };
102
+ }
103
+ catch (error) {
104
+ throw new McpAdrError(`Failed to analyze code changes: ${error instanceof Error ? error.message : String(error)}`, 'ANALYSIS_ERROR');
105
+ }
106
+ }
107
+ /**
108
+ * Generate ADR from decision data
109
+ */
110
+ export async function generateAdrFromDecision(decisionData, templateFormat = 'nygard', existingAdrs) {
111
+ try {
112
+ const { generateAdrTemplatePrompt } = await import('../prompts/adr-suggestion-prompts.js');
113
+ const generationPrompt = generateAdrTemplatePrompt(decisionData, templateFormat, existingAdrs);
114
+ const instructions = `
115
+ # ADR Generation Instructions
116
+
117
+ This will generate a complete Architectural Decision Record from the provided decision data.
118
+
119
+ ## Decision Summary
120
+ - **Title**: ${decisionData.title}
121
+ - **Template Format**: ${templateFormat.toUpperCase()}
122
+ - **Alternatives**: ${decisionData.alternatives?.length || 0} considered
123
+ - **Evidence**: ${decisionData.evidence?.length || 0} pieces
124
+
125
+ ## Next Steps
126
+ 1. **Submit the generation prompt** to an AI agent for ADR creation
127
+ 2. **Parse the JSON response** to get the complete ADR
128
+ 3. **Review the generated content** for quality and completeness
129
+ 4. **Save the ADR** to the appropriate location with suggested filename
130
+
131
+ ## Expected AI Response Format
132
+ The AI will return a JSON object with:
133
+ - \`adr\`: Complete ADR with content, metadata, and filename
134
+ - \`suggestions\`: Placement, numbering, and review suggestions
135
+ - \`qualityChecks\`: Quality assessment and improvement suggestions
136
+
137
+ ## Usage Example
138
+ \`\`\`typescript
139
+ const result = await generateAdrFromDecision(decisionData, 'nygard', existingAdrs);
140
+ // Submit result.generationPrompt to AI agent
141
+ // Parse AI response as GeneratedAdr
142
+ \`\`\`
143
+ `;
144
+ return {
145
+ generationPrompt,
146
+ instructions,
147
+ };
148
+ }
149
+ catch (error) {
150
+ throw new McpAdrError(`Failed to generate ADR: ${error instanceof Error ? error.message : String(error)}`, 'GENERATION_ERROR');
151
+ }
152
+ }
153
+ /**
154
+ * Extract code patterns from project structure for analysis
155
+ */
156
+ function extractCodePatterns(projectStructure) {
157
+ const patterns = [];
158
+ try {
159
+ // Extract patterns from file structure
160
+ if (projectStructure.filesByType) {
161
+ Object.entries(projectStructure.filesByType).forEach(([type, files]) => {
162
+ if (Array.isArray(files) && files.length > 0) {
163
+ patterns.push(`${type} files: ${files
164
+ .slice(0, 5)
165
+ .map((f) => f.name || f)
166
+ .join(', ')}${files.length > 5 ? ` and ${files.length - 5} more` : ''}`);
167
+ }
168
+ });
169
+ }
170
+ // Extract patterns from directory structure
171
+ if (projectStructure.directories) {
172
+ const dirNames = projectStructure.directories.slice(0, 10).join(', ');
173
+ patterns.push(`Directory structure: ${dirNames}${projectStructure.directories.length > 10 ? ` and ${projectStructure.directories.length - 10} more` : ''}`);
174
+ }
175
+ // Extract patterns from detected technologies
176
+ if (projectStructure.detectedTechnologies) {
177
+ patterns.push(`Technologies: ${projectStructure.detectedTechnologies.join(', ')}`);
178
+ }
179
+ // Add basic project metrics
180
+ patterns.push(`Project metrics: ${projectStructure.totalFiles} files, ${projectStructure.totalDirectories} directories`);
181
+ return patterns;
182
+ }
183
+ catch (error) {
184
+ console.warn('Failed to extract code patterns:', error);
185
+ return ['Unable to extract code patterns from project structure'];
186
+ }
187
+ }
188
+ /**
189
+ * Generate next ADR number based on existing ADRs
190
+ */
191
+ export function generateNextAdrNumber(existingAdrs) {
192
+ try {
193
+ // Extract numbers from existing ADR filenames/titles
194
+ const numbers = existingAdrs
195
+ .map(adr => {
196
+ const match = adr.match(/ADR[-_]?(\d+)/i) || adr.match(/(\d+)/);
197
+ return match && match[1] ? parseInt(match[1], 10) : 0;
198
+ })
199
+ .filter(num => num > 0);
200
+ const maxNumber = numbers.length > 0 ? Math.max(...numbers) : 0;
201
+ const nextNumber = maxNumber + 1;
202
+ return `ADR-${nextNumber.toString().padStart(4, '0')}`;
203
+ }
204
+ catch (error) {
205
+ console.warn('Failed to generate ADR number:', error);
206
+ return 'ADR-0001';
207
+ }
208
+ }
209
+ /**
210
+ * Suggest ADR filename based on title and number
211
+ */
212
+ export function suggestAdrFilename(title, adrNumber) {
213
+ try {
214
+ const number = adrNumber || 'XXXX';
215
+ const cleanTitle = title
216
+ .toLowerCase()
217
+ .replace(/[^a-z0-9\s-]/g, '')
218
+ .replace(/\s+/g, '-')
219
+ .replace(/-+/g, '-')
220
+ .replace(/^-|-$/g, '');
221
+ return `${number.toLowerCase()}-${cleanTitle}.md`;
222
+ }
223
+ catch (error) {
224
+ console.warn('Failed to suggest filename:', error);
225
+ return 'adr-new-decision.md';
226
+ }
227
+ }
228
+ //# sourceMappingURL=adr-suggestions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adr-suggestions.js","sourceRoot":"","sources":["../../../src/utils/adr-suggestions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAsEhD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,WAAmB,EACnB,YAAuB;IAEvB,IAAI,CAAC;QACH,MAAM,EAAE,uBAAuB,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QACrE,MAAM,EAAE,uBAAuB,EAAE,GAAG,MAAM,MAAM,CAAC,gCAAgC,CAAC,CAAC;QACnF,MAAM,EAAE,uCAAuC,EAAE,GAAG,MAAM,MAAM,CAC9D,sCAAsC,CACvC,CAAC;QAEF,4BAA4B;QAC5B,MAAM,gBAAgB,GAAG,MAAM,uBAAuB,CAAC,WAAW,CAAC,CAAC;QACpE,MAAM,eAAe,GAAG,uBAAuB,CAAC,gBAAgB,CAAC,CAAC;QAElE,+CAA+C;QAC/C,MAAM,YAAY,GAAG,mBAAmB,CAAC,gBAAgB,CAAC,CAAC;QAE3D,MAAM,cAAc,GAAG,uCAAuC,CAC5D,eAAe,EACf,YAAY,EACZ,YAAY,CACb,CAAC;QAEF,MAAM,YAAY,GAAG;;;;;;sBAMH,WAAW;wBACT,gBAAgB,CAAC,UAAU;qBAC9B,gBAAgB,CAAC,gBAAgB;uBAC/B,YAAY,EAAE,MAAM,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;CAqB/C,CAAC;QAEE,OAAO;YACL,cAAc;YACd,YAAY;SACb,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,WAAW,CACnB,yCAAyC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EACjG,gBAAgB,CACjB,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,UAAkB,EAClB,SAAiB,EACjB,iBAAyB,EACzB,cAAyB;IAEzB,IAAI,CAAC;QACH,MAAM,EAAE,gCAAgC,EAAE,GAAG,MAAM,MAAM,CACvD,sCAAsC,CACvC,CAAC;QAEF,MAAM,cAAc,GAAG,gCAAgC,CACrD,UAAU,EACV,SAAS,EACT,iBAAiB,EACjB,cAAc,CACf,CAAC;QAEF,MAAM,YAAY,GAAG;;;;;;4BAMG,iBAAiB;4BACjB,UAAU,CAAC,MAAM;2BAClB,SAAS,CAAC,MAAM;yBAClB,cAAc,EAAE,MAAM,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;CAqBnD,CAAC;QAEE,OAAO;YACL,cAAc;YACd,YAAY;SACb,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,WAAW,CACnB,mCAAmC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAC3F,gBAAgB,CACjB,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,YAOC,EACD,iBAA+C,QAAQ,EACvD,YAAuB;IAEvB,IAAI,CAAC;QACH,MAAM,EAAE,yBAAyB,EAAE,GAAG,MAAM,MAAM,CAAC,sCAAsC,CAAC,CAAC;QAE3F,MAAM,gBAAgB,GAAG,yBAAyB,CAAC,YAAY,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;QAE/F,MAAM,YAAY,GAAG;;;;;;eAMV,YAAY,CAAC,KAAK;yBACR,cAAc,CAAC,WAAW,EAAE;sBAC/B,YAAY,CAAC,YAAY,EAAE,MAAM,IAAI,CAAC;kBAC1C,YAAY,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;CAoBnD,CAAC;QAEE,OAAO;YACL,gBAAgB;YAChB,YAAY;SACb,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,WAAW,CACnB,2BAA2B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EACnF,kBAAkB,CACnB,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAAC,gBAAqB;IAChD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,IAAI,CAAC;QACH,uCAAuC;QACvC,IAAI,gBAAgB,CAAC,WAAW,EAAE,CAAC;YACjC,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAgB,EAAE,EAAE;gBACpF,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC7C,QAAQ,CAAC,IAAI,CACX,GAAG,IAAI,WAAW,KAAK;yBACpB,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;yBACX,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC;yBAC5B,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAC1E,CAAC;gBACJ,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAED,4CAA4C;QAC5C,IAAI,gBAAgB,CAAC,WAAW,EAAE,CAAC;YACjC,MAAM,QAAQ,GAAG,gBAAgB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtE,QAAQ,CAAC,IAAI,CACX,wBAAwB,QAAQ,GAAG,gBAAgB,CAAC,WAAW,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,QAAQ,gBAAgB,CAAC,WAAW,CAAC,MAAM,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAC7I,CAAC;QACJ,CAAC;QAED,8CAA8C;QAC9C,IAAI,gBAAgB,CAAC,oBAAoB,EAAE,CAAC;YAC1C,QAAQ,CAAC,IAAI,CAAC,iBAAiB,gBAAgB,CAAC,oBAAoB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrF,CAAC;QAED,4BAA4B;QAC5B,QAAQ,CAAC,IAAI,CACX,oBAAoB,gBAAgB,CAAC,UAAU,WAAW,gBAAgB,CAAC,gBAAgB,cAAc,CAC1G,CAAC;QAEF,OAAO,QAAQ,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAC;QACxD,OAAO,CAAC,wDAAwD,CAAC,CAAC;IACpE,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,YAAsB;IAC1D,IAAI,CAAC;QACH,qDAAqD;QACrD,MAAM,OAAO,GAAG,YAAY;aACzB,GAAG,CAAC,GAAG,CAAC,EAAE;YACT,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAChE,OAAO,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACxD,CAAC,CAAC;aACD,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QAE1B,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAChE,MAAM,UAAU,GAAG,SAAS,GAAG,CAAC,CAAC;QAEjC,OAAO,OAAO,UAAU,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;IACzD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;QACtD,OAAO,UAAU,CAAC;IACpB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAa,EAAE,SAAkB;IAClE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,SAAS,IAAI,MAAM,CAAC;QACnC,MAAM,UAAU,GAAG,KAAK;aACrB,WAAW,EAAE;aACb,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC;aAC5B,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;aACpB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;aACnB,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;QAEzB,OAAO,GAAG,MAAM,CAAC,WAAW,EAAE,IAAI,UAAU,KAAK,CAAC;IACpD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;QACnD,OAAO,qBAAqB,CAAC;IAC/B,CAAC;AACH,CAAC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Caching system for MCP resources and expensive operations
3
+ * Implements file-based caching with TTL and invalidation
4
+ */
5
+ export interface CacheOptions {
6
+ ttl?: number;
7
+ invalidateOnChange?: boolean;
8
+ compression?: boolean;
9
+ }
10
+ /**
11
+ * Initialize cache directory
12
+ */
13
+ export declare function initializeCache(): Promise<void>;
14
+ /**
15
+ * Store data in cache
16
+ */
17
+ export declare function setCache<T>(key: string, data: T, options?: CacheOptions): Promise<void>;
18
+ /**
19
+ * Retrieve data from cache
20
+ */
21
+ export declare function getCache<T>(key: string): Promise<T | null>;
22
+ /**
23
+ * Check if cache entry exists and is valid
24
+ */
25
+ export declare function hasValidCache(key: string): Promise<boolean>;
26
+ /**
27
+ * Invalidate specific cache entry
28
+ */
29
+ export declare function invalidateCache(key: string): Promise<void>;
30
+ /**
31
+ * Clear all cache entries
32
+ */
33
+ export declare function clearCache(): Promise<void>;
34
+ /**
35
+ * Get cache statistics
36
+ */
37
+ export declare function getCacheStats(): Promise<{
38
+ totalEntries: number;
39
+ totalSize: number;
40
+ oldestEntry: string | null;
41
+ newestEntry: string | null;
42
+ }>;
43
+ /**
44
+ * Cleanup expired cache entries
45
+ */
46
+ export declare function cleanupCache(): Promise<number>;
47
+ /**
48
+ * Get or set cache with automatic management
49
+ */
50
+ export declare function getCachedOrGenerate<T>(key: string, generator: () => Promise<T>, options?: CacheOptions): Promise<T>;
51
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../src/utils/cache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAsBrD;AAWD;;GAEG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBjG;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CA8BhE;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOjE;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOhE;AAED;;GAEG;AACH,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAehD;AAED;;GAEG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC;IAC7C,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC,CA6CD;AAED;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAsDpD;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,EACzC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,CAAC,CAAC,CAqBZ"}
@@ -0,0 +1,243 @@
1
+ /**
2
+ * Caching system for MCP resources and expensive operations
3
+ * Implements file-based caching with TTL and invalidation
4
+ */
5
+ import { promises as fs } from 'fs';
6
+ import { join } from 'path';
7
+ import { McpAdrError } from '../types/index.js';
8
+ const CACHE_DIR = '.mcp-adr-cache';
9
+ /**
10
+ * Initialize cache directory
11
+ */
12
+ export async function initializeCache() {
13
+ try {
14
+ await fs.mkdir(CACHE_DIR, { recursive: true });
15
+ // Create cache metadata file
16
+ const metadataPath = join(CACHE_DIR, 'metadata.json');
17
+ try {
18
+ await fs.access(metadataPath);
19
+ }
20
+ catch {
21
+ const metadata = {
22
+ version: '1.0.0',
23
+ created: new Date().toISOString(),
24
+ lastCleanup: new Date().toISOString(),
25
+ };
26
+ await fs.writeFile(metadataPath, JSON.stringify(metadata, null, 2));
27
+ }
28
+ }
29
+ catch (error) {
30
+ throw new McpAdrError(`Failed to initialize cache: ${error instanceof Error ? error.message : String(error)}`, 'CACHE_ERROR');
31
+ }
32
+ }
33
+ /**
34
+ * Generate cache file path from key
35
+ */
36
+ function getCacheFilePath(key) {
37
+ // Create safe filename from cache key
38
+ const safeKey = key.replace(/[^a-zA-Z0-9-_]/g, '_');
39
+ return join(CACHE_DIR, `${safeKey}.json`);
40
+ }
41
+ /**
42
+ * Store data in cache
43
+ */
44
+ export async function setCache(key, data, options = {}) {
45
+ try {
46
+ await initializeCache();
47
+ const cacheEntry = {
48
+ key,
49
+ data,
50
+ timestamp: new Date().toISOString(),
51
+ ttl: options.ttl || 3600, // Default 1 hour
52
+ metadata: {
53
+ version: '1.0.0',
54
+ compressed: options.compression || false,
55
+ },
56
+ };
57
+ const filePath = getCacheFilePath(key);
58
+ await fs.writeFile(filePath, JSON.stringify(cacheEntry, null, 2));
59
+ }
60
+ catch (error) {
61
+ throw new McpAdrError(`Failed to set cache: ${error instanceof Error ? error.message : String(error)}`, 'CACHE_ERROR');
62
+ }
63
+ }
64
+ /**
65
+ * Retrieve data from cache
66
+ */
67
+ export async function getCache(key) {
68
+ try {
69
+ const filePath = getCacheFilePath(key);
70
+ try {
71
+ const content = await fs.readFile(filePath, 'utf-8');
72
+ const cacheEntry = JSON.parse(content);
73
+ // Check if cache entry is expired
74
+ const now = new Date();
75
+ const cacheTime = new Date(cacheEntry.timestamp);
76
+ const ageInSeconds = (now.getTime() - cacheTime.getTime()) / 1000;
77
+ if (ageInSeconds > cacheEntry.ttl) {
78
+ // Cache expired, remove it
79
+ await fs.unlink(filePath);
80
+ return null;
81
+ }
82
+ return cacheEntry.data;
83
+ }
84
+ catch (error) {
85
+ // Cache file doesn't exist or is corrupted
86
+ return null;
87
+ }
88
+ }
89
+ catch (error) {
90
+ throw new McpAdrError(`Failed to get cache: ${error instanceof Error ? error.message : String(error)}`, 'CACHE_ERROR');
91
+ }
92
+ }
93
+ /**
94
+ * Check if cache entry exists and is valid
95
+ */
96
+ export async function hasValidCache(key) {
97
+ try {
98
+ const data = await getCache(key);
99
+ return data !== null;
100
+ }
101
+ catch {
102
+ return false;
103
+ }
104
+ }
105
+ /**
106
+ * Invalidate specific cache entry
107
+ */
108
+ export async function invalidateCache(key) {
109
+ try {
110
+ const filePath = getCacheFilePath(key);
111
+ await fs.unlink(filePath);
112
+ }
113
+ catch {
114
+ // File doesn't exist, which is fine
115
+ }
116
+ }
117
+ /**
118
+ * Clear all cache entries
119
+ */
120
+ export async function clearCache() {
121
+ try {
122
+ const files = await fs.readdir(CACHE_DIR);
123
+ for (const file of files) {
124
+ if (file.endsWith('.json') && file !== 'metadata.json') {
125
+ await fs.unlink(join(CACHE_DIR, file));
126
+ }
127
+ }
128
+ }
129
+ catch (error) {
130
+ throw new McpAdrError(`Failed to clear cache: ${error instanceof Error ? error.message : String(error)}`, 'CACHE_ERROR');
131
+ }
132
+ }
133
+ /**
134
+ * Get cache statistics
135
+ */
136
+ export async function getCacheStats() {
137
+ try {
138
+ await initializeCache();
139
+ const files = await fs.readdir(CACHE_DIR);
140
+ const cacheFiles = files.filter(f => f.endsWith('.json') && f !== 'metadata.json');
141
+ let totalSize = 0;
142
+ let oldestTime = Infinity;
143
+ let newestTime = 0;
144
+ let oldestEntry = null;
145
+ let newestEntry = null;
146
+ for (const file of cacheFiles) {
147
+ const filePath = join(CACHE_DIR, file);
148
+ const stats = await fs.stat(filePath);
149
+ totalSize += stats.size;
150
+ const content = await fs.readFile(filePath, 'utf-8');
151
+ const cacheEntry = JSON.parse(content);
152
+ const entryTime = new Date(cacheEntry.timestamp).getTime();
153
+ if (entryTime < oldestTime) {
154
+ oldestTime = entryTime;
155
+ oldestEntry = cacheEntry.key;
156
+ }
157
+ if (entryTime > newestTime) {
158
+ newestTime = entryTime;
159
+ newestEntry = cacheEntry.key;
160
+ }
161
+ }
162
+ return {
163
+ totalEntries: cacheFiles.length,
164
+ totalSize,
165
+ oldestEntry,
166
+ newestEntry,
167
+ };
168
+ }
169
+ catch (error) {
170
+ throw new McpAdrError(`Failed to get cache stats: ${error instanceof Error ? error.message : String(error)}`, 'CACHE_ERROR');
171
+ }
172
+ }
173
+ /**
174
+ * Cleanup expired cache entries
175
+ */
176
+ export async function cleanupCache() {
177
+ try {
178
+ await initializeCache();
179
+ const files = await fs.readdir(CACHE_DIR);
180
+ const cacheFiles = files.filter(f => f.endsWith('.json') && f !== 'metadata.json');
181
+ let cleanedCount = 0;
182
+ const now = new Date();
183
+ for (const file of cacheFiles) {
184
+ const filePath = join(CACHE_DIR, file);
185
+ try {
186
+ const content = await fs.readFile(filePath, 'utf-8');
187
+ const cacheEntry = JSON.parse(content);
188
+ const cacheTime = new Date(cacheEntry.timestamp);
189
+ const ageInSeconds = (now.getTime() - cacheTime.getTime()) / 1000;
190
+ if (ageInSeconds > cacheEntry.ttl) {
191
+ await fs.unlink(filePath);
192
+ cleanedCount++;
193
+ }
194
+ }
195
+ catch {
196
+ // Corrupted cache file, remove it
197
+ await fs.unlink(filePath);
198
+ cleanedCount++;
199
+ }
200
+ }
201
+ // Update metadata
202
+ const metadataPath = join(CACHE_DIR, 'metadata.json');
203
+ try {
204
+ const metadata = JSON.parse(await fs.readFile(metadataPath, 'utf-8'));
205
+ metadata.lastCleanup = now.toISOString();
206
+ await fs.writeFile(metadataPath, JSON.stringify(metadata, null, 2));
207
+ }
208
+ catch {
209
+ // Metadata file corrupted, recreate it
210
+ const metadata = {
211
+ version: '1.0.0',
212
+ created: now.toISOString(),
213
+ lastCleanup: now.toISOString(),
214
+ };
215
+ await fs.writeFile(metadataPath, JSON.stringify(metadata, null, 2));
216
+ }
217
+ return cleanedCount;
218
+ }
219
+ catch (error) {
220
+ throw new McpAdrError(`Failed to cleanup cache: ${error instanceof Error ? error.message : String(error)}`, 'CACHE_ERROR');
221
+ }
222
+ }
223
+ /**
224
+ * Get or set cache with automatic management
225
+ */
226
+ export async function getCachedOrGenerate(key, generator, options = {}) {
227
+ try {
228
+ // Try to get from cache first
229
+ const cached = await getCache(key);
230
+ if (cached !== null) {
231
+ return cached;
232
+ }
233
+ // Generate new data
234
+ const data = await generator();
235
+ // Store in cache
236
+ await setCache(key, data, options);
237
+ return data;
238
+ }
239
+ catch (error) {
240
+ throw new McpAdrError(`Failed to get cached or generate: ${error instanceof Error ? error.message : String(error)}`, 'CACHE_ERROR');
241
+ }
242
+ }
243
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../../src/utils/cache.ts"],"names":[],"mappings":"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"}