@cat-factory/integrations 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 (242) hide show
  1. package/LICENSE +21 -0
  2. package/dist/index.d.ts +68 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +84 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/modules/datadog/DatadogClient.d.ts +54 -0
  7. package/dist/modules/datadog/DatadogClient.d.ts.map +1 -0
  8. package/dist/modules/datadog/DatadogClient.js +132 -0
  9. package/dist/modules/datadog/DatadogClient.js.map +1 -0
  10. package/dist/modules/datadog/DatadogReleaseHealthProvider.d.ts +30 -0
  11. package/dist/modules/datadog/DatadogReleaseHealthProvider.d.ts.map +1 -0
  12. package/dist/modules/datadog/DatadogReleaseHealthProvider.js +101 -0
  13. package/dist/modules/datadog/DatadogReleaseHealthProvider.js.map +1 -0
  14. package/dist/modules/datadog/datadog.logic.d.ts +37 -0
  15. package/dist/modules/datadog/datadog.logic.d.ts.map +1 -0
  16. package/dist/modules/datadog/datadog.logic.js +90 -0
  17. package/dist/modules/datadog/datadog.logic.js.map +1 -0
  18. package/dist/modules/documents/ConfluenceProvider.d.ts +29 -0
  19. package/dist/modules/documents/ConfluenceProvider.d.ts.map +1 -0
  20. package/dist/modules/documents/ConfluenceProvider.js +180 -0
  21. package/dist/modules/documents/ConfluenceProvider.js.map +1 -0
  22. package/dist/modules/documents/DocumentConnectionService.d.ts +30 -0
  23. package/dist/modules/documents/DocumentConnectionService.d.ts.map +1 -0
  24. package/dist/modules/documents/DocumentConnectionService.js +69 -0
  25. package/dist/modules/documents/DocumentConnectionService.js.map +1 -0
  26. package/dist/modules/documents/DocumentImportService.d.ts +34 -0
  27. package/dist/modules/documents/DocumentImportService.d.ts.map +1 -0
  28. package/dist/modules/documents/DocumentImportService.js +83 -0
  29. package/dist/modules/documents/DocumentImportService.js.map +1 -0
  30. package/dist/modules/documents/DocumentLinkService.d.ts +31 -0
  31. package/dist/modules/documents/DocumentLinkService.d.ts.map +1 -0
  32. package/dist/modules/documents/DocumentLinkService.js +75 -0
  33. package/dist/modules/documents/DocumentLinkService.js.map +1 -0
  34. package/dist/modules/documents/DocumentPlannerService.d.ts +23 -0
  35. package/dist/modules/documents/DocumentPlannerService.d.ts.map +1 -0
  36. package/dist/modules/documents/DocumentPlannerService.js +96 -0
  37. package/dist/modules/documents/DocumentPlannerService.js.map +1 -0
  38. package/dist/modules/documents/GitHubDocsProvider.d.ts +42 -0
  39. package/dist/modules/documents/GitHubDocsProvider.d.ts.map +1 -0
  40. package/dist/modules/documents/GitHubDocsProvider.js +86 -0
  41. package/dist/modules/documents/GitHubDocsProvider.js.map +1 -0
  42. package/dist/modules/documents/NotionProvider.d.ts +32 -0
  43. package/dist/modules/documents/NotionProvider.d.ts.map +1 -0
  44. package/dist/modules/documents/NotionProvider.js +221 -0
  45. package/dist/modules/documents/NotionProvider.js.map +1 -0
  46. package/dist/modules/documents/confluence.logic.d.ts +37 -0
  47. package/dist/modules/documents/confluence.logic.d.ts.map +1 -0
  48. package/dist/modules/documents/confluence.logic.js +133 -0
  49. package/dist/modules/documents/confluence.logic.js.map +1 -0
  50. package/dist/modules/documents/documents.logic.d.ts +22 -0
  51. package/dist/modules/documents/documents.logic.d.ts.map +1 -0
  52. package/dist/modules/documents/documents.logic.js +138 -0
  53. package/dist/modules/documents/documents.logic.js.map +1 -0
  54. package/dist/modules/documents/github-docs.logic.d.ts +52 -0
  55. package/dist/modules/documents/github-docs.logic.d.ts.map +1 -0
  56. package/dist/modules/documents/github-docs.logic.js +94 -0
  57. package/dist/modules/documents/github-docs.logic.js.map +1 -0
  58. package/dist/modules/documents/notion.logic.d.ts +31 -0
  59. package/dist/modules/documents/notion.logic.d.ts.map +1 -0
  60. package/dist/modules/documents/notion.logic.js +142 -0
  61. package/dist/modules/documents/notion.logic.js.map +1 -0
  62. package/dist/modules/email/EmailConnectionService.d.ts +34 -0
  63. package/dist/modules/email/EmailConnectionService.d.ts.map +1 -0
  64. package/dist/modules/email/EmailConnectionService.js +82 -0
  65. package/dist/modules/email/EmailConnectionService.js.map +1 -0
  66. package/dist/modules/email/adapters.d.ts +39 -0
  67. package/dist/modules/email/adapters.d.ts.map +1 -0
  68. package/dist/modules/email/adapters.js +79 -0
  69. package/dist/modules/email/adapters.js.map +1 -0
  70. package/dist/modules/environments/EnvironmentConnectionService.d.ts +42 -0
  71. package/dist/modules/environments/EnvironmentConnectionService.d.ts.map +1 -0
  72. package/dist/modules/environments/EnvironmentConnectionService.js +120 -0
  73. package/dist/modules/environments/EnvironmentConnectionService.js.map +1 -0
  74. package/dist/modules/environments/EnvironmentProvisioningService.d.ts +56 -0
  75. package/dist/modules/environments/EnvironmentProvisioningService.d.ts.map +1 -0
  76. package/dist/modules/environments/EnvironmentProvisioningService.js +153 -0
  77. package/dist/modules/environments/EnvironmentProvisioningService.js.map +1 -0
  78. package/dist/modules/environments/EnvironmentTeardownService.d.ts +24 -0
  79. package/dist/modules/environments/EnvironmentTeardownService.d.ts.map +1 -0
  80. package/dist/modules/environments/EnvironmentTeardownService.js +54 -0
  81. package/dist/modules/environments/EnvironmentTeardownService.js.map +1 -0
  82. package/dist/modules/environments/HttpEnvironmentProvider.d.ts +30 -0
  83. package/dist/modules/environments/HttpEnvironmentProvider.d.ts.map +1 -0
  84. package/dist/modules/environments/HttpEnvironmentProvider.js +316 -0
  85. package/dist/modules/environments/HttpEnvironmentProvider.js.map +1 -0
  86. package/dist/modules/environments/environments.logic.d.ts +50 -0
  87. package/dist/modules/environments/environments.logic.d.ts.map +1 -0
  88. package/dist/modules/environments/environments.logic.js +257 -0
  89. package/dist/modules/environments/environments.logic.js.map +1 -0
  90. package/dist/modules/github/GitHubInstallationService.d.ts +66 -0
  91. package/dist/modules/github/GitHubInstallationService.d.ts.map +1 -0
  92. package/dist/modules/github/GitHubInstallationService.js +143 -0
  93. package/dist/modules/github/GitHubInstallationService.js.map +1 -0
  94. package/dist/modules/github/GitHubService.d.ts +29 -0
  95. package/dist/modules/github/GitHubService.d.ts.map +1 -0
  96. package/dist/modules/github/GitHubService.js +61 -0
  97. package/dist/modules/github/GitHubService.js.map +1 -0
  98. package/dist/modules/github/GitHubSyncService.d.ts +97 -0
  99. package/dist/modules/github/GitHubSyncService.d.ts.map +1 -0
  100. package/dist/modules/github/GitHubSyncService.js +241 -0
  101. package/dist/modules/github/GitHubSyncService.js.map +1 -0
  102. package/dist/modules/github/RepoProvisioningService.d.ts +26 -0
  103. package/dist/modules/github/RepoProvisioningService.d.ts.map +1 -0
  104. package/dist/modules/github/RepoProvisioningService.js +36 -0
  105. package/dist/modules/github/RepoProvisioningService.js.map +1 -0
  106. package/dist/modules/github/WebhookService.d.ts +28 -0
  107. package/dist/modules/github/WebhookService.d.ts.map +1 -0
  108. package/dist/modules/github/WebhookService.js +156 -0
  109. package/dist/modules/github/WebhookService.js.map +1 -0
  110. package/dist/modules/github/projection.logic.d.ts +95 -0
  111. package/dist/modules/github/projection.logic.d.ts.map +1 -0
  112. package/dist/modules/github/projection.logic.js +94 -0
  113. package/dist/modules/github/projection.logic.js.map +1 -0
  114. package/dist/modules/github/provisioning.logic.d.ts +11 -0
  115. package/dist/modules/github/provisioning.logic.d.ts.map +1 -0
  116. package/dist/modules/github/provisioning.logic.js +18 -0
  117. package/dist/modules/github/provisioning.logic.js.map +1 -0
  118. package/dist/modules/incident/incident.logic.d.ts +16 -0
  119. package/dist/modules/incident/incident.logic.d.ts.map +1 -0
  120. package/dist/modules/incident/incident.logic.js +23 -0
  121. package/dist/modules/incident/incident.logic.js.map +1 -0
  122. package/dist/modules/incidentio/IncidentIoEnrichmentProvider.d.ts +26 -0
  123. package/dist/modules/incidentio/IncidentIoEnrichmentProvider.d.ts.map +1 -0
  124. package/dist/modules/incidentio/IncidentIoEnrichmentProvider.js +84 -0
  125. package/dist/modules/incidentio/IncidentIoEnrichmentProvider.js.map +1 -0
  126. package/dist/modules/pagerduty/PagerDutyEnrichmentProvider.d.ts +27 -0
  127. package/dist/modules/pagerduty/PagerDutyEnrichmentProvider.d.ts.map +1 -0
  128. package/dist/modules/pagerduty/PagerDutyEnrichmentProvider.js +65 -0
  129. package/dist/modules/pagerduty/PagerDutyEnrichmentProvider.js.map +1 -0
  130. package/dist/modules/providers/ApiKeyService.d.ts +73 -0
  131. package/dist/modules/providers/ApiKeyService.d.ts.map +1 -0
  132. package/dist/modules/providers/ApiKeyService.js +122 -0
  133. package/dist/modules/providers/ApiKeyService.js.map +1 -0
  134. package/dist/modules/providers/LocalModelEndpointService.d.ts +52 -0
  135. package/dist/modules/providers/LocalModelEndpointService.d.ts.map +1 -0
  136. package/dist/modules/providers/LocalModelEndpointService.js +131 -0
  137. package/dist/modules/providers/LocalModelEndpointService.js.map +1 -0
  138. package/dist/modules/providers/PersonalSubscriptionService.d.ts +94 -0
  139. package/dist/modules/providers/PersonalSubscriptionService.d.ts.map +1 -0
  140. package/dist/modules/providers/PersonalSubscriptionService.js +218 -0
  141. package/dist/modules/providers/PersonalSubscriptionService.js.map +1 -0
  142. package/dist/modules/providers/ProviderSubscriptionService.d.ts +75 -0
  143. package/dist/modules/providers/ProviderSubscriptionService.d.ts.map +1 -0
  144. package/dist/modules/providers/ProviderSubscriptionService.js +130 -0
  145. package/dist/modules/providers/ProviderSubscriptionService.js.map +1 -0
  146. package/dist/modules/providers/localModelUrl.d.ts +7 -0
  147. package/dist/modules/providers/localModelUrl.d.ts.map +1 -0
  148. package/dist/modules/providers/localModelUrl.js +67 -0
  149. package/dist/modules/providers/localModelUrl.js.map +1 -0
  150. package/dist/modules/providers/providers.logic.d.ts +23 -0
  151. package/dist/modules/providers/providers.logic.d.ts.map +1 -0
  152. package/dist/modules/providers/providers.logic.js +46 -0
  153. package/dist/modules/providers/providers.logic.js.map +1 -0
  154. package/dist/modules/runners/HttpRunnerPoolProvider.d.ts +51 -0
  155. package/dist/modules/runners/HttpRunnerPoolProvider.d.ts.map +1 -0
  156. package/dist/modules/runners/HttpRunnerPoolProvider.js +304 -0
  157. package/dist/modules/runners/HttpRunnerPoolProvider.js.map +1 -0
  158. package/dist/modules/runners/RunnerPoolConnectionService.d.ts +47 -0
  159. package/dist/modules/runners/RunnerPoolConnectionService.d.ts.map +1 -0
  160. package/dist/modules/runners/RunnerPoolConnectionService.js +98 -0
  161. package/dist/modules/runners/RunnerPoolConnectionService.js.map +1 -0
  162. package/dist/modules/runners/RunnerPoolTransport.d.ts +11 -0
  163. package/dist/modules/runners/RunnerPoolTransport.d.ts.map +1 -0
  164. package/dist/modules/runners/RunnerPoolTransport.js +61 -0
  165. package/dist/modules/runners/RunnerPoolTransport.js.map +1 -0
  166. package/dist/modules/runners/runners.logic.d.ts +16 -0
  167. package/dist/modules/runners/runners.logic.d.ts.map +1 -0
  168. package/dist/modules/runners/runners.logic.js +52 -0
  169. package/dist/modules/runners/runners.logic.js.map +1 -0
  170. package/dist/modules/slack/SlackApiClient.d.ts +67 -0
  171. package/dist/modules/slack/SlackApiClient.d.ts.map +1 -0
  172. package/dist/modules/slack/SlackApiClient.js +132 -0
  173. package/dist/modules/slack/SlackApiClient.js.map +1 -0
  174. package/dist/modules/slack/SlackConnectionService.d.ts +41 -0
  175. package/dist/modules/slack/SlackConnectionService.d.ts.map +1 -0
  176. package/dist/modules/slack/SlackConnectionService.js +136 -0
  177. package/dist/modules/slack/SlackConnectionService.js.map +1 -0
  178. package/dist/modules/slack/SlackMemberMappingService.d.ts +17 -0
  179. package/dist/modules/slack/SlackMemberMappingService.d.ts.map +1 -0
  180. package/dist/modules/slack/SlackMemberMappingService.js +28 -0
  181. package/dist/modules/slack/SlackMemberMappingService.js.map +1 -0
  182. package/dist/modules/slack/SlackNotificationChannel.d.ts +45 -0
  183. package/dist/modules/slack/SlackNotificationChannel.d.ts.map +1 -0
  184. package/dist/modules/slack/SlackNotificationChannel.js +84 -0
  185. package/dist/modules/slack/SlackNotificationChannel.js.map +1 -0
  186. package/dist/modules/slack/SlackSettingsService.d.ts +16 -0
  187. package/dist/modules/slack/SlackSettingsService.d.ts.map +1 -0
  188. package/dist/modules/slack/SlackSettingsService.js +41 -0
  189. package/dist/modules/slack/SlackSettingsService.js.map +1 -0
  190. package/dist/modules/slack/slack.logic.d.ts +55 -0
  191. package/dist/modules/slack/slack.logic.d.ts.map +1 -0
  192. package/dist/modules/slack/slack.logic.js +149 -0
  193. package/dist/modules/slack/slack.logic.js.map +1 -0
  194. package/dist/modules/tasks/GitHubIssuesProvider.d.ts +50 -0
  195. package/dist/modules/tasks/GitHubIssuesProvider.d.ts.map +1 -0
  196. package/dist/modules/tasks/GitHubIssuesProvider.js +92 -0
  197. package/dist/modules/tasks/GitHubIssuesProvider.js.map +1 -0
  198. package/dist/modules/tasks/JiraProvider.d.ts +29 -0
  199. package/dist/modules/tasks/JiraProvider.d.ts.map +1 -0
  200. package/dist/modules/tasks/JiraProvider.js +114 -0
  201. package/dist/modules/tasks/JiraProvider.js.map +1 -0
  202. package/dist/modules/tasks/TaskConnectionService.d.ts +30 -0
  203. package/dist/modules/tasks/TaskConnectionService.d.ts.map +1 -0
  204. package/dist/modules/tasks/TaskConnectionService.js +69 -0
  205. package/dist/modules/tasks/TaskConnectionService.js.map +1 -0
  206. package/dist/modules/tasks/TaskImportService.d.ts +34 -0
  207. package/dist/modules/tasks/TaskImportService.d.ts.map +1 -0
  208. package/dist/modules/tasks/TaskImportService.js +96 -0
  209. package/dist/modules/tasks/TaskImportService.js.map +1 -0
  210. package/dist/modules/tasks/TaskLinkService.d.ts +30 -0
  211. package/dist/modules/tasks/TaskLinkService.d.ts.map +1 -0
  212. package/dist/modules/tasks/TaskLinkService.js +56 -0
  213. package/dist/modules/tasks/TaskLinkService.js.map +1 -0
  214. package/dist/modules/tasks/github-issues.logic.d.ts +35 -0
  215. package/dist/modules/tasks/github-issues.logic.d.ts.map +1 -0
  216. package/dist/modules/tasks/github-issues.logic.js +67 -0
  217. package/dist/modules/tasks/github-issues.logic.js.map +1 -0
  218. package/dist/modules/tasks/jira.logic.d.ts +28 -0
  219. package/dist/modules/tasks/jira.logic.d.ts.map +1 -0
  220. package/dist/modules/tasks/jira.logic.js +151 -0
  221. package/dist/modules/tasks/jira.logic.js.map +1 -0
  222. package/dist/modules/tasks/tasks.logic.d.ts +12 -0
  223. package/dist/modules/tasks/tasks.logic.d.ts.map +1 -0
  224. package/dist/modules/tasks/tasks.logic.js +17 -0
  225. package/dist/modules/tasks/tasks.logic.js.map +1 -0
  226. package/dist/modules/tracker/TicketTrackerService.d.ts +45 -0
  227. package/dist/modules/tracker/TicketTrackerService.d.ts.map +1 -0
  228. package/dist/modules/tracker/TicketTrackerService.js +52 -0
  229. package/dist/modules/tracker/TicketTrackerService.js.map +1 -0
  230. package/dist/modules/tracker/base64.d.ts +2 -0
  231. package/dist/modules/tracker/base64.d.ts.map +1 -0
  232. package/dist/modules/tracker/base64.js +18 -0
  233. package/dist/modules/tracker/base64.js.map +1 -0
  234. package/dist/modules/tracker/github.create.logic.d.ts +16 -0
  235. package/dist/modules/tracker/github.create.logic.d.ts.map +1 -0
  236. package/dist/modules/tracker/github.create.logic.js +25 -0
  237. package/dist/modules/tracker/github.create.logic.js.map +1 -0
  238. package/dist/modules/tracker/jira.create.logic.d.ts +31 -0
  239. package/dist/modules/tracker/jira.create.logic.d.ts.map +1 -0
  240. package/dist/modules/tracker/jira.create.logic.js +59 -0
  241. package/dist/modules/tracker/jira.create.logic.js.map +1 -0
  242. package/package.json +36 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PersonalSubscriptionService.js","sourceRoot":"","sources":["../../../src/modules/providers/PersonalSubscriptionService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ import type { Clock, IdGenerator, ProviderSubscriptionTokenRepository, SecretCipher, SubscriptionVendor } from '@cat-factory/kernel';
2
+ import type { WorkspaceRepository } from '@cat-factory/kernel';
3
+ export interface ProviderSubscriptionServiceDependencies {
4
+ providerSubscriptionTokenRepository: ProviderSubscriptionTokenRepository;
5
+ workspaceRepository: WorkspaceRepository;
6
+ secretCipher: SecretCipher;
7
+ idGenerator: IdGenerator;
8
+ clock: Clock;
9
+ /** Rolling usage window for rotation; defaults to ~5h. */
10
+ usageWindowMs?: number;
11
+ }
12
+ /** Safe metadata for one pool token (never the secret). */
13
+ export interface VendorCredentialSummary {
14
+ id: string;
15
+ vendor: SubscriptionVendor;
16
+ label: string;
17
+ createdAt: number;
18
+ lastUsedAt: number | null;
19
+ inputTokens: number;
20
+ outputTokens: number;
21
+ requestCount: number;
22
+ }
23
+ /** A leased credential: the decrypted secret plus the row id (for usage attribution). */
24
+ export interface LeasedSubscriptionToken {
25
+ tokenId: string;
26
+ vendor: SubscriptionVendor;
27
+ secret: string;
28
+ }
29
+ export declare class ProviderSubscriptionService {
30
+ private readonly deps;
31
+ constructor(deps: ProviderSubscriptionServiceDependencies);
32
+ private get windowMs();
33
+ /**
34
+ * Reject an individual-usage vendor (Claude) from the shared workspace pool: such a
35
+ * subscription is licensed for individual use only, so it is stored per-user by the
36
+ * PersonalSubscriptionService and never pooled/rotated/shared across a workspace.
37
+ */
38
+ private assertPoolable;
39
+ /** Add a token to the workspace's pool for a vendor. */
40
+ addToken(workspaceId: string, input: {
41
+ vendor: SubscriptionVendor;
42
+ label: string;
43
+ token: string;
44
+ }): Promise<VendorCredentialSummary>;
45
+ /** All live tokens for a workspace (optionally filtered by vendor), metadata only. */
46
+ listTokens(workspaceId: string, vendor?: SubscriptionVendor): Promise<VendorCredentialSummary[]>;
47
+ /**
48
+ * Whether the workspace has at least one live token for a vendor. Individual-usage
49
+ * vendors are never pooled, so this is always false for them — the executor routes
50
+ * those through the per-user PersonalSubscriptionService instead.
51
+ */
52
+ hasToken(workspaceId: string, vendor: SubscriptionVendor): Promise<boolean>;
53
+ /** Remove a token from the pool. */
54
+ removeToken(workspaceId: string, id: string): Promise<void>;
55
+ /**
56
+ * Lease the least-loaded live token for a vendor and return its decrypted
57
+ * secret. Throws ConflictError when the pool is empty so the dispatch path can
58
+ * surface a clear "connect a token" error rather than dispatching a doomed job.
59
+ *
60
+ * Rotation is best-effort, not transactional: the read → choose → markLeased
61
+ * sequence is not atomic, so two leases that interleave between the read and the
62
+ * mark can pick the same token. That window is benign (worst case one extra job on
63
+ * a token) and self-correcting — markLeased stamps `lastUsedAt` synchronously
64
+ * BEFORE this returns, so the next lease in a burst sees the just-leased token as
65
+ * least-recently-used and rotates to a different one even though real usage (folded
66
+ * in only when the job finishes, minutes later) is still zero across the pool.
67
+ */
68
+ leaseToken(workspaceId: string, vendor: SubscriptionVendor): Promise<LeasedSubscriptionToken>;
69
+ /** Fold a completed job's usage into the leased token's rolling-window counters. */
70
+ recordTokenUsage(workspaceId: string, id: string, usage: {
71
+ inputTokens: number;
72
+ outputTokens: number;
73
+ }): Promise<void>;
74
+ }
75
+ //# sourceMappingURL=ProviderSubscriptionService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProviderSubscriptionService.d.ts","sourceRoot":"","sources":["../../../src/modules/providers/ProviderSubscriptionService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,WAAW,EAEX,mCAAmC,EACnC,YAAY,EACZ,kBAAkB,EACnB,MAAM,qBAAqB,CAAA;AAI5B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAyB9D,MAAM,WAAW,uCAAuC;IACtD,mCAAmC,EAAE,mCAAmC,CAAA;IACxE,mBAAmB,EAAE,mBAAmB,CAAA;IACxC,YAAY,EAAE,YAAY,CAAA;IAC1B,WAAW,EAAE,WAAW,CAAA;IACxB,KAAK,EAAE,KAAK,CAAA;IACZ,0DAA0D;IAC1D,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,2DAA2D;AAC3D,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,kBAAkB,CAAA;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,yFAAyF;AACzF,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,kBAAkB,CAAA;IAC1B,MAAM,EAAE,MAAM,CAAA;CACf;AAED,qBAAa,2BAA2B;IAC1B,OAAO,CAAC,QAAQ,CAAC,IAAI;IAAjC,YAA6B,IAAI,EAAE,uCAAuC,EAAI;IAE9E,OAAO,KAAK,QAAQ,GAEnB;IAED;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAStB,wDAAwD;IAClD,QAAQ,CACZ,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE;QAAE,MAAM,EAAE,kBAAkB,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAClE,OAAO,CAAC,uBAAuB,CAAC,CA+BlC;IAED,sFAAsF;IAChF,UAAU,CACd,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAQpC;IAED;;;;OAIG;IACG,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAOhF;IAED,oCAAoC;IAC9B,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAMhE;IAED;;;;;;;;;;;;OAYG;IACG,UAAU,CACd,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,uBAAuB,CAAC,CAmBlC;IAED,oFAAoF;IAC9E,gBAAgB,CACpB,WAAW,EAAE,MAAM,EACnB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,GACnD,OAAO,CAAC,IAAI,CAAC,CAQf;CACF"}
@@ -0,0 +1,130 @@
1
+ import { ConflictError } from '@cat-factory/kernel';
2
+ import { requireWorkspace } from '@cat-factory/kernel';
3
+ import { SUBSCRIPTION_VENDORS, isIndividualVendor } from '@cat-factory/kernel';
4
+ import { DEFAULT_USAGE_WINDOW_MS, chooseToken } from './providers.logic.js';
5
+ // Every vendor whose subscription harness we support that is ALSO poolable — i.e.
6
+ // excluding the individual-usage vendors (Claude), which are stored per-user by the
7
+ // PersonalSubscriptionService and never shared in a workspace pool. The single source
8
+ // of truth is the SUBSCRIPTION_VENDORS map in the kernel, so adding a poolable vendor
9
+ // there automatically widens the unfiltered `listTokens` sweep below.
10
+ const ALL_VENDORS = Object.keys(SUBSCRIPTION_VENDORS).filter((v) => !isIndividualVendor(v));
11
+ // Upper bound on live tokens per workspace+vendor. The rotation pool is meant to hold
12
+ // a handful of subscriptions for quota headroom; a generous ceiling keeps the feature
13
+ // usable while bounding accidental/abusive unbounded growth (every lease lists the
14
+ // whole live pool, so an unbounded pool would also bloat that read).
15
+ const MAX_TOKENS_PER_VENDOR = 25;
16
+ export class ProviderSubscriptionService {
17
+ deps;
18
+ constructor(deps) {
19
+ this.deps = deps;
20
+ }
21
+ get windowMs() {
22
+ return this.deps.usageWindowMs ?? DEFAULT_USAGE_WINDOW_MS;
23
+ }
24
+ /**
25
+ * Reject an individual-usage vendor (Claude) from the shared workspace pool: such a
26
+ * subscription is licensed for individual use only, so it is stored per-user by the
27
+ * PersonalSubscriptionService and never pooled/rotated/shared across a workspace.
28
+ */
29
+ assertPoolable(vendor) {
30
+ if (isIndividualVendor(vendor)) {
31
+ throw new ConflictError(`The ${SUBSCRIPTION_VENDORS[vendor].label} subscription is licensed for individual use ` +
32
+ `only and cannot be pooled on a workspace. Connect it as a personal subscription instead.`);
33
+ }
34
+ }
35
+ /** Add a token to the workspace's pool for a vendor. */
36
+ async addToken(workspaceId, input) {
37
+ await requireWorkspace(this.deps.workspaceRepository, workspaceId);
38
+ this.assertPoolable(input.vendor);
39
+ const existing = await this.deps.providerSubscriptionTokenRepository.listByVendor(workspaceId, input.vendor);
40
+ if (existing.length >= MAX_TOKENS_PER_VENDOR) {
41
+ throw new ConflictError(`Workspace '${workspaceId}' already has the maximum of ${MAX_TOKENS_PER_VENDOR} ` +
42
+ `${input.vendor} subscription tokens; remove one before adding another`);
43
+ }
44
+ const tokenCipher = await this.deps.secretCipher.encrypt(input.token);
45
+ const now = this.deps.clock.now();
46
+ const record = {
47
+ id: this.deps.idGenerator.next('sub'),
48
+ workspaceId,
49
+ vendor: input.vendor,
50
+ label: input.label,
51
+ tokenCipher,
52
+ createdAt: now,
53
+ lastUsedAt: null,
54
+ windowStartedAt: null,
55
+ inputTokens: 0,
56
+ outputTokens: 0,
57
+ requestCount: 0,
58
+ deletedAt: null,
59
+ };
60
+ await this.deps.providerSubscriptionTokenRepository.add(record);
61
+ return toSummary(record);
62
+ }
63
+ /** All live tokens for a workspace (optionally filtered by vendor), metadata only. */
64
+ async listTokens(workspaceId, vendor) {
65
+ const vendors = vendor ? [vendor] : ALL_VENDORS;
66
+ const out = [];
67
+ for (const v of vendors) {
68
+ const rows = await this.deps.providerSubscriptionTokenRepository.listByVendor(workspaceId, v);
69
+ for (const row of rows)
70
+ out.push(toSummary(row));
71
+ }
72
+ return out;
73
+ }
74
+ /**
75
+ * Whether the workspace has at least one live token for a vendor. Individual-usage
76
+ * vendors are never pooled, so this is always false for them — the executor routes
77
+ * those through the per-user PersonalSubscriptionService instead.
78
+ */
79
+ async hasToken(workspaceId, vendor) {
80
+ if (isIndividualVendor(vendor))
81
+ return false;
82
+ const rows = await this.deps.providerSubscriptionTokenRepository.listByVendor(workspaceId, vendor);
83
+ return rows.length > 0;
84
+ }
85
+ /** Remove a token from the pool. */
86
+ async removeToken(workspaceId, id) {
87
+ await this.deps.providerSubscriptionTokenRepository.softDelete(workspaceId, id, this.deps.clock.now());
88
+ }
89
+ /**
90
+ * Lease the least-loaded live token for a vendor and return its decrypted
91
+ * secret. Throws ConflictError when the pool is empty so the dispatch path can
92
+ * surface a clear "connect a token" error rather than dispatching a doomed job.
93
+ *
94
+ * Rotation is best-effort, not transactional: the read → choose → markLeased
95
+ * sequence is not atomic, so two leases that interleave between the read and the
96
+ * mark can pick the same token. That window is benign (worst case one extra job on
97
+ * a token) and self-correcting — markLeased stamps `lastUsedAt` synchronously
98
+ * BEFORE this returns, so the next lease in a burst sees the just-leased token as
99
+ * least-recently-used and rotates to a different one even though real usage (folded
100
+ * in only when the job finishes, minutes later) is still zero across the pool.
101
+ */
102
+ async leaseToken(workspaceId, vendor) {
103
+ this.assertPoolable(vendor);
104
+ const rows = await this.deps.providerSubscriptionTokenRepository.listByVendor(workspaceId, vendor);
105
+ const chosen = chooseToken(rows, this.deps.clock.now(), this.windowMs);
106
+ if (!chosen) {
107
+ throw new ConflictError(`Workspace '${workspaceId}' has no ${vendor} subscription token connected`);
108
+ }
109
+ await this.deps.providerSubscriptionTokenRepository.markLeased(workspaceId, chosen.id, this.deps.clock.now());
110
+ const secret = await this.deps.secretCipher.decrypt(chosen.tokenCipher);
111
+ return { tokenId: chosen.id, vendor, secret };
112
+ }
113
+ /** Fold a completed job's usage into the leased token's rolling-window counters. */
114
+ async recordTokenUsage(workspaceId, id, usage) {
115
+ await this.deps.providerSubscriptionTokenRepository.recordUsage(workspaceId, id, usage, this.deps.clock.now(), this.windowMs);
116
+ }
117
+ }
118
+ function toSummary(record) {
119
+ return {
120
+ id: record.id,
121
+ vendor: record.vendor,
122
+ label: record.label,
123
+ createdAt: record.createdAt,
124
+ lastUsedAt: record.lastUsedAt,
125
+ inputTokens: record.inputTokens,
126
+ outputTokens: record.outputTokens,
127
+ requestCount: record.requestCount,
128
+ };
129
+ }
130
+ //# sourceMappingURL=ProviderSubscriptionService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProviderSubscriptionService.js","sourceRoot":"","sources":["../../../src/modules/providers/ProviderSubscriptionService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Validate a local-runner base URL. Returns a human-readable error string when the URL
3
+ * is malformed or points at a non-local host, or `null` when it's acceptable. Used by
4
+ * the service at the write boundary and by the "Test connection" probe.
5
+ */
6
+ export declare function localRunnerUrlError(rawUrl: string): string | null;
7
+ //# sourceMappingURL=localModelUrl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localModelUrl.d.ts","sourceRoot":"","sources":["../../../src/modules/providers/localModelUrl.ts"],"names":[],"mappings":"AAsCA;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAiBjE"}
@@ -0,0 +1,67 @@
1
+ // ---------------------------------------------------------------------------
2
+ // SSRF guard for local-runner base URLs. A runner lives on the user's OWN machine
3
+ // (or LAN), so we forward requests to a user-supplied base URL server-side (both the
4
+ // "Test connection" probe and the run-time LLM proxy). The usual "block private IPs"
5
+ // mitigation is backwards here — loopback/LAN is exactly the intended target — so
6
+ // instead we ALLOW only loopback + RFC1918/ULA private hosts and reject everything
7
+ // else. This keeps the feature working on a single-tenant Node/local deployment (the
8
+ // server shares the LAN with the runner) while denying a tenant on the shared
9
+ // Cloudflare facade the ability to probe arbitrary public hosts or the link-local
10
+ // cloud-metadata endpoint (169.254.169.254 / fe80::). Public/remote runners are not
11
+ // supported by design.
12
+ // ---------------------------------------------------------------------------
13
+ const IPV4 = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
14
+ /** Whether a hostname (no port) is a loopback or RFC1918/ULA private host we forward to. */
15
+ function isLoopbackOrPrivateHost(host) {
16
+ const h = host.toLowerCase().replace(/^\[/, '').replace(/\]$/, '');
17
+ if (h === 'localhost' || h.endsWith('.localhost'))
18
+ return true;
19
+ // mDNS `.local` names resolve only on the LAN — acceptable for a same-network runner.
20
+ if (h.endsWith('.local'))
21
+ return true;
22
+ const v4 = IPV4.exec(h);
23
+ if (v4) {
24
+ const [a, b] = [Number(v4[1]), Number(v4[2])];
25
+ if ([a, b, Number(v4[3]), Number(v4[4])].some((n) => n > 255))
26
+ return false;
27
+ if (a === 127)
28
+ return true; // loopback 127.0.0.0/8
29
+ if (a === 10)
30
+ return true; // private 10.0.0.0/8
31
+ if (a === 172 && b >= 16 && b <= 31)
32
+ return true; // private 172.16.0.0/12
33
+ if (a === 192 && b === 168)
34
+ return true; // private 192.168.0.0/16
35
+ return false; // public, 0.0.0.0, and link-local 169.254.0.0/16 (metadata) → denied
36
+ }
37
+ // IPv6 literals (URL.hostname strips the brackets).
38
+ if (h === '::1')
39
+ return true; // loopback
40
+ if (h.startsWith('fc') || h.startsWith('fd'))
41
+ return true; // ULA fc00::/7
42
+ // fe80::/10 (link-local), :: (unspecified), and global addresses → denied.
43
+ return false;
44
+ }
45
+ /**
46
+ * Validate a local-runner base URL. Returns a human-readable error string when the URL
47
+ * is malformed or points at a non-local host, or `null` when it's acceptable. Used by
48
+ * the service at the write boundary and by the "Test connection" probe.
49
+ */
50
+ export function localRunnerUrlError(rawUrl) {
51
+ let url;
52
+ try {
53
+ url = new URL(rawUrl);
54
+ }
55
+ catch {
56
+ return 'Enter a valid URL, e.g. http://localhost:11434/v1.';
57
+ }
58
+ if (url.protocol !== 'http:' && url.protocol !== 'https:') {
59
+ return 'A runner URL must use http or https.';
60
+ }
61
+ if (!isLoopbackOrPrivateHost(url.hostname)) {
62
+ return ('A local runner must live on your own machine or LAN (localhost, *.local, or a ' +
63
+ 'private 10./172.16–31./192.168. address). Public or remote hosts are not allowed.');
64
+ }
65
+ return null;
66
+ }
67
+ //# sourceMappingURL=localModelUrl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localModelUrl.js","sourceRoot":"","sources":["../../../src/modules/providers/localModelUrl.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,kFAAkF;AAClF,qFAAqF;AACrF,qFAAqF;AACrF,kFAAkF;AAClF,mFAAmF;AACnF,qFAAqF;AACrF,8EAA8E;AAC9E,kFAAkF;AAClF,oFAAoF;AACpF,uBAAuB;AACvB,8EAA8E;AAE9E,MAAM,IAAI,GAAG,8CAA8C,CAAA;AAE3D,4FAA4F;AAC5F,SAAS,uBAAuB,CAAC,IAAY;IAC3C,MAAM,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAClE,IAAI,CAAC,KAAK,WAAW,IAAI,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC;QAAE,OAAO,IAAI,CAAA;IAC9D,sFAAsF;IACtF,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAA;IACrC,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACvB,IAAI,EAAE,EAAE,CAAC;QACP,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAC7C,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,GAAG,CAAC;YAAE,OAAO,KAAK,CAAA;QAC3E,IAAI,CAAC,KAAK,GAAG;YAAE,OAAO,IAAI,CAAA,CAAC,uBAAuB;QAClD,IAAI,CAAC,KAAK,EAAE;YAAE,OAAO,IAAI,CAAA,CAAC,qBAAqB;QAC/C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;YAAE,OAAO,IAAI,CAAA,CAAC,wBAAwB;QACzE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG;YAAE,OAAO,IAAI,CAAA,CAAC,yBAAyB;QACjE,OAAO,KAAK,CAAA,CAAC,qEAAqE;IACpF,CAAC;IACD,oDAAoD;IACpD,IAAI,CAAC,KAAK,KAAK;QAAE,OAAO,IAAI,CAAA,CAAC,WAAW;IACxC,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA,CAAC,eAAe;IACzE,2EAA2E;IAC3E,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAChD,IAAI,GAAQ,CAAA;IACZ,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAA;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,oDAAoD,CAAA;IAC7D,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1D,OAAO,sCAAsC,CAAA;IAC/C,CAAC;IACD,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3C,OAAO,CACL,gFAAgF;YAChF,mFAAmF,CACpF,CAAA;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * The fields the rotation policy needs from a pool row. Both
3
+ * `ProviderSubscriptionTokenRecord` and `ProviderApiKeyRecord` satisfy this, so
4
+ * `chooseToken` rotates either pool without duplication.
5
+ */
6
+ export interface PoolRotationRecord {
7
+ inputTokens: number;
8
+ outputTokens: number;
9
+ windowStartedAt: number | null;
10
+ lastUsedAt: number | null;
11
+ createdAt: number;
12
+ }
13
+ /** Default rolling usage window (~5h) — mirrors subscription quota windows. */
14
+ export declare const DEFAULT_USAGE_WINDOW_MS: number;
15
+ /** Effective window usage for a row: counters reset once the window ages out. */
16
+ export declare function windowUsage(record: PoolRotationRecord, now: number, windowMs: number): number;
17
+ /**
18
+ * Choose the next row to lease from a non-empty list of live pool rows.
19
+ * Least window usage wins; ties break by least-recently-leased (nulls first =
20
+ * never leased), then oldest created. Returns null only for an empty list.
21
+ */
22
+ export declare function chooseToken<T extends PoolRotationRecord>(records: T[], now: number, windowMs: number): T | null;
23
+ //# sourceMappingURL=providers.logic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.logic.d.ts","sourceRoot":"","sources":["../../../src/modules/providers/providers.logic.ts"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,+EAA+E;AAC/E,eAAO,MAAM,uBAAuB,QAAqB,CAAA;AAEzD,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,MAAM,EAAE,kBAAkB,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG7F;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,kBAAkB,EACtD,OAAO,EAAE,CAAC,EAAE,EACZ,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,GACf,CAAC,GAAG,IAAI,CAWV"}
@@ -0,0 +1,46 @@
1
+ // Pure rotation logic for usage-aware credential pools (subscription tokens AND
2
+ // direct-provider API keys), kept separate from the services so it can be
3
+ // unit-tested without a repository. The policy is usage-aware: prefer the row
4
+ // that has consumed the fewest tokens in the current rolling window, falling back
5
+ // to least-recently-leased (round-robin) and then oldest-created for ties and
6
+ // cold-start rows.
7
+ /** Default rolling usage window (~5h) — mirrors subscription quota windows. */
8
+ export const DEFAULT_USAGE_WINDOW_MS = 5 * 60 * 60 * 1000;
9
+ /** Effective window usage for a row: counters reset once the window ages out. */
10
+ export function windowUsage(record, now, windowMs) {
11
+ if (record.windowStartedAt == null || now - record.windowStartedAt >= windowMs)
12
+ return 0;
13
+ return record.inputTokens + record.outputTokens;
14
+ }
15
+ /**
16
+ * Choose the next row to lease from a non-empty list of live pool rows.
17
+ * Least window usage wins; ties break by least-recently-leased (nulls first =
18
+ * never leased), then oldest created. Returns null only for an empty list.
19
+ */
20
+ export function chooseToken(records, now, windowMs) {
21
+ let best = null;
22
+ let bestUsage = Number.POSITIVE_INFINITY;
23
+ for (const record of records) {
24
+ const usage = windowUsage(record, now, windowMs);
25
+ if (best === null || usage < bestUsage || (usage === bestUsage && isFresher(record, best))) {
26
+ best = record;
27
+ bestUsage = usage;
28
+ }
29
+ }
30
+ return best;
31
+ }
32
+ // Tiebreak: a row never leased (lastUsedAt null) is preferred; otherwise the
33
+ // one leased longest ago; otherwise the one created first.
34
+ function isFresher(candidate, current) {
35
+ const a = candidate.lastUsedAt;
36
+ const b = current.lastUsedAt;
37
+ if (a !== b) {
38
+ if (a == null)
39
+ return true;
40
+ if (b == null)
41
+ return false;
42
+ return a < b;
43
+ }
44
+ return candidate.createdAt < current.createdAt;
45
+ }
46
+ //# sourceMappingURL=providers.logic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.logic.js","sourceRoot":"","sources":["../../../src/modules/providers/providers.logic.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,0EAA0E;AAC1E,8EAA8E;AAC9E,kFAAkF;AAClF,8EAA8E;AAC9E,mBAAmB;AAenB,+EAA+E;AAC/E,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;AAEzD,iFAAiF;AACjF,MAAM,UAAU,WAAW,CAAC,MAA0B,EAAE,GAAW,EAAE,QAAgB;IACnF,IAAI,MAAM,CAAC,eAAe,IAAI,IAAI,IAAI,GAAG,GAAG,MAAM,CAAC,eAAe,IAAI,QAAQ;QAAE,OAAO,CAAC,CAAA;IACxF,OAAO,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,YAAY,CAAA;AACjD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CACzB,OAAY,EACZ,GAAW,EACX,QAAgB;IAEhB,IAAI,IAAI,GAAa,IAAI,CAAA;IACzB,IAAI,SAAS,GAAG,MAAM,CAAC,iBAAiB,CAAA;IACxC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,WAAW,CAAC,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAA;QAChD,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK,GAAG,SAAS,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;YAC3F,IAAI,GAAG,MAAM,CAAA;YACb,SAAS,GAAG,KAAK,CAAA;QACnB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,6EAA6E;AAC7E,2DAA2D;AAC3D,SAAS,SAAS,CAAC,SAA6B,EAAE,OAA2B;IAC3E,MAAM,CAAC,GAAG,SAAS,CAAC,UAAU,CAAA;IAC9B,MAAM,CAAC,GAAG,OAAO,CAAC,UAAU,CAAA;IAC5B,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACZ,IAAI,CAAC,IAAI,IAAI;YAAE,OAAO,IAAI,CAAA;QAC1B,IAAI,CAAC,IAAI,IAAI;YAAE,OAAO,KAAK,CAAA;QAC3B,OAAO,CAAC,GAAG,CAAC,CAAA;IACd,CAAC;IACD,OAAO,SAAS,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAA;AAChD,CAAC"}
@@ -0,0 +1,51 @@
1
+ import type { RunnerDispatchRequest, RunnerJobView, RunnerPollRequest, RunnerPoolProvider, UrlSafetyPolicy } from '@cat-factory/kernel';
2
+ /** Carries the HTTP status so callers can surface a meaningful (redacted) error. */
3
+ export declare class RunnerPoolApiError extends Error {
4
+ readonly status: number;
5
+ constructor(status: number, message: string);
6
+ }
7
+ export interface HttpRunnerPoolProviderOptions {
8
+ defaultTimeoutMs?: number;
9
+ /** URL/host safety policy; defaults to strict (https-only, no private hosts). */
10
+ urlPolicy?: UrlSafetyPolicy;
11
+ }
12
+ export declare class HttpRunnerPoolProvider implements RunnerPoolProvider {
13
+ private readonly defaultTimeoutMs;
14
+ private readonly urlPolicy;
15
+ /** Per-isolate OAuth token cache, keyed by token URL + client id. */
16
+ private readonly oauthCache;
17
+ constructor(options?: HttpRunnerPoolProviderOptions);
18
+ dispatch(req: RunnerDispatchRequest): Promise<void>;
19
+ poll(req: RunnerPollRequest): Promise<RunnerJobView>;
20
+ release(req: RunnerPollRequest): Promise<void>;
21
+ /**
22
+ * The bounded interpolation scope a template sees:
23
+ * - `{{input.jobId}}` — the id the pool is keyed on (sticky routing target);
24
+ * - `{{input.job}}` — the full harness job spec as JSON, so a body template can
25
+ * forward it verbatim (`{"payload":{{input.job}}}`);
26
+ * - `{{input.kind}}` — the harness job kind (`run` | `blueprint` | `spec` |
27
+ * `explore` | `bootstrap` | `ci-fix` | `resolve-conflicts` |
28
+ * `merge` | `on-call` | `test` | `fix-tests`). The harness
29
+ * itself reads the kind from the job body (`POST /jobs`), so
30
+ * a manifest does NOT need to route by kind; this is exposed
31
+ * flat only so a manifest can map it to a scheduler-side
32
+ * node selector / queue / resource hint without decoding the
33
+ * embedded `{{input.job}}` JSON;
34
+ * - `{{input.instanceType}}` / `{{input.cloudProvider}}` — the provisioning hints
35
+ * the transport stamped on for a self-provisioning pool
36
+ * (present only when the service pins a size/provider), so a
37
+ * manifest can map them to a node selector / resource request
38
+ * / queue without decoding `{{input.job}}`.
39
+ * Reuses the environments interpolation machinery; the second (`provision`)
40
+ * namespace is unused by runner manifests.
41
+ */
42
+ private scope;
43
+ private execute;
44
+ private buildUrl;
45
+ private authHeaders;
46
+ private oauthToken;
47
+ /** Project the scheduler's arbitrary status response onto the canonical view. */
48
+ private mapJobView;
49
+ private mapProgress;
50
+ }
51
+ //# sourceMappingURL=HttpRunnerPoolProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HttpRunnerPoolProvider.d.ts","sourceRoot":"","sources":["../../../src/modules/runners/HttpRunnerPoolProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EAErB,aAAa,EACb,iBAAiB,EAGjB,kBAAkB,EAGlB,eAAe,EAChB,MAAM,qBAAqB,CAAA;AA0B5B,oFAAoF;AACpF,qBAAa,kBAAmB,SAAQ,KAAK;IAEzC,QAAQ,CAAC,MAAM,EAAE,MAAM;IADzB,YACW,MAAM,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,EAIhB;CACF;AAED,MAAM,WAAW,6BAA6B;IAC5C,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,iFAAiF;IACjF,SAAS,CAAC,EAAE,eAAe,CAAA;CAC5B;AAED,qBAAa,sBAAuB,YAAW,kBAAkB;IAC/D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAQ;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;IAC3C,qEAAqE;IACrE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA0D;IAErF,YAAY,OAAO,GAAE,6BAAkC,EAGtD;IAEK,QAAQ,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAOxD;IAEK,IAAI,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,aAAa,CAAC,CAQzD;IAEK,OAAO,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAGnD;IAID;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,OAAO,CAAC,KAAK;YAmBC,OAAO;IAiDrB,OAAO,CAAC,QAAQ;YAoBF,WAAW;YAgCX,UAAU;IA+CxB,iFAAiF;IACjF,OAAO,CAAC,UAAU;IA4ClB,OAAO,CAAC,WAAW;CAiBpB"}