@generacy-ai/orchestrator 0.0.0-preview-20260304013206

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 (274) hide show
  1. package/LICENSE +191 -0
  2. package/dist/auth/api-key.d.ts +63 -0
  3. package/dist/auth/api-key.d.ts.map +1 -0
  4. package/dist/auth/api-key.js +102 -0
  5. package/dist/auth/api-key.js.map +1 -0
  6. package/dist/auth/github-oauth.d.ts +29 -0
  7. package/dist/auth/github-oauth.d.ts.map +1 -0
  8. package/dist/auth/github-oauth.js +136 -0
  9. package/dist/auth/github-oauth.js.map +1 -0
  10. package/dist/auth/index.d.ts +5 -0
  11. package/dist/auth/index.d.ts.map +1 -0
  12. package/dist/auth/index.js +9 -0
  13. package/dist/auth/index.js.map +1 -0
  14. package/dist/auth/jwt.d.ts +34 -0
  15. package/dist/auth/jwt.d.ts.map +1 -0
  16. package/dist/auth/jwt.js +74 -0
  17. package/dist/auth/jwt.js.map +1 -0
  18. package/dist/auth/middleware.d.ts +43 -0
  19. package/dist/auth/middleware.d.ts.map +1 -0
  20. package/dist/auth/middleware.js +101 -0
  21. package/dist/auth/middleware.js.map +1 -0
  22. package/dist/config/index.d.ts +3 -0
  23. package/dist/config/index.d.ts.map +1 -0
  24. package/dist/config/index.js +5 -0
  25. package/dist/config/index.js.map +1 -0
  26. package/dist/config/loader.d.ts +21 -0
  27. package/dist/config/loader.d.ts.map +1 -0
  28. package/dist/config/loader.js +295 -0
  29. package/dist/config/loader.js.map +1 -0
  30. package/dist/config/schema.d.ts +733 -0
  31. package/dist/config/schema.d.ts.map +1 -0
  32. package/dist/config/schema.js +174 -0
  33. package/dist/config/schema.js.map +1 -0
  34. package/dist/index.d.ts +24 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +33 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/middleware/error-handler.d.ts +30 -0
  39. package/dist/middleware/error-handler.d.ts.map +1 -0
  40. package/dist/middleware/error-handler.js +173 -0
  41. package/dist/middleware/error-handler.js.map +1 -0
  42. package/dist/middleware/index.d.ts +4 -0
  43. package/dist/middleware/index.d.ts.map +1 -0
  44. package/dist/middleware/index.js +4 -0
  45. package/dist/middleware/index.js.map +1 -0
  46. package/dist/middleware/rate-limit.d.ts +32 -0
  47. package/dist/middleware/rate-limit.d.ts.map +1 -0
  48. package/dist/middleware/rate-limit.js +92 -0
  49. package/dist/middleware/rate-limit.js.map +1 -0
  50. package/dist/middleware/request-logger.d.ts +31 -0
  51. package/dist/middleware/request-logger.d.ts.map +1 -0
  52. package/dist/middleware/request-logger.js +89 -0
  53. package/dist/middleware/request-logger.js.map +1 -0
  54. package/dist/routes/agents.d.ts +7 -0
  55. package/dist/routes/agents.d.ts.map +1 -0
  56. package/dist/routes/agents.js +78 -0
  57. package/dist/routes/agents.js.map +1 -0
  58. package/dist/routes/dispatch.d.ts +8 -0
  59. package/dist/routes/dispatch.d.ts.map +1 -0
  60. package/dist/routes/dispatch.js +46 -0
  61. package/dist/routes/dispatch.js.map +1 -0
  62. package/dist/routes/events.d.ts +14 -0
  63. package/dist/routes/events.d.ts.map +1 -0
  64. package/dist/routes/events.js +240 -0
  65. package/dist/routes/events.js.map +1 -0
  66. package/dist/routes/health.d.ts +14 -0
  67. package/dist/routes/health.d.ts.map +1 -0
  68. package/dist/routes/health.js +132 -0
  69. package/dist/routes/health.js.map +1 -0
  70. package/dist/routes/index.d.ts +36 -0
  71. package/dist/routes/index.d.ts.map +1 -0
  72. package/dist/routes/index.js +34 -0
  73. package/dist/routes/index.js.map +1 -0
  74. package/dist/routes/integrations.d.ts +34 -0
  75. package/dist/routes/integrations.d.ts.map +1 -0
  76. package/dist/routes/integrations.js +81 -0
  77. package/dist/routes/integrations.js.map +1 -0
  78. package/dist/routes/metrics.d.ts +31 -0
  79. package/dist/routes/metrics.d.ts.map +1 -0
  80. package/dist/routes/metrics.js +157 -0
  81. package/dist/routes/metrics.js.map +1 -0
  82. package/dist/routes/pr-webhooks.d.ts +15 -0
  83. package/dist/routes/pr-webhooks.d.ts.map +1 -0
  84. package/dist/routes/pr-webhooks.js +114 -0
  85. package/dist/routes/pr-webhooks.js.map +1 -0
  86. package/dist/routes/queue.d.ts +7 -0
  87. package/dist/routes/queue.d.ts.map +1 -0
  88. package/dist/routes/queue.js +94 -0
  89. package/dist/routes/queue.js.map +1 -0
  90. package/dist/routes/webhooks.d.ts +15 -0
  91. package/dist/routes/webhooks.d.ts.map +1 -0
  92. package/dist/routes/webhooks.js +117 -0
  93. package/dist/routes/webhooks.js.map +1 -0
  94. package/dist/routes/workflows.d.ts +7 -0
  95. package/dist/routes/workflows.d.ts.map +1 -0
  96. package/dist/routes/workflows.js +138 -0
  97. package/dist/routes/workflows.js.map +1 -0
  98. package/dist/server.d.ts +35 -0
  99. package/dist/server.d.ts.map +1 -0
  100. package/dist/server.js +264 -0
  101. package/dist/server.js.map +1 -0
  102. package/dist/services/agent-registry.d.ts +89 -0
  103. package/dist/services/agent-registry.d.ts.map +1 -0
  104. package/dist/services/agent-registry.js +173 -0
  105. package/dist/services/agent-registry.js.map +1 -0
  106. package/dist/services/epic-completion-monitor-service.d.ts +69 -0
  107. package/dist/services/epic-completion-monitor-service.d.ts.map +1 -0
  108. package/dist/services/epic-completion-monitor-service.js +200 -0
  109. package/dist/services/epic-completion-monitor-service.js.map +1 -0
  110. package/dist/services/identity.d.ts +41 -0
  111. package/dist/services/identity.d.ts.map +1 -0
  112. package/dist/services/identity.js +91 -0
  113. package/dist/services/identity.js.map +1 -0
  114. package/dist/services/index.d.ts +13 -0
  115. package/dist/services/index.d.ts.map +1 -0
  116. package/dist/services/index.js +13 -0
  117. package/dist/services/index.js.map +1 -0
  118. package/dist/services/label-monitor-service.d.ts +95 -0
  119. package/dist/services/label-monitor-service.d.ts.map +1 -0
  120. package/dist/services/label-monitor-service.js +414 -0
  121. package/dist/services/label-monitor-service.js.map +1 -0
  122. package/dist/services/label-sync-service.d.ts +76 -0
  123. package/dist/services/label-sync-service.d.ts.map +1 -0
  124. package/dist/services/label-sync-service.js +108 -0
  125. package/dist/services/label-sync-service.js.map +1 -0
  126. package/dist/services/phase-tracker-service.d.ts +32 -0
  127. package/dist/services/phase-tracker-service.d.ts.map +1 -0
  128. package/dist/services/phase-tracker-service.js +82 -0
  129. package/dist/services/phase-tracker-service.js.map +1 -0
  130. package/dist/services/pr-feedback-monitor-service.d.ts +86 -0
  131. package/dist/services/pr-feedback-monitor-service.d.ts.map +1 -0
  132. package/dist/services/pr-feedback-monitor-service.js +423 -0
  133. package/dist/services/pr-feedback-monitor-service.js.map +1 -0
  134. package/dist/services/queue-service.d.ts +62 -0
  135. package/dist/services/queue-service.d.ts.map +1 -0
  136. package/dist/services/queue-service.js +147 -0
  137. package/dist/services/queue-service.js.map +1 -0
  138. package/dist/services/redis-queue-adapter.d.ts +35 -0
  139. package/dist/services/redis-queue-adapter.d.ts.map +1 -0
  140. package/dist/services/redis-queue-adapter.js +218 -0
  141. package/dist/services/redis-queue-adapter.js.map +1 -0
  142. package/dist/services/smee-receiver.d.ts +87 -0
  143. package/dist/services/smee-receiver.d.ts.map +1 -0
  144. package/dist/services/smee-receiver.js +225 -0
  145. package/dist/services/smee-receiver.js.map +1 -0
  146. package/dist/services/webhook-setup-service.d.ts +253 -0
  147. package/dist/services/webhook-setup-service.d.ts.map +1 -0
  148. package/dist/services/webhook-setup-service.js +369 -0
  149. package/dist/services/webhook-setup-service.js.map +1 -0
  150. package/dist/services/worker-dispatcher.d.ts +57 -0
  151. package/dist/services/worker-dispatcher.d.ts.map +1 -0
  152. package/dist/services/worker-dispatcher.js +211 -0
  153. package/dist/services/worker-dispatcher.js.map +1 -0
  154. package/dist/services/workflow-service.d.ts +65 -0
  155. package/dist/services/workflow-service.d.ts.map +1 -0
  156. package/dist/services/workflow-service.js +164 -0
  157. package/dist/services/workflow-service.js.map +1 -0
  158. package/dist/sse/events.d.ts +50 -0
  159. package/dist/sse/events.d.ts.map +1 -0
  160. package/dist/sse/events.js +152 -0
  161. package/dist/sse/events.js.map +1 -0
  162. package/dist/sse/index.d.ts +4 -0
  163. package/dist/sse/index.d.ts.map +1 -0
  164. package/dist/sse/index.js +7 -0
  165. package/dist/sse/index.js.map +1 -0
  166. package/dist/sse/stream.d.ts +109 -0
  167. package/dist/sse/stream.d.ts.map +1 -0
  168. package/dist/sse/stream.js +239 -0
  169. package/dist/sse/stream.js.map +1 -0
  170. package/dist/sse/subscriptions.d.ts +91 -0
  171. package/dist/sse/subscriptions.d.ts.map +1 -0
  172. package/dist/sse/subscriptions.js +299 -0
  173. package/dist/sse/subscriptions.js.map +1 -0
  174. package/dist/types/api.d.ts +651 -0
  175. package/dist/types/api.d.ts.map +1 -0
  176. package/dist/types/api.js +169 -0
  177. package/dist/types/api.js.map +1 -0
  178. package/dist/types/index.d.ts +6 -0
  179. package/dist/types/index.d.ts.map +1 -0
  180. package/dist/types/index.js +27 -0
  181. package/dist/types/index.js.map +1 -0
  182. package/dist/types/monitor.d.ts +243 -0
  183. package/dist/types/monitor.d.ts.map +1 -0
  184. package/dist/types/monitor.js +2 -0
  185. package/dist/types/monitor.js.map +1 -0
  186. package/dist/types/problem-details.d.ts +63 -0
  187. package/dist/types/problem-details.d.ts.map +1 -0
  188. package/dist/types/problem-details.js +37 -0
  189. package/dist/types/problem-details.js.map +1 -0
  190. package/dist/types/sse.d.ts +224 -0
  191. package/dist/types/sse.d.ts.map +1 -0
  192. package/dist/types/sse.js +103 -0
  193. package/dist/types/sse.js.map +1 -0
  194. package/dist/types/webhook.d.ts +59 -0
  195. package/dist/types/webhook.d.ts.map +1 -0
  196. package/dist/types/webhook.js +2 -0
  197. package/dist/types/webhook.js.map +1 -0
  198. package/dist/utils/correlation.d.ts +30 -0
  199. package/dist/utils/correlation.d.ts.map +1 -0
  200. package/dist/utils/correlation.js +34 -0
  201. package/dist/utils/correlation.js.map +1 -0
  202. package/dist/utils/index.d.ts +3 -0
  203. package/dist/utils/index.d.ts.map +1 -0
  204. package/dist/utils/index.js +3 -0
  205. package/dist/utils/index.js.map +1 -0
  206. package/dist/utils/shutdown.d.ts +28 -0
  207. package/dist/utils/shutdown.d.ts.map +1 -0
  208. package/dist/utils/shutdown.js +86 -0
  209. package/dist/utils/shutdown.js.map +1 -0
  210. package/dist/worker/claude-cli-worker.d.ts +61 -0
  211. package/dist/worker/claude-cli-worker.d.ts.map +1 -0
  212. package/dist/worker/claude-cli-worker.js +330 -0
  213. package/dist/worker/claude-cli-worker.js.map +1 -0
  214. package/dist/worker/cli-spawner.d.ts +42 -0
  215. package/dist/worker/cli-spawner.d.ts.map +1 -0
  216. package/dist/worker/cli-spawner.js +183 -0
  217. package/dist/worker/cli-spawner.js.map +1 -0
  218. package/dist/worker/config.d.ts +76 -0
  219. package/dist/worker/config.d.ts.map +1 -0
  220. package/dist/worker/config.js +39 -0
  221. package/dist/worker/config.js.map +1 -0
  222. package/dist/worker/epic-post-tasks.d.ts +73 -0
  223. package/dist/worker/epic-post-tasks.d.ts.map +1 -0
  224. package/dist/worker/epic-post-tasks.js +266 -0
  225. package/dist/worker/epic-post-tasks.js.map +1 -0
  226. package/dist/worker/gate-checker.d.ts +22 -0
  227. package/dist/worker/gate-checker.d.ts.map +1 -0
  228. package/dist/worker/gate-checker.js +41 -0
  229. package/dist/worker/gate-checker.js.map +1 -0
  230. package/dist/worker/index.d.ts +13 -0
  231. package/dist/worker/index.d.ts.map +1 -0
  232. package/dist/worker/index.js +19 -0
  233. package/dist/worker/index.js.map +1 -0
  234. package/dist/worker/label-manager.d.ts +89 -0
  235. package/dist/worker/label-manager.d.ts.map +1 -0
  236. package/dist/worker/label-manager.js +200 -0
  237. package/dist/worker/label-manager.js.map +1 -0
  238. package/dist/worker/output-capture.d.ts +58 -0
  239. package/dist/worker/output-capture.d.ts.map +1 -0
  240. package/dist/worker/output-capture.js +153 -0
  241. package/dist/worker/output-capture.js.map +1 -0
  242. package/dist/worker/phase-loop.d.ts +64 -0
  243. package/dist/worker/phase-loop.d.ts.map +1 -0
  244. package/dist/worker/phase-loop.js +185 -0
  245. package/dist/worker/phase-loop.js.map +1 -0
  246. package/dist/worker/phase-resolver.d.ts +62 -0
  247. package/dist/worker/phase-resolver.d.ts.map +1 -0
  248. package/dist/worker/phase-resolver.js +144 -0
  249. package/dist/worker/phase-resolver.js.map +1 -0
  250. package/dist/worker/pr-feedback-handler.d.ts +105 -0
  251. package/dist/worker/pr-feedback-handler.d.ts.map +1 -0
  252. package/dist/worker/pr-feedback-handler.js +391 -0
  253. package/dist/worker/pr-feedback-handler.js.map +1 -0
  254. package/dist/worker/pr-linker.d.ts +69 -0
  255. package/dist/worker/pr-linker.d.ts.map +1 -0
  256. package/dist/worker/pr-linker.js +108 -0
  257. package/dist/worker/pr-linker.js.map +1 -0
  258. package/dist/worker/pr-manager.d.ts +61 -0
  259. package/dist/worker/pr-manager.d.ts.map +1 -0
  260. package/dist/worker/pr-manager.js +140 -0
  261. package/dist/worker/pr-manager.js.map +1 -0
  262. package/dist/worker/repo-checkout.d.ts +63 -0
  263. package/dist/worker/repo-checkout.d.ts.map +1 -0
  264. package/dist/worker/repo-checkout.js +160 -0
  265. package/dist/worker/repo-checkout.js.map +1 -0
  266. package/dist/worker/stage-comment-manager.d.ts +34 -0
  267. package/dist/worker/stage-comment-manager.d.ts.map +1 -0
  268. package/dist/worker/stage-comment-manager.js +114 -0
  269. package/dist/worker/stage-comment-manager.js.map +1 -0
  270. package/dist/worker/types.d.ts +192 -0
  271. package/dist/worker/types.d.ts.map +1 -0
  272. package/dist/worker/types.js +53 -0
  273. package/dist/worker/types.js.map +1 -0
  274. package/package.json +64 -0
package/dist/server.js ADDED
@@ -0,0 +1,264 @@
1
+ import Fastify from 'fastify';
2
+ import cors from '@fastify/cors';
3
+ import helmet from '@fastify/helmet';
4
+ import jwt from '@fastify/jwt';
5
+ import { loadConfig, createTestConfig } from './config/index.js';
6
+ import { correlationIdHook, correlationIdResponseHook, setupGracefulShutdown } from './utils/index.js';
7
+ import { setupErrorHandler } from './middleware/error-handler.js';
8
+ import { setupRateLimit } from './middleware/rate-limit.js';
9
+ import { requestStartHook, requestEndHook } from './middleware/request-logger.js';
10
+ import { createAuthMiddleware, InMemoryApiKeyStore } from './auth/index.js';
11
+ import { registerRoutes, InMemoryIntegrationRegistry, closeAllSSEConnections } from './routes/index.js';
12
+ import { WorkflowService, InMemoryWorkflowStore } from './services/workflow-service.js';
13
+ import { QueueService, InMemoryQueueStore } from './services/queue-service.js';
14
+ import { AgentRegistry } from './services/agent-registry.js';
15
+ import { LabelSyncService } from './services/label-sync-service.js';
16
+ import { LabelMonitorService } from './services/label-monitor-service.js';
17
+ import { PrFeedbackMonitorService } from './services/pr-feedback-monitor-service.js';
18
+ import { PhaseTrackerService } from './services/phase-tracker-service.js';
19
+ import { RedisQueueAdapter } from './services/redis-queue-adapter.js';
20
+ import { WorkerDispatcher } from './services/worker-dispatcher.js';
21
+ import { setupWebhookRoutes } from './routes/webhooks.js';
22
+ import { setupPrWebhookRoutes } from './routes/pr-webhooks.js';
23
+ import { setupDispatchRoutes } from './routes/dispatch.js';
24
+ import { createGitHubClient } from '@generacy-ai/workflow-engine';
25
+ import { resolveClusterIdentity } from './services/identity.js';
26
+ import { Redis as IORedis } from 'ioredis';
27
+ import { ClaudeCliWorker } from './worker/claude-cli-worker.js';
28
+ /**
29
+ * Create and configure the Fastify server
30
+ */
31
+ export async function createServer(options = {}) {
32
+ const config = options.config ?? loadConfig();
33
+ // Configure Fastify logger
34
+ const loggerConfig = config.logging.pretty
35
+ ? {
36
+ transport: {
37
+ target: 'pino-pretty',
38
+ options: {
39
+ translateTime: 'HH:MM:ss Z',
40
+ ignore: 'pid,hostname',
41
+ },
42
+ },
43
+ }
44
+ : true;
45
+ // Create Fastify instance
46
+ const server = Fastify({
47
+ logger: {
48
+ level: config.logging.level,
49
+ ...(typeof loggerConfig === 'object' ? loggerConfig : {}),
50
+ },
51
+ ...options.fastifyOptions,
52
+ });
53
+ // Store config on server for access in routes
54
+ server.decorate('config', config);
55
+ // Add correlation ID hooks
56
+ server.addHook('onRequest', correlationIdHook);
57
+ server.addHook('onSend', correlationIdResponseHook);
58
+ // Add request logging hooks
59
+ server.addHook('onRequest', requestStartHook);
60
+ server.addHook('onResponse', requestEndHook);
61
+ // Register core plugins
62
+ await server.register(cors, {
63
+ origin: config.cors.origin,
64
+ credentials: config.cors.credentials,
65
+ });
66
+ await server.register(helmet, {
67
+ // Customize helmet for API server
68
+ contentSecurityPolicy: false, // Not needed for API
69
+ });
70
+ // Register JWT plugin
71
+ await server.register(jwt, {
72
+ secret: config.auth.jwt.secret,
73
+ sign: {
74
+ expiresIn: config.auth.jwt.expiresIn,
75
+ },
76
+ });
77
+ // Setup rate limiting
78
+ await setupRateLimit(server, config.rateLimit);
79
+ // Setup error handler
80
+ setupErrorHandler(server);
81
+ // Setup authentication middleware
82
+ const apiKeyStore = new InMemoryApiKeyStore();
83
+ const authMiddleware = createAuthMiddleware({
84
+ apiKeyStore,
85
+ enabled: config.auth.enabled,
86
+ skipRoutes: ['/health', '/metrics', '/webhooks/github', '/webhooks/github/pr-review'],
87
+ });
88
+ server.addHook('preHandler', authMiddleware);
89
+ // Resolve cluster identity for assignee-based issue filtering
90
+ const clusterGithubUsername = await resolveClusterIdentity(config.monitor.clusterGithubUsername, server.log);
91
+ // Sync labels for watched repositories
92
+ if (config.repositories.length > 0) {
93
+ const labelSyncService = new LabelSyncService(server.log, createGitHubClient);
94
+ try {
95
+ const syncResult = await labelSyncService.syncAll(config.repositories);
96
+ server.log.info(`Label sync complete: ${syncResult.successfulRepos}/${syncResult.totalRepos} repos succeeded`);
97
+ if (syncResult.failedRepos > 0) {
98
+ server.log.warn(`Label sync: ${syncResult.failedRepos} repo(s) failed`);
99
+ }
100
+ }
101
+ catch (error) {
102
+ server.log.warn(`Label sync failed: ${error instanceof Error ? error.message : String(error)}`);
103
+ }
104
+ }
105
+ // Initialize Redis client (shared across services)
106
+ let redisClient = null;
107
+ try {
108
+ redisClient = new IORedis(config.redis.url);
109
+ // Test connection
110
+ await redisClient.ping();
111
+ server.log.info('Redis connected');
112
+ }
113
+ catch (error) {
114
+ server.log.warn(`Redis connection failed: ${error instanceof Error ? error.message : String(error)}. Phase tracker will operate without deduplication.`);
115
+ redisClient = null;
116
+ }
117
+ // Initialize Redis queue adapter (replaces in-memory placeholder)
118
+ let redisQueueAdapter = null;
119
+ let workerDispatcher = null;
120
+ if (redisClient) {
121
+ redisQueueAdapter = new RedisQueueAdapter(redisClient, server.log, {
122
+ maxRetries: config.dispatch.maxRetries,
123
+ });
124
+ // Create CLI worker to handle queue items
125
+ const cliWorker = new ClaudeCliWorker(config.worker, server.log);
126
+ workerDispatcher = new WorkerDispatcher(redisQueueAdapter, redisClient, server.log, config.dispatch, cliWorker.handle.bind(cliWorker));
127
+ }
128
+ // Initialize label monitor service
129
+ let labelMonitorService = null;
130
+ let prFeedbackMonitorService = null;
131
+ if (config.repositories.length > 0) {
132
+ const phaseTracker = new PhaseTrackerService(server.log, redisClient);
133
+ // Use Redis queue adapter if available, otherwise fall back to a logging-only adapter
134
+ const queueAdapter = redisQueueAdapter ?? {
135
+ async enqueue(item) {
136
+ server.log.warn({ owner: item.owner, repo: item.repo, issue: item.issueNumber }, 'Item enqueued (fallback adapter — Redis unavailable)');
137
+ },
138
+ };
139
+ labelMonitorService = new LabelMonitorService(server.log, createGitHubClient, phaseTracker, queueAdapter, config.monitor, config.repositories, clusterGithubUsername);
140
+ // Initialize PR feedback monitor service (if enabled)
141
+ if (config.prMonitor.enabled) {
142
+ prFeedbackMonitorService = new PrFeedbackMonitorService(server.log, createGitHubClient, phaseTracker, queueAdapter, config.prMonitor, config.repositories, clusterGithubUsername);
143
+ }
144
+ }
145
+ // Register routes (unless skipped for testing)
146
+ if (!options.skipRoutes) {
147
+ // Create services with in-memory stores (can be replaced with real implementations)
148
+ const workflowStore = new InMemoryWorkflowStore();
149
+ const workflowService = new WorkflowService(workflowStore);
150
+ const queueStore = new InMemoryQueueStore();
151
+ const queueService = new QueueService(queueStore);
152
+ const agentRegistry = new AgentRegistry();
153
+ const integrationRegistry = new InMemoryIntegrationRegistry();
154
+ await registerRoutes(server, {
155
+ workflowService,
156
+ queueService,
157
+ agentRegistry,
158
+ integrationRegistry,
159
+ });
160
+ // Register webhook routes (if monitor service is available)
161
+ if (labelMonitorService) {
162
+ const watchedRepos = new Set(config.repositories.map(r => `${r.owner}/${r.repo}`));
163
+ await setupWebhookRoutes(server, {
164
+ monitorService: labelMonitorService,
165
+ webhookSecret: config.monitor.webhookSecret,
166
+ watchedRepos,
167
+ clusterGithubUsername,
168
+ });
169
+ }
170
+ // Register PR webhook routes (if PR feedback monitor service is available)
171
+ if (prFeedbackMonitorService) {
172
+ const watchedRepos = new Set(config.repositories.map(r => `${r.owner}/${r.repo}`));
173
+ await setupPrWebhookRoutes(server, {
174
+ monitorService: prFeedbackMonitorService,
175
+ webhookSecret: config.prMonitor.webhookSecret,
176
+ watchedRepos,
177
+ clusterGithubUsername,
178
+ });
179
+ }
180
+ // Register dispatch queue routes (if queue adapter is available)
181
+ if (redisQueueAdapter) {
182
+ await setupDispatchRoutes(server, redisQueueAdapter);
183
+ }
184
+ // Note: SSE routes are registered via registerRoutes() -> setupEventsRoutes()
185
+ }
186
+ // Start polling and dispatcher on server ready
187
+ server.addHook('onReady', async () => {
188
+ if (labelMonitorService) {
189
+ // Start polling in the background (non-blocking)
190
+ labelMonitorService.startPolling().catch((error) => {
191
+ server.log.error({ err: error }, 'Label monitor polling failed');
192
+ });
193
+ }
194
+ if (prFeedbackMonitorService) {
195
+ // Start PR feedback polling in the background (non-blocking)
196
+ prFeedbackMonitorService.startPolling().catch((error) => {
197
+ server.log.error({ err: error }, 'PR feedback monitor polling failed');
198
+ });
199
+ }
200
+ if (workerDispatcher) {
201
+ // Start worker dispatcher in the background (non-blocking)
202
+ workerDispatcher.start().catch((error) => {
203
+ server.log.error({ err: error }, 'Worker dispatcher failed');
204
+ });
205
+ }
206
+ });
207
+ // Setup graceful shutdown with SSE connection cleanup
208
+ setupGracefulShutdown(server, {
209
+ timeout: Math.max(30000, config.dispatch.shutdownTimeoutMs),
210
+ logger: {
211
+ info: (msg) => server.log.info(msg),
212
+ error: (msg, error) => server.log.error({ err: error }, msg),
213
+ },
214
+ cleanup: [
215
+ async () => {
216
+ // Stop worker dispatcher (waits for in-flight workers)
217
+ if (workerDispatcher) {
218
+ await workerDispatcher.stop();
219
+ }
220
+ // Stop label monitor polling
221
+ if (labelMonitorService) {
222
+ labelMonitorService.stopPolling();
223
+ }
224
+ // Stop PR feedback monitor polling
225
+ if (prFeedbackMonitorService) {
226
+ prFeedbackMonitorService.stopPolling();
227
+ }
228
+ // Close all active SSE connections before shutdown
229
+ closeAllSSEConnections();
230
+ // Close Redis connection
231
+ if (redisClient) {
232
+ await redisClient.quit();
233
+ }
234
+ },
235
+ ],
236
+ });
237
+ return server;
238
+ }
239
+ /**
240
+ * Start the server and begin listening
241
+ */
242
+ export async function startServer(server) {
243
+ const config = server.config;
244
+ const address = await server.listen({
245
+ port: config.server.port,
246
+ host: config.server.host,
247
+ });
248
+ return address;
249
+ }
250
+ /**
251
+ * Create a server for testing
252
+ */
253
+ export async function createTestServer(configOverrides = {}) {
254
+ const config = createTestConfig(configOverrides);
255
+ return createServer({ config, skipRoutes: true });
256
+ }
257
+ /**
258
+ * Create a fully configured server for production
259
+ */
260
+ export async function createProductionServer() {
261
+ const config = loadConfig();
262
+ return createServer({ config });
263
+ }
264
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,89 @@
1
+ import type { ConnectedAgent, AgentConnectionStatus, AgentType } from '../types/index.js';
2
+ /**
3
+ * Agent registration data
4
+ */
5
+ export interface AgentRegistration {
6
+ id: string;
7
+ name: string;
8
+ type: AgentType;
9
+ capabilities: string[];
10
+ metadata?: {
11
+ version?: string;
12
+ platform?: string;
13
+ };
14
+ }
15
+ /**
16
+ * Agent registry - tracks connected agents
17
+ */
18
+ export declare class AgentRegistry {
19
+ private agents;
20
+ private readonly heartbeatTimeout;
21
+ constructor(options?: {
22
+ heartbeatTimeout?: number;
23
+ });
24
+ /**
25
+ * Register a new agent
26
+ */
27
+ register(registration: AgentRegistration): ConnectedAgent;
28
+ /**
29
+ * Unregister an agent
30
+ */
31
+ unregister(id: string): boolean;
32
+ /**
33
+ * Update agent heartbeat
34
+ */
35
+ heartbeat(id: string): boolean;
36
+ /**
37
+ * Update agent status
38
+ */
39
+ updateStatus(id: string, status: AgentConnectionStatus): boolean;
40
+ /**
41
+ * Associate agent with a workflow
42
+ */
43
+ assignWorkflow(id: string, workflowId: string): boolean;
44
+ /**
45
+ * Release agent from workflow
46
+ */
47
+ releaseWorkflow(id: string): boolean;
48
+ /**
49
+ * Get agent by ID
50
+ */
51
+ get(id: string): ConnectedAgent | undefined;
52
+ /**
53
+ * List all connected agents
54
+ */
55
+ list(): ConnectedAgent[];
56
+ /**
57
+ * List agents by status
58
+ */
59
+ listByStatus(status: AgentConnectionStatus): ConnectedAgent[];
60
+ /**
61
+ * List agents by type
62
+ */
63
+ listByType(type: AgentType): ConnectedAgent[];
64
+ /**
65
+ * List available agents (connected and idle)
66
+ */
67
+ listAvailable(): ConnectedAgent[];
68
+ /**
69
+ * Check for stale agents and mark them as disconnected
70
+ */
71
+ checkHeartbeats(): string[];
72
+ /**
73
+ * Remove disconnected agents
74
+ */
75
+ pruneDisconnected(): number;
76
+ /**
77
+ * Get count of agents by status
78
+ */
79
+ getStats(): Record<AgentConnectionStatus, number>;
80
+ /**
81
+ * Clear all agents (for testing)
82
+ */
83
+ clear(): void;
84
+ /**
85
+ * Get total agent count
86
+ */
87
+ size(): number;
88
+ }
89
+ //# sourceMappingURL=agent-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-registry.d.ts","sourceRoot":"","sources":["../../src/services/agent-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,SAAS,EACV,MAAM,mBAAmB,CAAC;AAE3B;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,QAAQ,CAAC,EAAE;QACT,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAA0C;IACxD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;gBAE9B,OAAO,GAAE;QAAE,gBAAgB,CAAC,EAAE,MAAM,CAAA;KAAO;IAIvD;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,iBAAiB,GAAG,cAAc;IAkBzD;;OAEG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI/B;;OAEG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAc9B;;OAEG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,qBAAqB,GAAG,OAAO;IAWhE;;OAEG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO;IAYvD;;OAEG;IACH,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAYpC;;OAEG;IACH,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAI3C;;OAEG;IACH,IAAI,IAAI,cAAc,EAAE;IAIxB;;OAEG;IACH,YAAY,CAAC,MAAM,EAAE,qBAAqB,GAAG,cAAc,EAAE;IAI7D;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,SAAS,GAAG,cAAc,EAAE;IAI7C;;OAEG;IACH,aAAa,IAAI,cAAc,EAAE;IAMjC;;OAEG;IACH,eAAe,IAAI,MAAM,EAAE;IAe3B;;OAEG;IACH,iBAAiB,IAAI,MAAM;IAW3B;;OAEG;IACH,QAAQ,IAAI,MAAM,CAAC,qBAAqB,EAAE,MAAM,CAAC;IAejD;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,IAAI,IAAI,MAAM;CAGf"}
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Agent registry - tracks connected agents
3
+ */
4
+ export class AgentRegistry {
5
+ agents = new Map();
6
+ heartbeatTimeout;
7
+ constructor(options = {}) {
8
+ this.heartbeatTimeout = options.heartbeatTimeout ?? 30000; // 30 seconds
9
+ }
10
+ /**
11
+ * Register a new agent
12
+ */
13
+ register(registration) {
14
+ const agent = {
15
+ id: registration.id,
16
+ name: registration.name,
17
+ type: registration.type,
18
+ status: 'connected',
19
+ capabilities: registration.capabilities,
20
+ lastSeen: new Date().toISOString(),
21
+ metadata: {
22
+ version: registration.metadata?.version,
23
+ platform: registration.metadata?.platform,
24
+ },
25
+ };
26
+ this.agents.set(registration.id, agent);
27
+ return agent;
28
+ }
29
+ /**
30
+ * Unregister an agent
31
+ */
32
+ unregister(id) {
33
+ return this.agents.delete(id);
34
+ }
35
+ /**
36
+ * Update agent heartbeat
37
+ */
38
+ heartbeat(id) {
39
+ const agent = this.agents.get(id);
40
+ if (!agent) {
41
+ return false;
42
+ }
43
+ agent.lastSeen = new Date().toISOString();
44
+ if (agent.status === 'disconnected') {
45
+ agent.status = 'connected';
46
+ }
47
+ return true;
48
+ }
49
+ /**
50
+ * Update agent status
51
+ */
52
+ updateStatus(id, status) {
53
+ const agent = this.agents.get(id);
54
+ if (!agent) {
55
+ return false;
56
+ }
57
+ agent.status = status;
58
+ agent.lastSeen = new Date().toISOString();
59
+ return true;
60
+ }
61
+ /**
62
+ * Associate agent with a workflow
63
+ */
64
+ assignWorkflow(id, workflowId) {
65
+ const agent = this.agents.get(id);
66
+ if (!agent) {
67
+ return false;
68
+ }
69
+ agent.metadata.workflowId = workflowId;
70
+ agent.status = 'busy';
71
+ agent.lastSeen = new Date().toISOString();
72
+ return true;
73
+ }
74
+ /**
75
+ * Release agent from workflow
76
+ */
77
+ releaseWorkflow(id) {
78
+ const agent = this.agents.get(id);
79
+ if (!agent) {
80
+ return false;
81
+ }
82
+ agent.metadata.workflowId = undefined;
83
+ agent.status = 'idle';
84
+ agent.lastSeen = new Date().toISOString();
85
+ return true;
86
+ }
87
+ /**
88
+ * Get agent by ID
89
+ */
90
+ get(id) {
91
+ return this.agents.get(id);
92
+ }
93
+ /**
94
+ * List all connected agents
95
+ */
96
+ list() {
97
+ return Array.from(this.agents.values());
98
+ }
99
+ /**
100
+ * List agents by status
101
+ */
102
+ listByStatus(status) {
103
+ return this.list().filter((agent) => agent.status === status);
104
+ }
105
+ /**
106
+ * List agents by type
107
+ */
108
+ listByType(type) {
109
+ return this.list().filter((agent) => agent.type === type);
110
+ }
111
+ /**
112
+ * List available agents (connected and idle)
113
+ */
114
+ listAvailable() {
115
+ return this.list().filter((agent) => agent.status === 'connected' || agent.status === 'idle');
116
+ }
117
+ /**
118
+ * Check for stale agents and mark them as disconnected
119
+ */
120
+ checkHeartbeats() {
121
+ const now = Date.now();
122
+ const staleIds = [];
123
+ for (const agent of this.agents.values()) {
124
+ const lastSeen = new Date(agent.lastSeen).getTime();
125
+ if (now - lastSeen > this.heartbeatTimeout && agent.status !== 'disconnected') {
126
+ agent.status = 'disconnected';
127
+ staleIds.push(agent.id);
128
+ }
129
+ }
130
+ return staleIds;
131
+ }
132
+ /**
133
+ * Remove disconnected agents
134
+ */
135
+ pruneDisconnected() {
136
+ let removed = 0;
137
+ for (const [id, agent] of this.agents) {
138
+ if (agent.status === 'disconnected') {
139
+ this.agents.delete(id);
140
+ removed++;
141
+ }
142
+ }
143
+ return removed;
144
+ }
145
+ /**
146
+ * Get count of agents by status
147
+ */
148
+ getStats() {
149
+ const stats = {
150
+ connected: 0,
151
+ idle: 0,
152
+ busy: 0,
153
+ disconnected: 0,
154
+ };
155
+ for (const agent of this.agents.values()) {
156
+ stats[agent.status]++;
157
+ }
158
+ return stats;
159
+ }
160
+ /**
161
+ * Clear all agents (for testing)
162
+ */
163
+ clear() {
164
+ this.agents.clear();
165
+ }
166
+ /**
167
+ * Get total agent count
168
+ */
169
+ size() {
170
+ return this.agents.size;
171
+ }
172
+ }
173
+ //# sourceMappingURL=agent-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-registry.js","sourceRoot":"","sources":["../../src/services/agent-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Epic Completion Monitor Service
3
+ *
4
+ * Polls for epic issues with `waiting-for:children-complete` label and checks
5
+ * whether all child issues have completed. When all children are done, it
6
+ * removes the waiting label and adds `completed:children-complete`, which
7
+ * triggers the LabelMonitorService to enqueue an `epic-complete` command.
8
+ *
9
+ * Status comments are updated on each poll cycle using the `<!-- epic-status -->`
10
+ * HTML marker pattern.
11
+ */
12
+ import type { GitHubClientFactory } from '@generacy-ai/workflow-engine';
13
+ import type { RepositoryConfig } from '../config/schema.js';
14
+ interface Logger {
15
+ info(msg: string): void;
16
+ info(obj: Record<string, unknown>, msg: string): void;
17
+ warn(msg: string): void;
18
+ warn(obj: Record<string, unknown>, msg: string): void;
19
+ error(msg: string): void;
20
+ error(obj: Record<string, unknown>, msg: string): void;
21
+ }
22
+ export interface EpicMonitorConfig {
23
+ enabled: boolean;
24
+ pollIntervalMs: number;
25
+ }
26
+ /**
27
+ * Monitors epic issues for child completion. Runs as a standalone polling loop
28
+ * alongside the LabelMonitorService.
29
+ */
30
+ export declare class EpicCompletionMonitorService {
31
+ private readonly logger;
32
+ private readonly createClient;
33
+ private readonly config;
34
+ private readonly repositories;
35
+ private abortController;
36
+ constructor(logger: Logger, createClient: GitHubClientFactory, config: EpicMonitorConfig, repositories: RepositoryConfig[]);
37
+ startPolling(): Promise<void>;
38
+ stopPolling(): void;
39
+ /**
40
+ * Run a single poll cycle across all watched repositories.
41
+ */
42
+ poll(): Promise<void>;
43
+ /**
44
+ * Poll a single repository for epics waiting on children.
45
+ */
46
+ private pollRepo;
47
+ /**
48
+ * Check a single epic's child completion status, update the progress
49
+ * comment, and transition labels if all children are complete.
50
+ */
51
+ private checkEpic;
52
+ /**
53
+ * Find child issues that reference the given epic via `epic-parent: #N` in
54
+ * their body. Delegates to the shared `findChildIssues` utility from
55
+ * `@generacy-ai/workflow-engine`.
56
+ */
57
+ private findChildIssues;
58
+ /**
59
+ * Create or update the `<!-- epic-status -->` progress comment on the epic.
60
+ */
61
+ private updateStatusComment;
62
+ /**
63
+ * Generate the markdown body for the epic status comment.
64
+ */
65
+ private generateStatusComment;
66
+ private sleep;
67
+ }
68
+ export {};
69
+ //# sourceMappingURL=epic-completion-monitor-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"epic-completion-monitor-service.d.ts","sourceRoot":"","sources":["../../src/services/epic-completion-monitor-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,mBAAmB,EAAgB,MAAM,8BAA8B,CAAC;AAGtF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAM5D,UAAU,MAAM;IACd,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACtD,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACtD,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACxD;AAMD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;CACxB;AAgBD;;;GAGG;AACH,qBAAa,4BAA4B;IACvC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAsB;IACnD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAClD,OAAO,CAAC,eAAe,CAAgC;gBAGrD,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,mBAAmB,EACjC,MAAM,EAAE,iBAAiB,EACzB,YAAY,EAAE,gBAAgB,EAAE;IAY5B,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IA6BnC,WAAW,IAAI,IAAI;IAYnB;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAa3B;;OAEG;YACW,QAAQ;IA4BtB;;;OAGG;YACW,SAAS;IA8DvB;;;;OAIG;YACW,eAAe;IAe7B;;OAEG;YACW,mBAAmB;IAyBjC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAuC7B,OAAO,CAAC,KAAK;CAgBd"}