@172ai/containers-mcp-server 1.12.5 → 1.12.7
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 +63 -0
- package/dist/server.d.ts +29 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +547 -0
- package/dist/server.js.map +1 -1
- package/dist/services/fixService.d.ts +166 -0
- package/dist/services/fixService.d.ts.map +1 -0
- package/dist/services/fixService.js +430 -0
- package/dist/services/fixService.js.map +1 -0
- package/dist/services/modificationService.d.ts +121 -0
- package/dist/services/modificationService.d.ts.map +1 -0
- package/dist/services/modificationService.js +137 -0
- package/dist/services/modificationService.js.map +1 -0
- package/dist/services/streamingService.d.ts +15 -1
- package/dist/services/streamingService.d.ts.map +1 -1
- package/dist/services/streamingService.js +55 -0
- package/dist/services/streamingService.js.map +1 -1
- package/package.json +2 -1
package/dist/server.js
CHANGED
|
@@ -7,6 +7,7 @@ import { config } from './config.js';
|
|
|
7
7
|
import { authManager } from './auth.js';
|
|
8
8
|
import { containerService } from './services/containerService.js';
|
|
9
9
|
import { buildService } from './services/buildService.js';
|
|
10
|
+
import { fixService } from './services/fixService.js';
|
|
10
11
|
import { fileService } from './services/fileService.js';
|
|
11
12
|
import { capabilityService } from './services/capabilityService.js';
|
|
12
13
|
import { executionService } from './services/executionService.js';
|
|
@@ -15,6 +16,7 @@ import { exportService } from './services/exportService.js';
|
|
|
15
16
|
import { streamingService } from './services/streamingService.js';
|
|
16
17
|
import { userNotificationManager } from './services/userNotificationManager.js';
|
|
17
18
|
import { userService } from './services/userService.js';
|
|
19
|
+
import { modificationService } from './services/modificationService.js';
|
|
18
20
|
import { ErrorHandler } from './utils/errorHandler.js';
|
|
19
21
|
/**
|
|
20
22
|
* 172.ai Container Management MCP Server
|
|
@@ -30,9 +32,11 @@ class ContainerMCPServer {
|
|
|
30
32
|
});
|
|
31
33
|
// Initialize MCP server reference for progress notifications
|
|
32
34
|
buildService.setMCPServer(this.server);
|
|
35
|
+
fixService.setMCPServer(this.server);
|
|
33
36
|
executionService.setMCPServer(this.server);
|
|
34
37
|
importService.setMCPServer(this.server);
|
|
35
38
|
exportService.setMCPServer(this.server);
|
|
39
|
+
modificationService.setMCPServer(this.server);
|
|
36
40
|
this.setupTools();
|
|
37
41
|
this.setupErrorHandlers();
|
|
38
42
|
this.initializeStreaming();
|
|
@@ -83,6 +87,8 @@ class ContainerMCPServer {
|
|
|
83
87
|
this.setupContainerTools();
|
|
84
88
|
// Build Management Tools
|
|
85
89
|
this.setupBuildTools();
|
|
90
|
+
// Fix Management Tools
|
|
91
|
+
this.setupFixTools();
|
|
86
92
|
// File Management Tools
|
|
87
93
|
this.setupFileTools();
|
|
88
94
|
// Capability Management Tools
|
|
@@ -90,6 +96,13 @@ class ContainerMCPServer {
|
|
|
90
96
|
// Execution Management Tools
|
|
91
97
|
this.setupExecutionTools();
|
|
92
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Set up container fix management tools
|
|
101
|
+
*/
|
|
102
|
+
setupFixTools() {
|
|
103
|
+
// Fix tools are registered via CallToolRequestSchema handler
|
|
104
|
+
// No separate setup needed - they share the same request handler
|
|
105
|
+
}
|
|
93
106
|
/**
|
|
94
107
|
* Set up container management tools
|
|
95
108
|
*/
|
|
@@ -158,6 +171,16 @@ class ContainerMCPServer {
|
|
|
158
171
|
return await this.handleCancelBuildMonitoring(args);
|
|
159
172
|
case 'get_stream_analytics':
|
|
160
173
|
return await this.handleGetStreamAnalytics(args);
|
|
174
|
+
case 'fix_container':
|
|
175
|
+
return await this.handleFixContainer(args);
|
|
176
|
+
case 'analyze_container_failure':
|
|
177
|
+
return await this.handleAnalyzeContainerFailure(args);
|
|
178
|
+
case 'approve_and_apply_fix':
|
|
179
|
+
return await this.handleApproveAndApplyFix(args);
|
|
180
|
+
case 'get_fix_history':
|
|
181
|
+
return await this.handleGetFixHistory(args);
|
|
182
|
+
case 'get_fix_status':
|
|
183
|
+
return await this.handleGetFixStatus(args);
|
|
161
184
|
case 'import_container':
|
|
162
185
|
return await this.handleImportContainer(args);
|
|
163
186
|
case 'get_import_status':
|
|
@@ -236,6 +259,16 @@ class ContainerMCPServer {
|
|
|
236
259
|
return await this.handleGetExecutionProgressUpdate(args);
|
|
237
260
|
case 'get_all_progress_updates':
|
|
238
261
|
return await this.handleGetAllProgressUpdates(args);
|
|
262
|
+
case 'list_modifications':
|
|
263
|
+
return await this.handleListModifications(args);
|
|
264
|
+
case 'suggest_container_modifications':
|
|
265
|
+
return await this.handleSuggestContainerModifications(args);
|
|
266
|
+
case 'apply_container_modification':
|
|
267
|
+
return await this.handleApplyContainerModification(args);
|
|
268
|
+
case 'get_modification_status':
|
|
269
|
+
return await this.handleGetModificationStatus(args);
|
|
270
|
+
case 'list_applied_modifications':
|
|
271
|
+
return await this.handleListAppliedModifications(args);
|
|
239
272
|
default:
|
|
240
273
|
throw ErrorHandler.createValidationError(`Unknown tool: ${name}`);
|
|
241
274
|
}
|
|
@@ -765,6 +798,109 @@ Follow same metadata requirements as create_container.`,
|
|
|
765
798
|
}
|
|
766
799
|
}
|
|
767
800
|
},
|
|
801
|
+
// Fix Management Tools
|
|
802
|
+
{
|
|
803
|
+
name: 'fix_container',
|
|
804
|
+
description: 'Analyze container build failure, apply AI-generated fix, and rebuild automatically. This is the primary fix workflow that combines analysis, application, and rebuild into one operation.',
|
|
805
|
+
inputSchema: {
|
|
806
|
+
type: 'object',
|
|
807
|
+
properties: {
|
|
808
|
+
containerId: {
|
|
809
|
+
type: 'string',
|
|
810
|
+
description: 'ID of the container to fix'
|
|
811
|
+
},
|
|
812
|
+
autoApply: {
|
|
813
|
+
type: 'boolean',
|
|
814
|
+
description: 'Whether to automatically apply the fix after analysis (default: true). Set to false for analyze-only mode.',
|
|
815
|
+
default: true
|
|
816
|
+
},
|
|
817
|
+
progressToken: {
|
|
818
|
+
type: 'string',
|
|
819
|
+
description: 'Optional token for receiving real-time progress notifications during fix operation'
|
|
820
|
+
}
|
|
821
|
+
},
|
|
822
|
+
required: ['containerId']
|
|
823
|
+
}
|
|
824
|
+
},
|
|
825
|
+
{
|
|
826
|
+
name: 'analyze_container_failure',
|
|
827
|
+
description: 'Analyze container build/execution failure and generate fix suggestions WITHOUT automatically applying them. Returns fixAttemptId for later approval.',
|
|
828
|
+
inputSchema: {
|
|
829
|
+
type: 'object',
|
|
830
|
+
properties: {
|
|
831
|
+
containerId: {
|
|
832
|
+
type: 'string',
|
|
833
|
+
description: 'ID of the container to analyze'
|
|
834
|
+
},
|
|
835
|
+
progressToken: {
|
|
836
|
+
type: 'string',
|
|
837
|
+
description: 'Optional token for receiving real-time progress notifications'
|
|
838
|
+
}
|
|
839
|
+
},
|
|
840
|
+
required: ['containerId']
|
|
841
|
+
}
|
|
842
|
+
},
|
|
843
|
+
{
|
|
844
|
+
name: 'approve_and_apply_fix',
|
|
845
|
+
description: 'Apply a specific fix attempt and trigger automatic rebuild. Use this after reviewing analysis results from analyze_container_failure.',
|
|
846
|
+
inputSchema: {
|
|
847
|
+
type: 'object',
|
|
848
|
+
properties: {
|
|
849
|
+
containerId: {
|
|
850
|
+
type: 'string',
|
|
851
|
+
description: 'ID of the container'
|
|
852
|
+
},
|
|
853
|
+
fixAttemptId: {
|
|
854
|
+
type: 'string',
|
|
855
|
+
description: 'ID of the fix attempt to apply (from analyze_container_failure result)'
|
|
856
|
+
},
|
|
857
|
+
progressToken: {
|
|
858
|
+
type: 'string',
|
|
859
|
+
description: 'Optional token for receiving real-time progress notifications'
|
|
860
|
+
}
|
|
861
|
+
},
|
|
862
|
+
required: ['containerId', 'fixAttemptId']
|
|
863
|
+
}
|
|
864
|
+
},
|
|
865
|
+
{
|
|
866
|
+
name: 'get_fix_history',
|
|
867
|
+
description: 'Get the history of fix attempts for a container, showing all previous fixes and their outcomes',
|
|
868
|
+
inputSchema: {
|
|
869
|
+
type: 'object',
|
|
870
|
+
properties: {
|
|
871
|
+
containerId: {
|
|
872
|
+
type: 'string',
|
|
873
|
+
description: 'ID of the container'
|
|
874
|
+
},
|
|
875
|
+
limit: {
|
|
876
|
+
type: 'number',
|
|
877
|
+
minimum: 1,
|
|
878
|
+
maximum: 100,
|
|
879
|
+
description: 'Maximum number of fix attempts to return (default: 10)',
|
|
880
|
+
default: 10
|
|
881
|
+
}
|
|
882
|
+
},
|
|
883
|
+
required: ['containerId']
|
|
884
|
+
}
|
|
885
|
+
},
|
|
886
|
+
{
|
|
887
|
+
name: 'get_fix_status',
|
|
888
|
+
description: 'Get detailed status and information about a specific fix attempt',
|
|
889
|
+
inputSchema: {
|
|
890
|
+
type: 'object',
|
|
891
|
+
properties: {
|
|
892
|
+
containerId: {
|
|
893
|
+
type: 'string',
|
|
894
|
+
description: 'ID of the container'
|
|
895
|
+
},
|
|
896
|
+
fixAttemptId: {
|
|
897
|
+
type: 'string',
|
|
898
|
+
description: 'ID of the fix attempt to retrieve'
|
|
899
|
+
}
|
|
900
|
+
},
|
|
901
|
+
required: ['containerId', 'fixAttemptId']
|
|
902
|
+
}
|
|
903
|
+
},
|
|
768
904
|
// Import Management Tools
|
|
769
905
|
{
|
|
770
906
|
name: 'import_container',
|
|
@@ -1616,6 +1752,130 @@ Follow same metadata requirements as create_container.`,
|
|
|
1616
1752
|
type: 'object',
|
|
1617
1753
|
properties: {}
|
|
1618
1754
|
}
|
|
1755
|
+
},
|
|
1756
|
+
// Modification Management Tools
|
|
1757
|
+
{
|
|
1758
|
+
name: 'list_modifications',
|
|
1759
|
+
description: 'List all available modifications in the catalog',
|
|
1760
|
+
inputSchema: {
|
|
1761
|
+
type: 'object',
|
|
1762
|
+
properties: {
|
|
1763
|
+
category: {
|
|
1764
|
+
type: 'string',
|
|
1765
|
+
description: 'Filter by category (optional)'
|
|
1766
|
+
},
|
|
1767
|
+
tags: {
|
|
1768
|
+
type: 'string',
|
|
1769
|
+
description: 'Filter by tags (comma-separated, optional)'
|
|
1770
|
+
},
|
|
1771
|
+
active: {
|
|
1772
|
+
type: 'boolean',
|
|
1773
|
+
default: true,
|
|
1774
|
+
description: 'Filter by active status (default: true)'
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
},
|
|
1779
|
+
{
|
|
1780
|
+
name: 'suggest_container_modifications',
|
|
1781
|
+
description: 'Get AI-powered modification suggestions for a container',
|
|
1782
|
+
inputSchema: {
|
|
1783
|
+
type: 'object',
|
|
1784
|
+
properties: {
|
|
1785
|
+
containerId: {
|
|
1786
|
+
type: 'string',
|
|
1787
|
+
description: 'ID of the container to analyze'
|
|
1788
|
+
},
|
|
1789
|
+
categories: {
|
|
1790
|
+
type: 'array',
|
|
1791
|
+
items: { type: 'string' },
|
|
1792
|
+
description: 'Filter suggestions by categories (optional)'
|
|
1793
|
+
},
|
|
1794
|
+
includeRisks: {
|
|
1795
|
+
type: 'boolean',
|
|
1796
|
+
default: true,
|
|
1797
|
+
description: 'Include risk assessment (default: true)'
|
|
1798
|
+
}
|
|
1799
|
+
},
|
|
1800
|
+
required: ['containerId']
|
|
1801
|
+
}
|
|
1802
|
+
},
|
|
1803
|
+
{
|
|
1804
|
+
name: 'apply_container_modification',
|
|
1805
|
+
description: 'Apply a modification to a container',
|
|
1806
|
+
inputSchema: {
|
|
1807
|
+
type: 'object',
|
|
1808
|
+
properties: {
|
|
1809
|
+
containerId: {
|
|
1810
|
+
type: 'string',
|
|
1811
|
+
description: 'ID of the container'
|
|
1812
|
+
},
|
|
1813
|
+
modificationId: {
|
|
1814
|
+
type: 'string',
|
|
1815
|
+
description: 'ID of the modification to apply'
|
|
1816
|
+
},
|
|
1817
|
+
autoBuild: {
|
|
1818
|
+
type: 'boolean',
|
|
1819
|
+
default: true,
|
|
1820
|
+
description: 'Automatically build after applying (default: true)'
|
|
1821
|
+
},
|
|
1822
|
+
notes: {
|
|
1823
|
+
type: 'string',
|
|
1824
|
+
description: 'Optional notes about this application'
|
|
1825
|
+
}
|
|
1826
|
+
},
|
|
1827
|
+
required: ['containerId', 'modificationId']
|
|
1828
|
+
}
|
|
1829
|
+
},
|
|
1830
|
+
{
|
|
1831
|
+
name: 'get_modification_status',
|
|
1832
|
+
description: 'Get detailed information about a specific modification application',
|
|
1833
|
+
inputSchema: {
|
|
1834
|
+
type: 'object',
|
|
1835
|
+
properties: {
|
|
1836
|
+
containerId: {
|
|
1837
|
+
type: 'string',
|
|
1838
|
+
description: 'ID of the container'
|
|
1839
|
+
},
|
|
1840
|
+
modificationApplicationId: {
|
|
1841
|
+
type: 'string',
|
|
1842
|
+
description: 'ID of the modification application'
|
|
1843
|
+
}
|
|
1844
|
+
},
|
|
1845
|
+
required: ['containerId', 'modificationApplicationId']
|
|
1846
|
+
}
|
|
1847
|
+
},
|
|
1848
|
+
{
|
|
1849
|
+
name: 'list_applied_modifications',
|
|
1850
|
+
description: 'List modifications applied to a specific container',
|
|
1851
|
+
inputSchema: {
|
|
1852
|
+
type: 'object',
|
|
1853
|
+
properties: {
|
|
1854
|
+
containerId: {
|
|
1855
|
+
type: 'string',
|
|
1856
|
+
description: 'ID of the container'
|
|
1857
|
+
},
|
|
1858
|
+
status: {
|
|
1859
|
+
type: 'string',
|
|
1860
|
+
enum: ['in_progress', 'completed', 'failed'],
|
|
1861
|
+
description: 'Filter by status (optional)'
|
|
1862
|
+
},
|
|
1863
|
+
limit: {
|
|
1864
|
+
type: 'number',
|
|
1865
|
+
minimum: 1,
|
|
1866
|
+
maximum: 100,
|
|
1867
|
+
default: 50,
|
|
1868
|
+
description: 'Maximum number of results (default: 50)'
|
|
1869
|
+
},
|
|
1870
|
+
offset: {
|
|
1871
|
+
type: 'number',
|
|
1872
|
+
minimum: 0,
|
|
1873
|
+
default: 0,
|
|
1874
|
+
description: 'Number of results to skip (default: 0)'
|
|
1875
|
+
}
|
|
1876
|
+
},
|
|
1877
|
+
required: ['containerId']
|
|
1878
|
+
}
|
|
1619
1879
|
}
|
|
1620
1880
|
];
|
|
1621
1881
|
}
|
|
@@ -1939,6 +2199,151 @@ Follow same metadata requirements as create_container.`,
|
|
|
1939
2199
|
],
|
|
1940
2200
|
};
|
|
1941
2201
|
}
|
|
2202
|
+
// Fix handler methods
|
|
2203
|
+
async handleFixContainer(args) {
|
|
2204
|
+
const { progressToken, autoApply = true, ...fixParams } = args;
|
|
2205
|
+
const result = await fixService.fixContainer({
|
|
2206
|
+
containerId: args.containerId,
|
|
2207
|
+
autoApply,
|
|
2208
|
+
progressToken
|
|
2209
|
+
});
|
|
2210
|
+
return {
|
|
2211
|
+
content: [
|
|
2212
|
+
{
|
|
2213
|
+
type: 'text',
|
|
2214
|
+
text: `🔧 Fix operation ${autoApply ? 'started' : 'analyzed'} for container ${args.containerId}!\n\n` +
|
|
2215
|
+
`Fix Attempt ID: ${result.fixAttemptId}\n` +
|
|
2216
|
+
`Status: ${autoApply ? 'Applying fix and rebuilding' : 'Analysis complete - awaiting approval'}\n` +
|
|
2217
|
+
`Message: ${result.message}\n` +
|
|
2218
|
+
`${result.analysis ? `\nDiagnostic: ${result.analysis.diagnosticSummary}\nRoot Cause: ${result.analysis.rootCause}\n` : ''}` +
|
|
2219
|
+
`${result.buildStatus ? `Build Status: ${result.buildStatus}\n` : ''}` +
|
|
2220
|
+
`${progressToken ? `\n🔄 Progress updates will be sent via notifications using token: ${progressToken}` : ''}`,
|
|
2221
|
+
},
|
|
2222
|
+
],
|
|
2223
|
+
};
|
|
2224
|
+
}
|
|
2225
|
+
async handleAnalyzeContainerFailure(args) {
|
|
2226
|
+
const { progressToken } = args;
|
|
2227
|
+
const result = await fixService.analyzeFailure({
|
|
2228
|
+
containerId: args.containerId,
|
|
2229
|
+
progressToken
|
|
2230
|
+
});
|
|
2231
|
+
return {
|
|
2232
|
+
content: [
|
|
2233
|
+
{
|
|
2234
|
+
type: 'text',
|
|
2235
|
+
text: `**Container Failure Analysis**\n\n` +
|
|
2236
|
+
`Fix Attempt ID: ${result.fixAttemptId}\n` +
|
|
2237
|
+
`Attempt: ${result.attemptNumber} of ${result.maxAttempts}\n` +
|
|
2238
|
+
`Previous Attempts: ${result.previousAttempts}\n\n` +
|
|
2239
|
+
`**Diagnostic Summary**\n${result.diagnosticSummary}\n\n` +
|
|
2240
|
+
`**Root Cause**\n${result.rootCause}\n\n` +
|
|
2241
|
+
`**Proposed Fix**\n${result.fixApproach}\n\n` +
|
|
2242
|
+
`**Severity**: ${result.severity}\n` +
|
|
2243
|
+
`**Fix Confidence**: ${result.fixConfidence}\n` +
|
|
2244
|
+
`**Affected Files**: ${result.affectedFiles.join(', ')}\n\n` +
|
|
2245
|
+
`💡 Use approve_and_apply_fix with fixAttemptId: ${result.fixAttemptId} to apply this fix`,
|
|
2246
|
+
},
|
|
2247
|
+
],
|
|
2248
|
+
};
|
|
2249
|
+
}
|
|
2250
|
+
async handleApproveAndApplyFix(args) {
|
|
2251
|
+
const { progressToken } = args;
|
|
2252
|
+
const result = await fixService.applyFix({
|
|
2253
|
+
containerId: args.containerId,
|
|
2254
|
+
fixAttemptId: args.fixAttemptId,
|
|
2255
|
+
progressToken
|
|
2256
|
+
});
|
|
2257
|
+
return {
|
|
2258
|
+
content: [
|
|
2259
|
+
{
|
|
2260
|
+
type: 'text',
|
|
2261
|
+
text: `✅ Fix approved and applied!\n\n` +
|
|
2262
|
+
`Fix Attempt ID: ${result.fixAttemptId}\n` +
|
|
2263
|
+
`Container ID: ${result.containerId}\n` +
|
|
2264
|
+
`Message: ${result.message}\n` +
|
|
2265
|
+
`Build Status: ${result.buildStatus}\n` +
|
|
2266
|
+
`${progressToken ? `\n🔄 Progress updates will be sent via notifications using token: ${progressToken}` : ''}`,
|
|
2267
|
+
},
|
|
2268
|
+
],
|
|
2269
|
+
};
|
|
2270
|
+
}
|
|
2271
|
+
async handleGetFixHistory(args) {
|
|
2272
|
+
const result = await fixService.getFixHistory({
|
|
2273
|
+
containerId: args.containerId,
|
|
2274
|
+
limit: args.limit || 10
|
|
2275
|
+
});
|
|
2276
|
+
if (result.fixes.length === 0) {
|
|
2277
|
+
return {
|
|
2278
|
+
content: [
|
|
2279
|
+
{
|
|
2280
|
+
type: 'text',
|
|
2281
|
+
text: `No fix attempts found for container ${args.containerId}`,
|
|
2282
|
+
},
|
|
2283
|
+
],
|
|
2284
|
+
};
|
|
2285
|
+
}
|
|
2286
|
+
let historyText = `**Fix History for Container ${args.containerId}**\n\n` +
|
|
2287
|
+
`Found ${result.totalCount} fix attempt(s):\n\n`;
|
|
2288
|
+
result.fixes.forEach((fix, index) => {
|
|
2289
|
+
historyText += `${index + 1}. **Fix ${fix.id}**\n` +
|
|
2290
|
+
` • Attempt Number: ${fix.attemptNumber}\n` +
|
|
2291
|
+
` • Status: ${fix.status}\n` +
|
|
2292
|
+
` • Severity: ${fix.severity}\n` +
|
|
2293
|
+
` • Confidence: ${fix.fixConfidence}\n` +
|
|
2294
|
+
` • Created: ${fix.createdAt}\n` +
|
|
2295
|
+
` ${fix.appliedAt ? `• Applied: ${fix.appliedAt}\n` : ''}` +
|
|
2296
|
+
` ${fix.completedAt ? `• Completed: ${fix.completedAt}\n` : ''}` +
|
|
2297
|
+
` ${fix.errorMessage ? `• Error: ${fix.errorMessage}\n` : ''}\n`;
|
|
2298
|
+
});
|
|
2299
|
+
return {
|
|
2300
|
+
content: [
|
|
2301
|
+
{
|
|
2302
|
+
type: 'text',
|
|
2303
|
+
text: historyText,
|
|
2304
|
+
},
|
|
2305
|
+
],
|
|
2306
|
+
};
|
|
2307
|
+
}
|
|
2308
|
+
async handleGetFixStatus(args) {
|
|
2309
|
+
const result = await fixService.getFixStatus({
|
|
2310
|
+
containerId: args.containerId,
|
|
2311
|
+
fixAttemptId: args.fixAttemptId
|
|
2312
|
+
});
|
|
2313
|
+
let statusText = `**Fix Attempt Status**\n\n` +
|
|
2314
|
+
`Fix ID: ${result.id}\n` +
|
|
2315
|
+
`Container ID: ${result.containerId}\n` +
|
|
2316
|
+
`Attempt Number: ${result.attemptNumber}\n` +
|
|
2317
|
+
`Status: ${result.status}\n` +
|
|
2318
|
+
`Severity: ${result.severity}\n` +
|
|
2319
|
+
`Fix Confidence: ${result.fixConfidence}\n\n` +
|
|
2320
|
+
`**Diagnostic Summary**\n${result.diagnosticSummary}\n\n` +
|
|
2321
|
+
`**Root Cause**\n${result.rootCause}\n\n` +
|
|
2322
|
+
`**Fix Approach**\n${result.fixApproach}\n\n` +
|
|
2323
|
+
`**Timeline**\n` +
|
|
2324
|
+
`• Created: ${result.createdAt}\n` +
|
|
2325
|
+
`${result.updatedAt ? `• Updated: ${result.updatedAt}\n` : ''}` +
|
|
2326
|
+
`${result.appliedAt ? `• Applied: ${result.appliedAt}\n` : ''}` +
|
|
2327
|
+
`${result.completedAt ? `• Completed: ${result.completedAt}\n` : ''}`;
|
|
2328
|
+
if (result.fileChanges && result.fileChanges.length > 0) {
|
|
2329
|
+
statusText += `\n**File Changes (${result.fileChanges.length})**\n`;
|
|
2330
|
+
result.fileChanges.forEach((change, index) => {
|
|
2331
|
+
statusText += `${index + 1}. ${change.filePath} (${change.changeType})\n` +
|
|
2332
|
+
` Reason: ${change.changeReason}\n`;
|
|
2333
|
+
});
|
|
2334
|
+
}
|
|
2335
|
+
if (result.errorMessage) {
|
|
2336
|
+
statusText += `\n❌ **Error**: ${result.errorMessage}\n`;
|
|
2337
|
+
}
|
|
2338
|
+
return {
|
|
2339
|
+
content: [
|
|
2340
|
+
{
|
|
2341
|
+
type: 'text',
|
|
2342
|
+
text: statusText,
|
|
2343
|
+
},
|
|
2344
|
+
],
|
|
2345
|
+
};
|
|
2346
|
+
}
|
|
1942
2347
|
// Import handler methods
|
|
1943
2348
|
async handleImportContainer(args) {
|
|
1944
2349
|
const { progressToken, ...importParams } = args;
|
|
@@ -2856,6 +3261,148 @@ Follow same metadata requirements as create_container.`,
|
|
|
2856
3261
|
],
|
|
2857
3262
|
};
|
|
2858
3263
|
}
|
|
3264
|
+
/**
|
|
3265
|
+
* Handle list modifications
|
|
3266
|
+
*/
|
|
3267
|
+
async handleListModifications(args) {
|
|
3268
|
+
const { category, tags, active = true } = args;
|
|
3269
|
+
const result = await modificationService.listModifications(category, tags, active);
|
|
3270
|
+
let responseText = `**Available Modifications**\n\n`;
|
|
3271
|
+
responseText += `Found ${result.count} modification(s)\n\n`;
|
|
3272
|
+
result.modifications.forEach((mod, index) => {
|
|
3273
|
+
responseText += `${index + 1}. **${mod.name}** (${mod.modificationId})\n`;
|
|
3274
|
+
responseText += ` Category: ${mod.category}\n`;
|
|
3275
|
+
responseText += ` Description: ${mod.description}\n`;
|
|
3276
|
+
if (mod.estimatedImpact) {
|
|
3277
|
+
responseText += ` Impact: ${mod.estimatedImpact}\n`;
|
|
3278
|
+
}
|
|
3279
|
+
if (mod.priority) {
|
|
3280
|
+
responseText += ` Priority: ${mod.priority}\n`;
|
|
3281
|
+
}
|
|
3282
|
+
if (mod.tags && mod.tags.length > 0) {
|
|
3283
|
+
responseText += ` Tags: ${mod.tags.join(', ')}\n`;
|
|
3284
|
+
}
|
|
3285
|
+
if (mod.risks) {
|
|
3286
|
+
responseText += ` ⚠️ Risks: ${mod.risks}\n`;
|
|
3287
|
+
}
|
|
3288
|
+
responseText += `\n`;
|
|
3289
|
+
});
|
|
3290
|
+
return {
|
|
3291
|
+
content: [
|
|
3292
|
+
{
|
|
3293
|
+
type: 'text',
|
|
3294
|
+
text: responseText,
|
|
3295
|
+
},
|
|
3296
|
+
],
|
|
3297
|
+
};
|
|
3298
|
+
}
|
|
3299
|
+
/**
|
|
3300
|
+
* Handle suggest container modifications
|
|
3301
|
+
*/
|
|
3302
|
+
async handleSuggestContainerModifications(args) {
|
|
3303
|
+
const { containerId, categories, includeRisks = true } = args;
|
|
3304
|
+
const result = await modificationService.suggestModifications(containerId, categories, includeRisks);
|
|
3305
|
+
let responseText = `**AI-Powered Modification Suggestions**\n\n`;
|
|
3306
|
+
if (result.recommendations.length > 0) {
|
|
3307
|
+
responseText += `📋 **Recommended Modifications (${result.recommendations.length})**\n\n`;
|
|
3308
|
+
result.recommendations.forEach((rec, index) => {
|
|
3309
|
+
responseText += modificationService.formatRecommendation(rec);
|
|
3310
|
+
responseText += `\n`;
|
|
3311
|
+
});
|
|
3312
|
+
}
|
|
3313
|
+
if (result.alreadyApplied.length > 0) {
|
|
3314
|
+
responseText += `\n✅ **Already Applied (${result.alreadyApplied.length})**\n`;
|
|
3315
|
+
result.alreadyApplied.forEach((id) => {
|
|
3316
|
+
responseText += `- ${id}\n`;
|
|
3317
|
+
});
|
|
3318
|
+
}
|
|
3319
|
+
if (result.notApplicable.length > 0) {
|
|
3320
|
+
responseText += `\n❌ **Not Applicable (${result.notApplicable.length})**\n`;
|
|
3321
|
+
result.notApplicable.forEach((item) => {
|
|
3322
|
+
responseText += `- ${item.name}: ${item.reason}\n`;
|
|
3323
|
+
});
|
|
3324
|
+
}
|
|
3325
|
+
return {
|
|
3326
|
+
content: [
|
|
3327
|
+
{
|
|
3328
|
+
type: 'text',
|
|
3329
|
+
text: responseText,
|
|
3330
|
+
},
|
|
3331
|
+
],
|
|
3332
|
+
};
|
|
3333
|
+
}
|
|
3334
|
+
/**
|
|
3335
|
+
* Handle apply container modification
|
|
3336
|
+
*/
|
|
3337
|
+
async handleApplyContainerModification(args) {
|
|
3338
|
+
const { containerId, modificationId, autoBuild = true, notes } = args;
|
|
3339
|
+
const result = await modificationService.applyModification({
|
|
3340
|
+
containerId,
|
|
3341
|
+
modificationId,
|
|
3342
|
+
autoBuild,
|
|
3343
|
+
notes
|
|
3344
|
+
});
|
|
3345
|
+
let responseText = `**Modification Applied**\n\n`;
|
|
3346
|
+
responseText += `🔄 Application ID: ${result.modificationApplicationId}\n`;
|
|
3347
|
+
responseText += `📊 Status: ${result.status}\n`;
|
|
3348
|
+
responseText += `⏱️ Estimated Completion: ${result.estimatedCompletionTime}\n`;
|
|
3349
|
+
responseText += `🔗 Stream Token: ${result.streamToken}\n\n`;
|
|
3350
|
+
responseText += `Progress notifications will be sent automatically via user-notifications stream.\n`;
|
|
3351
|
+
return {
|
|
3352
|
+
content: [
|
|
3353
|
+
{
|
|
3354
|
+
type: 'text',
|
|
3355
|
+
text: responseText,
|
|
3356
|
+
},
|
|
3357
|
+
],
|
|
3358
|
+
};
|
|
3359
|
+
}
|
|
3360
|
+
/**
|
|
3361
|
+
* Handle get modification status
|
|
3362
|
+
*/
|
|
3363
|
+
async handleGetModificationStatus(args) {
|
|
3364
|
+
const { containerId, modificationApplicationId } = args;
|
|
3365
|
+
const result = await modificationService.getModificationDetails(containerId, modificationApplicationId);
|
|
3366
|
+
const responseText = modificationService.formatAppliedModification(result);
|
|
3367
|
+
return {
|
|
3368
|
+
content: [
|
|
3369
|
+
{
|
|
3370
|
+
type: 'text',
|
|
3371
|
+
text: responseText,
|
|
3372
|
+
},
|
|
3373
|
+
],
|
|
3374
|
+
};
|
|
3375
|
+
}
|
|
3376
|
+
/**
|
|
3377
|
+
* Handle list applied modifications
|
|
3378
|
+
*/
|
|
3379
|
+
async handleListAppliedModifications(args) {
|
|
3380
|
+
const { containerId, status, limit = 50, offset = 0 } = args;
|
|
3381
|
+
const result = await modificationService.listAppliedModifications(containerId, status, limit, offset);
|
|
3382
|
+
let responseText = `**Applied Modifications**\n\n`;
|
|
3383
|
+
responseText += `Found ${result.count} modification(s)`;
|
|
3384
|
+
if (result.hasMore) {
|
|
3385
|
+
responseText += ` (showing ${result.appliedModifications.length})`;
|
|
3386
|
+
}
|
|
3387
|
+
responseText += `\n\n`;
|
|
3388
|
+
if (result.appliedModifications.length === 0) {
|
|
3389
|
+
responseText += `No modifications have been applied to this container yet.\n`;
|
|
3390
|
+
}
|
|
3391
|
+
else {
|
|
3392
|
+
result.appliedModifications.forEach((mod, index) => {
|
|
3393
|
+
responseText += modificationService.formatAppliedModification(mod);
|
|
3394
|
+
responseText += `\n`;
|
|
3395
|
+
});
|
|
3396
|
+
}
|
|
3397
|
+
return {
|
|
3398
|
+
content: [
|
|
3399
|
+
{
|
|
3400
|
+
type: 'text',
|
|
3401
|
+
text: responseText,
|
|
3402
|
+
},
|
|
3403
|
+
],
|
|
3404
|
+
};
|
|
3405
|
+
}
|
|
2859
3406
|
/**
|
|
2860
3407
|
* Get container development workflow content
|
|
2861
3408
|
*/
|