@utaba/ucm-mcp-server 1.0.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/LICENSE +29 -0
- package/README.md +79 -0
- package/dist/clients/UcmApiClient.d.ts +53 -0
- package/dist/clients/UcmApiClient.js +297 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +68 -0
- package/dist/interfaces/ILogger.d.ts +8 -0
- package/dist/interfaces/ILogger.js +4 -0
- package/dist/interfaces/IMcpTool.d.ts +7 -0
- package/dist/interfaces/IMcpTool.js +3 -0
- package/dist/logging/ConsoleLogger.d.ts +16 -0
- package/dist/logging/ConsoleLogger.js +45 -0
- package/dist/logging/LoggerFactory.d.ts +9 -0
- package/dist/logging/LoggerFactory.js +12 -0
- package/dist/server/McpConfig.d.ts +26 -0
- package/dist/server/McpConfig.js +93 -0
- package/dist/server/McpHandler.d.ts +12 -0
- package/dist/server/McpHandler.js +69 -0
- package/dist/server/McpServer.d.ts +15 -0
- package/dist/server/McpServer.js +49 -0
- package/dist/server/ToolRegistry.d.ts +22 -0
- package/dist/server/ToolRegistry.js +85 -0
- package/dist/tools/artifacts/GetArtifactController.d.ts +34 -0
- package/dist/tools/artifacts/GetArtifactController.js +397 -0
- package/dist/tools/artifacts/GetLatestController.d.ts +39 -0
- package/dist/tools/artifacts/GetLatestController.js +469 -0
- package/dist/tools/artifacts/ListVersionsController.d.ts +43 -0
- package/dist/tools/artifacts/ListVersionsController.js +530 -0
- package/dist/tools/artifacts/PublishArtifactController.d.ts +37 -0
- package/dist/tools/artifacts/PublishArtifactController.js +605 -0
- package/dist/tools/base/BaseToolController.d.ts +16 -0
- package/dist/tools/base/BaseToolController.js +32 -0
- package/dist/tools/core/DeleteArtifactTool.d.ts +11 -0
- package/dist/tools/core/DeleteArtifactTool.js +82 -0
- package/dist/tools/core/GetArtifactTool.d.ts +13 -0
- package/dist/tools/core/GetArtifactTool.js +125 -0
- package/dist/tools/core/GetArtifactVersionsTool.d.ts +11 -0
- package/dist/tools/core/GetArtifactVersionsTool.js +63 -0
- package/dist/tools/core/GetChunkTool.d.ts +11 -0
- package/dist/tools/core/GetChunkTool.js +56 -0
- package/dist/tools/core/ListArtifactsTool.d.ts +11 -0
- package/dist/tools/core/ListArtifactsTool.js +84 -0
- package/dist/tools/core/PublishArtifactFromFileTool.d.ts +15 -0
- package/dist/tools/core/PublishArtifactFromFileTool.js +256 -0
- package/dist/tools/core/PublishArtifactTool.d.ts +13 -0
- package/dist/tools/core/PublishArtifactTool.js +197 -0
- package/dist/tools/discovery/BrowseCategoriesController.d.ts +25 -0
- package/dist/tools/discovery/BrowseCategoriesController.js +400 -0
- package/dist/tools/discovery/FindByPurposeController.d.ts +12 -0
- package/dist/tools/discovery/FindByPurposeController.js +131 -0
- package/dist/tools/discovery/ListAuthorsController.d.ts +20 -0
- package/dist/tools/discovery/ListAuthorsController.js +274 -0
- package/dist/tools/discovery/SearchArtifactsController.d.ts +14 -0
- package/dist/tools/discovery/SearchArtifactsController.js +226 -0
- package/dist/tools/list/ListNamespaceController.d.ts +1 -0
- package/dist/tools/list/ListNamespaceController.js +8 -0
- package/dist/tools/navigation/ExploreNamespaceController.d.ts +35 -0
- package/dist/tools/navigation/ExploreNamespaceController.js +548 -0
- package/dist/tools/utility/AuthorIndexTool.d.ts +11 -0
- package/dist/tools/utility/AuthorIndexTool.js +48 -0
- package/dist/tools/utility/HealthCheckController.d.ts +11 -0
- package/dist/tools/utility/HealthCheckController.js +56 -0
- package/dist/tools/utility/ListRepositoriesTool.d.ts +11 -0
- package/dist/tools/utility/ListRepositoriesTool.js +70 -0
- package/dist/tools/utility/QuickstartTool.d.ts +11 -0
- package/dist/tools/utility/QuickstartTool.js +36 -0
- package/dist/tools/utility/ValidatePathController.d.ts +30 -0
- package/dist/tools/utility/ValidatePathController.js +465 -0
- package/dist/types/UcmApiTypes.d.ts +40 -0
- package/dist/types/UcmApiTypes.js +4 -0
- package/dist/utils/McpErrorHandler.d.ts +25 -0
- package/dist/utils/McpErrorHandler.js +67 -0
- package/dist/utils/PathUtils.d.ts +61 -0
- package/dist/utils/PathUtils.js +178 -0
- package/dist/utils/ResponseChunker.d.ts +25 -0
- package/dist/utils/ResponseChunker.js +79 -0
- package/dist/utils/ValidationUtils.d.ts +10 -0
- package/dist/utils/ValidationUtils.js +50 -0
- package/package.json +37 -0
- package/package.json.backup +37 -0
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
import { BaseToolController } from '../base/BaseToolController.js';
|
|
2
|
+
import { parsePath } from '../../utils/PathUtils.js';
|
|
3
|
+
export class GetLatestController extends BaseToolController {
|
|
4
|
+
constructor(ucmClient, logger) {
|
|
5
|
+
super(ucmClient, logger);
|
|
6
|
+
}
|
|
7
|
+
get name() {
|
|
8
|
+
return 'mcp_ucm_get_latest';
|
|
9
|
+
}
|
|
10
|
+
get description() {
|
|
11
|
+
return 'Get the latest version of a UCM artifact with optional comparison to previous versions';
|
|
12
|
+
}
|
|
13
|
+
get inputSchema() {
|
|
14
|
+
return {
|
|
15
|
+
type: 'object',
|
|
16
|
+
properties: {
|
|
17
|
+
artifactPath: {
|
|
18
|
+
type: 'string',
|
|
19
|
+
description: 'Artifact path without version (e.g., "utaba/commands/create-user/typescript" or "utaba/commands/create-user")',
|
|
20
|
+
minLength: 5,
|
|
21
|
+
maxLength: 150
|
|
22
|
+
},
|
|
23
|
+
includeContent: {
|
|
24
|
+
type: 'boolean',
|
|
25
|
+
default: false,
|
|
26
|
+
description: 'Include the artifact source content'
|
|
27
|
+
},
|
|
28
|
+
includeMetadata: {
|
|
29
|
+
type: 'boolean',
|
|
30
|
+
default: true,
|
|
31
|
+
description: 'Include artifact metadata'
|
|
32
|
+
},
|
|
33
|
+
includeVersionComparison: {
|
|
34
|
+
type: 'boolean',
|
|
35
|
+
default: false,
|
|
36
|
+
description: 'Include comparison with previous version'
|
|
37
|
+
},
|
|
38
|
+
includeChangeLog: {
|
|
39
|
+
type: 'boolean',
|
|
40
|
+
default: false,
|
|
41
|
+
description: 'Include change log if available'
|
|
42
|
+
},
|
|
43
|
+
fallbackToPrevious: {
|
|
44
|
+
type: 'boolean',
|
|
45
|
+
default: false,
|
|
46
|
+
description: 'If latest is unavailable, return the most recent available version'
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
required: ['artifactPath']
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
async handleExecute(params) {
|
|
53
|
+
const { artifactPath, includeContent = false, includeMetadata = true, includeVersionComparison = false, includeChangeLog = false, fallbackToPrevious = false } = params;
|
|
54
|
+
// Validate the artifact path (should not include version)
|
|
55
|
+
this.validateBasePath(artifactPath);
|
|
56
|
+
this.logger.debug('GetLatestController', `Getting latest version for: ${artifactPath}`);
|
|
57
|
+
try {
|
|
58
|
+
// Try to get the latest version directly
|
|
59
|
+
let latestArtifact;
|
|
60
|
+
let isLatest = true;
|
|
61
|
+
try {
|
|
62
|
+
const parsed = parsePath(artifactPath);
|
|
63
|
+
if (!parsed.filename) {
|
|
64
|
+
throw new Error('Filename is required to get latest artifact');
|
|
65
|
+
}
|
|
66
|
+
latestArtifact = await this.ucmClient.getLatestArtifact(parsed.author, parsed.category, parsed.subcategory, parsed.filename);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
if (fallbackToPrevious) {
|
|
70
|
+
// If latest not found, try to get all versions and pick the most recent
|
|
71
|
+
this.logger.info('GetLatestController', 'Latest not found, falling back to most recent version');
|
|
72
|
+
latestArtifact = await this.getMostRecentVersion(artifactPath);
|
|
73
|
+
isLatest = false;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (!latestArtifact) {
|
|
80
|
+
throw new Error(`No versions found for artifact path: ${artifactPath}`);
|
|
81
|
+
}
|
|
82
|
+
// Build the response
|
|
83
|
+
const response = await this.buildLatestResponse(latestArtifact, {
|
|
84
|
+
artifactPath,
|
|
85
|
+
includeContent,
|
|
86
|
+
includeMetadata,
|
|
87
|
+
includeVersionComparison,
|
|
88
|
+
includeChangeLog,
|
|
89
|
+
isLatest
|
|
90
|
+
});
|
|
91
|
+
this.logger.info('GetLatestController', `Successfully retrieved latest version: ${latestArtifact.metadata?.version || 'unknown'}`);
|
|
92
|
+
return response;
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
this.logger.error('GetLatestController', `Failed to get latest version for: ${artifactPath}`, '', error);
|
|
96
|
+
throw error;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
validateBasePath(path) {
|
|
100
|
+
// Ensure path doesn't end with a version number
|
|
101
|
+
const pathParts = path.split('/');
|
|
102
|
+
const lastPart = pathParts[pathParts.length - 1];
|
|
103
|
+
// Check if last part looks like a version (e.g., "1.0.0")
|
|
104
|
+
if (lastPart.match(/^[0-9]+\.[0-9]+\.[0-9]+/)) {
|
|
105
|
+
throw this.formatError(new Error('Artifact path should not include version number. Use the base path instead.'));
|
|
106
|
+
}
|
|
107
|
+
// Basic path validation
|
|
108
|
+
if (pathParts.length < 3) {
|
|
109
|
+
throw this.formatError(new Error('Artifact path must include at least author/category/subcategory'));
|
|
110
|
+
}
|
|
111
|
+
// Validate path components
|
|
112
|
+
for (const part of pathParts) {
|
|
113
|
+
if (!part.match(/^[a-zA-Z0-9\-_]+$/)) {
|
|
114
|
+
throw this.formatError(new Error(`Invalid characters in path component: ${part}`));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async getMostRecentVersion(basePath) {
|
|
119
|
+
try {
|
|
120
|
+
const parsed = parsePath(basePath);
|
|
121
|
+
const versions = await this.ucmClient.getArtifactVersions(parsed.author, parsed.category, parsed.subcategory);
|
|
122
|
+
if (!versions || versions.length === 0) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
// Sort versions by semantic version or date
|
|
126
|
+
const sortedVersions = versions.sort((a, b) => {
|
|
127
|
+
const aVersion = a.metadata?.version || '0.0.0';
|
|
128
|
+
const bVersion = b.metadata?.version || '0.0.0';
|
|
129
|
+
// Try semantic version comparison first
|
|
130
|
+
const comparison = this.compareVersions(bVersion, aVersion);
|
|
131
|
+
if (comparison !== 0) {
|
|
132
|
+
return comparison;
|
|
133
|
+
}
|
|
134
|
+
// Fall back to date comparison
|
|
135
|
+
const aDate = new Date(a.lastUpdated || a.publishedAt || 0);
|
|
136
|
+
const bDate = new Date(b.lastUpdated || b.publishedAt || 0);
|
|
137
|
+
return bDate.getTime() - aDate.getTime();
|
|
138
|
+
});
|
|
139
|
+
return sortedVersions[0];
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
this.logger.error('GetLatestController', 'Failed to get version list', '', error);
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
async buildLatestResponse(artifact, options) {
|
|
147
|
+
const { artifactPath, includeContent, includeMetadata, includeVersionComparison, includeChangeLog, isLatest } = options;
|
|
148
|
+
const response = {
|
|
149
|
+
artifactPath,
|
|
150
|
+
latestVersion: artifact.metadata?.version || 'unknown',
|
|
151
|
+
isActualLatest: isLatest,
|
|
152
|
+
path: artifact.path,
|
|
153
|
+
lastUpdated: artifact.lastUpdated,
|
|
154
|
+
publishedAt: artifact.publishedAt
|
|
155
|
+
};
|
|
156
|
+
// Basic artifact information
|
|
157
|
+
if (artifact.metadata) {
|
|
158
|
+
response.name = artifact.metadata.name;
|
|
159
|
+
response.author = artifact.metadata.author;
|
|
160
|
+
response.category = artifact.metadata.category;
|
|
161
|
+
response.subcategory = artifact.metadata.subcategory;
|
|
162
|
+
response.technology = artifact.metadata.technology;
|
|
163
|
+
response.contractVersion = artifact.metadata.contractVersion;
|
|
164
|
+
response.description = artifact.metadata.description;
|
|
165
|
+
response.tags = artifact.metadata.tags || [];
|
|
166
|
+
}
|
|
167
|
+
// Include content if requested
|
|
168
|
+
if (includeContent && artifact.content) {
|
|
169
|
+
response.content = artifact.content;
|
|
170
|
+
response.contentType = this.detectContentType(artifact);
|
|
171
|
+
response.contentSize = artifact.content.length;
|
|
172
|
+
}
|
|
173
|
+
// Include detailed metadata if requested
|
|
174
|
+
if (includeMetadata && artifact.metadata) {
|
|
175
|
+
response.metadata = {
|
|
176
|
+
...artifact.metadata,
|
|
177
|
+
qualityScore: this.calculateQualityScore(artifact.metadata),
|
|
178
|
+
maturityLevel: this.assessMaturityLevel(artifact.metadata?.version),
|
|
179
|
+
stability: this.assessStability(artifact)
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
// Include version comparison if requested
|
|
183
|
+
if (includeVersionComparison) {
|
|
184
|
+
response.versionComparison = await this.getVersionComparison(artifactPath, artifact);
|
|
185
|
+
}
|
|
186
|
+
// Include change log if requested
|
|
187
|
+
if (includeChangeLog) {
|
|
188
|
+
response.changeLog = await this.getChangeLog(artifact);
|
|
189
|
+
}
|
|
190
|
+
// Add version status information
|
|
191
|
+
response.versionInfo = {
|
|
192
|
+
isLatest,
|
|
193
|
+
releaseType: this.determineReleaseType(artifact.metadata?.version),
|
|
194
|
+
lifecycle: this.determineLifecycleStage(artifact),
|
|
195
|
+
supportStatus: this.determineSupportStatus(artifact),
|
|
196
|
+
nextExpectedVersion: this.predictNextVersion(artifact.metadata?.version)
|
|
197
|
+
};
|
|
198
|
+
// Add usage and adoption metrics
|
|
199
|
+
response.metrics = {
|
|
200
|
+
downloadCount: this.getDownloadCount(artifact),
|
|
201
|
+
rating: this.calculateRating(artifact),
|
|
202
|
+
lastAccessedCount: this.getRecentAccessCount(),
|
|
203
|
+
trendingScore: this.calculateTrendingScore(artifact)
|
|
204
|
+
};
|
|
205
|
+
// Add recommendations
|
|
206
|
+
response.recommendations = {
|
|
207
|
+
shouldUpgrade: this.shouldRecommendUpgrade(artifact),
|
|
208
|
+
migrationRequired: this.requiresMigration(artifact),
|
|
209
|
+
deprecationWarnings: this.getDeprecationWarnings(artifact),
|
|
210
|
+
securityAlerts: this.getSecurityAlerts(artifact)
|
|
211
|
+
};
|
|
212
|
+
// Add metadata about this request
|
|
213
|
+
response.retrievalMetadata = {
|
|
214
|
+
timestamp: new Date().toISOString(),
|
|
215
|
+
requestType: 'latest-version',
|
|
216
|
+
fallbackUsed: !isLatest,
|
|
217
|
+
cached: false // In real implementation, would indicate if response was cached
|
|
218
|
+
};
|
|
219
|
+
return response;
|
|
220
|
+
}
|
|
221
|
+
async getVersionComparison(basePath, currentArtifact) {
|
|
222
|
+
try {
|
|
223
|
+
const parsed = parsePath(basePath);
|
|
224
|
+
const versions = await this.ucmClient.getArtifactVersions(parsed.author, parsed.category, parsed.subcategory);
|
|
225
|
+
if (!versions || versions.length <= 1) {
|
|
226
|
+
return {
|
|
227
|
+
hasPrevious: false,
|
|
228
|
+
message: 'No previous versions available for comparison'
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
// Sort versions and find the previous one
|
|
232
|
+
const sortedVersions = versions.sort((a, b) => {
|
|
233
|
+
const aVersion = a.metadata?.version || '0.0.0';
|
|
234
|
+
const bVersion = b.metadata?.version || '0.0.0';
|
|
235
|
+
return this.compareVersions(bVersion, aVersion);
|
|
236
|
+
});
|
|
237
|
+
const currentIndex = sortedVersions.findIndex(v => v.path === currentArtifact.path);
|
|
238
|
+
const previousVersion = currentIndex < sortedVersions.length - 1 ?
|
|
239
|
+
sortedVersions[currentIndex + 1] : null;
|
|
240
|
+
if (!previousVersion) {
|
|
241
|
+
return {
|
|
242
|
+
hasPrevious: false,
|
|
243
|
+
message: 'This is the first version'
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
hasPrevious: true,
|
|
248
|
+
previous: {
|
|
249
|
+
version: previousVersion.metadata?.version,
|
|
250
|
+
publishedAt: previousVersion.publishedAt,
|
|
251
|
+
path: previousVersion.path
|
|
252
|
+
},
|
|
253
|
+
changes: {
|
|
254
|
+
versionJump: this.calculateVersionJump(previousVersion.metadata?.version, currentArtifact.metadata?.version),
|
|
255
|
+
timespan: this.calculateTimespan(previousVersion.publishedAt, currentArtifact.publishedAt),
|
|
256
|
+
breakingChanges: this.detectBreakingChanges(previousVersion, currentArtifact),
|
|
257
|
+
newFeatures: this.detectNewFeatures(previousVersion, currentArtifact),
|
|
258
|
+
improvements: this.detectImprovements(previousVersion, currentArtifact)
|
|
259
|
+
}
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
catch (error) {
|
|
263
|
+
this.logger.warn('GetLatestController', 'Failed to get version comparison', '', error);
|
|
264
|
+
return {
|
|
265
|
+
hasPrevious: false,
|
|
266
|
+
error: 'Could not retrieve version comparison'
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
async getChangeLog(artifact) {
|
|
271
|
+
// In a real implementation, this would fetch actual changelog data
|
|
272
|
+
return {
|
|
273
|
+
available: false,
|
|
274
|
+
message: 'Change log not available for this artifact',
|
|
275
|
+
autoGenerated: {
|
|
276
|
+
summary: 'Latest version with improvements and updates',
|
|
277
|
+
estimatedChanges: this.generateEstimatedChanges(artifact)
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
compareVersions(version1, version2) {
|
|
282
|
+
const v1Parts = version1.split('.').map(Number);
|
|
283
|
+
const v2Parts = version2.split('.').map(Number);
|
|
284
|
+
for (let i = 0; i < Math.max(v1Parts.length, v2Parts.length); i++) {
|
|
285
|
+
const v1Part = v1Parts[i] || 0;
|
|
286
|
+
const v2Part = v2Parts[i] || 0;
|
|
287
|
+
if (v1Part > v2Part)
|
|
288
|
+
return 1;
|
|
289
|
+
if (v1Part < v2Part)
|
|
290
|
+
return -1;
|
|
291
|
+
}
|
|
292
|
+
return 0;
|
|
293
|
+
}
|
|
294
|
+
detectContentType(artifact) {
|
|
295
|
+
// Reuse logic from GetArtifactController
|
|
296
|
+
const path = artifact.path || '';
|
|
297
|
+
const content = artifact.content || '';
|
|
298
|
+
if (path.includes('/typescript/') || content.includes('interface '))
|
|
299
|
+
return 'typescript';
|
|
300
|
+
if (path.includes('/javascript/') || content.includes('function '))
|
|
301
|
+
return 'javascript';
|
|
302
|
+
if (path.includes('/python/') || content.includes('def '))
|
|
303
|
+
return 'python';
|
|
304
|
+
if (content.includes('```'))
|
|
305
|
+
return 'markdown';
|
|
306
|
+
return 'text';
|
|
307
|
+
}
|
|
308
|
+
// Quality and assessment methods
|
|
309
|
+
calculateQualityScore(metadata) {
|
|
310
|
+
let score = 50;
|
|
311
|
+
if (metadata.description?.length > 20)
|
|
312
|
+
score += 20;
|
|
313
|
+
if (metadata.tags?.length > 0)
|
|
314
|
+
score += 10;
|
|
315
|
+
if (metadata.dependencies)
|
|
316
|
+
score += 10;
|
|
317
|
+
if (metadata.contractVersion)
|
|
318
|
+
score += 10;
|
|
319
|
+
return Math.min(score, 100);
|
|
320
|
+
}
|
|
321
|
+
assessMaturityLevel(version) {
|
|
322
|
+
if (!version)
|
|
323
|
+
return 'unknown';
|
|
324
|
+
const [major] = version.split('.');
|
|
325
|
+
if (parseInt(major) >= 1)
|
|
326
|
+
return 'stable';
|
|
327
|
+
if (version.startsWith('0.'))
|
|
328
|
+
return 'beta';
|
|
329
|
+
return 'alpha';
|
|
330
|
+
}
|
|
331
|
+
assessStability(artifact) {
|
|
332
|
+
const version = artifact.metadata?.version || '0.0.0';
|
|
333
|
+
const hasBreakingChanges = false; // Would be determined from history
|
|
334
|
+
const recentUpdates = true; // Would check recent update frequency
|
|
335
|
+
if (version.startsWith('0.'))
|
|
336
|
+
return 'experimental';
|
|
337
|
+
if (hasBreakingChanges)
|
|
338
|
+
return 'evolving';
|
|
339
|
+
if (recentUpdates)
|
|
340
|
+
return 'active';
|
|
341
|
+
return 'stable';
|
|
342
|
+
}
|
|
343
|
+
determineReleaseType(version) {
|
|
344
|
+
if (!version)
|
|
345
|
+
return 'unknown';
|
|
346
|
+
if (version.includes('alpha'))
|
|
347
|
+
return 'alpha';
|
|
348
|
+
if (version.includes('beta'))
|
|
349
|
+
return 'beta';
|
|
350
|
+
if (version.includes('rc'))
|
|
351
|
+
return 'release-candidate';
|
|
352
|
+
const [major, minor, patch] = version.split('.').map(Number);
|
|
353
|
+
if (patch > 0)
|
|
354
|
+
return 'patch';
|
|
355
|
+
if (minor > 0)
|
|
356
|
+
return 'minor';
|
|
357
|
+
return 'major';
|
|
358
|
+
}
|
|
359
|
+
determineLifecycleStage(artifact) {
|
|
360
|
+
const publishedAt = new Date(artifact.publishedAt || Date.now());
|
|
361
|
+
const daysSincePublished = (Date.now() - publishedAt.getTime()) / (1000 * 60 * 60 * 24);
|
|
362
|
+
if (daysSincePublished < 30)
|
|
363
|
+
return 'new';
|
|
364
|
+
if (daysSincePublished < 365)
|
|
365
|
+
return 'active';
|
|
366
|
+
if (daysSincePublished < 1095)
|
|
367
|
+
return 'mature'; // 3 years
|
|
368
|
+
return 'legacy';
|
|
369
|
+
}
|
|
370
|
+
determineSupportStatus(artifact) {
|
|
371
|
+
const maturity = this.assessMaturityLevel(artifact.metadata?.version);
|
|
372
|
+
const lifecycle = this.determineLifecycleStage(artifact);
|
|
373
|
+
if (maturity === 'alpha' || maturity === 'beta')
|
|
374
|
+
return 'experimental';
|
|
375
|
+
if (lifecycle === 'legacy')
|
|
376
|
+
return 'maintenance';
|
|
377
|
+
return 'full-support';
|
|
378
|
+
}
|
|
379
|
+
predictNextVersion(currentVersion) {
|
|
380
|
+
if (!currentVersion)
|
|
381
|
+
return '1.0.0';
|
|
382
|
+
const [major, minor, patch] = currentVersion.split('.').map(Number);
|
|
383
|
+
return `${major}.${minor}.${patch + 1}`;
|
|
384
|
+
}
|
|
385
|
+
// Metrics and statistics
|
|
386
|
+
getDownloadCount(artifact) {
|
|
387
|
+
return Math.floor(Math.random() * 1000); // Simulated
|
|
388
|
+
}
|
|
389
|
+
calculateRating(artifact) {
|
|
390
|
+
return 3.0 + Math.random() * 2; // Simulated
|
|
391
|
+
}
|
|
392
|
+
getRecentAccessCount() {
|
|
393
|
+
return Math.floor(Math.random() * 100); // Simulated
|
|
394
|
+
}
|
|
395
|
+
calculateTrendingScore(artifact) {
|
|
396
|
+
return Math.random(); // Simulated
|
|
397
|
+
}
|
|
398
|
+
// Recommendation methods
|
|
399
|
+
shouldRecommendUpgrade(artifact) {
|
|
400
|
+
return false; // Since this is already the latest
|
|
401
|
+
}
|
|
402
|
+
requiresMigration(artifact) {
|
|
403
|
+
return false; // Simulated
|
|
404
|
+
}
|
|
405
|
+
getDeprecationWarnings(artifact) {
|
|
406
|
+
return []; // Simulated
|
|
407
|
+
}
|
|
408
|
+
getSecurityAlerts(artifact) {
|
|
409
|
+
return []; // Simulated
|
|
410
|
+
}
|
|
411
|
+
// Version comparison helpers
|
|
412
|
+
calculateVersionJump(oldVersion, newVersion) {
|
|
413
|
+
if (!oldVersion || !newVersion)
|
|
414
|
+
return 'unknown';
|
|
415
|
+
const comparison = this.compareVersions(newVersion, oldVersion);
|
|
416
|
+
if (comparison > 0)
|
|
417
|
+
return 'upgrade';
|
|
418
|
+
if (comparison < 0)
|
|
419
|
+
return 'downgrade';
|
|
420
|
+
return 'same';
|
|
421
|
+
}
|
|
422
|
+
calculateTimespan(oldDate, newDate) {
|
|
423
|
+
const old = new Date(oldDate || 0);
|
|
424
|
+
const current = new Date(newDate || Date.now());
|
|
425
|
+
const diffMs = current.getTime() - old.getTime();
|
|
426
|
+
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
|
427
|
+
if (diffDays < 1)
|
|
428
|
+
return 'same day';
|
|
429
|
+
if (diffDays < 7)
|
|
430
|
+
return `${diffDays} days`;
|
|
431
|
+
if (diffDays < 30)
|
|
432
|
+
return `${Math.floor(diffDays / 7)} weeks`;
|
|
433
|
+
if (diffDays < 365)
|
|
434
|
+
return `${Math.floor(diffDays / 30)} months`;
|
|
435
|
+
return `${Math.floor(diffDays / 365)} years`;
|
|
436
|
+
}
|
|
437
|
+
detectBreakingChanges(oldArtifact, newArtifact) {
|
|
438
|
+
// Simplified breaking change detection
|
|
439
|
+
const oldContract = oldArtifact.metadata?.contractVersion;
|
|
440
|
+
const newContract = newArtifact.metadata?.contractVersion;
|
|
441
|
+
if (oldContract && newContract && oldContract !== newContract) {
|
|
442
|
+
return ['Contract version changed'];
|
|
443
|
+
}
|
|
444
|
+
return [];
|
|
445
|
+
}
|
|
446
|
+
detectNewFeatures(oldArtifact, newArtifact) {
|
|
447
|
+
// Simplified new feature detection
|
|
448
|
+
const oldTags = oldArtifact.metadata?.tags || [];
|
|
449
|
+
const newTags = newArtifact.metadata?.tags || [];
|
|
450
|
+
const addedTags = newTags.filter((tag) => !oldTags.includes(tag));
|
|
451
|
+
return addedTags.map((tag) => `New feature: ${tag}`);
|
|
452
|
+
}
|
|
453
|
+
detectImprovements(oldArtifact, newArtifact) {
|
|
454
|
+
// Simplified improvement detection
|
|
455
|
+
const improvements = [];
|
|
456
|
+
if ((newArtifact.metadata?.description?.length || 0) > (oldArtifact.metadata?.description?.length || 0)) {
|
|
457
|
+
improvements.push('Enhanced documentation');
|
|
458
|
+
}
|
|
459
|
+
return improvements;
|
|
460
|
+
}
|
|
461
|
+
generateEstimatedChanges(artifact) {
|
|
462
|
+
return [
|
|
463
|
+
'General improvements and optimizations',
|
|
464
|
+
'Updated dependencies',
|
|
465
|
+
'Bug fixes and stability improvements'
|
|
466
|
+
];
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
//# sourceMappingURL=GetLatestController.js.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { BaseToolController } from '../base/BaseToolController.js';
|
|
2
|
+
import { UcmApiClient } from '../../clients/UcmApiClient.js';
|
|
3
|
+
import { ILogger } from '../../interfaces/ILogger.js';
|
|
4
|
+
export declare class ListVersionsController extends BaseToolController {
|
|
5
|
+
constructor(ucmClient: UcmApiClient, logger: ILogger);
|
|
6
|
+
get name(): string;
|
|
7
|
+
get description(): string;
|
|
8
|
+
get inputSchema(): any;
|
|
9
|
+
protected handleExecute(params: any): Promise<any>;
|
|
10
|
+
private validateBasePath;
|
|
11
|
+
private filterVersionsSince;
|
|
12
|
+
private filterVersionsByPattern;
|
|
13
|
+
private enrichVersionData;
|
|
14
|
+
private sortVersions;
|
|
15
|
+
private generateVersionSummary;
|
|
16
|
+
private analyzeVersionHistory;
|
|
17
|
+
private generateVersionRecommendations;
|
|
18
|
+
private generateChangeSummary;
|
|
19
|
+
private compareVersions;
|
|
20
|
+
private determineReleaseType;
|
|
21
|
+
private isPreRelease;
|
|
22
|
+
private determineLifecycleStage;
|
|
23
|
+
private assessVersionStability;
|
|
24
|
+
private calculateQualityScore;
|
|
25
|
+
private assessMetadataCompleteness;
|
|
26
|
+
private getLatestVersion;
|
|
27
|
+
private getOldestVersion;
|
|
28
|
+
private calculateVersionSpan;
|
|
29
|
+
private calculateReleaseFrequency;
|
|
30
|
+
private calculateAverageTimeBetweenReleases;
|
|
31
|
+
private groupByMajorVersion;
|
|
32
|
+
private determineChangeType;
|
|
33
|
+
private calculateTimespan;
|
|
34
|
+
private hasBreakingChanges;
|
|
35
|
+
private detectNewFeatures;
|
|
36
|
+
private detectImprovements;
|
|
37
|
+
private detectFixes;
|
|
38
|
+
private getDownloadCount;
|
|
39
|
+
private calculateRating;
|
|
40
|
+
private getUsageMetrics;
|
|
41
|
+
private calculateAdoptionRate;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=ListVersionsController.d.ts.map
|