@172ai/containers-mcp-server 1.9.3 → 1.10.1

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.
@@ -0,0 +1,198 @@
1
+ "use strict";
2
+ /**
3
+ * Log Buffer Utility for Runtime Log Streaming
4
+ * Prevents duplicate logs and manages streaming log display
5
+ *
6
+ * Features:
7
+ * - insertId-based deduplication (matches backend processor)
8
+ * - Per-execution log buffering with configurable max size
9
+ * - Automatic cleanup of old execution buffers
10
+ * - Statistics tracking for monitoring
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.logBuffer = exports.LogBuffer = void 0;
14
+ class LogBuffer {
15
+ constructor(maxLogsPerExecution = 1000, bufferInactivityTimeout = 60 * 60 * 1000 // 1 hour default
16
+ ) {
17
+ this.buffers = new Map();
18
+ this.cleanupInterval = null;
19
+ this.maxLogsPerExecution = maxLogsPerExecution;
20
+ this.bufferInactivityTimeout = bufferInactivityTimeout;
21
+ // Start automatic cleanup of stale buffers
22
+ this.startCleanupTimer();
23
+ }
24
+ /**
25
+ * Add logs for an execution with deduplication
26
+ * Returns only the new (non-duplicate) logs
27
+ */
28
+ addLogs(executionId, logs, containerId, containerName) {
29
+ // Get or create buffer for this execution
30
+ let buffer = this.buffers.get(executionId);
31
+ if (!buffer) {
32
+ buffer = {
33
+ executionId,
34
+ containerId: containerId || 'unknown',
35
+ containerName: containerName || 'Unknown Container',
36
+ logs: [],
37
+ seenInsertIds: new Set(),
38
+ createdAt: Date.now(),
39
+ lastActivity: Date.now(),
40
+ totalLogsReceived: 0,
41
+ duplicatesFiltered: 0
42
+ };
43
+ this.buffers.set(executionId, buffer);
44
+ }
45
+ // Filter out duplicates using insertId
46
+ const newLogs = [];
47
+ for (const log of logs) {
48
+ buffer.totalLogsReceived++;
49
+ if (!log.insertId || buffer.seenInsertIds.has(log.insertId)) {
50
+ buffer.duplicatesFiltered++;
51
+ continue;
52
+ }
53
+ buffer.seenInsertIds.add(log.insertId);
54
+ newLogs.push(log);
55
+ }
56
+ // Add new logs to buffer
57
+ buffer.logs.push(...newLogs);
58
+ buffer.lastActivity = Date.now();
59
+ // Enforce max size by removing oldest logs
60
+ if (buffer.logs.length > this.maxLogsPerExecution) {
61
+ const logsToRemove = buffer.logs.length - this.maxLogsPerExecution;
62
+ const removedLogs = buffer.logs.splice(0, logsToRemove);
63
+ // Remove insertIds from tracking for removed logs
64
+ removedLogs.forEach(log => {
65
+ if (log.insertId) {
66
+ buffer.seenInsertIds.delete(log.insertId);
67
+ }
68
+ });
69
+ }
70
+ return newLogs;
71
+ }
72
+ /**
73
+ * Get logs for a specific execution
74
+ */
75
+ getLogs(executionId, limit) {
76
+ const buffer = this.buffers.get(executionId);
77
+ if (!buffer) {
78
+ return [];
79
+ }
80
+ const logs = buffer.logs;
81
+ if (limit && limit < logs.length) {
82
+ return logs.slice(-limit); // Return most recent N logs
83
+ }
84
+ return logs;
85
+ }
86
+ /**
87
+ * Clear logs for a specific execution
88
+ */
89
+ clear(executionId) {
90
+ this.buffers.delete(executionId);
91
+ }
92
+ /**
93
+ * Get statistics about all buffers
94
+ */
95
+ getStats() {
96
+ const now = Date.now();
97
+ let totalLogs = 0;
98
+ let totalDuplicatesFiltered = 0;
99
+ let oldestBufferAge = 0;
100
+ let newestBufferAge = Infinity;
101
+ let totalBufferSize = 0;
102
+ for (const buffer of this.buffers.values()) {
103
+ totalLogs += buffer.logs.length;
104
+ totalDuplicatesFiltered += buffer.duplicatesFiltered;
105
+ const age = now - buffer.createdAt;
106
+ oldestBufferAge = Math.max(oldestBufferAge, age);
107
+ newestBufferAge = Math.min(newestBufferAge, age);
108
+ totalBufferSize += buffer.logs.length;
109
+ }
110
+ return {
111
+ totalBuffers: this.buffers.size,
112
+ totalLogs,
113
+ totalDuplicatesFiltered,
114
+ oldestBufferAge,
115
+ newestBufferAge: newestBufferAge === Infinity ? 0 : newestBufferAge,
116
+ averageBufferSize: this.buffers.size > 0 ? totalBufferSize / this.buffers.size : 0
117
+ };
118
+ }
119
+ /**
120
+ * Get all execution IDs with active buffers
121
+ */
122
+ getActiveExecutions() {
123
+ return Array.from(this.buffers.keys());
124
+ }
125
+ /**
126
+ * Check if an execution has an active buffer
127
+ */
128
+ hasBuffer(executionId) {
129
+ return this.buffers.has(executionId);
130
+ }
131
+ /**
132
+ * Get buffer info for monitoring
133
+ */
134
+ getBufferInfo(executionId) {
135
+ const buffer = this.buffers.get(executionId);
136
+ if (!buffer) {
137
+ return null;
138
+ }
139
+ return {
140
+ executionId: buffer.executionId,
141
+ containerId: buffer.containerId,
142
+ containerName: buffer.containerName,
143
+ logs: buffer.logs,
144
+ createdAt: buffer.createdAt,
145
+ lastActivity: buffer.lastActivity,
146
+ totalLogsReceived: buffer.totalLogsReceived,
147
+ duplicatesFiltered: buffer.duplicatesFiltered
148
+ };
149
+ }
150
+ /**
151
+ * Start automatic cleanup timer for stale buffers
152
+ */
153
+ startCleanupTimer() {
154
+ // Run cleanup every 5 minutes
155
+ this.cleanupInterval = setInterval(() => {
156
+ this.cleanupStaleBuffers();
157
+ }, 5 * 60 * 1000);
158
+ }
159
+ /**
160
+ * Clean up buffers that haven't had activity recently
161
+ */
162
+ cleanupStaleBuffers() {
163
+ const now = Date.now();
164
+ const staleExecutions = [];
165
+ for (const [executionId, buffer] of this.buffers.entries()) {
166
+ const inactiveTime = now - buffer.lastActivity;
167
+ if (inactiveTime > this.bufferInactivityTimeout) {
168
+ staleExecutions.push(executionId);
169
+ }
170
+ }
171
+ if (staleExecutions.length > 0) {
172
+ console.log(`[LogBuffer] Cleaning up ${staleExecutions.length} stale execution buffers`);
173
+ staleExecutions.forEach(executionId => {
174
+ this.buffers.delete(executionId);
175
+ });
176
+ }
177
+ }
178
+ /**
179
+ * Stop cleanup timer (for testing or shutdown)
180
+ */
181
+ destroy() {
182
+ if (this.cleanupInterval) {
183
+ clearInterval(this.cleanupInterval);
184
+ this.cleanupInterval = null;
185
+ }
186
+ this.buffers.clear();
187
+ }
188
+ /**
189
+ * Clear all buffers
190
+ */
191
+ clearAll() {
192
+ this.buffers.clear();
193
+ }
194
+ }
195
+ exports.LogBuffer = LogBuffer;
196
+ // Export singleton instance
197
+ exports.logBuffer = new LogBuffer();
198
+ //# sourceMappingURL=logBuffer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logBuffer.js","sourceRoot":"","sources":["../../src/utils/logBuffer.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@172ai/containers-mcp-server",
3
- "version": "1.9.3",
3
+ "version": "1.10.1",
4
4
  "description": "MCP server for 172.ai container management platform - enables AI assistants to manage containers, builds, and files with comprehensive workflow prompts",
5
5
  "main": "dist/cli.js",
6
6
  "bin": {