@cat-factory/server 0.6.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 (338) hide show
  1. package/LICENSE +21 -0
  2. package/dist/agents/CompositeAgentExecutor.d.ts +39 -0
  3. package/dist/agents/CompositeAgentExecutor.d.ts.map +1 -0
  4. package/dist/agents/CompositeAgentExecutor.js +169 -0
  5. package/dist/agents/CompositeAgentExecutor.js.map +1 -0
  6. package/dist/agents/ContainerAgentExecutor.d.ts +235 -0
  7. package/dist/agents/ContainerAgentExecutor.d.ts.map +1 -0
  8. package/dist/agents/ContainerAgentExecutor.js +825 -0
  9. package/dist/agents/ContainerAgentExecutor.js.map +1 -0
  10. package/dist/agents/ContainerRepoBootstrapper.d.ts +78 -0
  11. package/dist/agents/ContainerRepoBootstrapper.d.ts.map +1 -0
  12. package/dist/agents/ContainerRepoBootstrapper.js +279 -0
  13. package/dist/agents/ContainerRepoBootstrapper.js.map +1 -0
  14. package/dist/agents/ModelRouter.d.ts +69 -0
  15. package/dist/agents/ModelRouter.d.ts.map +1 -0
  16. package/dist/agents/ModelRouter.js +84 -0
  17. package/dist/agents/ModelRouter.js.map +1 -0
  18. package/dist/agents/RunnerJobClient.d.ts +41 -0
  19. package/dist/agents/RunnerJobClient.d.ts.map +1 -0
  20. package/dist/agents/RunnerJobClient.js +43 -0
  21. package/dist/agents/RunnerJobClient.js.map +1 -0
  22. package/dist/agents/modelProviderResolver.d.ts +33 -0
  23. package/dist/agents/modelProviderResolver.d.ts.map +1 -0
  24. package/dist/agents/modelProviderResolver.js +48 -0
  25. package/dist/agents/modelProviderResolver.js.map +1 -0
  26. package/dist/agents/providerCapabilities.d.ts +22 -0
  27. package/dist/agents/providerCapabilities.d.ts.map +1 -0
  28. package/dist/agents/providerCapabilities.js +43 -0
  29. package/dist/agents/providerCapabilities.js.map +1 -0
  30. package/dist/agents/resolveRepoTarget.d.ts +33 -0
  31. package/dist/agents/resolveRepoTarget.d.ts.map +1 -0
  32. package/dist/agents/resolveRepoTarget.js +81 -0
  33. package/dist/agents/resolveRepoTarget.js.map +1 -0
  34. package/dist/app.d.ts +12 -0
  35. package/dist/app.d.ts.map +1 -0
  36. package/dist/app.js +102 -0
  37. package/dist/app.js.map +1 -0
  38. package/dist/auth/GitHubOAuth.d.ts +39 -0
  39. package/dist/auth/GitHubOAuth.d.ts.map +1 -0
  40. package/dist/auth/GitHubOAuth.js +90 -0
  41. package/dist/auth/GitHubOAuth.js.map +1 -0
  42. package/dist/auth/GoogleOAuth.d.ts +35 -0
  43. package/dist/auth/GoogleOAuth.d.ts.map +1 -0
  44. package/dist/auth/GoogleOAuth.js +66 -0
  45. package/dist/auth/GoogleOAuth.js.map +1 -0
  46. package/dist/auth/middleware.d.ts +15 -0
  47. package/dist/auth/middleware.d.ts.map +1 -0
  48. package/dist/auth/middleware.js +63 -0
  49. package/dist/auth/middleware.js.map +1 -0
  50. package/dist/auth/signing.d.ts +50 -0
  51. package/dist/auth/signing.d.ts.map +1 -0
  52. package/dist/auth/signing.js +96 -0
  53. package/dist/auth/signing.js.map +1 -0
  54. package/dist/auth/wsTicket.d.ts +34 -0
  55. package/dist/auth/wsTicket.d.ts.map +1 -0
  56. package/dist/auth/wsTicket.js +50 -0
  57. package/dist/auth/wsTicket.js.map +1 -0
  58. package/dist/config/types.d.ts +294 -0
  59. package/dist/config/types.d.ts.map +1 -0
  60. package/dist/config/types.js +2 -0
  61. package/dist/config/types.js.map +1 -0
  62. package/dist/config/url-safety.d.ts +8 -0
  63. package/dist/config/url-safety.d.ts.map +1 -0
  64. package/dist/config/url-safety.js +11 -0
  65. package/dist/config/url-safety.js.map +1 -0
  66. package/dist/containers/ContainerSessionService.d.ts +67 -0
  67. package/dist/containers/ContainerSessionService.d.ts.map +1 -0
  68. package/dist/containers/ContainerSessionService.js +44 -0
  69. package/dist/containers/ContainerSessionService.js.map +1 -0
  70. package/dist/crypto/WebCryptoPasswordHasher.d.ts +9 -0
  71. package/dist/crypto/WebCryptoPasswordHasher.d.ts.map +1 -0
  72. package/dist/crypto/WebCryptoPasswordHasher.js +67 -0
  73. package/dist/crypto/WebCryptoPasswordHasher.js.map +1 -0
  74. package/dist/crypto/WebCryptoPersonalSecretCipher.d.ts +6 -0
  75. package/dist/crypto/WebCryptoPersonalSecretCipher.d.ts.map +1 -0
  76. package/dist/crypto/WebCryptoPersonalSecretCipher.js +57 -0
  77. package/dist/crypto/WebCryptoPersonalSecretCipher.js.map +1 -0
  78. package/dist/crypto/WebCryptoSecretCipher.d.ts +23 -0
  79. package/dist/crypto/WebCryptoSecretCipher.d.ts.map +1 -0
  80. package/dist/crypto/WebCryptoSecretCipher.js +60 -0
  81. package/dist/crypto/WebCryptoSecretCipher.js.map +1 -0
  82. package/dist/crypto/encoding.d.ts +14 -0
  83. package/dist/crypto/encoding.d.ts.map +1 -0
  84. package/dist/crypto/encoding.js +58 -0
  85. package/dist/crypto/encoding.js.map +1 -0
  86. package/dist/events/FanOutEventPublisher.d.ts +32 -0
  87. package/dist/events/FanOutEventPublisher.d.ts.map +1 -0
  88. package/dist/events/FanOutEventPublisher.js +76 -0
  89. package/dist/events/FanOutEventPublisher.js.map +1 -0
  90. package/dist/events/InAppNotificationChannel.d.ts +20 -0
  91. package/dist/events/InAppNotificationChannel.d.ts.map +1 -0
  92. package/dist/events/InAppNotificationChannel.js +23 -0
  93. package/dist/events/InAppNotificationChannel.js.map +1 -0
  94. package/dist/github/FetchGitHubClient.d.ts +72 -0
  95. package/dist/github/FetchGitHubClient.d.ts.map +1 -0
  96. package/dist/github/FetchGitHubClient.js +485 -0
  97. package/dist/github/FetchGitHubClient.js.map +1 -0
  98. package/dist/github/FetchGitHubProvisioningClient.d.ts +13 -0
  99. package/dist/github/FetchGitHubProvisioningClient.d.ts.map +1 -0
  100. package/dist/github/FetchGitHubProvisioningClient.js +59 -0
  101. package/dist/github/FetchGitHubProvisioningClient.js.map +1 -0
  102. package/dist/github/GitHubAppAuth.d.ts +30 -0
  103. package/dist/github/GitHubAppAuth.d.ts.map +1 -0
  104. package/dist/github/GitHubAppAuth.js +95 -0
  105. package/dist/github/GitHubAppAuth.js.map +1 -0
  106. package/dist/github/GitHubAppRegistry.d.ts +57 -0
  107. package/dist/github/GitHubAppRegistry.d.ts.map +1 -0
  108. package/dist/github/GitHubAppRegistry.js +51 -0
  109. package/dist/github/GitHubAppRegistry.js.map +1 -0
  110. package/dist/github/GitHubCiStatusProvider.d.ts +21 -0
  111. package/dist/github/GitHubCiStatusProvider.d.ts.map +1 -0
  112. package/dist/github/GitHubCiStatusProvider.js +39 -0
  113. package/dist/github/GitHubCiStatusProvider.js.map +1 -0
  114. package/dist/github/GitHubMergeabilityProvider.d.ts +26 -0
  115. package/dist/github/GitHubMergeabilityProvider.d.ts.map +1 -0
  116. package/dist/github/GitHubMergeabilityProvider.js +38 -0
  117. package/dist/github/GitHubMergeabilityProvider.js.map +1 -0
  118. package/dist/github/GitHubPullRequestMerger.d.ts +23 -0
  119. package/dist/github/GitHubPullRequestMerger.d.ts.map +1 -0
  120. package/dist/github/GitHubPullRequestMerger.js +38 -0
  121. package/dist/github/GitHubPullRequestMerger.js.map +1 -0
  122. package/dist/github/WebCryptoWebhookVerifier.d.ts +9 -0
  123. package/dist/github/WebCryptoWebhookVerifier.d.ts.map +1 -0
  124. package/dist/github/WebCryptoWebhookVerifier.js +40 -0
  125. package/dist/github/WebCryptoWebhookVerifier.js.map +1 -0
  126. package/dist/github/ensureWorkBranch.d.ts +26 -0
  127. package/dist/github/ensureWorkBranch.d.ts.map +1 -0
  128. package/dist/github/ensureWorkBranch.js +97 -0
  129. package/dist/github/ensureWorkBranch.js.map +1 -0
  130. package/dist/github/state.d.ts +19 -0
  131. package/dist/github/state.d.ts.map +1 -0
  132. package/dist/github/state.js +55 -0
  133. package/dist/github/state.js.map +1 -0
  134. package/dist/http/authGate.d.ts +21 -0
  135. package/dist/http/authGate.d.ts.map +1 -0
  136. package/dist/http/authGate.js +77 -0
  137. package/dist/http/authGate.js.map +1 -0
  138. package/dist/http/cors.d.ts +13 -0
  139. package/dist/http/cors.d.ts.map +1 -0
  140. package/dist/http/cors.js +30 -0
  141. package/dist/http/cors.js.map +1 -0
  142. package/dist/http/env.d.ts +68 -0
  143. package/dist/http/env.d.ts.map +1 -0
  144. package/dist/http/env.js +2 -0
  145. package/dist/http/env.js.map +1 -0
  146. package/dist/http/errorHandler.d.ts +4 -0
  147. package/dist/http/errorHandler.d.ts.map +1 -0
  148. package/dist/http/errorHandler.js +33 -0
  149. package/dist/http/errorHandler.js.map +1 -0
  150. package/dist/http/params.d.ts +8 -0
  151. package/dist/http/params.d.ts.map +1 -0
  152. package/dist/http/params.js +13 -0
  153. package/dist/http/params.js.map +1 -0
  154. package/dist/http/validation.d.ts +12 -0
  155. package/dist/http/validation.d.ts.map +1 -0
  156. package/dist/http/validation.js +21 -0
  157. package/dist/http/validation.js.map +1 -0
  158. package/dist/index.d.ts +46 -0
  159. package/dist/index.d.ts.map +1 -0
  160. package/dist/index.js +63 -0
  161. package/dist/index.js.map +1 -0
  162. package/dist/modules/accounts/AccountController.d.ts +10 -0
  163. package/dist/modules/accounts/AccountController.d.ts.map +1 -0
  164. package/dist/modules/accounts/AccountController.js +197 -0
  165. package/dist/modules/accounts/AccountController.js.map +1 -0
  166. package/dist/modules/agentRuns/AgentRunController.d.ts +10 -0
  167. package/dist/modules/agentRuns/AgentRunController.d.ts.map +1 -0
  168. package/dist/modules/agentRuns/AgentRunController.js +65 -0
  169. package/dist/modules/agentRuns/AgentRunController.js.map +1 -0
  170. package/dist/modules/auth/AuthController.d.ts +12 -0
  171. package/dist/modules/auth/AuthController.d.ts.map +1 -0
  172. package/dist/modules/auth/AuthController.js +457 -0
  173. package/dist/modules/auth/AuthController.js.map +1 -0
  174. package/dist/modules/board/BoardController.d.ts +8 -0
  175. package/dist/modules/board/BoardController.d.ts.map +1 -0
  176. package/dist/modules/board/BoardController.js +89 -0
  177. package/dist/modules/board/BoardController.js.map +1 -0
  178. package/dist/modules/boardScan/BoardScanController.d.ts +10 -0
  179. package/dist/modules/boardScan/BoardScanController.d.ts.map +1 -0
  180. package/dist/modules/boardScan/BoardScanController.js +53 -0
  181. package/dist/modules/boardScan/BoardScanController.js.map +1 -0
  182. package/dist/modules/bootstrap/BootstrapController.d.ts +10 -0
  183. package/dist/modules/bootstrap/BootstrapController.d.ts.map +1 -0
  184. package/dist/modules/bootstrap/BootstrapController.js +75 -0
  185. package/dist/modules/bootstrap/BootstrapController.js.map +1 -0
  186. package/dist/modules/clarity/ClarityReviewController.d.ts +11 -0
  187. package/dist/modules/clarity/ClarityReviewController.d.ts.map +1 -0
  188. package/dist/modules/clarity/ClarityReviewController.js +97 -0
  189. package/dist/modules/clarity/ClarityReviewController.js.map +1 -0
  190. package/dist/modules/consensus/ConsensusController.d.ts +12 -0
  191. package/dist/modules/consensus/ConsensusController.d.ts.map +1 -0
  192. package/dist/modules/consensus/ConsensusController.js +23 -0
  193. package/dist/modules/consensus/ConsensusController.js.map +1 -0
  194. package/dist/modules/documents/DocumentSourceController.d.ts +10 -0
  195. package/dist/modules/documents/DocumentSourceController.d.ts.map +1 -0
  196. package/dist/modules/documents/DocumentSourceController.js +116 -0
  197. package/dist/modules/documents/DocumentSourceController.js.map +1 -0
  198. package/dist/modules/environments/EnvironmentController.d.ts +10 -0
  199. package/dist/modules/environments/EnvironmentController.d.ts.map +1 -0
  200. package/dist/modules/environments/EnvironmentController.js +95 -0
  201. package/dist/modules/environments/EnvironmentController.js.map +1 -0
  202. package/dist/modules/events/EventsController.d.ts +26 -0
  203. package/dist/modules/events/EventsController.d.ts.map +1 -0
  204. package/dist/modules/events/EventsController.js +56 -0
  205. package/dist/modules/events/EventsController.js.map +1 -0
  206. package/dist/modules/execution/ExecutionController.d.ts +10 -0
  207. package/dist/modules/execution/ExecutionController.d.ts.map +1 -0
  208. package/dist/modules/execution/ExecutionController.js +156 -0
  209. package/dist/modules/execution/ExecutionController.js.map +1 -0
  210. package/dist/modules/fragmentLibrary/FragmentLibraryController.d.ts +14 -0
  211. package/dist/modules/fragmentLibrary/FragmentLibraryController.d.ts.map +1 -0
  212. package/dist/modules/fragmentLibrary/FragmentLibraryController.js +128 -0
  213. package/dist/modules/fragmentLibrary/FragmentLibraryController.js.map +1 -0
  214. package/dist/modules/github/GitHubController.d.ts +12 -0
  215. package/dist/modules/github/GitHubController.d.ts.map +1 -0
  216. package/dist/modules/github/GitHubController.js +234 -0
  217. package/dist/modules/github/GitHubController.js.map +1 -0
  218. package/dist/modules/github/GitHubWebhookController.d.ts +13 -0
  219. package/dist/modules/github/GitHubWebhookController.d.ts.map +1 -0
  220. package/dist/modules/github/GitHubWebhookController.js +74 -0
  221. package/dist/modules/github/GitHubWebhookController.js.map +1 -0
  222. package/dist/modules/llmProxy/LlmProxyController.d.ts +18 -0
  223. package/dist/modules/llmProxy/LlmProxyController.d.ts.map +1 -0
  224. package/dist/modules/llmProxy/LlmProxyController.js +567 -0
  225. package/dist/modules/llmProxy/LlmProxyController.js.map +1 -0
  226. package/dist/modules/localModels/LocalModelEndpointController.d.ts +4 -0
  227. package/dist/modules/localModels/LocalModelEndpointController.d.ts.map +1 -0
  228. package/dist/modules/localModels/LocalModelEndpointController.js +58 -0
  229. package/dist/modules/localModels/LocalModelEndpointController.js.map +1 -0
  230. package/dist/modules/merge/MergePresetController.d.ts +9 -0
  231. package/dist/modules/merge/MergePresetController.d.ts.map +1 -0
  232. package/dist/modules/merge/MergePresetController.js +46 -0
  233. package/dist/modules/merge/MergePresetController.js.map +1 -0
  234. package/dist/modules/modelDefaults/ModelDefaultsController.d.ts +9 -0
  235. package/dist/modules/modelDefaults/ModelDefaultsController.d.ts.map +1 -0
  236. package/dist/modules/modelDefaults/ModelDefaultsController.js +32 -0
  237. package/dist/modules/modelDefaults/ModelDefaultsController.js.map +1 -0
  238. package/dist/modules/models/ModelController.d.ts +11 -0
  239. package/dist/modules/models/ModelController.d.ts.map +1 -0
  240. package/dist/modules/models/ModelController.js +38 -0
  241. package/dist/modules/models/ModelController.js.map +1 -0
  242. package/dist/modules/notifications/NotificationController.d.ts +13 -0
  243. package/dist/modules/notifications/NotificationController.d.ts.map +1 -0
  244. package/dist/modules/notifications/NotificationController.js +67 -0
  245. package/dist/modules/notifications/NotificationController.js.map +1 -0
  246. package/dist/modules/pipelines/PipelineController.d.ts +5 -0
  247. package/dist/modules/pipelines/PipelineController.d.ts.map +1 -0
  248. package/dist/modules/pipelines/PipelineController.js +46 -0
  249. package/dist/modules/pipelines/PipelineController.js.map +1 -0
  250. package/dist/modules/promptFragments/PromptFragmentController.d.ts +11 -0
  251. package/dist/modules/promptFragments/PromptFragmentController.d.ts.map +1 -0
  252. package/dist/modules/promptFragments/PromptFragmentController.js +18 -0
  253. package/dist/modules/promptFragments/PromptFragmentController.js.map +1 -0
  254. package/dist/modules/providers/ApiKeyController.d.ts +13 -0
  255. package/dist/modules/providers/ApiKeyController.d.ts.map +1 -0
  256. package/dist/modules/providers/ApiKeyController.js +98 -0
  257. package/dist/modules/providers/ApiKeyController.js.map +1 -0
  258. package/dist/modules/providers/PersonalSubscriptionController.d.ts +4 -0
  259. package/dist/modules/providers/PersonalSubscriptionController.d.ts.map +1 -0
  260. package/dist/modules/providers/PersonalSubscriptionController.js +48 -0
  261. package/dist/modules/providers/PersonalSubscriptionController.js.map +1 -0
  262. package/dist/modules/providers/VendorCredentialController.d.ts +4 -0
  263. package/dist/modules/providers/VendorCredentialController.d.ts.map +1 -0
  264. package/dist/modules/providers/VendorCredentialController.js +55 -0
  265. package/dist/modules/providers/VendorCredentialController.js.map +1 -0
  266. package/dist/modules/providers/personalCredentialGate.d.ts +34 -0
  267. package/dist/modules/providers/personalCredentialGate.d.ts.map +1 -0
  268. package/dist/modules/providers/personalCredentialGate.js +106 -0
  269. package/dist/modules/providers/personalCredentialGate.js.map +1 -0
  270. package/dist/modules/recurring/RecurringPipelineController.d.ts +8 -0
  271. package/dist/modules/recurring/RecurringPipelineController.d.ts.map +1 -0
  272. package/dist/modules/recurring/RecurringPipelineController.js +58 -0
  273. package/dist/modules/recurring/RecurringPipelineController.js.map +1 -0
  274. package/dist/modules/recurring/TrackerSettingsController.d.ts +8 -0
  275. package/dist/modules/recurring/TrackerSettingsController.d.ts.map +1 -0
  276. package/dist/modules/recurring/TrackerSettingsController.js +30 -0
  277. package/dist/modules/recurring/TrackerSettingsController.js.map +1 -0
  278. package/dist/modules/releaseHealth/ReleaseHealthController.d.ts +9 -0
  279. package/dist/modules/releaseHealth/ReleaseHealthController.d.ts.map +1 -0
  280. package/dist/modules/releaseHealth/ReleaseHealthController.js +58 -0
  281. package/dist/modules/releaseHealth/ReleaseHealthController.js.map +1 -0
  282. package/dist/modules/requirements/RequirementReviewController.d.ts +12 -0
  283. package/dist/modules/requirements/RequirementReviewController.d.ts.map +1 -0
  284. package/dist/modules/requirements/RequirementReviewController.js +107 -0
  285. package/dist/modules/requirements/RequirementReviewController.js.map +1 -0
  286. package/dist/modules/runners/RunnerPoolController.d.ts +10 -0
  287. package/dist/modules/runners/RunnerPoolController.d.ts.map +1 -0
  288. package/dist/modules/runners/RunnerPoolController.js +52 -0
  289. package/dist/modules/runners/RunnerPoolController.js.map +1 -0
  290. package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsController.d.ts +9 -0
  291. package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsController.d.ts.map +1 -0
  292. package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsController.js +32 -0
  293. package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsController.js.map +1 -0
  294. package/dist/modules/services/ServiceMountController.d.ts +11 -0
  295. package/dist/modules/services/ServiceMountController.d.ts.map +1 -0
  296. package/dist/modules/services/ServiceMountController.js +64 -0
  297. package/dist/modules/services/ServiceMountController.js.map +1 -0
  298. package/dist/modules/settings/WorkspaceSettingsController.d.ts +9 -0
  299. package/dist/modules/settings/WorkspaceSettingsController.d.ts.map +1 -0
  300. package/dist/modules/settings/WorkspaceSettingsController.js +32 -0
  301. package/dist/modules/settings/WorkspaceSettingsController.js.map +1 -0
  302. package/dist/modules/slack/SlackController.d.ts +17 -0
  303. package/dist/modules/slack/SlackController.d.ts.map +1 -0
  304. package/dist/modules/slack/SlackController.js +135 -0
  305. package/dist/modules/slack/SlackController.js.map +1 -0
  306. package/dist/modules/tasks/TaskSourceController.d.ts +9 -0
  307. package/dist/modules/tasks/TaskSourceController.d.ts.map +1 -0
  308. package/dist/modules/tasks/TaskSourceController.js +103 -0
  309. package/dist/modules/tasks/TaskSourceController.js.map +1 -0
  310. package/dist/modules/webSearch/WebSearchProxyController.d.ts +4 -0
  311. package/dist/modules/webSearch/WebSearchProxyController.d.ts.map +1 -0
  312. package/dist/modules/webSearch/WebSearchProxyController.js +78 -0
  313. package/dist/modules/webSearch/WebSearchProxyController.js.map +1 -0
  314. package/dist/modules/webSearch/upstreams.d.ts +50 -0
  315. package/dist/modules/webSearch/upstreams.d.ts.map +1 -0
  316. package/dist/modules/webSearch/upstreams.js +107 -0
  317. package/dist/modules/webSearch/upstreams.js.map +1 -0
  318. package/dist/modules/workspaces/WorkspaceController.d.ts +5 -0
  319. package/dist/modules/workspaces/WorkspaceController.d.ts.map +1 -0
  320. package/dist/modules/workspaces/WorkspaceController.js +167 -0
  321. package/dist/modules/workspaces/WorkspaceController.js.map +1 -0
  322. package/dist/observability/logger.d.ts +9 -0
  323. package/dist/observability/logger.d.ts.map +1 -0
  324. package/dist/observability/logger.js +39 -0
  325. package/dist/observability/logger.js.map +1 -0
  326. package/dist/persistence/mappers.d.ts +101 -0
  327. package/dist/persistence/mappers.d.ts.map +1 -0
  328. package/dist/persistence/mappers.js +260 -0
  329. package/dist/persistence/mappers.js.map +1 -0
  330. package/dist/runtime/escalateNotifications.d.ts +12 -0
  331. package/dist/runtime/escalateNotifications.d.ts.map +1 -0
  332. package/dist/runtime/escalateNotifications.js +25 -0
  333. package/dist/runtime/escalateNotifications.js.map +1 -0
  334. package/dist/runtime/gateways.d.ts +159 -0
  335. package/dist/runtime/gateways.d.ts.map +1 -0
  336. package/dist/runtime/gateways.js +2 -0
  337. package/dist/runtime/gateways.js.map +1 -0
  338. package/package.json +44 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RunnerJobClient.d.ts","sourceRoot":"","sources":["../../src/agents/RunnerJobClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,kBAAkB,EAClB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,eAAe,EAChB,MAAM,qBAAqB,CAAA;AAE5B;;;;;;GAMG;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,KAAK,OAAO,CAAC,eAAe,CAAC,CAAA;AAElG;;;;;;;;;;;GAWG;AACH,qBAAa,eAAe;IACd,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IAA7C,YAA6B,gBAAgB,EAAE,sBAAsB,EAAI;IAEzE;;;;OAIG;IACG,QAAQ,CACZ,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,GAAG,EAAE,YAAY,EACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,IAAI,EAAE,kBAAkB,EACxB,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAGf;IAED,2EAA2E;IACrE,IAAI,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAGrF;IAED;;;;;OAKG;IACG,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAG/E;CACF"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * The shared dispatch → poll → release plumbing every container-backed flow rides
3
+ * (the implementation executor and the repo bootstrapper today; the scanner next).
4
+ * Each flow keeps its own "mint tokens + build the harness body" and "map the
5
+ * runner view into its result" — the parts that genuinely differ — and delegates
6
+ * the backend-polymorphic transport mechanics here so they are written once.
7
+ *
8
+ * It is a thin wrapper over {@link ResolveRunnerTransport}: it resolves the right
9
+ * backend (Cloudflare container vs. self-hosted pool) for the job's workspace on
10
+ * every call, then dispatches/polls/releases through it. Stateless, so a caller may
11
+ * construct one per flow and reuse it across jobs.
12
+ */
13
+ export class RunnerJobClient {
14
+ resolveTransport;
15
+ constructor(resolveTransport) {
16
+ this.resolveTransport = resolveTransport;
17
+ }
18
+ /**
19
+ * Start (or idempotently re-attach to) job `ref` for `workspaceId`. `kind`
20
+ * selects the harness endpoint; the Cloudflare backend serves every kind, a
21
+ * self-hosted pool only `run` (and throws a clear "unsupported" for the rest).
22
+ */
23
+ async dispatch(workspaceId, ref, spec, kind, options) {
24
+ const transport = await this.resolveTransport(workspaceId);
25
+ await transport.dispatch(ref, spec, kind, options);
26
+ }
27
+ /** Poll the job's current state from the same backend it dispatched to. */
28
+ async poll(workspaceId, ref) {
29
+ const transport = await this.resolveTransport(workspaceId);
30
+ return transport.poll(ref);
31
+ }
32
+ /**
33
+ * Reclaim a run's backing runner (for the Cloudflare backend, SIGKILL the per-run
34
+ * container instead of letting it idle out its sleep timer; for a pool, cancel the
35
+ * run's in-flight job `ref.jobId`). Best-effort and idempotent: a transport without
36
+ * `release`, or an already-gone run/job, is a no-op.
37
+ */
38
+ async release(workspaceId, ref) {
39
+ const transport = await this.resolveTransport(workspaceId);
40
+ await transport.release?.(ref);
41
+ }
42
+ }
43
+ //# sourceMappingURL=RunnerJobClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RunnerJobClient.js","sourceRoot":"","sources":["../../src/agents/RunnerJobClient.ts"],"names":[],"mappings":"AAiBA;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,eAAe;IACG,gBAAgB;IAA7C,YAA6B,gBAAwC;gCAAxC,gBAAgB;IAA2B,CAAC;IAEzE;;;;OAIG;IACH,KAAK,CAAC,QAAQ,CACZ,WAA+B,EAC/B,GAAiB,EACjB,IAA6B,EAC7B,IAAwB,EACxB,OAA+B;QAE/B,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAA;QAC1D,MAAM,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAA;IACpD,CAAC;IAED,2EAA2E;IAC3E,KAAK,CAAC,IAAI,CAAC,WAA+B,EAAE,GAAiB;QAC3D,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAA;QAC1D,OAAO,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,OAAO,CAAC,WAA+B,EAAE,GAAiB;QAC9D,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAA;QAC1D,MAAM,SAAS,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAA;IAChC,CAAC;CACF"}
@@ -0,0 +1,33 @@
1
+ import { type ProviderRegistry } from '@cat-factory/agents';
2
+ import type { ApiKeyService } from '@cat-factory/integrations';
3
+ import type { LlmTraceSink, ModelProviderResolver } from '@cat-factory/kernel';
4
+ export interface ScopedModelProviderOptions {
5
+ /**
6
+ * The direct-provider API-key pool (account/workspace/user scoped). Absent (no
7
+ * ENCRYPTION_KEY) → no direct providers are configured; only the opt-in registries
8
+ * (Cloudflare/Bedrock) can resolve, and a direct-provider ref fails clearly.
9
+ */
10
+ apiKeys?: ApiKeyService;
11
+ /** Base URL for a direct provider's API (the OpenAI-compatible vendors need one). */
12
+ baseUrlFor: (provider: string) => string | undefined;
13
+ /** Opt-in registries that need no DB key — the Cloudflare lib + Bedrock. */
14
+ extraRegistries?: ProviderRegistry[];
15
+ /**
16
+ * Resolve a user's locally-run model endpoints (Ollama / LM Studio / …) so inline LLM
17
+ * calls reach them like the proxied path. Keyless by design (the endpoint carries an
18
+ * optional key), so these register into the per-scope registry directly rather than via
19
+ * the DB API-key pool. Keyed by the scope's user (the run initiator).
20
+ */
21
+ localEndpointsFor?: (userId: string) => Promise<{
22
+ provider: string;
23
+ baseUrl: string;
24
+ apiKey: string | null;
25
+ }[]>;
26
+ /** Wrap the scoped provider so inline calls feed the trace sink (Langfuse). */
27
+ instrument?: {
28
+ traceSink: LlmTraceSink;
29
+ recordPrompts?: boolean;
30
+ };
31
+ }
32
+ export declare function createScopedModelProviderResolver(opts: ScopedModelProviderOptions): ModelProviderResolver;
33
+ //# sourceMappingURL=modelProviderResolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modelProviderResolver.d.ts","sourceRoot":"","sources":["../../src/agents/modelProviderResolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,gBAAgB,EAItB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,KAAK,EACV,YAAY,EAEZ,qBAAqB,EAEtB,MAAM,qBAAqB,CAAA;AAa5B,MAAM,WAAW,0BAA0B;IACzC;;;;OAIG;IACH,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,qFAAqF;IACrF,UAAU,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;IACpD,4EAA4E;IAC5E,eAAe,CAAC,EAAE,gBAAgB,EAAE,CAAA;IACpC;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,CAClB,MAAM,EAAE,MAAM,KACX,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,EAAE,CAAC,CAAA;IAC5E,+EAA+E;IAC/E,UAAU,CAAC,EAAE;QAAE,SAAS,EAAE,YAAY,CAAC;QAAC,aAAa,CAAC,EAAE,OAAO,CAAA;KAAE,CAAA;CAClE;AAED,wBAAgB,iCAAiC,CAC/C,IAAI,EAAE,0BAA0B,GAC/B,qBAAqB,CAqCvB"}
@@ -0,0 +1,48 @@
1
+ import { CompositeModelProvider, InstrumentedModelProvider, anthropicResolver, openAiCompatibleResolver, openAiResolver, } from '@cat-factory/agents';
2
+ export function createScopedModelProviderResolver(opts) {
3
+ return {
4
+ async forScope(scope) {
5
+ const poolOpts = { accountId: scope.accountId, userId: scope.userId };
6
+ const registry = {};
7
+ if (opts.apiKeys) {
8
+ const providers = await opts.apiKeys.configuredProviders(scope.workspaceId, poolOpts);
9
+ for (const provider of providers) {
10
+ const leased = await opts.apiKeys.lease(scope.workspaceId, provider, poolOpts);
11
+ registry[provider] = buildDirectResolver(provider, leased.secret, opts.baseUrlFor(provider));
12
+ }
13
+ }
14
+ // The initiating user's locally-run runners (keyless OpenAI-compatible endpoints).
15
+ if (scope.userId && opts.localEndpointsFor) {
16
+ for (const ep of await opts.localEndpointsFor(scope.userId)) {
17
+ registry[ep.provider] = openAiCompatibleResolver({
18
+ name: ep.provider,
19
+ apiKey: ep.apiKey || 'local',
20
+ baseURL: ep.baseUrl,
21
+ });
22
+ }
23
+ }
24
+ const composite = new CompositeModelProvider(registry, ...(opts.extraRegistries ?? []));
25
+ if (opts.instrument) {
26
+ return new InstrumentedModelProvider({
27
+ inner: composite,
28
+ traceSink: opts.instrument.traceSink,
29
+ recordPrompts: opts.instrument.recordPrompts,
30
+ });
31
+ }
32
+ return composite;
33
+ },
34
+ };
35
+ }
36
+ /** Build the AI-SDK resolver for one direct provider given a leased key + base URL. */
37
+ function buildDirectResolver(provider, apiKey, baseURL) {
38
+ if (provider === 'openai')
39
+ return openAiResolver({ apiKey, baseURL });
40
+ if (provider === 'anthropic')
41
+ return anthropicResolver({ apiKey, baseURL });
42
+ // qwen / deepseek / moonshot expose an OpenAI-compatible API and need a base URL.
43
+ if (!baseURL) {
44
+ throw new Error(`No base URL configured for OpenAI-compatible provider '${provider}'`);
45
+ }
46
+ return openAiCompatibleResolver({ name: provider, apiKey, baseURL });
47
+ }
48
+ //# sourceMappingURL=modelProviderResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modelProviderResolver.js","sourceRoot":"","sources":["../../src/agents/modelProviderResolver.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EAGzB,iBAAiB,EACjB,wBAAwB,EACxB,cAAc,GACf,MAAM,qBAAqB,CAAA;AA4C5B,MAAM,UAAU,iCAAiC,CAC/C,IAAgC;IAEhC,OAAO;QACL,KAAK,CAAC,QAAQ,CAAC,KAAiB;YAC9B,MAAM,QAAQ,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAA;YACrE,MAAM,QAAQ,GAAqB,EAAE,CAAA;YACrC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,mBAAmB,CAAC,KAAK,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAA;gBACrF,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;oBACjC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;oBAC9E,QAAQ,CAAC,QAAQ,CAAC,GAAG,mBAAmB,CACtC,QAAQ,EACR,MAAM,CAAC,MAAM,EACb,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAC1B,CAAA;gBACH,CAAC;YACH,CAAC;YACD,mFAAmF;YACnF,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;gBAC3C,KAAK,MAAM,EAAE,IAAI,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC5D,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,wBAAwB,CAAC;wBAC/C,IAAI,EAAE,EAAE,CAAC,QAAQ;wBACjB,MAAM,EAAE,EAAE,CAAC,MAAM,IAAI,OAAO;wBAC5B,OAAO,EAAE,EAAE,CAAC,OAAO;qBACpB,CAAC,CAAA;gBACJ,CAAC;YACH,CAAC;YACD,MAAM,SAAS,GAAG,IAAI,sBAAsB,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,CAAA;YACvF,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACpB,OAAO,IAAI,yBAAyB,CAAC;oBACnC,KAAK,EAAE,SAAS;oBAChB,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,SAAS;oBACpC,aAAa,EAAE,IAAI,CAAC,UAAU,CAAC,aAAa;iBAC7C,CAAC,CAAA;YACJ,CAAC;YACD,OAAO,SAAS,CAAA;QAClB,CAAC;KACF,CAAA;AACH,CAAC;AAED,uFAAuF;AACvF,SAAS,mBAAmB,CAC1B,QAAgB,EAChB,MAAc,EACd,OAA2B;IAE3B,IAAI,QAAQ,KAAK,QAAQ;QAAE,OAAO,cAAc,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;IACrE,IAAI,QAAQ,KAAK,WAAW;QAAE,OAAO,iBAAiB,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;IAC3E,kFAAkF;IAClF,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,0DAA0D,QAAQ,GAAG,CAAC,CAAA;IACxF,CAAC;IACD,OAAO,wBAAwB,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAA;AACtE,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { ApiKeyService, LocalModelEndpointService, PersonalSubscriptionService, ProviderSubscriptionService } from '@cat-factory/integrations';
2
+ import { type ProviderCapabilities } from '@cat-factory/kernel';
3
+ export interface CapabilityServices {
4
+ apiKeys?: ApiKeyService;
5
+ subscriptions?: ProviderSubscriptionService;
6
+ personalSubscriptions?: PersonalSubscriptionService;
7
+ /** Whether the opt-in Cloudflare Workers AI lib is registered for this deployment. */
8
+ cloudflareModelsEnabled?: boolean;
9
+ /**
10
+ * The deployment's base-URL resolver (the same one the model-provider resolver uses).
11
+ * OpenAI-compatible providers (everything but `openai`/`anthropic`) cannot resolve
12
+ * without a base URL — most carry a built-in default, but an operator-hosted gateway
13
+ * like LiteLLM has none until `LITELLM_BASE_URL` is set. When this resolver is wired, a
14
+ * configured key for such a provider is treated as selectable ONLY once its base URL
15
+ * resolves, so the catalog + start guard don't offer a model that fails at dispatch.
16
+ */
17
+ baseUrlFor?: (provider: string) => string | null | undefined;
18
+ /** Per-user locally-run model endpoints (resolved by the requesting/initiating user). */
19
+ localModelEndpoints?: LocalModelEndpointService;
20
+ }
21
+ export declare function resolveWorkspaceCapabilities(services: CapabilityServices, workspaceId: string, userId?: string | null): Promise<ProviderCapabilities>;
22
+ //# sourceMappingURL=providerCapabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providerCapabilities.d.ts","sourceRoot":"","sources":["../../src/agents/providerCapabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,yBAAyB,EACzB,2BAA2B,EAC3B,2BAA2B,EAC5B,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAEL,KAAK,oBAAoB,EAE1B,MAAM,qBAAqB,CAAA;AAM5B,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,aAAa,CAAC,EAAE,2BAA2B,CAAA;IAC3C,qBAAqB,CAAC,EAAE,2BAA2B,CAAA;IACnD,sFAAsF;IACtF,uBAAuB,CAAC,EAAE,OAAO,CAAA;IACjC;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;IAC5D,yFAAyF;IACzF,mBAAmB,CAAC,EAAE,yBAAyB,CAAA;CAChD;AAOD,wBAAsB,4BAA4B,CAChD,QAAQ,EAAE,kBAAkB,EAC5B,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAAC,oBAAoB,CAAC,CAoC/B"}
@@ -0,0 +1,43 @@
1
+ import { ALL_SUBSCRIPTION_VENDORS, } from '@cat-factory/kernel';
2
+ // Direct providers whose AI-SDK resolver works without an explicit base URL (the SDK
3
+ // has a built-in default). Every OTHER direct provider is OpenAI-compatible and needs a
4
+ // base URL (see `buildDirectResolver`), so it is unusable until that URL resolves.
5
+ const BASE_URL_OPTIONAL = new Set(['openai', 'anthropic']);
6
+ export async function resolveWorkspaceCapabilities(services, workspaceId, userId) {
7
+ const configured = services.apiKeys
8
+ ? await services.apiKeys.configuredProviders(workspaceId, { userId })
9
+ : [];
10
+ const baseUrlFor = services.baseUrlFor;
11
+ const directProviders = new Set(
12
+ // Drop a key whose provider needs a base URL the deployment hasn't configured: it
13
+ // would pass the catalog/start guard but throw "No base URL configured" at dispatch.
14
+ baseUrlFor ? configured.filter((p) => BASE_URL_OPTIONAL.has(p) || !!baseUrlFor(p)) : configured);
15
+ const subscriptionVendors = new Set();
16
+ for (const vendor of ALL_SUBSCRIPTION_VENDORS) {
17
+ const pooled = services.subscriptions
18
+ ? await services.subscriptions.hasToken(workspaceId, vendor)
19
+ : false;
20
+ const personal = !pooled && userId && services.personalSubscriptions
21
+ ? await services.personalSubscriptions.has(userId, vendor)
22
+ : false;
23
+ if (pooled || personal)
24
+ subscriptionVendors.add(vendor);
25
+ }
26
+ // Local runners are per-user: a model is usable when the resolving user has enabled it.
27
+ // Keyed by the dynamic model id (`"<provider>:<model>"`) so usability is model-granular
28
+ // (a runner configured but with this model un-enabled must not pass).
29
+ const localModels = new Set();
30
+ if (userId && services.localModelEndpoints) {
31
+ for (const cap of await services.localModelEndpoints.capabilitiesFor(userId)) {
32
+ for (const model of cap.models)
33
+ localModels.add(`${cap.provider}:${model}`);
34
+ }
35
+ }
36
+ return {
37
+ directProviders,
38
+ subscriptionVendors,
39
+ cloudflareEnabled: services.cloudflareModelsEnabled ?? false,
40
+ localModels,
41
+ };
42
+ }
43
+ //# sourceMappingURL=providerCapabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providerCapabilities.js","sourceRoot":"","sources":["../../src/agents/providerCapabilities.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,wBAAwB,GAGzB,MAAM,qBAAqB,CAAA;AAyB5B,qFAAqF;AACrF,wFAAwF;AACxF,mFAAmF;AACnF,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAA;AAE1D,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,QAA4B,EAC5B,WAAmB,EACnB,MAAsB;IAEtB,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO;QACjC,CAAC,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,mBAAmB,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,CAAC;QACrE,CAAC,CAAC,EAAE,CAAA;IACN,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAA;IACtC,MAAM,eAAe,GAAG,IAAI,GAAG;IAC7B,kFAAkF;IAClF,qFAAqF;IACrF,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAChG,CAAA;IACD,MAAM,mBAAmB,GAAG,IAAI,GAAG,EAAsB,CAAA;IACzD,KAAK,MAAM,MAAM,IAAI,wBAAwB,EAAE,CAAC;QAC9C,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa;YACnC,CAAC,CAAC,MAAM,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;YAC5D,CAAC,CAAC,KAAK,CAAA;QACT,MAAM,QAAQ,GACZ,CAAC,MAAM,IAAI,MAAM,IAAI,QAAQ,CAAC,qBAAqB;YACjD,CAAC,CAAC,MAAM,QAAQ,CAAC,qBAAqB,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC;YAC1D,CAAC,CAAC,KAAK,CAAA;QACX,IAAI,MAAM,IAAI,QAAQ;YAAE,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IACzD,CAAC;IACD,wFAAwF;IACxF,wFAAwF;IACxF,sEAAsE;IACtE,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAA;IACrC,IAAI,MAAM,IAAI,QAAQ,CAAC,mBAAmB,EAAE,CAAC;QAC3C,KAAK,MAAM,GAAG,IAAI,MAAM,QAAQ,CAAC,mBAAmB,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7E,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,MAAM;gBAAE,WAAW,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,QAAQ,IAAI,KAAK,EAAE,CAAC,CAAA;QAC7E,CAAC;IACH,CAAC;IACD,OAAO;QACL,eAAe;QACf,mBAAmB;QACnB,iBAAiB,EAAE,QAAQ,CAAC,uBAAuB,IAAI,KAAK;QAC5D,WAAW;KACZ,CAAA;AACH,CAAC"}
@@ -0,0 +1,33 @@
1
+ import type { BlockRepository, GitHubInstallationRepository, RepoProjectionRepository, ServiceRepository } from '@cat-factory/kernel';
2
+ import type { ResolveRepoTarget } from './ContainerAgentExecutor.js';
3
+ export interface ResolveRepoTargetDependencies {
4
+ installationRepository: Pick<GitHubInstallationRepository, 'getByWorkspace'>;
5
+ repoProjectionRepository: Pick<RepoProjectionRepository, 'list'>;
6
+ blockRepository: Pick<BlockRepository, 'get'>;
7
+ /**
8
+ * Resolves the {@link Service} owning a frame block, used to find which repo a
9
+ * frame targets AND (for a monorepo) the subdirectory the service pins. Optional:
10
+ * a facade/test without in-org services wired falls back to the repo-projection
11
+ * `block_id` link (one whole-repo service per repo, no subdirectory).
12
+ */
13
+ serviceRepository?: Pick<ServiceRepository, 'getByFrameBlock'>;
14
+ }
15
+ /**
16
+ * Resolve the repo linked to a running block's enclosing service, shared verbatim by
17
+ * both runtime facades (Worker D1 + Node Drizzle/Postgres). Repos are linked at the
18
+ * service-frame level (see `linkBlock`), but execution runs at the task/module level,
19
+ * so we walk up the block's ancestry to find the frame's repo.
20
+ *
21
+ * There is deliberately NO "first repo" fallback: a workspace can have many repos, and
22
+ * guessing silently pushes work into the wrong one (this is how a simple-service task
23
+ * ended up force-pushing to butter-spread). If nothing in the chain is linked we throw
24
+ * so the misconfiguration surfaces instead of corrupting another repo. Returns null
25
+ * (rather than throwing) only when GitHub isn't connected at all — no installation, or
26
+ * no repos projected yet — so an unconfigured workspace degrades cleanly.
27
+ *
28
+ * Single-sourcing this here keeps the security-sensitive ancestry walk from drifting
29
+ * between the two stores (the per-facade conformance suites can't catch a divergence
30
+ * because each wires its own resolver).
31
+ */
32
+ export declare function buildResolveRepoTarget(deps: ResolveRepoTargetDependencies): ResolveRepoTarget;
33
+ //# sourceMappingURL=resolveRepoTarget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveRepoTarget.d.ts","sourceRoot":"","sources":["../../src/agents/resolveRepoTarget.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,4BAA4B,EAC5B,wBAAwB,EACxB,iBAAiB,EAClB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AAMpE,MAAM,WAAW,6BAA6B;IAC5C,sBAAsB,EAAE,IAAI,CAAC,4BAA4B,EAAE,gBAAgB,CAAC,CAAA;IAC5E,wBAAwB,EAAE,IAAI,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAAA;IAChE,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,CAAA;IAC7C;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,IAAI,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,CAAA;CAC/D;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,6BAA6B,GAAG,iBAAiB,CAmE7F"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Resolve the repo linked to a running block's enclosing service, shared verbatim by
3
+ * both runtime facades (Worker D1 + Node Drizzle/Postgres). Repos are linked at the
4
+ * service-frame level (see `linkBlock`), but execution runs at the task/module level,
5
+ * so we walk up the block's ancestry to find the frame's repo.
6
+ *
7
+ * There is deliberately NO "first repo" fallback: a workspace can have many repos, and
8
+ * guessing silently pushes work into the wrong one (this is how a simple-service task
9
+ * ended up force-pushing to butter-spread). If nothing in the chain is linked we throw
10
+ * so the misconfiguration surfaces instead of corrupting another repo. Returns null
11
+ * (rather than throwing) only when GitHub isn't connected at all — no installation, or
12
+ * no repos projected yet — so an unconfigured workspace degrades cleanly.
13
+ *
14
+ * Single-sourcing this here keeps the security-sensitive ancestry walk from drifting
15
+ * between the two stores (the per-facade conformance suites can't catch a divergence
16
+ * because each wires its own resolver).
17
+ */
18
+ export function buildResolveRepoTarget(deps) {
19
+ const { installationRepository, repoProjectionRepository, blockRepository, serviceRepository } = deps;
20
+ return async (workspaceId, blockId) => {
21
+ const installation = await installationRepository.getByWorkspace(workspaceId);
22
+ if (!installation)
23
+ return null;
24
+ const repos = await repoProjectionRepository.list(workspaceId);
25
+ if (repos.length === 0)
26
+ return null;
27
+ const reposByGithubId = new Map(repos.map((r) => [r.githubId, r]));
28
+ const reposByBlock = new Map(repos.filter((r) => r.blockId).map((r) => [r.blockId, r]));
29
+ // Walk up the block's ancestry to the enclosing service frame, then resolve its
30
+ // repo. Two linkage mechanisms, checked in this order at each level:
31
+ // 1. The account-owned `Service` for the frame (`getByFrameBlock`) → its
32
+ // `repoGithubId`. This is the only mechanism that supports a MONOREPO, where
33
+ // several frames each own a service pinned to a different subdirectory of the
34
+ // SAME repo (the projection's single `block_id` can't express that), and it is
35
+ // the only one carrying the per-service `directory`.
36
+ // 2. The legacy repo-projection `block_id` link (one whole-repo service per repo),
37
+ // for frames created before in-org services / without a service wired.
38
+ // There is deliberately NO "first repo" fallback: a workspace can have many repos,
39
+ // and guessing silently pushes work into the wrong one. If nothing in the chain is
40
+ // linked we throw so the misconfiguration surfaces instead of corrupting another repo.
41
+ let resolved;
42
+ let cursor = blockId;
43
+ const seen = new Set();
44
+ while (cursor && !seen.has(cursor)) {
45
+ const service = await serviceRepository?.getByFrameBlock(cursor);
46
+ if (service?.repoGithubId != null) {
47
+ const repo = reposByGithubId.get(service.repoGithubId);
48
+ if (repo) {
49
+ resolved = { repo, directory: service.directory ?? null };
50
+ break;
51
+ }
52
+ }
53
+ const linked = reposByBlock.get(cursor);
54
+ if (linked) {
55
+ resolved = { repo: linked, directory: null };
56
+ break;
57
+ }
58
+ seen.add(cursor);
59
+ const block = await blockRepository.get(workspaceId, cursor);
60
+ cursor = block?.parentId ?? null;
61
+ }
62
+ if (!resolved) {
63
+ throw new Error(`Block '${blockId}' is not under a service linked to a GitHub repository ` +
64
+ `(workspace '${workspaceId}'). Link the service frame to its repo so execution ` +
65
+ `targets the right repository instead of guessing one.`);
66
+ }
67
+ const { repo, directory } = resolved;
68
+ // The subdirectory is fed to agents ONLY when the repo is flagged a monorepo: a
69
+ // single-service repo's service may carry a stale/irrelevant directory, but its
70
+ // agents must keep operating on the repo root (the historical behaviour).
71
+ const serviceDirectory = repo.isMonorepo && directory ? directory : undefined;
72
+ return {
73
+ installationId: installation.installationId,
74
+ owner: repo.owner,
75
+ name: repo.name,
76
+ baseBranch: repo.defaultBranch ?? 'main',
77
+ ...(serviceDirectory ? { serviceDirectory } : {}),
78
+ };
79
+ };
80
+ }
81
+ //# sourceMappingURL=resolveRepoTarget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolveRepoTarget.js","sourceRoot":"","sources":["../../src/agents/resolveRepoTarget.ts"],"names":[],"mappings":"AAyBA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAmC;IACxE,MAAM,EAAE,sBAAsB,EAAE,wBAAwB,EAAE,eAAe,EAAE,iBAAiB,EAAE,GAC5F,IAAI,CAAA;IACN,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,EAAE;QACpC,MAAM,YAAY,GAAG,MAAM,sBAAsB,CAAC,cAAc,CAAC,WAAW,CAAC,CAAA;QAC7E,IAAI,CAAC,YAAY;YAAE,OAAO,IAAI,CAAA;QAC9B,MAAM,KAAK,GAAG,MAAM,wBAAwB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QAC9D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAA;QACnC,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;QAClE,MAAM,YAAY,GAAG,IAAI,GAAG,CAC1B,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAiB,EAAE,CAAC,CAAC,CAAC,CACpE,CAAA;QAED,gFAAgF;QAChF,qEAAqE;QACrE,0EAA0E;QAC1E,iFAAiF;QACjF,kFAAkF;QAClF,mFAAmF;QACnF,yDAAyD;QACzD,oFAAoF;QACpF,2EAA2E;QAC3E,mFAAmF;QACnF,mFAAmF;QACnF,uFAAuF;QACvF,IAAI,QAAgF,CAAA;QACpF,IAAI,MAAM,GAAkB,OAAO,CAAA;QACnC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;QAC9B,OAAO,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,MAAM,iBAAiB,EAAE,eAAe,CAAC,MAAM,CAAC,CAAA;YAChE,IAAI,OAAO,EAAE,YAAY,IAAI,IAAI,EAAE,CAAC;gBAClC,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;gBACtD,IAAI,IAAI,EAAE,CAAC;oBACT,QAAQ,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI,EAAE,CAAA;oBACzD,MAAK;gBACP,CAAC;YACH,CAAC;YACD,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;YACvC,IAAI,MAAM,EAAE,CAAC;gBACX,QAAQ,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAA;gBAC5C,MAAK;YACP,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;YAChB,MAAM,KAAK,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;YAC5D,MAAM,GAAG,KAAK,EAAE,QAAQ,IAAI,IAAI,CAAA;QAClC,CAAC;QAED,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CACb,UAAU,OAAO,yDAAyD;gBACxE,eAAe,WAAW,sDAAsD;gBAChF,uDAAuD,CAC1D,CAAA;QACH,CAAC;QACD,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAA;QACpC,gFAAgF;QAChF,gFAAgF;QAChF,0EAA0E;QAC1E,MAAM,gBAAgB,GAAG,IAAI,CAAC,UAAU,IAAI,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAA;QAC7E,OAAO;YACL,cAAc,EAAE,YAAY,CAAC,cAAc;YAC3C,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,UAAU,EAAE,IAAI,CAAC,aAAa,IAAI,MAAM;YACxC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAClD,CAAA;IACH,CAAC,CAAA;AACH,CAAC"}
package/dist/app.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ import type { Hono } from 'hono';
2
+ import type { AppEnv } from './http/env.js';
3
+ /**
4
+ * Mount the runtime-neutral controllers onto a facade's Hono app, preserving the
5
+ * canonical mount prefixes. A facade (the Cloudflare Worker, the Node service)
6
+ * creates its own app — adding CORS, the per-request container, the auth gate and
7
+ * any runtime-specific controllers (events/webhooks/llm-proxy) — then calls this to
8
+ * mount everything shared. The app's Env may extend {@link AppEnv} with runtime
9
+ * `Bindings`; the controllers only touch `Variables` (`container`, `user`).
10
+ */
11
+ export declare function registerCoreControllers<E extends AppEnv>(app: Hono<E>): void;
12
+ //# sourceMappingURL=app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAChC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AA0C3C;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAuD5E"}
package/dist/app.js ADDED
@@ -0,0 +1,102 @@
1
+ import { accountController } from './modules/accounts/AccountController.js';
2
+ import { agentRunController } from './modules/agentRuns/AgentRunController.js';
3
+ import { authController } from './modules/auth/AuthController.js';
4
+ import { boardController } from './modules/board/BoardController.js';
5
+ import { bootstrapController } from './modules/bootstrap/BootstrapController.js';
6
+ import { documentSourceController } from './modules/documents/DocumentSourceController.js';
7
+ import { environmentController } from './modules/environments/EnvironmentController.js';
8
+ import { eventsController } from './modules/events/EventsController.js';
9
+ import { executionController } from './modules/execution/ExecutionController.js';
10
+ import { fragmentLibraryController } from './modules/fragmentLibrary/FragmentLibraryController.js';
11
+ import { githubController } from './modules/github/GitHubController.js';
12
+ import { githubWebhookController } from './modules/github/GitHubWebhookController.js';
13
+ import { llmProxyController } from './modules/llmProxy/LlmProxyController.js';
14
+ import { mergePresetController } from './modules/merge/MergePresetController.js';
15
+ import { workspaceSettingsController } from './modules/settings/WorkspaceSettingsController.js';
16
+ import { releaseHealthController } from './modules/releaseHealth/ReleaseHealthController.js';
17
+ import { modelDefaultsController } from './modules/modelDefaults/ModelDefaultsController.js';
18
+ import { serviceFragmentDefaultsController } from './modules/serviceFragmentDefaults/ServiceFragmentDefaultsController.js';
19
+ import { modelController } from './modules/models/ModelController.js';
20
+ import { notificationController } from './modules/notifications/NotificationController.js';
21
+ import { pipelineController } from './modules/pipelines/PipelineController.js';
22
+ import { promptFragmentController } from './modules/promptFragments/PromptFragmentController.js';
23
+ import { recurringPipelineController } from './modules/recurring/RecurringPipelineController.js';
24
+ import { trackerSettingsController } from './modules/recurring/TrackerSettingsController.js';
25
+ import { requirementReviewController } from './modules/requirements/RequirementReviewController.js';
26
+ import { consensusController } from './modules/consensus/ConsensusController.js';
27
+ import { clarityReviewController } from './modules/clarity/ClarityReviewController.js';
28
+ import { webSearchProxyController } from './modules/webSearch/WebSearchProxyController.js';
29
+ import { runnerPoolController } from './modules/runners/RunnerPoolController.js';
30
+ import { slackController, slackOAuthController } from './modules/slack/SlackController.js';
31
+ import { vendorCredentialController } from './modules/providers/VendorCredentialController.js';
32
+ import { personalSubscriptionController } from './modules/providers/PersonalSubscriptionController.js';
33
+ import { localModelEndpointController } from './modules/localModels/LocalModelEndpointController.js';
34
+ import { userApiKeyController, workspaceApiKeyController, } from './modules/providers/ApiKeyController.js';
35
+ import { serviceMountController } from './modules/services/ServiceMountController.js';
36
+ import { taskSourceController } from './modules/tasks/TaskSourceController.js';
37
+ import { workspaceController } from './modules/workspaces/WorkspaceController.js';
38
+ /**
39
+ * Mount the runtime-neutral controllers onto a facade's Hono app, preserving the
40
+ * canonical mount prefixes. A facade (the Cloudflare Worker, the Node service)
41
+ * creates its own app — adding CORS, the per-request container, the auth gate and
42
+ * any runtime-specific controllers (events/webhooks/llm-proxy) — then calls this to
43
+ * mount everything shared. The app's Env may extend {@link AppEnv} with runtime
44
+ * `Bindings`; the controllers only touch `Variables` (`container`, `user`).
45
+ */
46
+ export function registerCoreControllers(app) {
47
+ // OpenAI-compatible LLM proxy for implementation containers (authenticated by a
48
+ // signed, model-locked container token; upstream/in-process via the llmUpstream gateway).
49
+ app.route('/', llmProxyController());
50
+ // SearXNG-compatible web-search proxy for implementation containers (same
51
+ // model-locked container token; the search runs server-side under the deployment's
52
+ // own key via the `webSearch` gateway, so no provider key reaches the sandbox). A
53
+ // no-op 503 when no upstream is wired.
54
+ app.route('/', webSearchProxyController());
55
+ // "Login with GitHub" (public; no-op endpoints when auth is unconfigured).
56
+ app.route('/auth', authController());
57
+ // Read-only catalogs + account/workspace roots (gated by the facade's auth middleware).
58
+ app.route('/', promptFragmentController());
59
+ app.route('/', modelController());
60
+ app.route('/', accountController());
61
+ app.route('/', personalSubscriptionController());
62
+ app.route('/', localModelEndpointController());
63
+ app.route('/', userApiKeyController());
64
+ app.route('/accounts/:accountId', fragmentLibraryController('account'));
65
+ app.route('/', workspaceController());
66
+ // Real-time WebSocket event stream (self-authenticates via ?ticket=; the facade's
67
+ // gate bypasses only its exact upgrade shape). The upgrade is delegated to the
68
+ // facade's realtime gateway.
69
+ app.route('/', eventsController());
70
+ // Per-workspace API.
71
+ app.route('/workspaces/:workspaceId', boardController());
72
+ app.route('/workspaces/:workspaceId', pipelineController());
73
+ app.route('/workspaces/:workspaceId', executionController());
74
+ app.route('/workspaces/:workspaceId', documentSourceController());
75
+ app.route('/workspaces/:workspaceId', taskSourceController());
76
+ app.route('/workspaces/:workspaceId', environmentController());
77
+ app.route('/workspaces/:workspaceId', runnerPoolController());
78
+ app.route('/workspaces/:workspaceId', vendorCredentialController());
79
+ app.route('/workspaces/:workspaceId', workspaceApiKeyController());
80
+ app.route('/workspaces/:workspaceId', bootstrapController());
81
+ app.route('/workspaces/:workspaceId', agentRunController());
82
+ app.route('/workspaces/:workspaceId', requirementReviewController());
83
+ app.route('/workspaces/:workspaceId', consensusController());
84
+ app.route('/workspaces/:workspaceId', clarityReviewController());
85
+ app.route('/workspaces/:workspaceId', notificationController());
86
+ app.route('/workspaces/:workspaceId', mergePresetController());
87
+ app.route('/workspaces/:workspaceId', workspaceSettingsController());
88
+ app.route('/workspaces/:workspaceId', releaseHealthController());
89
+ app.route('/workspaces/:workspaceId', modelDefaultsController());
90
+ app.route('/workspaces/:workspaceId', serviceFragmentDefaultsController());
91
+ app.route('/workspaces/:workspaceId', recurringPipelineController());
92
+ app.route('/workspaces/:workspaceId', trackerSettingsController());
93
+ app.route('/workspaces/:workspaceId', serviceMountController());
94
+ app.route('/workspaces/:workspaceId', fragmentLibraryController('workspace'));
95
+ app.route('/workspaces/:workspaceId', githubController());
96
+ app.route('/workspaces/:workspaceId', slackController());
97
+ // GitHub-facing (webhooks + setup callback); not workspace-scoped.
98
+ app.route('/github', githubWebhookController());
99
+ // Slack-facing OAuth callback (browser redirect); not workspace-scoped.
100
+ app.route('/slack', slackOAuthController());
101
+ }
102
+ //# sourceMappingURL=app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../src/app.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ export interface GitHubOAuthDependencies {
2
+ clientId: string;
3
+ clientSecret: string;
4
+ /** REST API base (e.g. https://api.github.com), used to read the user. */
5
+ apiBase: string;
6
+ /** OAuth host (e.g. https://github.com), used for authorize/token. */
7
+ oauthBase: string;
8
+ }
9
+ /** The GitHub identity behind an access token (the OAuth provider's subject). */
10
+ export interface GitHubIdentity {
11
+ /** GitHub numeric user id (stable across renames) — the identity subject. */
12
+ id: number;
13
+ login: string;
14
+ name: string | null;
15
+ avatarUrl: string | null;
16
+ email: string | null;
17
+ }
18
+ export declare class GitHubOAuth {
19
+ private readonly deps;
20
+ constructor(deps: GitHubOAuthDependencies);
21
+ /** The github.com URL the browser is sent to in order to authorise. */
22
+ authorizeUrl(params: {
23
+ redirectUri: string;
24
+ state: string;
25
+ scope?: string;
26
+ }): string;
27
+ /** Exchange the callback `code` for a user access token. */
28
+ exchangeCode(code: string, redirectUri: string): Promise<string>;
29
+ /** Resolve the authenticated GitHub user behind an access token. */
30
+ fetchUser(accessToken: string): Promise<GitHubIdentity>;
31
+ /**
32
+ * List the orgs the token's user belongs to, as lowercased logins. Requires
33
+ * the token to carry `read:org` (the login flow requests it only when an org
34
+ * allowlist is configured) so private memberships are visible. A single page
35
+ * of up to 100 is read — well beyond any realistic membership count.
36
+ */
37
+ fetchUserOrgs(accessToken: string): Promise<string[]>;
38
+ }
39
+ //# sourceMappingURL=GitHubOAuth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GitHubOAuth.d.ts","sourceRoot":"","sources":["../../src/auth/GitHubOAuth.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAA;IACf,sEAAsE;IACtE,SAAS,EAAE,MAAM,CAAA;CAClB;AAgBD,iFAAiF;AACjF,MAAM,WAAW,cAAc;IAC7B,6EAA6E;IAC7E,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CACrB;AAMD,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,uBAAuB,EAAI;IAE9D,uEAAuE;IACvE,YAAY,CAAC,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAUnF;IAED,4DAA4D;IACtD,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAqBrE;IAED,oEAAoE;IAC9D,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAkB5D;IAED;;;;;OAKG;IACG,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAY1D;CACF"}
@@ -0,0 +1,90 @@
1
+ // Minimal GitHub OAuth web-flow client (the user-to-server login flow). Works
2
+ // with either a GitHub App's OAuth credentials or a classic OAuth App — both
3
+ // expose the same `/login/oauth/*` endpoints on github.com and `/user` on the
4
+ // REST API. Built on `fetch` only, so it runs in a plain Workers isolate and in Node.
5
+ const USER_AGENT = 'cat-factory';
6
+ const API_VERSION = '2022-11-28';
7
+ export class GitHubOAuth {
8
+ deps;
9
+ constructor(deps) {
10
+ this.deps = deps;
11
+ }
12
+ /** The github.com URL the browser is sent to in order to authorise. */
13
+ authorizeUrl(params) {
14
+ const url = new URL('/login/oauth/authorize', this.deps.oauthBase);
15
+ url.searchParams.set('client_id', this.deps.clientId);
16
+ url.searchParams.set('redirect_uri', params.redirectUri);
17
+ url.searchParams.set('state', params.state);
18
+ // read:user is enough to identify the signer; harmless for GitHub Apps,
19
+ // whose effective access is governed by the App's configured permissions.
20
+ url.searchParams.set('scope', params.scope ?? 'read:user');
21
+ url.searchParams.set('allow_signup', 'false');
22
+ return url.toString();
23
+ }
24
+ /** Exchange the callback `code` for a user access token. */
25
+ async exchangeCode(code, redirectUri) {
26
+ const res = await fetch(new URL('/login/oauth/access_token', this.deps.oauthBase), {
27
+ method: 'POST',
28
+ headers: {
29
+ accept: 'application/json',
30
+ 'content-type': 'application/json',
31
+ 'user-agent': USER_AGENT,
32
+ },
33
+ body: JSON.stringify({
34
+ client_id: this.deps.clientId,
35
+ client_secret: this.deps.clientSecret,
36
+ code,
37
+ redirect_uri: redirectUri,
38
+ }),
39
+ });
40
+ if (!res.ok)
41
+ throw new Error(`GitHub token exchange failed (HTTP ${res.status})`);
42
+ const body = (await res.json());
43
+ if (!body.access_token) {
44
+ throw new Error(body.error_description || body.error || 'GitHub returned no access token');
45
+ }
46
+ return body.access_token;
47
+ }
48
+ /** Resolve the authenticated GitHub user behind an access token. */
49
+ async fetchUser(accessToken) {
50
+ const res = await fetch(new URL('/user', this.deps.apiBase), {
51
+ headers: {
52
+ accept: 'application/vnd.github+json',
53
+ authorization: `Bearer ${accessToken}`,
54
+ 'user-agent': USER_AGENT,
55
+ 'x-github-api-version': API_VERSION,
56
+ },
57
+ });
58
+ if (!res.ok)
59
+ throw new Error(`GitHub user fetch failed (HTTP ${res.status})`);
60
+ const user = (await res.json());
61
+ return {
62
+ id: user.id,
63
+ login: user.login,
64
+ name: user.name,
65
+ avatarUrl: user.avatar_url,
66
+ email: user.email ?? null,
67
+ };
68
+ }
69
+ /**
70
+ * List the orgs the token's user belongs to, as lowercased logins. Requires
71
+ * the token to carry `read:org` (the login flow requests it only when an org
72
+ * allowlist is configured) so private memberships are visible. A single page
73
+ * of up to 100 is read — well beyond any realistic membership count.
74
+ */
75
+ async fetchUserOrgs(accessToken) {
76
+ const res = await fetch(new URL('/user/orgs?per_page=100', this.deps.apiBase), {
77
+ headers: {
78
+ accept: 'application/vnd.github+json',
79
+ authorization: `Bearer ${accessToken}`,
80
+ 'user-agent': USER_AGENT,
81
+ 'x-github-api-version': API_VERSION,
82
+ },
83
+ });
84
+ if (!res.ok)
85
+ throw new Error(`GitHub org list failed (HTTP ${res.status})`);
86
+ const orgs = (await res.json());
87
+ return orgs.map((org) => org.login.toLowerCase());
88
+ }
89
+ }
90
+ //# sourceMappingURL=GitHubOAuth.js.map