agent-relay 2.0.23 → 2.0.25

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 (168) hide show
  1. package/dist/src/cli/index.js +160 -17
  2. package/package.json +18 -52
  3. package/packages/api-types/package.json +1 -1
  4. package/packages/bridge/package.json +8 -8
  5. package/packages/cli-tester/package.json +1 -1
  6. package/packages/config/package.json +2 -2
  7. package/packages/continuity/package.json +1 -1
  8. package/packages/daemon/package.json +12 -12
  9. package/packages/hooks/package.json +4 -4
  10. package/packages/mcp/package.json +2 -2
  11. package/packages/memory/package.json +2 -2
  12. package/packages/policy/package.json +2 -2
  13. package/packages/protocol/package.json +1 -1
  14. package/packages/resiliency/package.json +1 -1
  15. package/packages/sdk/package.json +2 -2
  16. package/packages/spawner/package.json +1 -1
  17. package/packages/state/package.json +1 -1
  18. package/packages/storage/package.json +2 -2
  19. package/packages/telemetry/package.json +1 -1
  20. package/packages/trajectory/package.json +2 -2
  21. package/packages/user-directory/package.json +2 -2
  22. package/packages/utils/package.json +1 -1
  23. package/packages/wrapper/package.json +6 -6
  24. package/deploy/init-db.sql +0 -5
  25. package/deploy/scripts/setup-fly-workspaces.sh +0 -69
  26. package/deploy/scripts/setup-railway.sh +0 -75
  27. package/dist/src/cloud/index.d.ts +0 -8
  28. package/dist/src/cloud/index.js +0 -8
  29. package/packages/cloud/dist/api/admin.d.ts +0 -8
  30. package/packages/cloud/dist/api/admin.js +0 -225
  31. package/packages/cloud/dist/api/auth.d.ts +0 -20
  32. package/packages/cloud/dist/api/auth.js +0 -138
  33. package/packages/cloud/dist/api/billing.d.ts +0 -7
  34. package/packages/cloud/dist/api/billing.js +0 -564
  35. package/packages/cloud/dist/api/cli-pty-runner.d.ts +0 -53
  36. package/packages/cloud/dist/api/cli-pty-runner.js +0 -175
  37. package/packages/cloud/dist/api/codex-auth-helper.d.ts +0 -21
  38. package/packages/cloud/dist/api/codex-auth-helper.js +0 -327
  39. package/packages/cloud/dist/api/consensus.d.ts +0 -13
  40. package/packages/cloud/dist/api/consensus.js +0 -261
  41. package/packages/cloud/dist/api/coordinators.d.ts +0 -8
  42. package/packages/cloud/dist/api/coordinators.js +0 -750
  43. package/packages/cloud/dist/api/daemons.d.ts +0 -12
  44. package/packages/cloud/dist/api/daemons.js +0 -535
  45. package/packages/cloud/dist/api/email-auth.d.ts +0 -11
  46. package/packages/cloud/dist/api/email-auth.js +0 -347
  47. package/packages/cloud/dist/api/generic-webhooks.d.ts +0 -8
  48. package/packages/cloud/dist/api/generic-webhooks.js +0 -129
  49. package/packages/cloud/dist/api/git.d.ts +0 -8
  50. package/packages/cloud/dist/api/git.js +0 -269
  51. package/packages/cloud/dist/api/github-app.d.ts +0 -11
  52. package/packages/cloud/dist/api/github-app.js +0 -223
  53. package/packages/cloud/dist/api/middleware/planLimits.d.ts +0 -43
  54. package/packages/cloud/dist/api/middleware/planLimits.js +0 -202
  55. package/packages/cloud/dist/api/monitoring.d.ts +0 -11
  56. package/packages/cloud/dist/api/monitoring.js +0 -578
  57. package/packages/cloud/dist/api/nango-auth.d.ts +0 -9
  58. package/packages/cloud/dist/api/nango-auth.js +0 -741
  59. package/packages/cloud/dist/api/onboarding.d.ts +0 -15
  60. package/packages/cloud/dist/api/onboarding.js +0 -679
  61. package/packages/cloud/dist/api/policy.d.ts +0 -8
  62. package/packages/cloud/dist/api/policy.js +0 -229
  63. package/packages/cloud/dist/api/provider-env.d.ts +0 -26
  64. package/packages/cloud/dist/api/provider-env.js +0 -141
  65. package/packages/cloud/dist/api/providers.d.ts +0 -7
  66. package/packages/cloud/dist/api/providers.js +0 -574
  67. package/packages/cloud/dist/api/repos.d.ts +0 -8
  68. package/packages/cloud/dist/api/repos.js +0 -577
  69. package/packages/cloud/dist/api/sessions.d.ts +0 -11
  70. package/packages/cloud/dist/api/sessions.js +0 -302
  71. package/packages/cloud/dist/api/teams.d.ts +0 -7
  72. package/packages/cloud/dist/api/teams.js +0 -281
  73. package/packages/cloud/dist/api/test-helpers.d.ts +0 -10
  74. package/packages/cloud/dist/api/test-helpers.js +0 -745
  75. package/packages/cloud/dist/api/usage.d.ts +0 -7
  76. package/packages/cloud/dist/api/usage.js +0 -111
  77. package/packages/cloud/dist/api/webhooks.d.ts +0 -8
  78. package/packages/cloud/dist/api/webhooks.js +0 -645
  79. package/packages/cloud/dist/api/workspaces.d.ts +0 -25
  80. package/packages/cloud/dist/api/workspaces.js +0 -1799
  81. package/packages/cloud/dist/billing/index.d.ts +0 -9
  82. package/packages/cloud/dist/billing/index.js +0 -9
  83. package/packages/cloud/dist/billing/plans.d.ts +0 -39
  84. package/packages/cloud/dist/billing/plans.js +0 -245
  85. package/packages/cloud/dist/billing/service.d.ts +0 -80
  86. package/packages/cloud/dist/billing/service.js +0 -388
  87. package/packages/cloud/dist/billing/types.d.ts +0 -141
  88. package/packages/cloud/dist/billing/types.js +0 -7
  89. package/packages/cloud/dist/config.d.ts +0 -5
  90. package/packages/cloud/dist/config.js +0 -5
  91. package/packages/cloud/dist/db/bulk-ingest.d.ts +0 -89
  92. package/packages/cloud/dist/db/bulk-ingest.js +0 -268
  93. package/packages/cloud/dist/db/drizzle.d.ts +0 -290
  94. package/packages/cloud/dist/db/drizzle.js +0 -1422
  95. package/packages/cloud/dist/db/index.d.ts +0 -56
  96. package/packages/cloud/dist/db/index.js +0 -70
  97. package/packages/cloud/dist/db/schema.d.ts +0 -5117
  98. package/packages/cloud/dist/db/schema.js +0 -656
  99. package/packages/cloud/dist/index.d.ts +0 -11
  100. package/packages/cloud/dist/index.js +0 -38
  101. package/packages/cloud/dist/provisioner/index.d.ts +0 -207
  102. package/packages/cloud/dist/provisioner/index.js +0 -2118
  103. package/packages/cloud/dist/server.d.ts +0 -17
  104. package/packages/cloud/dist/server.js +0 -2055
  105. package/packages/cloud/dist/services/auto-scaler.d.ts +0 -152
  106. package/packages/cloud/dist/services/auto-scaler.js +0 -439
  107. package/packages/cloud/dist/services/capacity-manager.d.ts +0 -148
  108. package/packages/cloud/dist/services/capacity-manager.js +0 -449
  109. package/packages/cloud/dist/services/ci-agent-spawner.d.ts +0 -49
  110. package/packages/cloud/dist/services/ci-agent-spawner.js +0 -373
  111. package/packages/cloud/dist/services/cloud-message-bus.d.ts +0 -28
  112. package/packages/cloud/dist/services/cloud-message-bus.js +0 -19
  113. package/packages/cloud/dist/services/compute-enforcement.d.ts +0 -57
  114. package/packages/cloud/dist/services/compute-enforcement.js +0 -175
  115. package/packages/cloud/dist/services/coordinator.d.ts +0 -62
  116. package/packages/cloud/dist/services/coordinator.js +0 -389
  117. package/packages/cloud/dist/services/index.d.ts +0 -17
  118. package/packages/cloud/dist/services/index.js +0 -25
  119. package/packages/cloud/dist/services/intro-expiration.d.ts +0 -60
  120. package/packages/cloud/dist/services/intro-expiration.js +0 -252
  121. package/packages/cloud/dist/services/mention-handler.d.ts +0 -65
  122. package/packages/cloud/dist/services/mention-handler.js +0 -405
  123. package/packages/cloud/dist/services/nango.d.ts +0 -219
  124. package/packages/cloud/dist/services/nango.js +0 -424
  125. package/packages/cloud/dist/services/persistence.d.ts +0 -131
  126. package/packages/cloud/dist/services/persistence.js +0 -200
  127. package/packages/cloud/dist/services/planLimits.d.ts +0 -147
  128. package/packages/cloud/dist/services/planLimits.js +0 -335
  129. package/packages/cloud/dist/services/presence-registry.d.ts +0 -56
  130. package/packages/cloud/dist/services/presence-registry.js +0 -91
  131. package/packages/cloud/dist/services/scaling-orchestrator.d.ts +0 -159
  132. package/packages/cloud/dist/services/scaling-orchestrator.js +0 -502
  133. package/packages/cloud/dist/services/scaling-policy.d.ts +0 -121
  134. package/packages/cloud/dist/services/scaling-policy.js +0 -415
  135. package/packages/cloud/dist/services/ssh-security.d.ts +0 -31
  136. package/packages/cloud/dist/services/ssh-security.js +0 -63
  137. package/packages/cloud/dist/services/workspace-keepalive.d.ts +0 -76
  138. package/packages/cloud/dist/services/workspace-keepalive.js +0 -234
  139. package/packages/cloud/dist/shims/consensus.d.ts +0 -23
  140. package/packages/cloud/dist/shims/consensus.js +0 -5
  141. package/packages/cloud/dist/webhooks/index.d.ts +0 -24
  142. package/packages/cloud/dist/webhooks/index.js +0 -29
  143. package/packages/cloud/dist/webhooks/parsers/github.d.ts +0 -8
  144. package/packages/cloud/dist/webhooks/parsers/github.js +0 -234
  145. package/packages/cloud/dist/webhooks/parsers/index.d.ts +0 -23
  146. package/packages/cloud/dist/webhooks/parsers/index.js +0 -30
  147. package/packages/cloud/dist/webhooks/parsers/linear.d.ts +0 -9
  148. package/packages/cloud/dist/webhooks/parsers/linear.js +0 -258
  149. package/packages/cloud/dist/webhooks/parsers/slack.d.ts +0 -9
  150. package/packages/cloud/dist/webhooks/parsers/slack.js +0 -214
  151. package/packages/cloud/dist/webhooks/responders/github.d.ts +0 -8
  152. package/packages/cloud/dist/webhooks/responders/github.js +0 -73
  153. package/packages/cloud/dist/webhooks/responders/index.d.ts +0 -23
  154. package/packages/cloud/dist/webhooks/responders/index.js +0 -30
  155. package/packages/cloud/dist/webhooks/responders/linear.d.ts +0 -9
  156. package/packages/cloud/dist/webhooks/responders/linear.js +0 -149
  157. package/packages/cloud/dist/webhooks/responders/slack.d.ts +0 -20
  158. package/packages/cloud/dist/webhooks/responders/slack.js +0 -178
  159. package/packages/cloud/dist/webhooks/router.d.ts +0 -25
  160. package/packages/cloud/dist/webhooks/router.js +0 -504
  161. package/packages/cloud/dist/webhooks/rules-engine.d.ts +0 -24
  162. package/packages/cloud/dist/webhooks/rules-engine.js +0 -287
  163. package/packages/cloud/dist/webhooks/types.d.ts +0 -186
  164. package/packages/cloud/dist/webhooks/types.js +0 -8
  165. package/packages/cloud/package.json +0 -60
  166. package/scripts/run-migrations.js +0 -43
  167. package/scripts/setup-stripe-products.ts +0 -312
  168. package/scripts/verify-schema.js +0 -134
@@ -1,504 +0,0 @@
1
- /**
2
- * Generic Webhook Router
3
- *
4
- * Routes incoming webhooks from any source through the configurable pipeline:
5
- * 1. Verify signature
6
- * 2. Parse payload into normalized events
7
- * 3. Match events against rules
8
- * 4. Execute actions
9
- * 5. Send responses
10
- */
11
- import crypto from 'crypto';
12
- import { getParser } from './parsers/index.js';
13
- import { getResponder } from './responders/index.js';
14
- import { findMatchingRules, resolveActionTemplate, defaultRules } from './rules-engine.js';
15
- import { db } from '../db/index.js';
16
- /**
17
- * Default webhook source configurations
18
- */
19
- export const defaultSources = {
20
- github: {
21
- id: 'github',
22
- name: 'GitHub',
23
- enabled: true,
24
- signature: {
25
- header: 'x-hub-signature-256',
26
- algorithm: 'sha256',
27
- secretEnvVar: 'GITHUB_WEBHOOK_SECRET',
28
- signaturePrefix: 'sha256=',
29
- },
30
- parser: 'github',
31
- responder: 'github',
32
- },
33
- linear: {
34
- id: 'linear',
35
- name: 'Linear',
36
- enabled: true,
37
- signature: {
38
- header: 'linear-signature',
39
- algorithm: 'sha256',
40
- secretEnvVar: 'LINEAR_WEBHOOK_SECRET',
41
- },
42
- parser: 'linear',
43
- responder: 'linear',
44
- },
45
- slack: {
46
- id: 'slack',
47
- name: 'Slack',
48
- enabled: true,
49
- signature: {
50
- header: 'x-slack-signature',
51
- algorithm: 'slack-v0',
52
- secretEnvVar: 'SLACK_SIGNING_SECRET',
53
- },
54
- parser: 'slack',
55
- responder: 'slack',
56
- },
57
- };
58
- /**
59
- * Get webhook configuration
60
- * In the future, this could load from database per-workspace
61
- */
62
- export function getWebhookConfig() {
63
- return {
64
- sources: defaultSources,
65
- rules: defaultRules,
66
- };
67
- }
68
- /**
69
- * Verify webhook signature
70
- */
71
- function verifySignature(payload, signature, config, headers) {
72
- if (config.signature.algorithm === 'none') {
73
- return true;
74
- }
75
- if (!signature) {
76
- return false;
77
- }
78
- const secret = process.env[config.signature.secretEnvVar];
79
- if (!secret) {
80
- console.warn(`[webhook-router] Secret not configured: ${config.signature.secretEnvVar}`);
81
- return false;
82
- }
83
- try {
84
- let expectedSignature;
85
- let actualSignature = signature;
86
- // Remove prefix if configured
87
- if (config.signature.signaturePrefix && actualSignature.startsWith(config.signature.signaturePrefix)) {
88
- actualSignature = actualSignature.slice(config.signature.signaturePrefix.length);
89
- }
90
- switch (config.signature.algorithm) {
91
- case 'sha256':
92
- expectedSignature = crypto
93
- .createHmac('sha256', secret)
94
- .update(payload)
95
- .digest('hex');
96
- break;
97
- case 'sha1':
98
- expectedSignature = crypto
99
- .createHmac('sha1', secret)
100
- .update(payload)
101
- .digest('hex');
102
- break;
103
- case 'token':
104
- // Direct token comparison
105
- return actualSignature === secret;
106
- case 'slack-v0': {
107
- // Slack signature verification
108
- // Format: v0=<HMAC-SHA256 of v0:timestamp:body>
109
- const timestamp = headers?.['x-slack-request-timestamp'];
110
- if (!timestamp)
111
- return false;
112
- // Check timestamp is within 5 minutes
113
- const now = Math.floor(Date.now() / 1000);
114
- if (Math.abs(now - parseInt(timestamp, 10)) > 300) {
115
- console.warn('[webhook-router] Slack request timestamp too old');
116
- return false;
117
- }
118
- const sigBasestring = `v0:${timestamp}:${payload}`;
119
- expectedSignature = 'v0=' + crypto
120
- .createHmac('sha256', secret)
121
- .update(sigBasestring)
122
- .digest('hex');
123
- return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expectedSignature));
124
- }
125
- default:
126
- console.warn(`[webhook-router] Unknown signature algorithm: ${config.signature.algorithm}`);
127
- return false;
128
- }
129
- return crypto.timingSafeEqual(Buffer.from(actualSignature), Buffer.from(expectedSignature));
130
- }
131
- catch (error) {
132
- console.error('[webhook-router] Signature verification error:', error);
133
- return false;
134
- }
135
- }
136
- /**
137
- * Execute an action for an event
138
- */
139
- async function executeAction(action, event, responder, responderConfig) {
140
- const resolvedAction = resolveActionTemplate(action, event);
141
- switch (resolvedAction.type) {
142
- case 'spawn_agent': {
143
- const agentType = resolvedAction.agentType || 'lead';
144
- const prompt = buildPrompt(resolvedAction.prompt || 'default', event);
145
- // Find the repository and queue spawn command
146
- const repository = await db.repositories.findByFullName(event.context.name);
147
- if (!repository?.userId) {
148
- return { success: false, error: 'Repository not found or not linked' };
149
- }
150
- // Find an available daemon
151
- const daemons = await db.linkedDaemons.findByUserId(repository.userId);
152
- const onlineDaemon = daemons.find(d => d.status === 'online');
153
- if (!onlineDaemon) {
154
- // Post a response indicating no daemon available
155
- if (responder && event.item?.number) {
156
- await responder.respond(event, {
157
- type: 'comment',
158
- target: event.item.number,
159
- body: `⚠️ No Agent Relay daemon is available to handle this request. Please ensure you have a linked daemon running.`,
160
- }, responderConfig);
161
- }
162
- return { success: false, error: 'No available daemon' };
163
- }
164
- // Post acknowledgment
165
- if (responder && event.item?.number) {
166
- await responder.respond(event, {
167
- type: 'comment',
168
- target: event.item.number,
169
- body: `👋 Routing to **@${agentType}** agent. The agent will respond shortly.`,
170
- }, responderConfig);
171
- }
172
- // Queue spawn command
173
- const agentName = `${agentType}-${event.id.slice(0, 8)}`;
174
- await db.linkedDaemons.queueMessage(onlineDaemon.id, {
175
- from: { daemonId: 'cloud', daemonName: 'Agent Relay Cloud', agent: 'system' },
176
- to: '__spawner__',
177
- content: JSON.stringify({
178
- type: 'spawn_agent',
179
- agentName,
180
- cli: 'claude',
181
- task: prompt,
182
- metadata: {
183
- eventId: event.id,
184
- source: event.source,
185
- eventType: event.type,
186
- repository: event.context.name,
187
- itemNumber: event.item?.number,
188
- },
189
- }),
190
- metadata: { type: 'spawn_command' },
191
- timestamp: new Date().toISOString(),
192
- });
193
- console.log(`[webhook-router] Queued spawn command for ${agentName}`);
194
- return { success: true };
195
- }
196
- case 'message_agent': {
197
- // Send message to existing agent
198
- return { success: false, error: 'message_agent not yet implemented' };
199
- }
200
- case 'post_comment': {
201
- if (!responder) {
202
- return { success: false, error: 'No responder available' };
203
- }
204
- const body = resolvedAction.config?.body || 'Action received.';
205
- const target = event.item?.number || event.item?.id || '';
206
- const result = await responder.respond(event, {
207
- type: 'comment',
208
- target,
209
- body,
210
- }, responderConfig);
211
- return { success: result.success, error: result.error };
212
- }
213
- case 'create_issue': {
214
- return { success: false, error: 'create_issue not yet implemented' };
215
- }
216
- case 'custom': {
217
- // Custom action handler
218
- const handler = resolvedAction.config?.handler;
219
- if (handler) {
220
- await handler(event);
221
- return { success: true };
222
- }
223
- return { success: false, error: 'No custom handler defined' };
224
- }
225
- default:
226
- return { success: false, error: `Unknown action type: ${resolvedAction.type}` };
227
- }
228
- }
229
- /**
230
- * Build a prompt from a template name and event
231
- */
232
- function buildPrompt(templateName, event) {
233
- const templates = {
234
- 'ci-failure': (e) => `
235
- # CI Failure Fix Task
236
-
237
- A CI check has failed in ${e.context.name}.
238
-
239
- ## Failure Details
240
-
241
- **Check Name:** ${e.item?.title || 'Unknown'}
242
- **Branch:** ${e.metadata?.branch || 'unknown'}
243
- **Commit:** ${e.metadata?.commitSha || 'unknown'}
244
-
245
- ${e.metadata?.failureSummary ? `**Summary:**\n${e.metadata.failureSummary}` : ''}
246
-
247
- ${e.metadata?.annotations ? `## Annotations\n\n${formatAnnotations(e.metadata.annotations)}` : ''}
248
-
249
- ## Your Task
250
-
251
- 1. Analyze the failure
252
- 2. Fix the issues
253
- 3. Push your changes
254
- 4. Report back with a summary
255
- `.trim(),
256
- 'mention': (e) => `
257
- # Agent Mention Task
258
-
259
- You were mentioned in ${e.source} in ${e.context.name}.
260
-
261
- ## Context
262
-
263
- **Item:** ${e.item?.title || 'N/A'} (#${e.item?.number || e.item?.id || 'N/A'})
264
- **Author:** @${e.actor.name}
265
-
266
- ## Message
267
-
268
- ${e.item?.body || 'No message content'}
269
-
270
- ## Your Task
271
-
272
- Respond helpfully to the mention. If code changes are needed, make them and push.
273
- `.trim(),
274
- 'issue': (e) => `
275
- # Issue Assignment
276
-
277
- You've been assigned to work on an issue in ${e.context.name}.
278
-
279
- ## Issue Details
280
-
281
- **Title:** ${e.item?.title}
282
- **Priority:** ${e.priority || 'normal'}
283
- **Labels:** ${e.labels.join(', ') || 'none'}
284
-
285
- ## Description
286
-
287
- ${e.item?.body || 'No description provided.'}
288
-
289
- ## Your Task
290
-
291
- 1. Analyze the issue
292
- 2. Implement a solution
293
- 3. Create a PR
294
- `.trim(),
295
- 'linear-issue': (e) => `
296
- # Linear Issue
297
-
298
- A new issue was created in ${e.context.name}.
299
-
300
- ## Issue Details
301
-
302
- **Identifier:** ${e.metadata?.identifier || 'N/A'}
303
- **Title:** ${e.item?.title}
304
- **Priority:** ${e.priority || 'normal'}
305
- **State:** ${e.item?.state || 'unknown'}
306
-
307
- ## Description
308
-
309
- ${e.item?.body || 'No description provided.'}
310
-
311
- ## Your Task
312
-
313
- Analyze and work on this issue if appropriate.
314
- `.trim(),
315
- 'slack-request': (e) => `
316
- # Slack Request
317
-
318
- Someone mentioned you in Slack.
319
-
320
- ## Message
321
-
322
- ${e.item?.body || 'No message content'}
323
-
324
- ## Your Task
325
-
326
- Respond to the request. Use the Slack API to post your response.
327
- `.trim(),
328
- 'default': (e) => `
329
- # Webhook Event
330
-
331
- A webhook event was received from ${e.source}.
332
-
333
- ## Event Details
334
-
335
- **Type:** ${e.type}
336
- **Context:** ${e.context.name}
337
- **Actor:** ${e.actor.name}
338
-
339
- ## Item
340
-
341
- ${e.item ? `**${e.item.type}:** ${e.item.title || e.item.id}` : 'No item'}
342
-
343
- ## Body
344
-
345
- ${e.item?.body || 'No content'}
346
- `.trim(),
347
- };
348
- const template = templates[templateName] || templates['default'];
349
- return template(event);
350
- }
351
- /**
352
- * Format annotations for prompt
353
- */
354
- function formatAnnotations(annotations) {
355
- return annotations
356
- .slice(0, 20)
357
- .map(a => `- ${a.path}:${a.startLine} - ${a.message}`)
358
- .join('\n');
359
- }
360
- /**
361
- * Process a webhook from any source
362
- */
363
- export async function processWebhook(source, payload, headers, config) {
364
- const webhookConfig = config || getWebhookConfig();
365
- const sourceConfig = webhookConfig.sources[source];
366
- if (!sourceConfig) {
367
- return {
368
- success: false,
369
- eventId: 'unknown',
370
- source,
371
- eventType: 'unknown',
372
- matchedRules: [],
373
- actions: [],
374
- responses: [{
375
- type: 'error',
376
- success: false,
377
- error: `Unknown webhook source: ${source}`,
378
- }],
379
- };
380
- }
381
- if (!sourceConfig.enabled) {
382
- return {
383
- success: false,
384
- eventId: 'unknown',
385
- source,
386
- eventType: 'unknown',
387
- matchedRules: [],
388
- actions: [],
389
- responses: [{
390
- type: 'error',
391
- success: false,
392
- error: `Webhook source disabled: ${source}`,
393
- }],
394
- };
395
- }
396
- // Verify signature
397
- const signature = headers[sourceConfig.signature.header];
398
- if (!verifySignature(payload, signature, sourceConfig, headers)) {
399
- console.error(`[webhook-router] Invalid signature for source: ${source}`);
400
- return {
401
- success: false,
402
- eventId: 'unknown',
403
- source,
404
- eventType: 'unknown',
405
- matchedRules: [],
406
- actions: [],
407
- responses: [{
408
- type: 'error',
409
- success: false,
410
- error: 'Invalid signature',
411
- }],
412
- };
413
- }
414
- // Parse payload
415
- const parser = getParser(sourceConfig.parser);
416
- if (!parser) {
417
- return {
418
- success: false,
419
- eventId: 'unknown',
420
- source,
421
- eventType: 'unknown',
422
- matchedRules: [],
423
- actions: [],
424
- responses: [{
425
- type: 'error',
426
- success: false,
427
- error: `Parser not found: ${sourceConfig.parser}`,
428
- }],
429
- };
430
- }
431
- let parsedPayload;
432
- try {
433
- parsedPayload = JSON.parse(payload);
434
- }
435
- catch {
436
- return {
437
- success: false,
438
- eventId: 'unknown',
439
- source,
440
- eventType: 'unknown',
441
- matchedRules: [],
442
- actions: [],
443
- responses: [{
444
- type: 'error',
445
- success: false,
446
- error: 'Invalid JSON payload',
447
- }],
448
- };
449
- }
450
- const events = parser.parse(parsedPayload, headers, sourceConfig.parserConfig);
451
- if (events.length === 0) {
452
- return {
453
- success: true,
454
- eventId: 'none',
455
- source,
456
- eventType: 'none',
457
- matchedRules: [],
458
- actions: [],
459
- responses: [],
460
- };
461
- }
462
- // Get responder
463
- const responder = getResponder(sourceConfig.responder);
464
- // Process each event
465
- const results = [];
466
- for (const event of events) {
467
- const matchedRules = findMatchingRules(webhookConfig.rules, event);
468
- const actionResults = [];
469
- const responseResults = [];
470
- console.log(`[webhook-router] Event ${event.id}: type=${event.type}, matched ${matchedRules.length} rules`);
471
- for (const rule of matchedRules) {
472
- const result = await executeAction(rule.action, event, responder, sourceConfig.responderConfig);
473
- actionResults.push({
474
- ruleId: rule.id,
475
- action: rule.action,
476
- success: result.success,
477
- error: result.error,
478
- });
479
- }
480
- results.push({
481
- success: actionResults.every(a => a.success),
482
- eventId: event.id,
483
- source: event.source,
484
- eventType: event.type,
485
- matchedRules: matchedRules.map(r => r.id),
486
- actions: actionResults,
487
- responses: responseResults,
488
- });
489
- }
490
- // Return combined result
491
- if (results.length === 1) {
492
- return results[0];
493
- }
494
- return {
495
- success: results.every(r => r.success),
496
- eventId: events[0].id,
497
- source,
498
- eventType: events.map(e => e.type).join(','),
499
- matchedRules: results.flatMap(r => r.matchedRules),
500
- actions: results.flatMap(r => r.actions),
501
- responses: results.flatMap(r => r.responses),
502
- };
503
- }
504
- //# sourceMappingURL=router.js.map
@@ -1,24 +0,0 @@
1
- /**
2
- * Webhook Rules Engine
3
- *
4
- * Matches normalized events against configured rules and determines actions to take.
5
- */
6
- import type { NormalizedEvent, WebhookRule, WebhookAction } from './types.js';
7
- /**
8
- * Check if a rule matches an event
9
- */
10
- export declare function matchesRule(rule: WebhookRule, event: NormalizedEvent): boolean;
11
- /**
12
- * Find all matching rules for an event, sorted by priority
13
- */
14
- export declare function findMatchingRules(rules: WebhookRule[], event: NormalizedEvent): WebhookRule[];
15
- /**
16
- * Resolve template variables in action configuration
17
- * Supports: ${event.field}, ${event.field.subfield}
18
- */
19
- export declare function resolveActionTemplate(action: WebhookAction, event: NormalizedEvent): WebhookAction;
20
- /**
21
- * Default rules for common patterns
22
- */
23
- export declare const defaultRules: WebhookRule[];
24
- //# sourceMappingURL=rules-engine.d.ts.map