@burdenoff/vibe-agent 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/.env.example +8 -0
  2. package/LICENSE +22 -0
  3. package/README.md +290 -0
  4. package/dist/app.d.ts +15 -0
  5. package/dist/app.d.ts.map +1 -0
  6. package/dist/app.js +445 -0
  7. package/dist/app.js.map +1 -0
  8. package/dist/cli.d.ts +3 -0
  9. package/dist/cli.d.ts.map +1 -0
  10. package/dist/cli.js +1043 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/db/schema.d.ts +145 -0
  13. package/dist/db/schema.d.ts.map +1 -0
  14. package/dist/db/schema.js +536 -0
  15. package/dist/db/schema.js.map +1 -0
  16. package/dist/index.d.ts +2 -0
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/index.js +61 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/middleware/ModuleAuth.d.ts +61 -0
  21. package/dist/middleware/ModuleAuth.d.ts.map +1 -0
  22. package/dist/middleware/ModuleAuth.js +220 -0
  23. package/dist/middleware/ModuleAuth.js.map +1 -0
  24. package/dist/middleware/auth.d.ts +3 -0
  25. package/dist/middleware/auth.d.ts.map +1 -0
  26. package/dist/middleware/auth.js +11 -0
  27. package/dist/middleware/auth.js.map +1 -0
  28. package/dist/migrations/remove-notes-prompts.d.ts +13 -0
  29. package/dist/migrations/remove-notes-prompts.d.ts.map +1 -0
  30. package/dist/migrations/remove-notes-prompts.js +148 -0
  31. package/dist/migrations/remove-notes-prompts.js.map +1 -0
  32. package/dist/routes/bookmarks.d.ts +3 -0
  33. package/dist/routes/bookmarks.d.ts.map +1 -0
  34. package/dist/routes/bookmarks.js +186 -0
  35. package/dist/routes/bookmarks.js.map +1 -0
  36. package/dist/routes/config.d.ts +3 -0
  37. package/dist/routes/config.d.ts.map +1 -0
  38. package/dist/routes/config.js +108 -0
  39. package/dist/routes/config.js.map +1 -0
  40. package/dist/routes/files.d.ts +3 -0
  41. package/dist/routes/files.d.ts.map +1 -0
  42. package/dist/routes/files.js +471 -0
  43. package/dist/routes/files.js.map +1 -0
  44. package/dist/routes/git.d.ts +3 -0
  45. package/dist/routes/git.d.ts.map +1 -0
  46. package/dist/routes/git.js +498 -0
  47. package/dist/routes/git.js.map +1 -0
  48. package/dist/routes/moduleRegistry.d.ts +41 -0
  49. package/dist/routes/moduleRegistry.d.ts.map +1 -0
  50. package/dist/routes/moduleRegistry.js +356 -0
  51. package/dist/routes/moduleRegistry.js.map +1 -0
  52. package/dist/routes/notifications.d.ts +3 -0
  53. package/dist/routes/notifications.d.ts.map +1 -0
  54. package/dist/routes/notifications.js +250 -0
  55. package/dist/routes/notifications.js.map +1 -0
  56. package/dist/routes/port-forward.d.ts +3 -0
  57. package/dist/routes/port-forward.d.ts.map +1 -0
  58. package/dist/routes/port-forward.js +205 -0
  59. package/dist/routes/port-forward.js.map +1 -0
  60. package/dist/routes/projects.d.ts +3 -0
  61. package/dist/routes/projects.d.ts.map +1 -0
  62. package/dist/routes/projects.js +442 -0
  63. package/dist/routes/projects.js.map +1 -0
  64. package/dist/routes/ssh.d.ts +3 -0
  65. package/dist/routes/ssh.d.ts.map +1 -0
  66. package/dist/routes/ssh.js +192 -0
  67. package/dist/routes/ssh.js.map +1 -0
  68. package/dist/routes/tasks.d.ts +3 -0
  69. package/dist/routes/tasks.d.ts.map +1 -0
  70. package/dist/routes/tasks.js +183 -0
  71. package/dist/routes/tasks.js.map +1 -0
  72. package/dist/routes/tmux.d.ts +3 -0
  73. package/dist/routes/tmux.d.ts.map +1 -0
  74. package/dist/routes/tmux.js +1191 -0
  75. package/dist/routes/tmux.js.map +1 -0
  76. package/dist/routes/tunnel.d.ts +25 -0
  77. package/dist/routes/tunnel.d.ts.map +1 -0
  78. package/dist/routes/tunnel.js +449 -0
  79. package/dist/routes/tunnel.js.map +1 -0
  80. package/dist/services/ModulePermissions.d.ts +100 -0
  81. package/dist/services/ModulePermissions.d.ts.map +1 -0
  82. package/dist/services/ModulePermissions.js +312 -0
  83. package/dist/services/ModulePermissions.js.map +1 -0
  84. package/dist/services/ModuleRegistryService.d.ts +152 -0
  85. package/dist/services/ModuleRegistryService.d.ts.map +1 -0
  86. package/dist/services/ModuleRegistryService.js +522 -0
  87. package/dist/services/ModuleRegistryService.js.map +1 -0
  88. package/dist/services/agent.service.d.ts +19 -0
  89. package/dist/services/agent.service.d.ts.map +1 -0
  90. package/dist/services/agent.service.js +88 -0
  91. package/dist/services/agent.service.js.map +1 -0
  92. package/dist/services/bootstrap.d.ts +22 -0
  93. package/dist/services/bootstrap.d.ts.map +1 -0
  94. package/dist/services/bootstrap.js +206 -0
  95. package/dist/services/bootstrap.js.map +1 -0
  96. package/dist/services/service-manager.d.ts +50 -0
  97. package/dist/services/service-manager.d.ts.map +1 -0
  98. package/dist/services/service-manager.js +382 -0
  99. package/dist/services/service-manager.js.map +1 -0
  100. package/package.json +107 -0
@@ -0,0 +1,356 @@
1
+ import { ModuleRegistryService } from '../services/ModuleRegistryService.js';
2
+ import { ModuleAuthMiddleware } from '../middleware/ModuleAuth.js';
3
+ import { ModulePermissionManager } from '../services/ModulePermissions.js';
4
+ export async function moduleRegistryRoutes(fastify) {
5
+ const moduleRegistry = new ModuleRegistryService();
6
+ const moduleAuth = new ModuleAuthMiddleware();
7
+ const permissions = new ModulePermissionManager();
8
+ // Initialize services
9
+ fastify.decorate('moduleRegistry', moduleRegistry);
10
+ fastify.decorate('moduleAuth', moduleAuth);
11
+ fastify.decorate('permissions', permissions);
12
+ // Register module (called by module during startup)
13
+ fastify.post('/api/registry/register', async (request, reply) => {
14
+ try {
15
+ const result = await moduleRegistry.registerModule(request.body);
16
+ if (result.success) {
17
+ // Generate authentication token for the module
18
+ const token = moduleAuth.generateModuleToken(request.body.name);
19
+ // Grant permissions to the module
20
+ permissions.grantPermissions(request.body.name, request.body.permissions);
21
+ reply.code(201).send({
22
+ ...result,
23
+ token,
24
+ message: 'Module registered successfully'
25
+ });
26
+ }
27
+ else {
28
+ reply.code(400).send(result);
29
+ }
30
+ }
31
+ catch (error) {
32
+ fastify.log.error(error);
33
+ reply.code(500).send({
34
+ success: false,
35
+ message: 'Internal server error during registration'
36
+ });
37
+ }
38
+ });
39
+ // Unregister module (called during shutdown)
40
+ fastify.delete('/api/registry/unregister/:moduleId', async (request, reply) => {
41
+ try {
42
+ const { moduleId } = request.params;
43
+ // Authenticate the module making the request
44
+ const auth = moduleAuth.authenticateModule(request);
45
+ if (!auth.valid || auth.moduleId !== moduleId) {
46
+ reply.code(401).send({ error: 'Unauthorized' });
47
+ return;
48
+ }
49
+ const result = await moduleRegistry.unregisterModule(moduleId);
50
+ if (result.success) {
51
+ // Revoke authentication token
52
+ moduleAuth.revokeModuleToken(moduleId);
53
+ // Remove permissions
54
+ permissions.revokePermissions(moduleId);
55
+ reply.code(200).send(result);
56
+ }
57
+ else {
58
+ reply.code(400).send(result);
59
+ }
60
+ }
61
+ catch (error) {
62
+ fastify.log.error(error);
63
+ reply.code(500).send({
64
+ success: false,
65
+ message: 'Internal server error during unregistration'
66
+ });
67
+ }
68
+ });
69
+ // List all modules
70
+ fastify.get('/api/registry/modules', async (request, reply) => {
71
+ try {
72
+ const modules = await moduleRegistry.listModules();
73
+ reply.code(200).send({
74
+ success: true,
75
+ data: modules,
76
+ count: modules.length
77
+ });
78
+ }
79
+ catch (error) {
80
+ fastify.log.error(error);
81
+ reply.code(500).send({
82
+ success: false,
83
+ message: 'Failed to list modules'
84
+ });
85
+ }
86
+ });
87
+ // Get specific module
88
+ fastify.get('/api/registry/modules/:moduleId', async (request, reply) => {
89
+ try {
90
+ const { moduleId } = request.params;
91
+ const module = await moduleRegistry.getModule(moduleId);
92
+ if (module) {
93
+ reply.code(200).send({
94
+ success: true,
95
+ data: module
96
+ });
97
+ }
98
+ else {
99
+ reply.code(404).send({
100
+ success: false,
101
+ message: 'Module not found'
102
+ });
103
+ }
104
+ }
105
+ catch (error) {
106
+ fastify.log.error(error);
107
+ reply.code(500).send({
108
+ success: false,
109
+ message: 'Failed to get module'
110
+ });
111
+ }
112
+ });
113
+ // Update module heartbeat
114
+ fastify.post('/api/registry/modules/:moduleId/heartbeat', async (request, reply) => {
115
+ try {
116
+ const { moduleId } = request.params;
117
+ // Authenticate the module
118
+ const auth = moduleAuth.authenticateModule(request);
119
+ if (!auth.valid || auth.moduleId !== moduleId) {
120
+ reply.code(401).send({ error: 'Unauthorized' });
121
+ return;
122
+ }
123
+ const result = await moduleRegistry.updateHeartbeat(moduleId, request.body);
124
+ if (result.success) {
125
+ reply.code(200).send(result);
126
+ }
127
+ else {
128
+ reply.code(400).send(result);
129
+ }
130
+ }
131
+ catch (error) {
132
+ fastify.log.error(error);
133
+ reply.code(500).send({
134
+ success: false,
135
+ message: 'Failed to update heartbeat'
136
+ });
137
+ }
138
+ });
139
+ // Install module from remote source
140
+ fastify.post('/api/registry/install', async (request, reply) => {
141
+ try {
142
+ const installation = await moduleRegistry.installModule(request.body.moduleId, request.body.source, request.body.version);
143
+ reply.code(202).send({
144
+ success: true,
145
+ data: installation,
146
+ message: 'Module installation started'
147
+ });
148
+ }
149
+ catch (error) {
150
+ fastify.log.error(error);
151
+ reply.code(500).send({
152
+ success: false,
153
+ message: 'Failed to start module installation'
154
+ });
155
+ }
156
+ });
157
+ // Activate installed module
158
+ fastify.post('/api/registry/activate/:moduleId', async (request, reply) => {
159
+ try {
160
+ const { moduleId } = request.params;
161
+ const result = await moduleRegistry.activateModule(moduleId);
162
+ if (result.success) {
163
+ reply.code(200).send(result);
164
+ }
165
+ else {
166
+ reply.code(400).send(result);
167
+ }
168
+ }
169
+ catch (error) {
170
+ fastify.log.error(error);
171
+ reply.code(500).send({
172
+ success: false,
173
+ message: 'Failed to activate module'
174
+ });
175
+ }
176
+ });
177
+ // Deactivate module
178
+ fastify.post('/api/registry/deactivate/:moduleId', async (request, reply) => {
179
+ try {
180
+ const { moduleId } = request.params;
181
+ const result = await moduleRegistry.deactivateModule(moduleId);
182
+ if (result.success) {
183
+ reply.code(200).send(result);
184
+ }
185
+ else {
186
+ reply.code(400).send(result);
187
+ }
188
+ }
189
+ catch (error) {
190
+ fastify.log.error(error);
191
+ reply.code(500).send({
192
+ success: false,
193
+ message: 'Failed to deactivate module'
194
+ });
195
+ }
196
+ });
197
+ // Search available modules
198
+ fastify.get('/api/registry/search', async (request, reply) => {
199
+ try {
200
+ const { query, category, tags, status = 'all', limit = 50, offset = 0 } = request.query;
201
+ const modules = await moduleRegistry.searchModules(query, category, tags?.split(','), status, limit, offset);
202
+ reply.code(200).send({
203
+ success: true,
204
+ data: modules,
205
+ pagination: {
206
+ limit,
207
+ offset,
208
+ total: modules.length
209
+ }
210
+ });
211
+ }
212
+ catch (error) {
213
+ fastify.log.error(error);
214
+ reply.code(500).send({
215
+ success: false,
216
+ message: 'Failed to search modules'
217
+ });
218
+ }
219
+ });
220
+ // Get module installation history
221
+ fastify.get('/api/registry/installations', async (request, reply) => {
222
+ try {
223
+ const installations = await moduleRegistry.getInstallationHistory();
224
+ reply.code(200).send({
225
+ success: true,
226
+ data: installations
227
+ });
228
+ }
229
+ catch (error) {
230
+ fastify.log.error(error);
231
+ reply.code(500).send({
232
+ success: false,
233
+ message: 'Failed to get installation history'
234
+ });
235
+ }
236
+ });
237
+ // Get specific installation status
238
+ fastify.get('/api/registry/installations/:installationId', async (request, reply) => {
239
+ try {
240
+ const { installationId } = request.params;
241
+ const installation = await moduleRegistry.getInstallation(installationId);
242
+ if (installation) {
243
+ reply.code(200).send({
244
+ success: true,
245
+ data: installation
246
+ });
247
+ }
248
+ else {
249
+ reply.code(404).send({
250
+ success: false,
251
+ message: 'Installation not found'
252
+ });
253
+ }
254
+ }
255
+ catch (error) {
256
+ fastify.log.error(error);
257
+ reply.code(500).send({
258
+ success: false,
259
+ message: 'Failed to get installation'
260
+ });
261
+ }
262
+ });
263
+ // Module health check endpoint
264
+ fastify.get('/api/registry/modules/:moduleId/health', async (request, reply) => {
265
+ try {
266
+ const { moduleId } = request.params;
267
+ const health = await moduleRegistry.checkModuleHealth(moduleId);
268
+ if (health) {
269
+ reply.code(health.healthy ? 200 : 503).send({
270
+ success: true,
271
+ data: health
272
+ });
273
+ }
274
+ else {
275
+ reply.code(404).send({
276
+ success: false,
277
+ message: 'Module not found'
278
+ });
279
+ }
280
+ }
281
+ catch (error) {
282
+ fastify.log.error(error);
283
+ reply.code(500).send({
284
+ success: false,
285
+ message: 'Failed to check module health'
286
+ });
287
+ }
288
+ });
289
+ // Get module statistics
290
+ fastify.get('/api/registry/stats', async (request, reply) => {
291
+ try {
292
+ const stats = await moduleRegistry.getStats();
293
+ reply.code(200).send({
294
+ success: true,
295
+ data: stats
296
+ });
297
+ }
298
+ catch (error) {
299
+ fastify.log.error(error);
300
+ reply.code(500).send({
301
+ success: false,
302
+ message: 'Failed to get statistics'
303
+ });
304
+ }
305
+ });
306
+ // Module logs endpoint
307
+ fastify.get('/api/registry/modules/:moduleId/logs', async (request, reply) => {
308
+ try {
309
+ const { moduleId } = request.params;
310
+ const { limit = 100, since, level } = request.query;
311
+ const logs = await moduleRegistry.getModuleLogs(moduleId, {
312
+ limit,
313
+ since: since ? new Date(since) : undefined,
314
+ level
315
+ });
316
+ reply.code(200).send({
317
+ success: true,
318
+ data: logs
319
+ });
320
+ }
321
+ catch (error) {
322
+ fastify.log.error(error);
323
+ reply.code(500).send({
324
+ success: false,
325
+ message: 'Failed to get module logs'
326
+ });
327
+ }
328
+ });
329
+ // Bulk operations
330
+ fastify.post('/api/registry/bulk', async (request, reply) => {
331
+ try {
332
+ const { operation, moduleIds } = request.body;
333
+ const results = await moduleRegistry.bulkOperation(operation, moduleIds);
334
+ reply.code(200).send({
335
+ success: true,
336
+ data: results
337
+ });
338
+ }
339
+ catch (error) {
340
+ fastify.log.error(error);
341
+ reply.code(500).send({
342
+ success: false,
343
+ message: 'Failed to perform bulk operation'
344
+ });
345
+ }
346
+ });
347
+ // WebSocket endpoint for real-time module updates
348
+ // TODO: Implement WebSocket support for real-time updates
349
+ fastify.get('/api/registry/ws', async (request, reply) => {
350
+ reply.code(501).send({
351
+ success: false,
352
+ message: 'WebSocket endpoint not yet implemented'
353
+ });
354
+ });
355
+ }
356
+ //# sourceMappingURL=moduleRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"moduleRegistry.js","sourceRoot":"","sources":["../../src/routes/moduleRegistry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { FastifyPluginAsync } from 'fastify';
2
+ export declare const notificationRoutes: FastifyPluginAsync;
3
+ //# sourceMappingURL=notifications.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../../src/routes/notifications.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAmB7C,eAAO,MAAM,kBAAkB,EAAE,kBA4RhC,CAAC"}
@@ -0,0 +1,250 @@
1
+ import { v4 as uuidv4 } from 'uuid';
2
+ export const notificationRoutes = async (fastify) => {
3
+ // Get all notifications
4
+ fastify.get('/', async (request, _reply) => {
5
+ const { projectId, status } = request.query;
6
+ let notifications;
7
+ if (status === 'unread') {
8
+ notifications = fastify.db.getUnreadNotifications();
9
+ }
10
+ else if (projectId !== undefined) {
11
+ notifications = fastify.db.getNotificationsByProject(projectId);
12
+ }
13
+ else {
14
+ notifications = fastify.db.getNotificationsByProject(null);
15
+ }
16
+ return { notifications };
17
+ });
18
+ // Get notifications for project
19
+ fastify.get('/project/:projectId', async (request, _reply) => {
20
+ const { projectId } = request.params;
21
+ const notifications = fastify.db.getNotificationsByProject(projectId);
22
+ return { notifications };
23
+ });
24
+ // Get unread notifications
25
+ fastify.get('/unread', async (_request, _reply) => {
26
+ const notifications = fastify.db.getUnreadNotifications();
27
+ return {
28
+ notifications,
29
+ count: notifications.length
30
+ };
31
+ });
32
+ // Get global notifications (not tied to specific project)
33
+ fastify.get('/global', async (_request, _reply) => {
34
+ const notifications = fastify.db.getNotificationsByProject(null);
35
+ return {
36
+ notifications,
37
+ count: notifications.length
38
+ };
39
+ });
40
+ // Get notification by ID
41
+ fastify.get('/:id', async (request, reply) => {
42
+ const { id } = request.params;
43
+ const notification = fastify.db.getNotification(id);
44
+ if (!notification) {
45
+ return reply.code(404).send({ error: 'Notification not found' });
46
+ }
47
+ return { notification };
48
+ });
49
+ // Create notification
50
+ fastify.post('/', async (request, reply) => {
51
+ const { sessionName, projectId, type = 'info', title, message } = request.body;
52
+ try {
53
+ const notification = fastify.db.createNotification({
54
+ id: uuidv4(),
55
+ sessionName,
56
+ projectId,
57
+ type,
58
+ title,
59
+ message,
60
+ status: 'unread'
61
+ });
62
+ // Emit notification created event
63
+ fastify.io.emit('notification:created', notification);
64
+ // Check if sound is enabled in config
65
+ const soundEnabled = fastify.db.getConfig('notification_sound') === 'true';
66
+ if (soundEnabled) {
67
+ fastify.io.emit('notification:sound', { type });
68
+ }
69
+ return { notification };
70
+ }
71
+ catch (error) {
72
+ return reply.code(500).send({
73
+ error: 'Failed to create notification',
74
+ details: error instanceof Error ? error.message : 'Unknown error'
75
+ });
76
+ }
77
+ });
78
+ // Mark notification as read
79
+ fastify.put('/:id/read', async (request, reply) => {
80
+ const { id } = request.params;
81
+ try {
82
+ const notification = fastify.db.getNotification(id);
83
+ if (!notification) {
84
+ return reply.code(404).send({ error: 'Notification not found' });
85
+ }
86
+ fastify.db.updateNotificationStatus(id, 'read');
87
+ // Emit notification read event
88
+ fastify.io.emit('notification:read', { id });
89
+ return { success: true };
90
+ }
91
+ catch (error) {
92
+ return reply.code(500).send({
93
+ error: 'Failed to mark notification as read',
94
+ details: error instanceof Error ? error.message : 'Unknown error'
95
+ });
96
+ }
97
+ });
98
+ // Mark notification as unread
99
+ fastify.put('/:id/unread', async (request, reply) => {
100
+ const { id } = request.params;
101
+ try {
102
+ const notification = fastify.db.getNotification(id);
103
+ if (!notification) {
104
+ return reply.code(404).send({ error: 'Notification not found' });
105
+ }
106
+ fastify.db.updateNotificationStatus(id, 'unread');
107
+ // Emit notification unread event
108
+ fastify.io.emit('notification:unread', { id });
109
+ return { success: true };
110
+ }
111
+ catch (error) {
112
+ return reply.code(500).send({
113
+ error: 'Failed to mark notification as unread',
114
+ details: error instanceof Error ? error.message : 'Unknown error'
115
+ });
116
+ }
117
+ });
118
+ // Mark all notifications as read
119
+ fastify.put('/read-all', async (_request, reply) => {
120
+ try {
121
+ const unreadNotifications = fastify.db.getUnreadNotifications();
122
+ for (const notification of unreadNotifications) {
123
+ fastify.db.updateNotificationStatus(notification.id, 'read');
124
+ }
125
+ // Emit all read event
126
+ fastify.io.emit('notification:all-read', {
127
+ count: unreadNotifications.length,
128
+ ids: unreadNotifications.map(n => n.id)
129
+ });
130
+ return {
131
+ success: true,
132
+ markedCount: unreadNotifications.length
133
+ };
134
+ }
135
+ catch (error) {
136
+ return reply.code(500).send({
137
+ error: 'Failed to mark all notifications as read',
138
+ details: error instanceof Error ? error.message : 'Unknown error'
139
+ });
140
+ }
141
+ });
142
+ // Delete notification
143
+ fastify.delete('/:id', async (request, reply) => {
144
+ const { id } = request.params;
145
+ try {
146
+ const notification = fastify.db.getNotification(id);
147
+ if (!notification) {
148
+ return reply.code(404).send({ error: 'Notification not found' });
149
+ }
150
+ fastify.db.deleteNotification(id);
151
+ // Emit notification deleted event
152
+ fastify.io.emit('notification:deleted', { id });
153
+ return { success: true };
154
+ }
155
+ catch (error) {
156
+ return reply.code(500).send({
157
+ error: 'Failed to delete notification',
158
+ details: error instanceof Error ? error.message : 'Unknown error'
159
+ });
160
+ }
161
+ });
162
+ // Webhook endpoint for external notifications
163
+ fastify.post('/webhook/:sessionId', async (request, reply) => {
164
+ const { sessionId } = request.params;
165
+ const { type = 'info', title, message, metadata, projectName } = request.body;
166
+ try {
167
+ // Map task_completed to success for database compatibility
168
+ // Map unknown types to info as fallback
169
+ let mappedType;
170
+ switch (type) {
171
+ case 'task_completed':
172
+ mappedType = 'success';
173
+ break;
174
+ case 'info':
175
+ case 'success':
176
+ case 'warning':
177
+ case 'error':
178
+ mappedType = type;
179
+ break;
180
+ default:
181
+ mappedType = 'info'; // Default fallback for unknown types
182
+ }
183
+ // Try to find session first, then fall back to project-based notification
184
+ const session = fastify.db.getTmuxSession(sessionId);
185
+ let sessionName;
186
+ let projectId;
187
+ if (session) {
188
+ // Session-based notification
189
+ sessionName = session.sessionName;
190
+ projectId = session.projectId;
191
+ }
192
+ else {
193
+ // Project-based notification using sessionId as projectId
194
+ projectId = sessionId;
195
+ sessionName = projectName || undefined;
196
+ }
197
+ const notification = fastify.db.createNotification({
198
+ id: uuidv4(),
199
+ sessionName,
200
+ projectId,
201
+ type: mappedType,
202
+ title,
203
+ message: metadata ? `${message}\n\nMetadata: ${JSON.stringify(metadata, null, 2)}` : message,
204
+ status: 'unread'
205
+ });
206
+ // Emit notification with webhook flag
207
+ fastify.io.emit('notification:webhook', {
208
+ ...notification,
209
+ metadata,
210
+ originalType: type // Include original type for frontend handling
211
+ });
212
+ // Check if sound is enabled
213
+ const soundEnabled = fastify.db.getConfig('notification_sound') === 'true';
214
+ if (soundEnabled) {
215
+ fastify.io.emit('notification:sound', { type: mappedType, webhook: true });
216
+ }
217
+ return {
218
+ notification,
219
+ webhook: true,
220
+ originalType: type,
221
+ mappedType
222
+ };
223
+ }
224
+ catch (error) {
225
+ return reply.code(500).send({
226
+ error: 'Failed to create webhook notification',
227
+ details: error instanceof Error ? error.message : 'Unknown error'
228
+ });
229
+ }
230
+ });
231
+ // Clear old notifications
232
+ fastify.delete('/clear/old', async (request, reply) => {
233
+ const { days = 30 } = request.query;
234
+ try {
235
+ // This would need a new database method to delete old notifications
236
+ // For now, we'll just return a placeholder
237
+ return {
238
+ success: true,
239
+ message: `Would clear notifications older than ${days} days`
240
+ };
241
+ }
242
+ catch (error) {
243
+ return reply.code(500).send({
244
+ error: 'Failed to clear old notifications',
245
+ details: error instanceof Error ? error.message : 'Unknown error'
246
+ });
247
+ }
248
+ });
249
+ };
250
+ //# sourceMappingURL=notifications.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notifications.js","sourceRoot":"","sources":["../../src/routes/notifications.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { FastifyPluginAsync } from 'fastify';
2
+ export declare const portForwardRoutes: FastifyPluginAsync;
3
+ //# sourceMappingURL=port-forward.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"port-forward.d.ts","sourceRoot":"","sources":["../../src/routes/port-forward.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAgB7C,eAAO,MAAM,iBAAiB,EAAE,kBAgP/B,CAAC"}