@elliotding/ai-agent-mcp 0.1.25 → 0.1.26

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 (237) hide show
  1. package/package.json +4 -1
  2. package/.prompt-cache/cmd-cmd-client-sdk-ai-hub-generate-testcase.md +0 -101
  3. package/.prompt-cache/cmd-cmd-client-sdk-ai-hub-submit_zct_job.md +0 -158
  4. package/.prompt-cache/skill-skill-client-sdk-ai-hub-analyze-conf-status.md +0 -311
  5. package/.prompt-cache/skill-skill-client-sdk-ai-hub-analyze-sdk-log.md +0 -64
  6. package/.prompt-cache/skill-skill-client-sdk-ai-hub-analyze-zmb-log-errors.md +0 -84
  7. package/ai-resource-telemetry.json +0 -40
  8. package/dist/api/cached-client.d.ts +0 -48
  9. package/dist/api/cached-client.d.ts.map +0 -1
  10. package/dist/api/cached-client.js +0 -126
  11. package/dist/api/cached-client.js.map +0 -1
  12. package/dist/api/client.d.ts +0 -281
  13. package/dist/api/client.d.ts.map +0 -1
  14. package/dist/api/client.js +0 -371
  15. package/dist/api/client.js.map +0 -1
  16. package/dist/auth/index.d.ts +0 -8
  17. package/dist/auth/index.d.ts.map +0 -1
  18. package/dist/auth/index.js +0 -26
  19. package/dist/auth/index.js.map +0 -1
  20. package/dist/auth/middleware.d.ts +0 -36
  21. package/dist/auth/middleware.d.ts.map +0 -1
  22. package/dist/auth/middleware.js +0 -194
  23. package/dist/auth/middleware.js.map +0 -1
  24. package/dist/auth/permissions.d.ts +0 -60
  25. package/dist/auth/permissions.d.ts.map +0 -1
  26. package/dist/auth/permissions.js +0 -262
  27. package/dist/auth/permissions.js.map +0 -1
  28. package/dist/auth/token-validator.d.ts +0 -52
  29. package/dist/auth/token-validator.d.ts.map +0 -1
  30. package/dist/auth/token-validator.js +0 -215
  31. package/dist/auth/token-validator.js.map +0 -1
  32. package/dist/cache/cache-manager.d.ts +0 -49
  33. package/dist/cache/cache-manager.d.ts.map +0 -1
  34. package/dist/cache/cache-manager.js +0 -191
  35. package/dist/cache/cache-manager.js.map +0 -1
  36. package/dist/cache/index.d.ts +0 -6
  37. package/dist/cache/index.d.ts.map +0 -1
  38. package/dist/cache/index.js +0 -12
  39. package/dist/cache/index.js.map +0 -1
  40. package/dist/cache/redis-client.d.ts +0 -45
  41. package/dist/cache/redis-client.d.ts.map +0 -1
  42. package/dist/cache/redis-client.js +0 -210
  43. package/dist/cache/redis-client.js.map +0 -1
  44. package/dist/config/constants.d.ts +0 -28
  45. package/dist/config/constants.d.ts.map +0 -1
  46. package/dist/config/constants.js +0 -31
  47. package/dist/config/constants.js.map +0 -1
  48. package/dist/config/index.d.ts +0 -71
  49. package/dist/config/index.d.ts.map +0 -1
  50. package/dist/config/index.js +0 -190
  51. package/dist/config/index.js.map +0 -1
  52. package/dist/filesystem/manager.d.ts +0 -45
  53. package/dist/filesystem/manager.d.ts.map +0 -1
  54. package/dist/filesystem/manager.js +0 -246
  55. package/dist/filesystem/manager.js.map +0 -1
  56. package/dist/git/multi-source-manager.d.ts +0 -78
  57. package/dist/git/multi-source-manager.d.ts.map +0 -1
  58. package/dist/git/multi-source-manager.js +0 -577
  59. package/dist/git/multi-source-manager.js.map +0 -1
  60. package/dist/git/operations.d.ts +0 -27
  61. package/dist/git/operations.d.ts.map +0 -1
  62. package/dist/git/operations.js +0 -83
  63. package/dist/git/operations.js.map +0 -1
  64. package/dist/index.d.ts +0 -6
  65. package/dist/index.d.ts.map +0 -1
  66. package/dist/index.js +0 -122
  67. package/dist/index.js.map +0 -1
  68. package/dist/monitoring/health.d.ts +0 -35
  69. package/dist/monitoring/health.d.ts.map +0 -1
  70. package/dist/monitoring/health.js +0 -105
  71. package/dist/monitoring/health.js.map +0 -1
  72. package/dist/prompts/cache.d.ts +0 -69
  73. package/dist/prompts/cache.d.ts.map +0 -1
  74. package/dist/prompts/cache.js +0 -163
  75. package/dist/prompts/cache.js.map +0 -1
  76. package/dist/prompts/generator.d.ts +0 -49
  77. package/dist/prompts/generator.d.ts.map +0 -1
  78. package/dist/prompts/generator.js +0 -160
  79. package/dist/prompts/generator.js.map +0 -1
  80. package/dist/prompts/index.d.ts +0 -13
  81. package/dist/prompts/index.d.ts.map +0 -1
  82. package/dist/prompts/index.js +0 -24
  83. package/dist/prompts/index.js.map +0 -1
  84. package/dist/prompts/manager.d.ts +0 -207
  85. package/dist/prompts/manager.d.ts.map +0 -1
  86. package/dist/prompts/manager.js +0 -566
  87. package/dist/prompts/manager.js.map +0 -1
  88. package/dist/resources/index.d.ts +0 -6
  89. package/dist/resources/index.d.ts.map +0 -1
  90. package/dist/resources/index.js +0 -10
  91. package/dist/resources/index.js.map +0 -1
  92. package/dist/resources/loader.d.ts +0 -88
  93. package/dist/resources/loader.d.ts.map +0 -1
  94. package/dist/resources/loader.js +0 -492
  95. package/dist/resources/loader.js.map +0 -1
  96. package/dist/server/http.d.ts +0 -57
  97. package/dist/server/http.d.ts.map +0 -1
  98. package/dist/server/http.js +0 -435
  99. package/dist/server/http.js.map +0 -1
  100. package/dist/server.d.ts +0 -13
  101. package/dist/server.d.ts.map +0 -1
  102. package/dist/server.js +0 -201
  103. package/dist/server.js.map +0 -1
  104. package/dist/session/manager.d.ts +0 -91
  105. package/dist/session/manager.d.ts.map +0 -1
  106. package/dist/session/manager.js +0 -251
  107. package/dist/session/manager.js.map +0 -1
  108. package/dist/telemetry/index.d.ts +0 -3
  109. package/dist/telemetry/index.d.ts.map +0 -1
  110. package/dist/telemetry/index.js +0 -7
  111. package/dist/telemetry/index.js.map +0 -1
  112. package/dist/telemetry/manager.d.ts +0 -151
  113. package/dist/telemetry/manager.d.ts.map +0 -1
  114. package/dist/telemetry/manager.js +0 -367
  115. package/dist/telemetry/manager.js.map +0 -1
  116. package/dist/tools/index.d.ts +0 -13
  117. package/dist/tools/index.d.ts.map +0 -1
  118. package/dist/tools/index.js +0 -29
  119. package/dist/tools/index.js.map +0 -1
  120. package/dist/tools/manage-subscription.d.ts +0 -47
  121. package/dist/tools/manage-subscription.d.ts.map +0 -1
  122. package/dist/tools/manage-subscription.js +0 -317
  123. package/dist/tools/manage-subscription.js.map +0 -1
  124. package/dist/tools/registry.d.ts +0 -40
  125. package/dist/tools/registry.d.ts.map +0 -1
  126. package/dist/tools/registry.js +0 -85
  127. package/dist/tools/registry.js.map +0 -1
  128. package/dist/tools/resolve-prompt-content.d.ts +0 -35
  129. package/dist/tools/resolve-prompt-content.d.ts.map +0 -1
  130. package/dist/tools/resolve-prompt-content.js +0 -99
  131. package/dist/tools/resolve-prompt-content.js.map +0 -1
  132. package/dist/tools/search-resources.d.ts +0 -35
  133. package/dist/tools/search-resources.d.ts.map +0 -1
  134. package/dist/tools/search-resources.js +0 -159
  135. package/dist/tools/search-resources.js.map +0 -1
  136. package/dist/tools/sync-resources.d.ts +0 -54
  137. package/dist/tools/sync-resources.d.ts.map +0 -1
  138. package/dist/tools/sync-resources.js +0 -735
  139. package/dist/tools/sync-resources.js.map +0 -1
  140. package/dist/tools/track-usage.d.ts +0 -63
  141. package/dist/tools/track-usage.d.ts.map +0 -1
  142. package/dist/tools/track-usage.js +0 -90
  143. package/dist/tools/track-usage.js.map +0 -1
  144. package/dist/tools/uninstall-resource.d.ts +0 -30
  145. package/dist/tools/uninstall-resource.d.ts.map +0 -1
  146. package/dist/tools/uninstall-resource.js +0 -174
  147. package/dist/tools/uninstall-resource.js.map +0 -1
  148. package/dist/tools/upload-resource.d.ts +0 -81
  149. package/dist/tools/upload-resource.d.ts.map +0 -1
  150. package/dist/tools/upload-resource.js +0 -393
  151. package/dist/tools/upload-resource.js.map +0 -1
  152. package/dist/transport/sse.d.ts +0 -29
  153. package/dist/transport/sse.d.ts.map +0 -1
  154. package/dist/transport/sse.js +0 -271
  155. package/dist/transport/sse.js.map +0 -1
  156. package/dist/types/errors.d.ts +0 -60
  157. package/dist/types/errors.d.ts.map +0 -1
  158. package/dist/types/errors.js +0 -112
  159. package/dist/types/errors.js.map +0 -1
  160. package/dist/types/index.d.ts +0 -7
  161. package/dist/types/index.d.ts.map +0 -1
  162. package/dist/types/index.js +0 -23
  163. package/dist/types/index.js.map +0 -1
  164. package/dist/types/mcp.d.ts +0 -50
  165. package/dist/types/mcp.d.ts.map +0 -1
  166. package/dist/types/mcp.js +0 -6
  167. package/dist/types/mcp.js.map +0 -1
  168. package/dist/types/resources.d.ts +0 -109
  169. package/dist/types/resources.d.ts.map +0 -1
  170. package/dist/types/resources.js +0 -7
  171. package/dist/types/resources.js.map +0 -1
  172. package/dist/types/tools.d.ts +0 -253
  173. package/dist/types/tools.d.ts.map +0 -1
  174. package/dist/types/tools.js +0 -6
  175. package/dist/types/tools.js.map +0 -1
  176. package/dist/utils/cursor-paths.d.ts +0 -84
  177. package/dist/utils/cursor-paths.d.ts.map +0 -1
  178. package/dist/utils/cursor-paths.js +0 -166
  179. package/dist/utils/cursor-paths.js.map +0 -1
  180. package/dist/utils/log-cleaner.d.ts +0 -18
  181. package/dist/utils/log-cleaner.d.ts.map +0 -1
  182. package/dist/utils/log-cleaner.js +0 -112
  183. package/dist/utils/log-cleaner.js.map +0 -1
  184. package/dist/utils/logger.d.ts +0 -59
  185. package/dist/utils/logger.d.ts.map +0 -1
  186. package/dist/utils/logger.js +0 -292
  187. package/dist/utils/logger.js.map +0 -1
  188. package/dist/utils/validation.d.ts +0 -58
  189. package/dist/utils/validation.d.ts.map +0 -1
  190. package/dist/utils/validation.js +0 -214
  191. package/dist/utils/validation.js.map +0 -1
  192. package/src/api/cached-client.ts +0 -144
  193. package/src/api/client.ts +0 -697
  194. package/src/auth/index.ts +0 -11
  195. package/src/auth/middleware.ts +0 -244
  196. package/src/auth/permissions.ts +0 -323
  197. package/src/auth/token-validator.ts +0 -292
  198. package/src/cache/cache-manager.ts +0 -243
  199. package/src/cache/index.ts +0 -6
  200. package/src/cache/redis-client.ts +0 -249
  201. package/src/config/constants.ts +0 -33
  202. package/src/config/index.ts +0 -269
  203. package/src/filesystem/manager.ts +0 -235
  204. package/src/git/multi-source-manager.ts +0 -654
  205. package/src/git/operations.ts +0 -93
  206. package/src/index.ts +0 -157
  207. package/src/monitoring/health.ts +0 -132
  208. package/src/prompts/cache.ts +0 -140
  209. package/src/prompts/generator.ts +0 -143
  210. package/src/prompts/index.ts +0 -20
  211. package/src/prompts/manager.ts +0 -718
  212. package/src/resources/index.ts +0 -13
  213. package/src/resources/loader.ts +0 -563
  214. package/src/server/http.ts +0 -549
  215. package/src/server.ts +0 -206
  216. package/src/session/manager.ts +0 -296
  217. package/src/telemetry/index.ts +0 -10
  218. package/src/telemetry/manager.ts +0 -419
  219. package/src/tools/index.ts +0 -13
  220. package/src/tools/manage-subscription.ts +0 -388
  221. package/src/tools/registry.ts +0 -97
  222. package/src/tools/resolve-prompt-content.ts +0 -113
  223. package/src/tools/search-resources.ts +0 -185
  224. package/src/tools/sync-resources.ts +0 -829
  225. package/src/tools/track-usage.ts +0 -113
  226. package/src/tools/uninstall-resource.ts +0 -199
  227. package/src/tools/upload-resource.ts +0 -431
  228. package/src/transport/sse.ts +0 -308
  229. package/src/types/errors.ts +0 -146
  230. package/src/types/index.ts +0 -7
  231. package/src/types/mcp.ts +0 -61
  232. package/src/types/resources.ts +0 -141
  233. package/src/types/tools.ts +0 -305
  234. package/src/utils/cursor-paths.ts +0 -135
  235. package/src/utils/log-cleaner.ts +0 -92
  236. package/src/utils/logger.ts +0 -333
  237. package/src/utils/validation.ts +0 -262
package/src/server.ts DELETED
@@ -1,206 +0,0 @@
1
- /**
2
- * MCP Server Main Logic
3
- * Implements Model Context Protocol server with dual transport support
4
- */
5
-
6
- import { Server } from '@modelcontextprotocol/sdk/server/index.js';
7
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
8
- import {
9
- CallToolRequestSchema,
10
- ListToolsRequestSchema,
11
- } from '@modelcontextprotocol/sdk/types.js';
12
- import { logger } from './utils/logger';
13
- import { config } from './config';
14
- import { toolRegistry } from './tools/registry';
15
- import {
16
- syncResourcesTool,
17
- manageSubscriptionTool,
18
- searchResourcesTool,
19
- uploadResourceTool,
20
- uninstallResourceTool,
21
- trackUsageTool,
22
- resolvePromptContentTool,
23
- } from './tools';
24
- import { httpServer } from './server/http';
25
-
26
- let server: Server | null = null;
27
-
28
- /**
29
- * Register all MCP tools
30
- */
31
- function registerTools() {
32
- logger.info('Registering MCP tools...');
33
-
34
- toolRegistry.registerTool(syncResourcesTool);
35
- toolRegistry.registerTool(manageSubscriptionTool);
36
- toolRegistry.registerTool(searchResourcesTool);
37
- toolRegistry.registerTool(uploadResourceTool);
38
- toolRegistry.registerTool(uninstallResourceTool);
39
- toolRegistry.registerTool(trackUsageTool);
40
- toolRegistry.registerTool(resolvePromptContentTool);
41
-
42
- logger.info(
43
- { toolCount: toolRegistry.getToolCount() },
44
- `Registered ${toolRegistry.getToolCount()} MCP tools`
45
- );
46
- }
47
-
48
- /**
49
- * Start MCP Server with stdio transport
50
- */
51
- async function startStdioServer(): Promise<void> {
52
- logger.info('Starting MCP Server with stdio transport...');
53
-
54
- // Create MCP Server
55
- server = new Server(
56
- {
57
- name: 'csp-ai-agent-mcp',
58
- version: '0.2.0',
59
- },
60
- {
61
- capabilities: {
62
- tools: {},
63
- prompts: {},
64
- },
65
- }
66
- );
67
-
68
- // Install Prompt list/get handlers so Command and Skill resources are
69
- // exposed as MCP Prompts (Cursor slash commands).
70
- const { promptManager } = await import('./prompts/index.js');
71
- promptManager.installHandlers(server);
72
-
73
- // Handle tools/list request
74
- server.setRequestHandler(ListToolsRequestSchema, () => {
75
- const tools = toolRegistry.getMCPToolDefinitions();
76
- logger.debug({ toolCount: tools.length }, 'tools/list request handled');
77
- return {
78
- tools,
79
- };
80
- });
81
-
82
- // Handle tools/call request
83
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
84
- const { name, arguments: args } = request.params;
85
-
86
- logger.info({ toolName: name, arguments: args }, `tools/call request: ${name}`);
87
-
88
- const tool = toolRegistry.getTool(name);
89
- if (!tool) {
90
- const error = `Tool not found: ${name}`;
91
- logger.error({ toolName: name }, error);
92
- return {
93
- content: [
94
- {
95
- type: 'text' as const,
96
- text: JSON.stringify({
97
- success: false,
98
- error: {
99
- code: 'TOOL_NOT_FOUND',
100
- message: error,
101
- },
102
- }),
103
- },
104
- ],
105
- isError: true,
106
- };
107
- }
108
-
109
- try {
110
- // Call the tool handler
111
- const result = await tool.handler(args || {});
112
-
113
- return {
114
- content: [
115
- {
116
- type: 'text' as const,
117
- text: JSON.stringify(result),
118
- },
119
- ],
120
- };
121
- } catch (error) {
122
- const errorMessage = error instanceof Error ? error.message : String(error);
123
- logger.error({ toolName: name, error: errorMessage }, `Tool execution failed: ${name}`);
124
-
125
- return {
126
- content: [
127
- {
128
- type: 'text' as const,
129
- text: JSON.stringify({
130
- success: false,
131
- error: {
132
- code: 'TOOL_EXECUTION_ERROR',
133
- message: errorMessage,
134
- },
135
- }),
136
- },
137
- ],
138
- isError: true,
139
- };
140
- }
141
- });
142
-
143
- // Connect to stdio transport
144
- const transport = new StdioServerTransport();
145
- await server.connect(transport);
146
-
147
- // Flush any pending telemetry immediately — stdio reconnects when Cursor
148
- // restarts the process, so treat connect as a reconnect event.
149
- const { telemetry: tel } = await import('./telemetry/index.js');
150
- tel.flushOnReconnect();
151
-
152
- logger.info('✅ MCP Server started successfully (stdio transport)');
153
- }
154
-
155
- /**
156
- * Start MCP Server with SSE transport
157
- */
158
- async function startSSEServer(): Promise<void> {
159
- logger.info('Starting MCP Server with SSE transport...');
160
-
161
- // Start HTTP server
162
- await httpServer.start();
163
-
164
- logger.info('✅ MCP Server started successfully (SSE transport)');
165
- }
166
-
167
- /**
168
- * Start MCP Server (auto-detect transport mode)
169
- */
170
- export async function startServer(): Promise<void> {
171
- // Register all tools (common for both transports)
172
- registerTools();
173
-
174
- // Start server based on transport mode
175
- const transportMode = config.transport.mode;
176
-
177
- logger.info({ transportMode }, `Starting server with ${transportMode} transport`);
178
-
179
- if (transportMode === 'sse') {
180
- await startSSEServer();
181
- } else {
182
- await startStdioServer();
183
- }
184
- }
185
-
186
- /**
187
- * Stop MCP Server
188
- */
189
- export async function stopServer(): Promise<void> {
190
- logger.info('Stopping MCP Server...');
191
-
192
- const transportMode = config.transport.mode;
193
-
194
- if (transportMode === 'sse') {
195
- // Stop HTTP server
196
- await httpServer.stop();
197
- } else {
198
- // Stop stdio server
199
- if (server) {
200
- await server.close();
201
- server = null;
202
- }
203
- }
204
-
205
- logger.info('MCP Server stopped');
206
- }
@@ -1,296 +0,0 @@
1
- /**
2
- * Session Manager
3
- * Manages SSE sessions and connections
4
- */
5
-
6
- import { randomUUID } from 'crypto';
7
- import type { ServerResponse } from 'http';
8
- import { logger } from '../utils/logger';
9
- import { config } from '../config';
10
-
11
- export interface Session {
12
- id: string;
13
- userId: string;
14
- email: string;
15
- groups: string[]; // Changed from 'roles' to 'groups'
16
- token: string;
17
- ip: string;
18
- createdAt: Date;
19
- lastActivity: Date;
20
- connection?: ServerResponse;
21
- }
22
-
23
- export interface CreateSessionOptions {
24
- userId?: string;
25
- email?: string;
26
- groups?: string[]; // Changed from 'roles' to 'groups'
27
- }
28
-
29
- export class SessionManager {
30
- private sessions: Map<string, Session> = new Map();
31
- private totalSessions: number = 0;
32
- private cleanupInterval?: NodeJS.Timeout;
33
-
34
- constructor() {
35
- // Start cleanup interval
36
- this.startCleanup();
37
- }
38
-
39
- /**
40
- * Create new session
41
- * @param token - Auth token (JWT from CSP)
42
- * @param ip - Client IP address
43
- * @param options - User info from /user/permissions API (userId, email, groups)
44
- */
45
- async createSession(
46
- token: string,
47
- ip: string,
48
- options?: CreateSessionOptions
49
- ): Promise<Session> {
50
- const sessionId = randomUUID();
51
-
52
- const userId = options?.userId ?? this.extractUserIdFromToken(token);
53
- const email = options?.email ?? '';
54
- const groups = options?.groups ?? [];
55
-
56
- const session: Session = {
57
- id: sessionId,
58
- userId,
59
- email,
60
- groups,
61
- token,
62
- ip,
63
- createdAt: new Date(),
64
- lastActivity: new Date(),
65
- };
66
-
67
- this.sessions.set(sessionId, session);
68
- this.totalSessions++;
69
-
70
- logger.info({ sessionId, userId, email, groups, ip }, 'Session created');
71
-
72
- return session;
73
- }
74
-
75
- /**
76
- * Get session by ID
77
- */
78
- getSession(sessionId: string): Session | undefined {
79
- return this.sessions.get(sessionId);
80
- }
81
-
82
- /**
83
- * Register SSE connection with session
84
- */
85
- registerConnection(sessionId: string, connection: ServerResponse): void {
86
- const session = this.sessions.get(sessionId);
87
- if (session) {
88
- session.connection = connection;
89
- logger.debug({ sessionId }, 'Connection registered with session');
90
- }
91
- }
92
-
93
- /**
94
- * Send message to session via SSE
95
- * Enhanced error handling to prevent EPIPE errors
96
- * Note: This is synchronous for SSE transport compatibility
97
- */
98
- sendMessage(sessionId: string, message: unknown): boolean {
99
- const session = this.sessions.get(sessionId);
100
- if (!session || !session.connection || session.connection.destroyed) {
101
- logger.debug({ sessionId }, 'Cannot send message: session not found or connection closed');
102
- return false;
103
- }
104
-
105
- try {
106
- const data = JSON.stringify(message);
107
-
108
- // Use write callback to detect errors (fire-and-forget)
109
- let writeSuccess = true;
110
- session.connection.write(`data: ${data}\n\n`, (err: Error | null | undefined) => {
111
- if (err) {
112
- // Handle specific error types
113
- if (err.message.includes('EPIPE') || err.message.includes('ECONNRESET')) {
114
- logger.debug({
115
- sessionId,
116
- error: err.message
117
- }, 'Message write failed (client disconnected)');
118
- } else {
119
- logger.warn({
120
- sessionId,
121
- error: err.message
122
- }, 'Message write failed');
123
- }
124
- writeSuccess = false;
125
- } else {
126
- logger.debug({ sessionId, messageSize: data.length }, 'Message sent to session');
127
- }
128
- });
129
-
130
- return writeSuccess;
131
- } catch (error) {
132
- // Catch synchronous errors
133
- if (error instanceof Error) {
134
- if (error.message.includes('EPIPE') || error.message.includes('ECONNRESET')) {
135
- logger.debug({
136
- sessionId,
137
- error: error.message
138
- }, 'Message send failed (client disconnected)');
139
- } else {
140
- logger.error({
141
- error: error.message,
142
- sessionId
143
- }, 'Failed to send message to session');
144
- }
145
- }
146
- return false;
147
- }
148
- }
149
-
150
- /**
151
- * Update session activity timestamp
152
- */
153
- updateActivity(sessionId: string): void {
154
- const session = this.sessions.get(sessionId);
155
- if (session) {
156
- session.lastActivity = new Date();
157
- }
158
- }
159
-
160
- /**
161
- * Close session with improved error handling
162
- */
163
- closeSession(sessionId: string): void {
164
- const session = this.sessions.get(sessionId);
165
- if (session) {
166
- // Close connection if exists
167
- if (session.connection && !session.connection.destroyed) {
168
- try {
169
- // Try to send close message
170
- session.connection.write(`data: ${JSON.stringify({ type: 'close' })}\n\n`, (err) => {
171
- if (err) {
172
- logger.debug({
173
- sessionId,
174
- error: err.message
175
- }, 'Close message write failed (expected if client already disconnected)');
176
- }
177
- });
178
-
179
- // End connection
180
- session.connection.end();
181
- } catch (error) {
182
- if (error instanceof Error) {
183
- // Only log non-EPIPE errors as warnings
184
- if (error.message.includes('EPIPE') || error.message.includes('ECONNRESET')) {
185
- logger.debug({
186
- sessionId,
187
- error: error.message
188
- }, 'Connection already closed');
189
- } else {
190
- logger.warn({
191
- sessionId,
192
- error: error.message
193
- }, 'Error closing connection');
194
- }
195
- }
196
- }
197
- }
198
-
199
- // Remove session
200
- this.sessions.delete(sessionId);
201
- logger.info({ sessionId }, 'Session closed');
202
- }
203
- }
204
-
205
- /**
206
- * Close all sessions
207
- */
208
- closeAllSessions(): void {
209
- logger.info({ count: this.sessions.size }, 'Closing all sessions');
210
-
211
- for (const [sessionId] of this.sessions) {
212
- this.closeSession(sessionId);
213
- }
214
- }
215
-
216
- /**
217
- * Get active session count
218
- */
219
- getActiveSessionCount(): number {
220
- return this.sessions.size;
221
- }
222
-
223
- /**
224
- * Get total session count (since server start)
225
- */
226
- getTotalSessionCount(): number {
227
- return this.totalSessions;
228
- }
229
-
230
- /**
231
- * Get all active sessions
232
- */
233
- getActiveSessions(): Session[] {
234
- return Array.from(this.sessions.values());
235
- }
236
-
237
- /**
238
- * Start cleanup interval for expired sessions
239
- */
240
- private startCleanup(): void {
241
- const timeout = config.session?.timeout || 3600; // Default 1 hour
242
- const cleanupInterval = 60000; // Check every 1 minute
243
-
244
- this.cleanupInterval = setInterval(() => {
245
- this.cleanupExpiredSessions(timeout);
246
- }, cleanupInterval);
247
-
248
- logger.info({ timeout, cleanupInterval }, 'Session cleanup started');
249
- }
250
-
251
- /**
252
- * Stop cleanup interval
253
- */
254
- stopCleanup(): void {
255
- if (this.cleanupInterval) {
256
- clearInterval(this.cleanupInterval);
257
- this.cleanupInterval = undefined;
258
- logger.info('Session cleanup stopped');
259
- }
260
- }
261
-
262
- /**
263
- * Cleanup expired sessions
264
- */
265
- private cleanupExpiredSessions(timeoutSeconds: number): void {
266
- const now = Date.now();
267
- const expiredSessions: string[] = [];
268
-
269
- for (const [sessionId, session] of this.sessions) {
270
- const inactiveTime = (now - session.lastActivity.getTime()) / 1000;
271
- if (inactiveTime > timeoutSeconds) {
272
- expiredSessions.push(sessionId);
273
- }
274
- }
275
-
276
- if (expiredSessions.length > 0) {
277
- logger.info({ count: expiredSessions.length }, 'Cleaning up expired sessions');
278
- for (const sessionId of expiredSessions) {
279
- this.closeSession(sessionId);
280
- }
281
- }
282
- }
283
-
284
- /**
285
- * Extract user ID from token (simplified)
286
- * TODO: Implement proper JWT validation in Stage 5
287
- */
288
- private extractUserIdFromToken(token: string): string {
289
- // For now, use a simple hash or the token itself
290
- // In Stage 5, this should decode and validate JWT
291
- return token.substring(0, 16);
292
- }
293
- }
294
-
295
- // Singleton instance
296
- export const sessionManager = new SessionManager();
@@ -1,10 +0,0 @@
1
- export { TelemetryManager, telemetry } from './manager.js';
2
- export type {
3
- ResourceCategory,
4
- InvocationEvent,
5
- SubscribedRule,
6
- ConfiguredMcp,
7
- TelemetryFile,
8
- TelemetryReportPayload,
9
- ReportFn,
10
- } from './manager.js';