@hailer/mcp 0.1.17 → 0.2.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.
Files changed (200) hide show
  1. package/dist/app.js +24 -20
  2. package/dist/core.d.ts +33 -9
  3. package/dist/core.js +279 -147
  4. package/dist/mcp/UserContextCache.js +18 -0
  5. package/dist/mcp/hailer-clients.d.ts +9 -1
  6. package/dist/mcp/hailer-clients.js +13 -3
  7. package/dist/mcp/signal-handler.js +1 -1
  8. package/dist/mcp/tool-registry.d.ts +3 -1
  9. package/dist/mcp/tool-registry.js +4 -1
  10. package/dist/mcp/tools/activity.js +43 -34
  11. package/dist/mcp/tools/bot-config/constants.d.ts +23 -0
  12. package/dist/mcp/tools/bot-config/constants.js +94 -0
  13. package/dist/mcp/tools/{bot-config.d.ts → bot-config/core.d.ts} +6 -6
  14. package/dist/mcp/tools/{bot-config.js → bot-config/core.js} +15 -15
  15. package/dist/mcp/tools/bot-config/index.d.ts +10 -0
  16. package/dist/mcp/tools/bot-config/index.js +59 -0
  17. package/dist/mcp/tools/bot-config/tools.d.ts +7 -0
  18. package/dist/mcp/tools/bot-config/tools.js +15 -0
  19. package/dist/mcp/tools/bot-config/types.d.ts +50 -0
  20. package/dist/mcp/tools/bot-config/types.js +6 -0
  21. package/dist/mcp/tools/bug-fixer-tools.d.ts +21 -0
  22. package/dist/mcp/tools/{giuseppe-tools.js → bug-fixer-tools.js} +61 -61
  23. package/dist/mcp/tools/user.js +10 -29
  24. package/dist/mcp/tools/workflow.js +36 -2
  25. package/dist/mcp/utils/data-transformers.d.ts +0 -8
  26. package/dist/mcp/utils/data-transformers.js +0 -28
  27. package/dist/mcp/utils/index.d.ts +4 -1
  28. package/dist/mcp/utils/index.js +17 -3
  29. package/dist/mcp/utils/pagination.d.ts +40 -0
  30. package/dist/mcp/utils/pagination.js +55 -0
  31. package/dist/mcp/utils/response-builder.d.ts +53 -0
  32. package/dist/mcp/utils/response-builder.js +110 -0
  33. package/dist/mcp/utils/tool-helpers.d.ts +0 -8
  34. package/dist/mcp/utils/tool-helpers.js +0 -24
  35. package/dist/mcp/utils/types.d.ts +1 -33
  36. package/dist/mcp-server.d.ts +2 -2
  37. package/dist/mcp-server.js +161 -139
  38. package/package.json +1 -1
  39. package/REFACTOR_STATUS.md +0 -127
  40. package/dist/agents/bot-manager.d.ts +0 -48
  41. package/dist/agents/bot-manager.js +0 -254
  42. package/dist/agents/factory.d.ts +0 -150
  43. package/dist/agents/factory.js +0 -650
  44. package/dist/agents/giuseppe/ai.d.ts +0 -83
  45. package/dist/agents/giuseppe/ai.js +0 -466
  46. package/dist/agents/giuseppe/bot.d.ts +0 -110
  47. package/dist/agents/giuseppe/bot.js +0 -780
  48. package/dist/agents/giuseppe/config.d.ts +0 -25
  49. package/dist/agents/giuseppe/config.js +0 -227
  50. package/dist/agents/giuseppe/files.d.ts +0 -52
  51. package/dist/agents/giuseppe/files.js +0 -338
  52. package/dist/agents/giuseppe/git.d.ts +0 -48
  53. package/dist/agents/giuseppe/git.js +0 -298
  54. package/dist/agents/giuseppe/index.d.ts +0 -97
  55. package/dist/agents/giuseppe/index.js +0 -258
  56. package/dist/agents/giuseppe/lsp.d.ts +0 -113
  57. package/dist/agents/giuseppe/lsp.js +0 -485
  58. package/dist/agents/giuseppe/monitor.d.ts +0 -118
  59. package/dist/agents/giuseppe/monitor.js +0 -621
  60. package/dist/agents/giuseppe/prompt.d.ts +0 -5
  61. package/dist/agents/giuseppe/prompt.js +0 -94
  62. package/dist/agents/giuseppe/registries/pending-classification.d.ts +0 -28
  63. package/dist/agents/giuseppe/registries/pending-classification.js +0 -50
  64. package/dist/agents/giuseppe/registries/pending-fix.d.ts +0 -30
  65. package/dist/agents/giuseppe/registries/pending-fix.js +0 -42
  66. package/dist/agents/giuseppe/registries/pending.d.ts +0 -27
  67. package/dist/agents/giuseppe/registries/pending.js +0 -49
  68. package/dist/agents/giuseppe/specialist.d.ts +0 -47
  69. package/dist/agents/giuseppe/specialist.js +0 -237
  70. package/dist/agents/giuseppe/types.d.ts +0 -123
  71. package/dist/agents/giuseppe/types.js +0 -9
  72. package/dist/agents/hailer-expert/index.d.ts +0 -8
  73. package/dist/agents/hailer-expert/index.js +0 -14
  74. package/dist/agents/hal/daemon.d.ts +0 -142
  75. package/dist/agents/hal/daemon.js +0 -1103
  76. package/dist/agents/hal/definitions.d.ts +0 -55
  77. package/dist/agents/hal/definitions.js +0 -263
  78. package/dist/agents/hal/index.d.ts +0 -3
  79. package/dist/agents/hal/index.js +0 -8
  80. package/dist/agents/index.d.ts +0 -18
  81. package/dist/agents/index.js +0 -48
  82. package/dist/agents/shared/base.d.ts +0 -216
  83. package/dist/agents/shared/base.js +0 -846
  84. package/dist/agents/shared/services/agent-registry.d.ts +0 -107
  85. package/dist/agents/shared/services/agent-registry.js +0 -629
  86. package/dist/agents/shared/services/conversation-manager.d.ts +0 -50
  87. package/dist/agents/shared/services/conversation-manager.js +0 -136
  88. package/dist/agents/shared/services/mcp-client.d.ts +0 -56
  89. package/dist/agents/shared/services/mcp-client.js +0 -124
  90. package/dist/agents/shared/services/message-classifier.d.ts +0 -37
  91. package/dist/agents/shared/services/message-classifier.js +0 -187
  92. package/dist/agents/shared/services/message-formatter.d.ts +0 -89
  93. package/dist/agents/shared/services/message-formatter.js +0 -371
  94. package/dist/agents/shared/services/session-logger.d.ts +0 -106
  95. package/dist/agents/shared/services/session-logger.js +0 -446
  96. package/dist/agents/shared/services/tool-executor.d.ts +0 -41
  97. package/dist/agents/shared/services/tool-executor.js +0 -169
  98. package/dist/agents/shared/services/workspace-schema-cache.d.ts +0 -125
  99. package/dist/agents/shared/services/workspace-schema-cache.js +0 -578
  100. package/dist/agents/shared/specialist.d.ts +0 -91
  101. package/dist/agents/shared/specialist.js +0 -399
  102. package/dist/agents/shared/tool-schema-loader.d.ts +0 -62
  103. package/dist/agents/shared/tool-schema-loader.js +0 -232
  104. package/dist/agents/shared/types.d.ts +0 -327
  105. package/dist/agents/shared/types.js +0 -121
  106. package/dist/client/agents/base.d.ts +0 -207
  107. package/dist/client/agents/base.js +0 -744
  108. package/dist/client/agents/definitions.d.ts +0 -53
  109. package/dist/client/agents/definitions.js +0 -263
  110. package/dist/client/agents/orchestrator.d.ts +0 -141
  111. package/dist/client/agents/orchestrator.js +0 -1062
  112. package/dist/client/agents/specialist.d.ts +0 -86
  113. package/dist/client/agents/specialist.js +0 -340
  114. package/dist/client/bot-entrypoint.d.ts +0 -7
  115. package/dist/client/bot-entrypoint.js +0 -103
  116. package/dist/client/bot-manager.d.ts +0 -44
  117. package/dist/client/bot-manager.js +0 -173
  118. package/dist/client/bot-runner.d.ts +0 -35
  119. package/dist/client/bot-runner.js +0 -188
  120. package/dist/client/chat-agent-daemon.d.ts +0 -464
  121. package/dist/client/chat-agent-daemon.js +0 -1774
  122. package/dist/client/daemon-factory.d.ts +0 -106
  123. package/dist/client/daemon-factory.js +0 -301
  124. package/dist/client/factory.d.ts +0 -111
  125. package/dist/client/factory.js +0 -314
  126. package/dist/client/index.d.ts +0 -17
  127. package/dist/client/index.js +0 -38
  128. package/dist/client/multi-bot-manager.d.ts +0 -42
  129. package/dist/client/multi-bot-manager.js +0 -161
  130. package/dist/client/orchestrator-daemon.d.ts +0 -87
  131. package/dist/client/orchestrator-daemon.js +0 -444
  132. package/dist/client/server.d.ts +0 -8
  133. package/dist/client/server.js +0 -251
  134. package/dist/client/services/agent-registry.d.ts +0 -108
  135. package/dist/client/services/agent-registry.js +0 -630
  136. package/dist/client/services/conversation-manager.d.ts +0 -50
  137. package/dist/client/services/conversation-manager.js +0 -136
  138. package/dist/client/services/mcp-client.d.ts +0 -48
  139. package/dist/client/services/mcp-client.js +0 -105
  140. package/dist/client/services/message-classifier.d.ts +0 -37
  141. package/dist/client/services/message-classifier.js +0 -187
  142. package/dist/client/services/message-formatter.d.ts +0 -84
  143. package/dist/client/services/message-formatter.js +0 -353
  144. package/dist/client/services/session-logger.d.ts +0 -106
  145. package/dist/client/services/session-logger.js +0 -446
  146. package/dist/client/services/tool-executor.d.ts +0 -41
  147. package/dist/client/services/tool-executor.js +0 -169
  148. package/dist/client/services/workspace-schema-cache.d.ts +0 -149
  149. package/dist/client/services/workspace-schema-cache.js +0 -732
  150. package/dist/client/specialist-daemon.d.ts +0 -77
  151. package/dist/client/specialist-daemon.js +0 -197
  152. package/dist/client/specialists.d.ts +0 -53
  153. package/dist/client/specialists.js +0 -178
  154. package/dist/client/tool-schema-loader.d.ts +0 -62
  155. package/dist/client/tool-schema-loader.js +0 -232
  156. package/dist/client/types.d.ts +0 -327
  157. package/dist/client/types.js +0 -121
  158. package/dist/commands/seed-config.d.ts +0 -9
  159. package/dist/commands/seed-config.js +0 -372
  160. package/dist/lib/context-manager.d.ts +0 -111
  161. package/dist/lib/context-manager.js +0 -431
  162. package/dist/lib/prompt-length-manager.d.ts +0 -81
  163. package/dist/lib/prompt-length-manager.js +0 -457
  164. package/dist/mcp/tools/giuseppe-tools.d.ts +0 -21
  165. package/dist/modules/bug-reports/bug-config.d.ts +0 -25
  166. package/dist/modules/bug-reports/bug-config.js +0 -187
  167. package/dist/modules/bug-reports/bug-monitor.d.ts +0 -108
  168. package/dist/modules/bug-reports/bug-monitor.js +0 -510
  169. package/dist/modules/bug-reports/giuseppe-agent.d.ts +0 -58
  170. package/dist/modules/bug-reports/giuseppe-agent.js +0 -467
  171. package/dist/modules/bug-reports/giuseppe-ai.d.ts +0 -83
  172. package/dist/modules/bug-reports/giuseppe-ai.js +0 -466
  173. package/dist/modules/bug-reports/giuseppe-bot.d.ts +0 -110
  174. package/dist/modules/bug-reports/giuseppe-bot.js +0 -804
  175. package/dist/modules/bug-reports/giuseppe-daemon.d.ts +0 -80
  176. package/dist/modules/bug-reports/giuseppe-daemon.js +0 -617
  177. package/dist/modules/bug-reports/giuseppe-files.d.ts +0 -64
  178. package/dist/modules/bug-reports/giuseppe-files.js +0 -375
  179. package/dist/modules/bug-reports/giuseppe-git.d.ts +0 -48
  180. package/dist/modules/bug-reports/giuseppe-git.js +0 -298
  181. package/dist/modules/bug-reports/giuseppe-lsp.d.ts +0 -113
  182. package/dist/modules/bug-reports/giuseppe-lsp.js +0 -485
  183. package/dist/modules/bug-reports/giuseppe-prompt.d.ts +0 -5
  184. package/dist/modules/bug-reports/giuseppe-prompt.js +0 -94
  185. package/dist/modules/bug-reports/index.d.ts +0 -77
  186. package/dist/modules/bug-reports/index.js +0 -215
  187. package/dist/modules/bug-reports/pending-classification-registry.d.ts +0 -28
  188. package/dist/modules/bug-reports/pending-classification-registry.js +0 -50
  189. package/dist/modules/bug-reports/pending-fix-registry.d.ts +0 -30
  190. package/dist/modules/bug-reports/pending-fix-registry.js +0 -42
  191. package/dist/modules/bug-reports/pending-registry.d.ts +0 -27
  192. package/dist/modules/bug-reports/pending-registry.js +0 -49
  193. package/dist/modules/bug-reports/types.d.ts +0 -123
  194. package/dist/modules/bug-reports/types.js +0 -9
  195. package/dist/routes/agents.d.ts +0 -44
  196. package/dist/routes/agents.js +0 -311
  197. package/dist/services/agent-credential-store.d.ts +0 -73
  198. package/dist/services/agent-credential-store.js +0 -212
  199. package/dist/services/bug-monitor.d.ts +0 -23
  200. package/dist/services/bug-monitor.js +0 -275
@@ -1,311 +0,0 @@
1
- "use strict";
2
- /**
3
- * Agent Routes and Connection Manager
4
- *
5
- * REST API endpoints for enabling/disabling agents in workspaces
6
- * and managing their persistent connections.
7
- */
8
- var __importDefault = (this && this.__importDefault) || function (mod) {
9
- return (mod && mod.__esModule) ? mod : { "default": mod };
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.AgentConnectionManager = void 0;
13
- exports.createAgentRouter = createAgentRouter;
14
- const express_1 = require("express");
15
- const crypto_1 = __importDefault(require("crypto"));
16
- const zod_1 = require("zod");
17
- const cli_1 = require("@hailer/cli");
18
- const hailer_clients_1 = require("../mcp/hailer-clients");
19
- const config_1 = require("../config");
20
- const logger_1 = require("../lib/logger");
21
- // ================================================================================
22
- // AGENT CONNECTION MANAGER
23
- // ================================================================================
24
- /**
25
- * Manages persistent connections for enabled agents.
26
- * Handles connection lifecycle, reconnection, and signal handling.
27
- */
28
- class AgentConnectionManager {
29
- credentialStore;
30
- connections = new Map();
31
- logger = (0, logger_1.createLogger)({ component: 'agent-connection-manager' });
32
- constructor(credentialStore) {
33
- this.credentialStore = credentialStore;
34
- }
35
- /**
36
- * Connect an agent using stored credentials
37
- */
38
- async connect(credentials) {
39
- const connectionKey = `${credentials.workspaceId}:${credentials.agentType}`;
40
- // Check existing connection
41
- const existing = this.connections.get(connectionKey);
42
- if (existing && existing.isConnected()) {
43
- return existing.getClient();
44
- }
45
- // Clean stale connection
46
- if (existing) {
47
- existing.disconnect();
48
- this.connections.delete(connectionKey);
49
- }
50
- // Create new connection
51
- const password = this.credentialStore.decryptPassword(credentials.encryptedPassword);
52
- const clientManager = new hailer_clients_1.HailerClientManager(config_1.environment.HAILER_API_URL, credentials.email, password);
53
- await clientManager.connect();
54
- this.connections.set(connectionKey, clientManager);
55
- // Set up @mention listener
56
- clientManager.onSignal('messenger.new', (data) => {
57
- this.handleMentionSignal(credentials, data);
58
- });
59
- this.logger.info('Agent connected', {
60
- agentType: credentials.agentType,
61
- workspaceId: credentials.workspaceId
62
- });
63
- return clientManager.getClient();
64
- }
65
- /**
66
- * Disconnect an agent
67
- */
68
- async disconnect(workspaceId, agentType) {
69
- const connectionKey = `${workspaceId}:${agentType}`;
70
- const clientManager = this.connections.get(connectionKey);
71
- if (clientManager) {
72
- clientManager.disconnect();
73
- this.connections.delete(connectionKey);
74
- this.logger.info('Agent disconnected', { agentType, workspaceId });
75
- }
76
- }
77
- /**
78
- * Check if agent is connected
79
- */
80
- isConnected(workspaceId, agentType) {
81
- const connectionKey = `${workspaceId}:${agentType}`;
82
- const clientManager = this.connections.get(connectionKey);
83
- return clientManager?.isConnected() ?? false;
84
- }
85
- /**
86
- * Reconnect all agents on server startup
87
- */
88
- async reconnectAll() {
89
- const allCredentials = await this.credentialStore.listAll();
90
- const activeCredentials = allCredentials.filter(c => c.status === 'active');
91
- this.logger.info('Reconnecting agents', { count: activeCredentials.length });
92
- for (const credentials of activeCredentials) {
93
- try {
94
- await this.connect(credentials);
95
- }
96
- catch (error) {
97
- this.logger.error('Failed to reconnect agent', error, {
98
- agentType: credentials.agentType,
99
- workspaceId: credentials.workspaceId
100
- });
101
- // Update status to error
102
- await this.credentialStore.save({
103
- ...credentials,
104
- status: 'error',
105
- lastError: error instanceof Error ? error.message : String(error)
106
- });
107
- }
108
- }
109
- }
110
- /**
111
- * Handle @mention signals (placeholder for agent logic)
112
- */
113
- handleMentionSignal(credentials, data) {
114
- this.logger.debug('Mention signal received', {
115
- agentType: credentials.agentType,
116
- workspaceId: credentials.workspaceId,
117
- data
118
- });
119
- // TODO: Implement agent response logic
120
- }
121
- }
122
- exports.AgentConnectionManager = AgentConnectionManager;
123
- // ================================================================================
124
- // REQUEST VALIDATION SCHEMAS
125
- // ================================================================================
126
- const enableAgentSchema = zod_1.z.object({
127
- invite_key: zod_1.z.string().min(1, 'invite_key is required'),
128
- email: zod_1.z.string().email('Invalid email format'),
129
- agentType: zod_1.z.string().min(1, 'agentType is required'),
130
- displayName: zod_1.z.string().min(1, 'displayName is required'),
131
- workspaceId: zod_1.z.string().length(24, 'workspaceId must be 24 characters'),
132
- ownerId: zod_1.z.string().length(24, 'ownerId must be 24 characters'),
133
- });
134
- const disableAgentSchema = zod_1.z.object({
135
- agentType: zod_1.z.string().min(1, 'agentType is required'),
136
- workspaceId: zod_1.z.string().length(24, 'workspaceId must be 24 characters'),
137
- });
138
- // ================================================================================
139
- // ROUTER FACTORY
140
- // ================================================================================
141
- /**
142
- * Create Express router for agent management endpoints
143
- */
144
- function createAgentRouter(credentialStore, connectionManager) {
145
- const router = (0, express_1.Router)();
146
- const logger = (0, logger_1.createLogger)({ component: 'agent-routes' });
147
- // POST /enable - Enable an agent in a workspace
148
- router.post('/enable', async (req, res) => {
149
- try {
150
- // Validate request
151
- const validation = enableAgentSchema.safeParse(req.body);
152
- if (!validation.success) {
153
- return res.status(400).json({
154
- error: 'Validation failed',
155
- details: validation.error.flatten().fieldErrors
156
- });
157
- }
158
- const { invite_key, email, agentType, displayName, workspaceId, ownerId } = validation.data;
159
- // Check if already enabled
160
- const existing = await credentialStore.get(workspaceId, agentType);
161
- if (existing) {
162
- return res.status(409).json({
163
- error: 'Agent already enabled',
164
- agent: {
165
- agentType: existing.agentType,
166
- displayName: existing.displayName,
167
- status: existing.status,
168
- enabledAt: existing.enabledAt
169
- }
170
- });
171
- }
172
- // Generate secure password
173
- const password = crypto_1.default.randomBytes(32).toString('hex');
174
- // Create temp client for public invite registration (unauthenticated)
175
- logger.info('Registering agent via invite', { agentType, workspaceId });
176
- const tempClient = await cli_1.Client.create({ host: config_1.environment.HAILER_API_URL });
177
- try {
178
- await tempClient.request('v2.user.invite.register', [{
179
- firstname: displayName,
180
- lastname: 'Agent',
181
- password: password
182
- }, invite_key]);
183
- }
184
- finally {
185
- tempClient.disconnect();
186
- }
187
- // Store encrypted credentials
188
- const credentials = {
189
- workspaceId,
190
- agentType,
191
- email,
192
- encryptedPassword: credentialStore.encryptPassword(password),
193
- displayName,
194
- enabledBy: ownerId,
195
- enabledAt: new Date().toISOString(),
196
- status: 'pending'
197
- };
198
- await credentialStore.save(credentials);
199
- // Connect the agent
200
- try {
201
- await connectionManager.connect(credentials);
202
- credentials.status = 'active';
203
- credentials.lastConnectedAt = new Date().toISOString();
204
- await credentialStore.save(credentials);
205
- }
206
- catch (connectError) {
207
- credentials.status = 'error';
208
- credentials.lastError = connectError instanceof Error ? connectError.message : String(connectError);
209
- await credentialStore.save(credentials);
210
- logger.error('Agent registered but connection failed', connectError, { agentType, workspaceId });
211
- return res.status(207).json({
212
- success: true,
213
- warning: 'Agent registered but connection failed',
214
- agent: {
215
- agentType,
216
- displayName,
217
- workspaceId,
218
- status: 'error',
219
- error: credentials.lastError
220
- }
221
- });
222
- }
223
- logger.info('Agent enabled successfully', { agentType, workspaceId, displayName });
224
- res.json({
225
- success: true,
226
- agent: {
227
- agentType,
228
- displayName,
229
- workspaceId,
230
- status: 'active'
231
- }
232
- });
233
- }
234
- catch (error) {
235
- logger.error('Failed to enable agent', error);
236
- res.status(500).json({
237
- error: 'Failed to enable agent',
238
- details: error instanceof Error ? error.message : String(error)
239
- });
240
- }
241
- });
242
- // POST /disable - Disable an agent in a workspace
243
- router.post('/disable', async (req, res) => {
244
- try {
245
- const validation = disableAgentSchema.safeParse(req.body);
246
- if (!validation.success) {
247
- return res.status(400).json({
248
- error: 'Validation failed',
249
- details: validation.error.flatten().fieldErrors
250
- });
251
- }
252
- const { agentType, workspaceId } = validation.data;
253
- // Check if exists
254
- const existing = await credentialStore.get(workspaceId, agentType);
255
- if (!existing) {
256
- return res.status(404).json({
257
- error: 'Agent not found',
258
- agentType,
259
- workspaceId
260
- });
261
- }
262
- // Disconnect and remove
263
- await connectionManager.disconnect(workspaceId, agentType);
264
- await credentialStore.delete(workspaceId, agentType);
265
- logger.info('Agent disabled', { agentType, workspaceId });
266
- res.json({
267
- success: true,
268
- message: `Agent ${agentType} disabled in workspace ${workspaceId}`
269
- });
270
- }
271
- catch (error) {
272
- logger.error('Failed to disable agent', error);
273
- res.status(500).json({
274
- error: 'Failed to disable agent',
275
- details: error instanceof Error ? error.message : String(error)
276
- });
277
- }
278
- });
279
- // GET /list/:workspaceId - List enabled agents for a workspace
280
- router.get('/list/:workspaceId', async (req, res) => {
281
- try {
282
- const { workspaceId } = req.params;
283
- if (!workspaceId || workspaceId.length !== 24) {
284
- return res.status(400).json({
285
- error: 'Invalid workspaceId - must be 24 characters'
286
- });
287
- }
288
- const credentials = await credentialStore.listByWorkspace(workspaceId);
289
- const agents = credentials.map(cred => ({
290
- agentType: cred.agentType,
291
- displayName: cred.displayName,
292
- status: cred.status,
293
- enabledAt: cred.enabledAt,
294
- enabledBy: cred.enabledBy,
295
- connected: connectionManager.isConnected(workspaceId, cred.agentType),
296
- lastConnectedAt: cred.lastConnectedAt,
297
- lastError: cred.lastError
298
- }));
299
- res.json({ agents });
300
- }
301
- catch (error) {
302
- logger.error('Failed to list agents', error);
303
- res.status(500).json({
304
- error: 'Failed to list agents',
305
- details: error instanceof Error ? error.message : String(error)
306
- });
307
- }
308
- });
309
- return router;
310
- }
311
- //# sourceMappingURL=agents.js.map
@@ -1,73 +0,0 @@
1
- /**
2
- * Agent Credential Store
3
- *
4
- * Encrypted JSON file storage for agent credentials.
5
- * Uses AES-256-GCM encryption for password storage.
6
- */
7
- export interface AgentCredentials {
8
- workspaceId: string;
9
- agentType: string;
10
- email: string;
11
- encryptedPassword: string;
12
- userId?: string;
13
- displayName: string;
14
- enabledBy: string;
15
- enabledAt: string;
16
- status: 'pending' | 'active' | 'disconnected' | 'error';
17
- lastConnectedAt?: string;
18
- lastError?: string;
19
- }
20
- export declare class AgentCredentialStore {
21
- private dataDir;
22
- private filePath;
23
- private encryptionKey;
24
- constructor(dataDir?: string);
25
- /**
26
- * Generate storage key from workspaceId and agentType
27
- */
28
- private getStorageKey;
29
- /**
30
- * Ensure data directory exists
31
- */
32
- private ensureDataDir;
33
- /**
34
- * Read credentials file with graceful error handling
35
- */
36
- private readStorage;
37
- /**
38
- * Write credentials file atomically
39
- */
40
- private writeStorage;
41
- /**
42
- * Encrypt password using AES-256-GCM
43
- * Format: iv:authTag:ciphertext (all hex-encoded)
44
- */
45
- encryptPassword(plaintext: string): string;
46
- /**
47
- * Decrypt password from AES-256-GCM format
48
- * Expects format: iv:authTag:ciphertext (all hex-encoded)
49
- */
50
- decryptPassword(ciphertext: string): string;
51
- /**
52
- * Save or update agent credentials
53
- */
54
- save(credentials: AgentCredentials): Promise<void>;
55
- /**
56
- * Get agent credentials by workspace and type
57
- */
58
- get(workspaceId: string, agentType: string): Promise<AgentCredentials | null>;
59
- /**
60
- * Delete agent credentials
61
- * Returns true if credentials were found and deleted
62
- */
63
- delete(workspaceId: string, agentType: string): Promise<boolean>;
64
- /**
65
- * List all credentials for a workspace
66
- */
67
- listByWorkspace(workspaceId: string): Promise<AgentCredentials[]>;
68
- /**
69
- * List all stored credentials
70
- */
71
- listAll(): Promise<AgentCredentials[]>;
72
- }
73
- //# sourceMappingURL=agent-credential-store.d.ts.map
@@ -1,212 +0,0 @@
1
- "use strict";
2
- /**
3
- * Agent Credential Store
4
- *
5
- * Encrypted JSON file storage for agent credentials.
6
- * Uses AES-256-GCM encryption for password storage.
7
- */
8
- var __importDefault = (this && this.__importDefault) || function (mod) {
9
- return (mod && mod.__esModule) ? mod : { "default": mod };
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.AgentCredentialStore = void 0;
13
- const crypto_1 = __importDefault(require("crypto"));
14
- const promises_1 = __importDefault(require("fs/promises"));
15
- const path_1 = __importDefault(require("path"));
16
- const config_1 = require("../config");
17
- const logger_1 = require("../lib/logger");
18
- const logger = (0, logger_1.createLogger)({ component: 'agent-credential-store' });
19
- // ================================================================================
20
- // ENCRYPTION HELPERS
21
- // ================================================================================
22
- const ALGORITHM = 'aes-256-gcm';
23
- const IV_LENGTH = 12; // GCM standard
24
- const AUTH_TAG_LENGTH = 16;
25
- /**
26
- * Get encryption key from environment or generate dev fallback
27
- */
28
- function getEncryptionKey() {
29
- if (config_1.environment.CREDENTIAL_ENCRYPTION_KEY) {
30
- return Buffer.from(config_1.environment.CREDENTIAL_ENCRYPTION_KEY, 'hex');
31
- }
32
- // Development fallback - deterministic key from a fixed seed
33
- // WARNING: This is NOT secure for production
34
- if (config_1.environment.NODE_ENV === 'development' || config_1.environment.NODE_ENV === 'test') {
35
- logger.warn('Using development fallback encryption key - NOT SECURE FOR PRODUCTION');
36
- // Generate deterministic key from seed phrase
37
- return crypto_1.default.createHash('sha256').update('hailer-mcp-dev-key-DO-NOT-USE-IN-PRODUCTION').digest();
38
- }
39
- throw new Error('CREDENTIAL_ENCRYPTION_KEY must be set in production');
40
- }
41
- // ================================================================================
42
- // AGENT CREDENTIAL STORE CLASS
43
- // ================================================================================
44
- class AgentCredentialStore {
45
- dataDir;
46
- filePath;
47
- encryptionKey;
48
- constructor(dataDir) {
49
- // Default to 'data/' relative to project root
50
- this.dataDir = dataDir || path_1.default.join(process.cwd(), 'data');
51
- this.filePath = path_1.default.join(this.dataDir, 'agent-credentials.json');
52
- this.encryptionKey = getEncryptionKey();
53
- }
54
- /**
55
- * Generate storage key from workspaceId and agentType
56
- */
57
- getStorageKey(workspaceId, agentType) {
58
- return `${workspaceId}:${agentType}`;
59
- }
60
- /**
61
- * Ensure data directory exists
62
- */
63
- async ensureDataDir() {
64
- try {
65
- await promises_1.default.mkdir(this.dataDir, { recursive: true });
66
- }
67
- catch (error) {
68
- // Directory might already exist
69
- if (error.code !== 'EEXIST') {
70
- throw error;
71
- }
72
- }
73
- }
74
- /**
75
- * Read credentials file with graceful error handling
76
- */
77
- async readStorage() {
78
- try {
79
- const content = await promises_1.default.readFile(this.filePath, 'utf-8');
80
- const storage = JSON.parse(content);
81
- // Validate structure
82
- if (typeof storage !== 'object' || !storage.credentials) {
83
- throw new Error('Invalid storage format');
84
- }
85
- return storage;
86
- }
87
- catch (error) {
88
- if (error.code === 'ENOENT') {
89
- // File doesn't exist - return empty storage
90
- return { version: 1, credentials: {} };
91
- }
92
- // JSON parsing error or other issue - log and return empty
93
- logger.error('Failed to read credentials file, initializing empty storage', error);
94
- return { version: 1, credentials: {} };
95
- }
96
- }
97
- /**
98
- * Write credentials file atomically
99
- */
100
- async writeStorage(storage) {
101
- await this.ensureDataDir();
102
- const content = JSON.stringify(storage, null, 2);
103
- const tempPath = `${this.filePath}.tmp.${Date.now()}`;
104
- try {
105
- // Write to temp file first
106
- await promises_1.default.writeFile(tempPath, content, 'utf-8');
107
- // Atomic rename
108
- await promises_1.default.rename(tempPath, this.filePath);
109
- }
110
- catch (error) {
111
- // Clean up temp file if it exists
112
- try {
113
- await promises_1.default.unlink(tempPath);
114
- }
115
- catch {
116
- // Ignore cleanup errors
117
- }
118
- throw error;
119
- }
120
- }
121
- /**
122
- * Encrypt password using AES-256-GCM
123
- * Format: iv:authTag:ciphertext (all hex-encoded)
124
- */
125
- encryptPassword(plaintext) {
126
- const iv = crypto_1.default.randomBytes(IV_LENGTH);
127
- const cipher = crypto_1.default.createCipheriv(ALGORITHM, this.encryptionKey, iv);
128
- let encrypted = cipher.update(plaintext, 'utf8', 'hex');
129
- encrypted += cipher.final('hex');
130
- const authTag = cipher.getAuthTag();
131
- // Format: iv:authTag:ciphertext
132
- return `${iv.toString('hex')}:${authTag.toString('hex')}:${encrypted}`;
133
- }
134
- /**
135
- * Decrypt password from AES-256-GCM format
136
- * Expects format: iv:authTag:ciphertext (all hex-encoded)
137
- */
138
- decryptPassword(ciphertext) {
139
- const parts = ciphertext.split(':');
140
- if (parts.length !== 3) {
141
- throw new Error('Invalid encrypted password format');
142
- }
143
- const [ivHex, authTagHex, encryptedHex] = parts;
144
- const iv = Buffer.from(ivHex, 'hex');
145
- const authTag = Buffer.from(authTagHex, 'hex');
146
- const encrypted = Buffer.from(encryptedHex, 'hex');
147
- if (iv.length !== IV_LENGTH) {
148
- throw new Error(`Invalid IV length: expected ${IV_LENGTH}, got ${iv.length}`);
149
- }
150
- if (authTag.length !== AUTH_TAG_LENGTH) {
151
- throw new Error(`Invalid auth tag length: expected ${AUTH_TAG_LENGTH}, got ${authTag.length}`);
152
- }
153
- const decipher = crypto_1.default.createDecipheriv(ALGORITHM, this.encryptionKey, iv);
154
- decipher.setAuthTag(authTag);
155
- let decrypted = decipher.update(encrypted);
156
- decrypted = Buffer.concat([decrypted, decipher.final()]);
157
- return decrypted.toString('utf8');
158
- }
159
- /**
160
- * Save or update agent credentials
161
- */
162
- async save(credentials) {
163
- const storage = await this.readStorage();
164
- const key = this.getStorageKey(credentials.workspaceId, credentials.agentType);
165
- storage.credentials[key] = credentials;
166
- await this.writeStorage(storage);
167
- logger.info('Saved agent credentials', {
168
- workspaceId: credentials.workspaceId,
169
- agentType: credentials.agentType,
170
- status: credentials.status,
171
- });
172
- }
173
- /**
174
- * Get agent credentials by workspace and type
175
- */
176
- async get(workspaceId, agentType) {
177
- const storage = await this.readStorage();
178
- const key = this.getStorageKey(workspaceId, agentType);
179
- return storage.credentials[key] || null;
180
- }
181
- /**
182
- * Delete agent credentials
183
- * Returns true if credentials were found and deleted
184
- */
185
- async delete(workspaceId, agentType) {
186
- const storage = await this.readStorage();
187
- const key = this.getStorageKey(workspaceId, agentType);
188
- if (!(key in storage.credentials)) {
189
- return false;
190
- }
191
- delete storage.credentials[key];
192
- await this.writeStorage(storage);
193
- logger.info('Deleted agent credentials', { workspaceId, agentType });
194
- return true;
195
- }
196
- /**
197
- * List all credentials for a workspace
198
- */
199
- async listByWorkspace(workspaceId) {
200
- const storage = await this.readStorage();
201
- return Object.values(storage.credentials).filter((cred) => cred.workspaceId === workspaceId);
202
- }
203
- /**
204
- * List all stored credentials
205
- */
206
- async listAll() {
207
- const storage = await this.readStorage();
208
- return Object.values(storage.credentials);
209
- }
210
- }
211
- exports.AgentCredentialStore = AgentCredentialStore;
212
- //# sourceMappingURL=agent-credential-store.js.map
@@ -1,23 +0,0 @@
1
- /**
2
- * Bug Monitor Service
3
- *
4
- * Periodically checks for new bug reports and can trigger auto-fix workflows.
5
- * Configuration is read from Hailer's MCP Config workflow.
6
- */
7
- export declare class BugMonitorService {
8
- private interval?;
9
- private config?;
10
- private userContext?;
11
- private bugWorkflowId?;
12
- private newPhaseId?;
13
- private fixedPhaseId?;
14
- private processedBugIds;
15
- start(): Promise<void>;
16
- stop(): Promise<void>;
17
- private loadConfig;
18
- private findBugWorkflow;
19
- private checkForNewBugs;
20
- private processBug;
21
- }
22
- export declare function getBugMonitor(): BugMonitorService;
23
- //# sourceMappingURL=bug-monitor.d.ts.map