@buildinternet/releases-api-types 0.59.0 → 0.60.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 (126) hide show
  1. package/README.md +14 -6
  2. package/dist/api-types.d.ts +1168 -0
  3. package/dist/api-types.d.ts.map +1 -0
  4. package/dist/api-types.js +134 -0
  5. package/dist/schemas/account-profile.d.ts +29 -0
  6. package/dist/schemas/account-profile.d.ts.map +1 -0
  7. package/dist/schemas/account-profile.js +24 -0
  8. package/dist/schemas/ai-models.d.ts +67 -0
  9. package/dist/schemas/ai-models.d.ts.map +1 -0
  10. package/{src/schemas/ai-models.ts → dist/schemas/ai-models.js} +25 -31
  11. package/dist/schemas/api-keys.d.ts +71 -0
  12. package/dist/schemas/api-keys.d.ts.map +1 -0
  13. package/dist/schemas/api-keys.js +32 -0
  14. package/dist/schemas/classifications.d.ts +134 -0
  15. package/dist/schemas/classifications.d.ts.map +1 -0
  16. package/dist/schemas/classifications.js +96 -0
  17. package/dist/schemas/collections.d.ts +605 -0
  18. package/dist/schemas/collections.d.ts.map +1 -0
  19. package/dist/schemas/collections.js +320 -0
  20. package/dist/schemas/datasets.d.ts +34 -0
  21. package/dist/schemas/datasets.d.ts.map +1 -0
  22. package/dist/schemas/datasets.js +11 -0
  23. package/dist/schemas/errors.d.ts +43 -0
  24. package/dist/schemas/errors.d.ts.map +1 -0
  25. package/dist/schemas/errors.js +61 -0
  26. package/dist/schemas/feedback.d.ts +134 -0
  27. package/dist/schemas/feedback.d.ts.map +1 -0
  28. package/dist/schemas/feedback.js +76 -0
  29. package/dist/schemas/follows.d.ts +154 -0
  30. package/dist/schemas/follows.d.ts.map +1 -0
  31. package/dist/schemas/follows.js +42 -0
  32. package/dist/schemas/listing.d.ts +374 -0
  33. package/dist/schemas/listing.d.ts.map +1 -0
  34. package/dist/schemas/listing.js +175 -0
  35. package/dist/schemas/lookups.d.ts +285 -0
  36. package/dist/schemas/lookups.d.ts.map +1 -0
  37. package/{src/schemas/lookups.ts → dist/schemas/lookups.js} +67 -80
  38. package/dist/schemas/marketing-classifier.d.ts +32 -0
  39. package/dist/schemas/marketing-classifier.d.ts.map +1 -0
  40. package/{src/schemas/marketing-classifier.ts → dist/schemas/marketing-classifier.js} +14 -18
  41. package/dist/schemas/orgs.d.ts +950 -0
  42. package/dist/schemas/orgs.d.ts.map +1 -0
  43. package/dist/schemas/orgs.js +473 -0
  44. package/dist/schemas/overviews.d.ts +205 -0
  45. package/dist/schemas/overviews.d.ts.map +1 -0
  46. package/{src/schemas/overviews.ts → dist/schemas/overviews.js} +41 -54
  47. package/dist/schemas/products.d.ts +595 -0
  48. package/dist/schemas/products.d.ts.map +1 -0
  49. package/{src/schemas/products.ts → dist/schemas/products.js} +113 -136
  50. package/dist/schemas/publish-tokens.d.ts +55 -0
  51. package/dist/schemas/publish-tokens.d.ts.map +1 -0
  52. package/{src/schemas/publish-tokens.ts → dist/schemas/publish-tokens.js} +18 -29
  53. package/dist/schemas/recommendations.d.ts +52 -0
  54. package/dist/schemas/recommendations.d.ts.map +1 -0
  55. package/dist/schemas/recommendations.js +58 -0
  56. package/dist/schemas/related.d.ts +331 -0
  57. package/dist/schemas/related.d.ts.map +1 -0
  58. package/dist/schemas/related.js +115 -0
  59. package/dist/schemas/releases.d.ts +623 -0
  60. package/dist/schemas/releases.d.ts.map +1 -0
  61. package/dist/schemas/releases.js +414 -0
  62. package/dist/schemas/resolve.d.ts +259 -0
  63. package/dist/schemas/resolve.d.ts.map +1 -0
  64. package/{src/schemas/resolve.ts → dist/schemas/resolve.js} +2 -5
  65. package/dist/schemas/search.d.ts +475 -0
  66. package/dist/schemas/search.d.ts.map +1 -0
  67. package/dist/schemas/search.js +258 -0
  68. package/dist/schemas/semantic-alert-summary.d.ts +54 -0
  69. package/dist/schemas/semantic-alert-summary.d.ts.map +1 -0
  70. package/dist/schemas/semantic-alert-summary.js +57 -0
  71. package/dist/schemas/semantic-alerts.d.ts +41 -0
  72. package/dist/schemas/semantic-alerts.d.ts.map +1 -0
  73. package/dist/schemas/semantic-alerts.js +42 -0
  74. package/dist/schemas/shared.d.ts +247 -0
  75. package/dist/schemas/shared.d.ts.map +1 -0
  76. package/dist/schemas/shared.js +248 -0
  77. package/dist/schemas/site-notice.d.ts +35 -0
  78. package/dist/schemas/site-notice.d.ts.map +1 -0
  79. package/{src/schemas/site-notice.ts → dist/schemas/site-notice.js} +14 -18
  80. package/dist/schemas/sitemap.d.ts +97 -0
  81. package/dist/schemas/sitemap.d.ts.map +1 -0
  82. package/dist/schemas/sitemap.js +107 -0
  83. package/dist/schemas/sources.d.ts +1145 -0
  84. package/dist/schemas/sources.d.ts.map +1 -0
  85. package/dist/schemas/sources.js +645 -0
  86. package/dist/schemas/stats.d.ts +82 -0
  87. package/dist/schemas/stats.d.ts.map +1 -0
  88. package/dist/schemas/stats.js +59 -0
  89. package/dist/schemas/taxonomy.d.ts +344 -0
  90. package/dist/schemas/taxonomy.d.ts.map +1 -0
  91. package/{src/schemas/taxonomy.ts → dist/schemas/taxonomy.js} +47 -58
  92. package/dist/schemas/webhooks.d.ts +618 -0
  93. package/dist/schemas/webhooks.d.ts.map +1 -0
  94. package/dist/schemas/webhooks.js +191 -0
  95. package/dist/schemas/well-known.d.ts +302 -0
  96. package/dist/schemas/well-known.d.ts.map +1 -0
  97. package/dist/schemas/well-known.js +192 -0
  98. package/dist/schemas/workspace-integrations.d.ts +27 -0
  99. package/dist/schemas/workspace-integrations.d.ts.map +1 -0
  100. package/dist/schemas/workspace-integrations.js +22 -0
  101. package/package.json +16 -5
  102. package/src/api-types.ts +0 -2229
  103. package/src/schemas/account-profile.ts +0 -28
  104. package/src/schemas/ai-models.test.ts +0 -29
  105. package/src/schemas/classifications.ts +0 -109
  106. package/src/schemas/collections.ts +0 -346
  107. package/src/schemas/datasets.ts +0 -31
  108. package/src/schemas/errors.test.ts +0 -55
  109. package/src/schemas/errors.ts +0 -81
  110. package/src/schemas/feedback.ts +0 -56
  111. package/src/schemas/listing.ts +0 -226
  112. package/src/schemas/orgs.ts +0 -533
  113. package/src/schemas/recommendations.ts +0 -39
  114. package/src/schemas/related.ts +0 -126
  115. package/src/schemas/releases.ts +0 -449
  116. package/src/schemas/search.ts +0 -274
  117. package/src/schemas/semantic-alert-summary.ts +0 -65
  118. package/src/schemas/shared.notice.test.ts +0 -36
  119. package/src/schemas/shared.ts +0 -267
  120. package/src/schemas/site-notice.test.ts +0 -67
  121. package/src/schemas/sitemap.ts +0 -117
  122. package/src/schemas/sources.ts +0 -674
  123. package/src/schemas/stats.ts +0 -62
  124. package/src/schemas/well-known.test.ts +0 -264
  125. package/src/schemas/well-known.ts +0 -252
  126. package/src/schemas/workspace-integrations.ts +0 -26
package/src/api-types.ts DELETED
@@ -1,2229 +0,0 @@
1
- /**
2
- * Shared API response types — single source of truth for the wire protocol.
3
- * Consumed by: web frontend, MCP worker, OSS CLI, and the API worker.
4
- */
5
-
6
- import type { z } from "zod";
7
-
8
- export type {
9
- SourceType,
10
- SourceDiscovery,
11
- SourceFetchPriority,
12
- } from "@buildinternet/releases-core/source-enums";
13
- // Re-export above doesn't create local bindings; import for use in interfaces below.
14
- import type { SourceType, SourceFetchPriority } from "@buildinternet/releases-core/source-enums";
15
- import type { ApiScope } from "@buildinternet/releases-core/api-token";
16
- import type { BreakingLevel } from "@buildinternet/releases-core/breaking";
17
- import type {
18
- AiLaneIdSchema,
19
- AiLaneModelsPutSchema,
20
- AiLaneStateSchema,
21
- OpenRouterCatalogModelSchema,
22
- AiLaneModelsResponseSchema,
23
- } from "./schemas/ai-models.js";
24
- import type {
25
- MarketingClassifierThresholdPutSchema,
26
- MarketingFilteredSourceSchema,
27
- MarketingClassifierStateSchema,
28
- } from "./schemas/marketing-classifier.js";
29
- import type {
30
- MediaItemSchema,
31
- PaginationSchema,
32
- StatsSchema,
33
- ReleaseTypeSchema,
34
- ReleaseCompositionSchema,
35
- ReleaseItemSchema,
36
- ReleaseSummaryItemSchema,
37
- OverviewPageItemSchema,
38
- OverviewCitationSchema,
39
- OrgStatusSchema,
40
- ReleaseLocationItemSchema,
41
- } from "./schemas/shared.js";
42
- import type {
43
- OrgListItemSchema,
44
- OrgListResponseSchema,
45
- OrgAccountItemSchema,
46
- OrgAccountsResponseSchema,
47
- OrgTagsResponseSchema,
48
- CreateOrgBodySchema,
49
- UpdateOrgBodySchema,
50
- SetOrgAvatarBodySchema,
51
- SetOrgAvatarResponseSchema,
52
- OrgDetailSchema,
53
- OrgCatalogItemSchema,
54
- OrgCatalogResponseSchema,
55
- OrgCollectionsResponseSchema,
56
- AddOrgAccountBodySchema,
57
- IgnoredUrlItemSchema,
58
- OrgIgnoredUrlsResponseSchema,
59
- AddIgnoredUrlBodySchema,
60
- AddIgnoredUrlResponseSchema,
61
- DeleteIgnoredUrlResponseSchema,
62
- OrgTagsBodySchema,
63
- OrgTagsMutationResponseSchema,
64
- CreateTagBodySchema,
65
- TagRowSchema,
66
- OrgActivityResponseSchema,
67
- OrgHeatmapResponseSchema,
68
- OrgSparklinesResponseSchema,
69
- OrgReleaseItemSchema,
70
- OrgFeedPaginationSchema,
71
- OrgReleasesFeedResponseSchema,
72
- OrgRecentReleaseItemSchema,
73
- OrgRecentReleasesResponseSchema,
74
- DeleteOrgAccountResponseSchema,
75
- } from "./schemas/orgs.js";
76
- import type {
77
- UploadAvatarResponseSchema,
78
- WorkspaceProfileFieldsSchema,
79
- PatchWorkspaceProfileBodySchema,
80
- WorkspaceProfileResponseSchema,
81
- } from "./schemas/account-profile.js";
82
- import type {
83
- UploadsIntegrationStatusSchema,
84
- UploadsOAuthConnectResponseSchema,
85
- UploadsOAuthCallbackBodySchema,
86
- UploadsOAuthCallbackResponseSchema,
87
- } from "./schemas/workspace-integrations.js";
88
- import type {
89
- SourceListItemSchema,
90
- SourceWithOrgSchema,
91
- SourceListResponseSchema,
92
- SourceListResultSchema,
93
- SourceDetailSchema,
94
- SourceFeedPaginationSchema,
95
- SourceMutationResponseSchema,
96
- AppStoreMaterializeResponseSchema,
97
- SourceOrgRefSchema,
98
- SourcePatchInputSchema,
99
- CreateSourceBodySchema,
100
- ChangelogFileSummarySchema,
101
- SourceChangelogResponseSchema,
102
- SourceActivityResponseSchema,
103
- SourceHeatmapResponseSchema,
104
- SourceKnownReleaseItemSchema,
105
- SourceKnownReleasesResponseSchema,
106
- SourceRecentReleasesResponseSchema,
107
- SourceSessionsResponseSchema,
108
- SourceSummaryRowSchema,
109
- SourceSummariesResponseSchema,
110
- CreateSourceSummaryBodySchema,
111
- CreateSourceSummaryResponseSchema,
112
- SourceFetchResponseSchema,
113
- SourceContentHashResponseSchema,
114
- SourceContentHashBodySchema,
115
- ChangelogTokensResponseSchema,
116
- SourceMetadataResponseSchema,
117
- ChangelogProbeResponseSchema,
118
- DeleteSourceResponseSchema,
119
- DeleteSourceReleasesResponseSchema,
120
- InsertReleaseResponseSchema,
121
- BatchReleasesResponseSchema,
122
- RawSnapshotResponseSchema,
123
- OversizedChangelogFileRowSchema,
124
- OversizedChangelogFilesResponseSchema,
125
- FetchableSourcesResponseSchema,
126
- FeedSourcesResponseSchema,
127
- ChangedSourcesResponseSchema,
128
- } from "./schemas/sources.js";
129
- import type {
130
- ProductRowSchema,
131
- ProductCreateResponseSchema,
132
- ProductListItemSchema,
133
- ProductListResponseSchema,
134
- ProductDetailSourceSchema,
135
- ProductDetailSchema,
136
- CreateProductBodySchema,
137
- UpdateProductBodySchema,
138
- AdoptProductBodySchema,
139
- ProductAdoptResultSchema,
140
- ProductAdoptDryRunSchema,
141
- ProductAdoptResponseSchema,
142
- ProductDeleteResponseSchema,
143
- ProductTagsListResponseSchema,
144
- ProductTagsBodySchema,
145
- ProductTagsMutationResponseSchema,
146
- ProductActivityResponseSchema,
147
- ProductHeatmapResponseSchema,
148
- } from "./schemas/products.js";
149
- import type {
150
- ReleaseLatestSourceSchema,
151
- ReleaseLatestProductSchema,
152
- ReleaseLatestItemSchema,
153
- ReleaseLatestResponseSchema,
154
- ReleaseCoverageSiblingSchema,
155
- ReleaseCoverageRowSchema,
156
- ReleaseCoverageResponseSchema,
157
- LinkReleaseCoverageBodySchema,
158
- LinkReleaseCoverageResponseSchema,
159
- UnlinkReleaseCoverageResponseSchema,
160
- ReleaseWithMediaRowSchema,
161
- ReleasesWithMediaResponseSchema,
162
- ReleaseDetailOrgSchema,
163
- ReleaseDetailResponseSchema,
164
- ReleaseUrlConflictDetailsSchema,
165
- UpdateReleaseBodySchema,
166
- ReleasePatchResponseSchema,
167
- ReleaseDeleteResponseSchema,
168
- ReleaseBatchDeleteBodySchema,
169
- ReleaseBatchDeleteResponseSchema,
170
- ReleaseSuppressResponseSchema,
171
- ReleaseUnsuppressResponseSchema,
172
- ReleaseSuppressBodySchema,
173
- ReleaseBatchSuppressBodySchema,
174
- ReleaseBatchSuppressResponseSchema,
175
- ReleaseStreamMessageSchema,
176
- } from "./schemas/releases.js";
177
- import type {
178
- LookupStatusSchema,
179
- LookupBodySchema,
180
- LookupSourceSchema,
181
- LookupReleaseSchema,
182
- LookupRelatedOrgSchema,
183
- LookupResponseSchema,
184
- LookupSourceBySlugResponseSchema,
185
- LookupProductBySlugResponseSchema,
186
- DomainLookupOrgSchema,
187
- DomainLookupProductSchema,
188
- DomainLookupResponseSchema,
189
- } from "./schemas/lookups.js";
190
- import type {
191
- SearchOrgHitSchema,
192
- SearchCatalogHitSchema,
193
- SearchSourceHitSchema,
194
- SearchReleaseHitSchema,
195
- SearchChunkHitSchema,
196
- SearchCollectionHitSchema,
197
- LookupResultPayloadSchema,
198
- UnifiedSearchResponseSchema,
199
- } from "./schemas/search.js";
200
- import type {
201
- TaxonomyOrgSchema,
202
- TaxonomyProductSchema,
203
- CategoryListItemSchema,
204
- CategoryListResponseSchema,
205
- CategoryDetailSchema,
206
- UpdateCategoryRequestSchema,
207
- UpdateCategoryResponseSchema,
208
- CategoryFeedPaginationSchema,
209
- CategoryReleasesResponseSchema,
210
- TagDetailSchema,
211
- } from "./schemas/taxonomy.js";
212
- import type {
213
- StatsSourceActivitySchema,
214
- StatsRecentActivitySchema,
215
- StatsResponseSchema,
216
- } from "./schemas/stats.js";
217
- import type {
218
- FeedbackTypeSchema,
219
- FeedbackStatusSchema,
220
- FeedbackItemSchema,
221
- FeedbackListResponseSchema,
222
- FeedbackUpdateBodySchema,
223
- FeedbackDeleteResponseSchema,
224
- } from "./schemas/feedback.js";
225
- import type {
226
- ClassificationSummarySchema,
227
- ClassificationRecentResponseSchema,
228
- ClassificationRecentItemSchema,
229
- } from "./schemas/classifications.js";
230
- import type { SemanticAlertSummarySchema } from "./schemas/semantic-alert-summary.js";
231
- import type {
232
- RecommendationNotifyAddedBodySchema,
233
- RecommendationNotifyAddedResultSchema,
234
- } from "./schemas/recommendations.js";
235
- import type {
236
- SitemapSourceSchema,
237
- SitemapPayloadSchema,
238
- SitemapReleaseSchema,
239
- SitemapReleasesPayloadSchema,
240
- } from "./schemas/sitemap.js";
241
- import type {
242
- RelatedScopeSchema,
243
- RelatedReleaseThumbnailSchema,
244
- RelatedReleaseSourceSchema,
245
- RelatedReleaseItemSchema,
246
- RelatedSourceItemSchema,
247
- RelatedReleasesOkResponseSchema,
248
- RelatedReleasesDegradedResponseSchema,
249
- RelatedReleasesResponseSchema,
250
- RelatedSourcesOkResponseSchema,
251
- RelatedSourcesDegradedResponseSchema,
252
- RelatedSourcesResponseSchema,
253
- } from "./schemas/related.js";
254
- import type {
255
- CollectionMemberOrgSchema,
256
- ProductParentOrgSchema,
257
- CollectionMemberProductSchema,
258
- CollectionMemberSchema,
259
- CollectionListItemSchema,
260
- CollectionListResponseSchema,
261
- CollectionDetailSchema,
262
- CollectionReleaseItemSchema,
263
- CollectionFeedPaginationSchema,
264
- CollectionReleasesResponseSchema,
265
- CollectionRowSchema,
266
- CreateCollectionRequestSchema,
267
- UpdateCollectionRequestSchema,
268
- CollectionMemberInputSchema,
269
- AddCollectionMemberRequestSchema,
270
- ReplaceCollectionMembersRequestSchema,
271
- ResolvedCollectionMemberSchema,
272
- ReplaceCollectionMembersResponseSchema,
273
- AddCollectionMemberResponseSchema,
274
- CollectionDailySummarySchema,
275
- CollectionDailySummariesResponseSchema,
276
- CollectionWeeklyDigestListItemSchema,
277
- CollectionWeeklyDigestsResponseSchema,
278
- DigestCoveredReleaseSchema,
279
- DigestSectionSchema,
280
- CollectionWeeklyDigestDetailSchema,
281
- } from "./schemas/collections.js";
282
- import type {
283
- OrgOverviewResponseSchema,
284
- IncomingOverviewCitationSchema,
285
- RegenerateOverviewBodySchema,
286
- RegenerateOverviewResponseSchema,
287
- ProductOverviewResponseSchema,
288
- OverviewInputsCheckResponseSchema,
289
- OverviewInputsFullResponseSchema,
290
- OverviewInputsResponseSchema,
291
- PlaybookResponseSchema,
292
- UpdatePlaybookNotesBodySchema,
293
- UpdatePlaybookNotesResponseSchema,
294
- } from "./schemas/overviews.js";
295
-
296
- export {
297
- MediaItemSchema,
298
- PaginationSchema,
299
- ListResponseSchema,
300
- StatsSchema,
301
- ReleaseTypeSchema,
302
- ReleaseCompositionSchema,
303
- ReleaseItemSchema,
304
- ReleaseSummaryItemSchema,
305
- OverviewPageItemSchema,
306
- OverviewCitationSchema,
307
- OrgStatusSchema,
308
- ReleaseLocationItemSchema,
309
- CategorySchema,
310
- NoticeSchema,
311
- } from "./schemas/shared.js";
312
- export { SiteNoticeSchema, SiteNoticeResponseSchema } from "./schemas/site-notice.js";
313
- export {
314
- AiLaneIdSchema,
315
- AiLaneModelsPutSchema,
316
- AiLaneStateSchema,
317
- OpenRouterCatalogModelSchema,
318
- AiLaneModelsResponseSchema,
319
- } from "./schemas/ai-models.js";
320
- export {
321
- MarketingClassifierThresholdPutSchema,
322
- MarketingFilteredSourceSchema,
323
- MarketingClassifierStateSchema,
324
- MARKETING_THRESHOLD_MIN,
325
- MARKETING_THRESHOLD_MAX,
326
- } from "./schemas/marketing-classifier.js";
327
- export {
328
- OrgListItemSchema,
329
- OrgListResponseSchema,
330
- OrgAccountItemSchema,
331
- OrgAccountsResponseSchema,
332
- OrgTagsResponseSchema,
333
- CreateOrgBodySchema,
334
- UpdateOrgBodySchema,
335
- SetOrgAvatarBodySchema,
336
- SetOrgAvatarResponseSchema,
337
- OrgDetailSchema,
338
- OrgCatalogItemSchema,
339
- OrgCatalogResponseSchema,
340
- OrgCollectionsResponseSchema,
341
- AddOrgAccountBodySchema,
342
- IgnoredUrlItemSchema,
343
- OrgIgnoredUrlsResponseSchema,
344
- AddIgnoredUrlBodySchema,
345
- AddIgnoredUrlResponseSchema,
346
- DeleteIgnoredUrlResponseSchema,
347
- OrgTagsBodySchema,
348
- OrgTagsMutationResponseSchema,
349
- CreateTagBodySchema,
350
- TagRowSchema,
351
- OrgActivityResponseSchema,
352
- OrgHeatmapResponseSchema,
353
- OrgSparklinesResponseSchema,
354
- OrgReleaseItemSchema,
355
- OrgFeedPaginationSchema,
356
- OrgReleasesFeedResponseSchema,
357
- OrgRecentReleaseItemSchema,
358
- OrgRecentReleasesResponseSchema,
359
- DeleteOrgAccountResponseSchema,
360
- } from "./schemas/orgs.js";
361
- export {
362
- UploadAvatarResponseSchema,
363
- WorkspaceProfileFieldsSchema,
364
- PatchWorkspaceProfileBodySchema,
365
- WorkspaceProfileResponseSchema,
366
- } from "./schemas/account-profile.js";
367
- export {
368
- UploadsIntegrationStatusSchema,
369
- UploadsOAuthConnectResponseSchema,
370
- UploadsOAuthCallbackBodySchema,
371
- UploadsOAuthCallbackResponseSchema,
372
- } from "./schemas/workspace-integrations.js";
373
- export {
374
- CreateStubOrgBodySchema,
375
- StubFromDomainBodySchema,
376
- ReleasesJsonConfigSchema,
377
- ReleasesJsonDomainReleaseSchema,
378
- ReleasesJsonDomainSchema,
379
- ReleasesJsonProductSchema,
380
- ReleasesJsonRegistriesSchema,
381
- ReleasesJsonRepoProductSchema,
382
- ReleasesJsonRepoReleaseSchema,
383
- ReleasesJsonRepoSchema,
384
- SyncWellKnownResponseSchema,
385
- } from "./schemas/well-known.js";
386
- export type {
387
- CreateStubOrgBody,
388
- StubFromDomainBody,
389
- ReleasesJsonConfig,
390
- ReleasesJsonDomain,
391
- ReleasesJsonDomainRelease,
392
- ReleasesJsonProduct,
393
- ReleasesJsonRepo,
394
- ReleasesJsonRepoRelease,
395
- } from "./schemas/well-known.js";
396
- export {
397
- ListingValidateBodySchema,
398
- ListingActivateBodySchema,
399
- ListingIssueSchema,
400
- ListingSetupStepSchema,
401
- ListingLocationSchema,
402
- ListingOrgPointerSchema,
403
- ListingValidationResultSchema,
404
- ListingActivateResultSchema,
405
- ListingClaimBodySchema,
406
- ListingClaimVerifyBodySchema,
407
- OrgClaimStatusSchema,
408
- ClaimMethodSchema,
409
- OrgClaimSchema,
410
- ClaimCheckOutcomeSchema,
411
- ClaimVerifyResultSchema,
412
- ListingClaimsResultSchema,
413
- AdminOrgClaimSchema,
414
- ListOrgClaimsResponseSchema,
415
- RevokeOrgClaimBodySchema,
416
- ListingPromoteBodySchema,
417
- ListingPromoteLocatorOutcomeSchema,
418
- ListingPromoteLocatorSchema,
419
- ListingPromoteResultSchema,
420
- ListingCapabilitiesSchema,
421
- type ListingValidateBody,
422
- type ListingActivateBody,
423
- type ListingIssue,
424
- type ListingSetupStep,
425
- type ListingLocation,
426
- type ListingValidationResult,
427
- type ListingActivateResult,
428
- type ListingClaimBody,
429
- type ListingClaimVerifyBody,
430
- type OrgClaimStatus,
431
- type ClaimMethod,
432
- type OrgClaim,
433
- type ClaimCheckOutcome,
434
- type ClaimVerifyResult,
435
- type ListingClaimsResult,
436
- type AdminOrgClaim,
437
- type ListOrgClaimsResponse,
438
- type RevokeOrgClaimBody,
439
- type ListingPromoteBody,
440
- type ListingPromoteLocatorOutcome,
441
- type ListingPromoteLocator,
442
- type ListingPromoteResult,
443
- type ListingCapabilities,
444
- } from "./schemas/listing.js";
445
- export {
446
- CreatePublishTokenBodySchema,
447
- CreatedPublishTokenSchema,
448
- PublishTokenSchema,
449
- ListPublishTokensResponseSchema,
450
- RevokePublishTokenResponseSchema,
451
- type CreatePublishTokenBody,
452
- type CreatedPublishToken,
453
- type PublishToken,
454
- type ListPublishTokensResponse,
455
- type RevokePublishTokenResponse,
456
- } from "./schemas/publish-tokens.js";
457
- export {
458
- SourceListItemSchema,
459
- SourceWithOrgSchema,
460
- SourceListResponseSchema,
461
- SourceListResultSchema,
462
- SourceDetailSchema,
463
- SourceFeedPaginationSchema,
464
- SourceMutationResponseSchema,
465
- AppStoreMaterializeResponseSchema,
466
- SourceOrgRefSchema,
467
- SourcePatchInputSchema,
468
- CreateSourceBodySchema,
469
- ChangelogFileSummarySchema,
470
- SourceChangelogResponseSchema,
471
- SourceActivityResponseSchema,
472
- SourceHeatmapResponseSchema,
473
- SourceKnownReleaseItemSchema,
474
- SourceKnownReleasesResponseSchema,
475
- SourceRecentReleasesResponseSchema,
476
- SourceSessionsResponseSchema,
477
- SourceSummaryRowSchema,
478
- SourceSummariesResponseSchema,
479
- CreateSourceSummaryBodySchema,
480
- CreateSourceSummaryResponseSchema,
481
- SourceFetchResponseSchema,
482
- SourceContentHashResponseSchema,
483
- SourceContentHashBodySchema,
484
- ChangelogTokensResponseSchema,
485
- SourceMetadataResponseSchema,
486
- ChangelogProbeResponseSchema,
487
- DeleteSourceResponseSchema,
488
- DeleteSourceReleasesResponseSchema,
489
- InsertReleaseResponseSchema,
490
- BatchReleasesResponseSchema,
491
- RawSnapshotResponseSchema,
492
- OversizedChangelogFileRowSchema,
493
- OversizedChangelogFilesResponseSchema,
494
- FetchableSourcesResponseSchema,
495
- FeedSourcesResponseSchema,
496
- ChangedSourcesResponseSchema,
497
- } from "./schemas/sources.js";
498
- export {
499
- ProductRowSchema,
500
- ProductCreateResponseSchema,
501
- ProductListItemSchema,
502
- ProductListResponseSchema,
503
- ProductDetailSourceSchema,
504
- ProductDetailSchema,
505
- CreateProductBodySchema,
506
- UpdateProductBodySchema,
507
- AdoptProductBodySchema,
508
- ProductAdoptResultSchema,
509
- ProductAdoptDryRunSchema,
510
- ProductAdoptResponseSchema,
511
- ProductDeleteResponseSchema,
512
- ProductTagsListResponseSchema,
513
- ProductTagsBodySchema,
514
- ProductTagsMutationResponseSchema,
515
- ProductActivityResponseSchema,
516
- ProductHeatmapResponseSchema,
517
- } from "./schemas/products.js";
518
- export {
519
- LookupStatusSchema,
520
- LookupBodySchema,
521
- LookupSourceSchema,
522
- LookupReleaseSchema,
523
- LookupRelatedOrgSchema,
524
- LookupResponseSchema,
525
- LookupSourceBySlugResponseSchema,
526
- LookupProductBySlugResponseSchema,
527
- DomainLookupOrgSchema,
528
- DomainLookupProductSchema,
529
- DomainLookupResponseSchema,
530
- } from "./schemas/lookups.js";
531
- export {
532
- TaxonomyOrgSchema,
533
- TaxonomyProductSchema,
534
- CategoryListItemSchema,
535
- CategoryListResponseSchema,
536
- CategoryDetailSchema,
537
- UpdateCategoryRequestSchema,
538
- UpdateCategoryResponseSchema,
539
- CategoryReleaseItemSchema,
540
- CategoryFeedPaginationSchema,
541
- CategoryReleasesResponseSchema,
542
- TagDetailSchema,
543
- } from "./schemas/taxonomy.js";
544
- export {
545
- ReleaseLatestSourceSchema,
546
- ReleaseLatestProductSchema,
547
- ReleaseLatestItemSchema,
548
- ReleaseLatestResponseSchema,
549
- ReleaseCoverageSiblingSchema,
550
- ReleaseCoverageRowSchema,
551
- ReleaseCoverageResponseSchema,
552
- LinkReleaseCoverageBodySchema,
553
- LinkReleaseCoverageResponseSchema,
554
- UnlinkReleaseCoverageResponseSchema,
555
- ReleaseWithMediaRowSchema,
556
- ReleasesWithMediaResponseSchema,
557
- ReleaseDetailOrgSchema,
558
- ReleaseDetailResponseSchema,
559
- ReleaseUrlConflictDetailsSchema,
560
- UpdateReleaseBodySchema,
561
- ReleasePatchResponseSchema,
562
- ReleaseDeleteResponseSchema,
563
- ReleaseBatchDeleteBodySchema,
564
- ReleaseBatchDeleteResponseSchema,
565
- ReleaseSuppressResponseSchema,
566
- ReleaseUnsuppressResponseSchema,
567
- ReleaseSuppressBodySchema,
568
- ReleaseBatchSuppressBodySchema,
569
- ReleaseBatchSuppressResponseSchema,
570
- ReleaseStreamMessageSchema,
571
- } from "./schemas/releases.js";
572
- export {
573
- SearchOrgHitSchema,
574
- SearchCatalogHitSchema,
575
- SearchSourceHitSchema,
576
- SearchReleaseHitSchema,
577
- SearchChunkHitSchema,
578
- SearchCollectionHitSchema,
579
- LookupResultPayloadSchema,
580
- UnifiedSearchResponseSchema,
581
- } from "./schemas/search.js";
582
- export {
583
- StatsSourceActivitySchema,
584
- StatsRecentActivitySchema,
585
- StatsResponseSchema,
586
- } from "./schemas/stats.js";
587
- export {
588
- FeedbackTypeSchema,
589
- FeedbackStatusSchema,
590
- FeedbackItemSchema,
591
- FeedbackListResponseSchema,
592
- FeedbackUpdateBodySchema,
593
- FeedbackDeleteResponseSchema,
594
- } from "./schemas/feedback.js";
595
- export {
596
- ClassificationSummarySchema,
597
- ClassificationRecentResponseSchema,
598
- ClassificationRecentItemSchema,
599
- } from "./schemas/classifications.js";
600
- export { SemanticAlertSummarySchema } from "./schemas/semantic-alert-summary.js";
601
- export {
602
- RecommendationNotifyAddedBodySchema,
603
- RecommendationNotifyAddedResultSchema,
604
- } from "./schemas/recommendations.js";
605
- export {
606
- SitemapSourceSchema,
607
- SitemapPayloadSchema,
608
- SitemapReleaseSchema,
609
- SitemapReleasesPayloadSchema,
610
- } from "./schemas/sitemap.js";
611
- export { errorEnvelopeSchema, decodeApiError, isApiError } from "./schemas/errors.js";
612
- export type { ErrorEnvelope, DecodedApiError } from "./schemas/errors.js";
613
- export {
614
- RelatedScopeSchema,
615
- RelatedReleaseThumbnailSchema,
616
- RelatedReleaseSourceSchema,
617
- RelatedReleaseItemSchema,
618
- RelatedSourceItemSchema,
619
- RelatedReleasesOkResponseSchema,
620
- RelatedReleasesDegradedResponseSchema,
621
- RelatedReleasesResponseSchema,
622
- RelatedSourcesOkResponseSchema,
623
- RelatedSourcesDegradedResponseSchema,
624
- RelatedSourcesResponseSchema,
625
- } from "./schemas/related.js";
626
- export {
627
- CollectionMemberOrgSchema,
628
- ProductParentOrgSchema,
629
- CollectionMemberProductSchema,
630
- CollectionMemberSchema,
631
- CollectionListItemSchema,
632
- CollectionListResponseSchema,
633
- CollectionDetailSchema,
634
- CollectionReleaseItemSchema,
635
- CollectionFeedPaginationSchema,
636
- CollectionReleasesResponseSchema,
637
- CollectionRowSchema,
638
- CreateCollectionRequestSchema,
639
- UpdateCollectionRequestSchema,
640
- CollectionMemberInputSchema,
641
- AddCollectionMemberRequestSchema,
642
- ReplaceCollectionMembersRequestSchema,
643
- ResolvedCollectionMemberSchema,
644
- ReplaceCollectionMembersResponseSchema,
645
- AddCollectionMemberResponseSchema,
646
- CollectionDailySummarySchema,
647
- CollectionDailySummariesResponseSchema,
648
- CollectionWeeklyDigestListItemSchema,
649
- CollectionWeeklyDigestsResponseSchema,
650
- DigestCoveredReleaseSchema,
651
- DigestSectionSchema,
652
- CollectionWeeklyDigestDetailSchema,
653
- } from "./schemas/collections.js";
654
- export {
655
- OrgOverviewResponseSchema,
656
- IncomingOverviewCitationSchema,
657
- RegenerateOverviewBodySchema,
658
- RegenerateOverviewResponseSchema,
659
- ProductOverviewResponseSchema,
660
- OverviewInputsCheckResponseSchema,
661
- OverviewInputsFullResponseSchema,
662
- OverviewInputsResponseSchema,
663
- PlaybookResponseSchema,
664
- UpdatePlaybookNotesBodySchema,
665
- UpdatePlaybookNotesResponseSchema,
666
- } from "./schemas/overviews.js";
667
- export { ResolveResponseSchema } from "./schemas/resolve.js";
668
- export type { ResolveResponse } from "./schemas/resolve.js";
669
-
670
- // ── Media ──
671
-
672
- export type MediaItem = z.infer<typeof MediaItemSchema>;
673
-
674
- export type AiLaneId = z.infer<typeof AiLaneIdSchema>;
675
- export type AiLaneModelsPut = z.infer<typeof AiLaneModelsPutSchema>;
676
- export type AiLaneState = z.infer<typeof AiLaneStateSchema>;
677
- export type OpenRouterCatalogModel = z.infer<typeof OpenRouterCatalogModelSchema>;
678
- export type AiLaneModelsResponse = z.infer<typeof AiLaneModelsResponseSchema>;
679
-
680
- export type MarketingClassifierThresholdPut = z.infer<typeof MarketingClassifierThresholdPutSchema>;
681
- export type MarketingFilteredSource = z.infer<typeof MarketingFilteredSourceSchema>;
682
- export type MarketingClassifierState = z.infer<typeof MarketingClassifierStateSchema>;
683
-
684
- // ── Stub tier (#1947) ──
685
-
686
- export type OrgStatus = z.infer<typeof OrgStatusSchema>;
687
- export type ReleaseLocationItem = z.infer<typeof ReleaseLocationItemSchema>;
688
-
689
- // ── Stats ──
690
-
691
- export type Stats = z.infer<typeof StatsSchema>;
692
-
693
- // ── Pagination ──
694
-
695
- export type Pagination = z.infer<typeof PaginationSchema>;
696
-
697
- export interface ListResponse<T> {
698
- items: T[];
699
- pagination: Pagination;
700
- }
701
-
702
- // === User-owned API keys (relu_) — self-serve surface served by /v1/api-keys ===
703
-
704
- /** A user-owned API key (relu_) as returned by GET /v1/api-keys. */
705
- export interface UserApiKey {
706
- id: string;
707
- name: string | null;
708
- start: string | null;
709
- scope: ApiScope | null;
710
- enabled: boolean | null;
711
- remaining: number | null;
712
- lastRequest: string | null; // ISO 8601
713
- createdAt: string; // ISO 8601
714
- expiresAt: string | null; // ISO 8601
715
- }
716
-
717
- /** POST /v1/api-keys create response — includes the full key string exactly once. */
718
- export interface CreatedUserApiKey extends Omit<UserApiKey, "enabled" | "lastRequest"> {
719
- key: string;
720
- }
721
-
722
- /** GET /v1/api-keys response envelope. */
723
- export interface ListUserApiKeysResponse {
724
- apiKeys: UserApiKey[];
725
- }
726
-
727
- /** POST /v1/api-keys request body. Self-serve mints are capped at read server-side. */
728
- export interface CreateUserApiKeyBody {
729
- name: string;
730
- scope?: ApiScope;
731
- expiresInDays?: number;
732
- }
733
-
734
- // ── Sitemap (bulk URL emission) ──
735
-
736
- export type SitemapSource = z.infer<typeof SitemapSourceSchema>;
737
- export type SitemapPayload = z.infer<typeof SitemapPayloadSchema>;
738
- /** @deprecated The `GET /v1/sitemap/releases` endpoint was retired in #2219. */
739
- export type SitemapRelease = z.infer<typeof SitemapReleaseSchema>;
740
- /** @deprecated The `GET /v1/sitemap/releases` endpoint was retired in #2219. */
741
- export type SitemapReleasesPayload = z.infer<typeof SitemapReleasesPayloadSchema>;
742
-
743
- // ── Related (Vectorize neighbors) ──
744
-
745
- export type RelatedScope = z.infer<typeof RelatedScopeSchema>;
746
- export type RelatedReleaseThumbnail = z.infer<typeof RelatedReleaseThumbnailSchema>;
747
- export type RelatedReleaseSource = z.infer<typeof RelatedReleaseSourceSchema>;
748
- export type RelatedReleaseItem = z.infer<typeof RelatedReleaseItemSchema>;
749
- export type RelatedSourceItem = z.infer<typeof RelatedSourceItemSchema>;
750
- export type RelatedReleasesOkResponse = z.infer<typeof RelatedReleasesOkResponseSchema>;
751
- export type RelatedReleasesDegradedResponse = z.infer<typeof RelatedReleasesDegradedResponseSchema>;
752
- export type RelatedReleasesResponse = z.infer<typeof RelatedReleasesResponseSchema>;
753
- export type RelatedSourcesOkResponse = z.infer<typeof RelatedSourcesOkResponseSchema>;
754
- export type RelatedSourcesDegradedResponse = z.infer<typeof RelatedSourcesDegradedResponseSchema>;
755
- export type RelatedSourcesResponse = z.infer<typeof RelatedSourcesResponseSchema>;
756
-
757
- // ── Organizations ──
758
-
759
- export type OrgListItem = z.infer<typeof OrgListItemSchema>;
760
- export type OrgListResponse = z.infer<typeof OrgListResponseSchema>;
761
- export type OrgAccountItem = z.infer<typeof OrgAccountItemSchema>;
762
- export type OrgAccountsResponse = z.infer<typeof OrgAccountsResponseSchema>;
763
- export type OrgTagsResponse = z.infer<typeof OrgTagsResponseSchema>;
764
- export type CreateOrgBody = z.infer<typeof CreateOrgBodySchema>;
765
- export type UpdateOrgBody = z.infer<typeof UpdateOrgBodySchema>;
766
- export type SetOrgAvatarBody = z.infer<typeof SetOrgAvatarBodySchema>;
767
- export type SetOrgAvatarResponse = z.infer<typeof SetOrgAvatarResponseSchema>;
768
- export type UploadAvatarResponse = z.infer<typeof UploadAvatarResponseSchema>;
769
- export type WorkspaceProfileFields = z.infer<typeof WorkspaceProfileFieldsSchema>;
770
- export type PatchWorkspaceProfileBody = z.infer<typeof PatchWorkspaceProfileBodySchema>;
771
- export type WorkspaceProfileResponse = z.infer<typeof WorkspaceProfileResponseSchema>;
772
- export type UploadsIntegrationStatus = z.infer<typeof UploadsIntegrationStatusSchema>;
773
- export type UploadsOAuthConnectResponse = z.infer<typeof UploadsOAuthConnectResponseSchema>;
774
- export type UploadsOAuthCallbackBody = z.infer<typeof UploadsOAuthCallbackBodySchema>;
775
- export type UploadsOAuthCallbackResponse = z.infer<typeof UploadsOAuthCallbackResponseSchema>;
776
- export type OrgDetail = z.infer<typeof OrgDetailSchema>;
777
-
778
- export type OrgCatalogItem = z.infer<typeof OrgCatalogItemSchema>;
779
- export type OrgCatalogResponse = z.infer<typeof OrgCatalogResponseSchema>;
780
- export type OrgCollectionsResponse = z.infer<typeof OrgCollectionsResponseSchema>;
781
- export type AddOrgAccountBody = z.infer<typeof AddOrgAccountBodySchema>;
782
- export type IgnoredUrlItem = z.infer<typeof IgnoredUrlItemSchema>;
783
- export type OrgIgnoredUrlsResponse = z.infer<typeof OrgIgnoredUrlsResponseSchema>;
784
- export type AddIgnoredUrlBody = z.infer<typeof AddIgnoredUrlBodySchema>;
785
- export type AddIgnoredUrlResponse = z.infer<typeof AddIgnoredUrlResponseSchema>;
786
- export type DeleteIgnoredUrlResponse = z.infer<typeof DeleteIgnoredUrlResponseSchema>;
787
- export type OrgTagsBody = z.infer<typeof OrgTagsBodySchema>;
788
- export type OrgTagsMutationResponse = z.infer<typeof OrgTagsMutationResponseSchema>;
789
- export type CreateTagBody = z.infer<typeof CreateTagBodySchema>;
790
- export type TagRow = z.infer<typeof TagRowSchema>;
791
- export type OrgActivityResponse = z.infer<typeof OrgActivityResponseSchema>;
792
- export type OrgHeatmapResponse = z.infer<typeof OrgHeatmapResponseSchema>;
793
- export type OrgSparklinesResponse = z.infer<typeof OrgSparklinesResponseSchema>;
794
- export type OrgReleaseItem = z.infer<typeof OrgReleaseItemSchema>;
795
- export type OrgFeedPagination = z.infer<typeof OrgFeedPaginationSchema>;
796
- export type OrgReleasesFeedResponse = z.infer<typeof OrgReleasesFeedResponseSchema>;
797
- export type OrgRecentReleaseItem = z.infer<typeof OrgRecentReleaseItemSchema>;
798
- export type OrgRecentReleasesResponse = z.infer<typeof OrgRecentReleasesResponseSchema>;
799
- export type DeleteOrgAccountResponse = z.infer<typeof DeleteOrgAccountResponseSchema>;
800
-
801
- // ── Sources ──
802
-
803
- export type SourceListItem = z.infer<typeof SourceListItemSchema>;
804
- export type SourceWithOrg = z.infer<typeof SourceWithOrgSchema>;
805
- export type SourceListResponse = z.infer<typeof SourceListResponseSchema>;
806
- export type SourceListResult = z.infer<typeof SourceListResultSchema>;
807
- export type SourcePatchInput = z.infer<typeof SourcePatchInputSchema>;
808
- export type CreateSourceBody = z.infer<typeof CreateSourceBodySchema>;
809
- export type ChangelogFileSummary = z.infer<typeof ChangelogFileSummarySchema>;
810
- export type SourceChangelogResponse = z.infer<typeof SourceChangelogResponseSchema>;
811
- export type SourceDetail = z.infer<typeof SourceDetailSchema>;
812
- export type SourceFeedPagination = z.infer<typeof SourceFeedPaginationSchema>;
813
- export type SourceMutationResponse = z.infer<typeof SourceMutationResponseSchema>;
814
- export type AppStoreMaterializeResponse = z.infer<typeof AppStoreMaterializeResponseSchema>;
815
- export type SourceOrgRef = z.infer<typeof SourceOrgRefSchema>;
816
- export type SourceActivityResponse = z.infer<typeof SourceActivityResponseSchema>;
817
- export type SourceHeatmapResponse = z.infer<typeof SourceHeatmapResponseSchema>;
818
- export type SourceKnownReleaseItem = z.infer<typeof SourceKnownReleaseItemSchema>;
819
- export type SourceKnownReleasesResponse = z.infer<typeof SourceKnownReleasesResponseSchema>;
820
- export type SourceRecentReleasesResponse = z.infer<typeof SourceRecentReleasesResponseSchema>;
821
- export type SourceSessionsResponse = z.infer<typeof SourceSessionsResponseSchema>;
822
- export type SourceSummaryRow = z.infer<typeof SourceSummaryRowSchema>;
823
- export type SourceSummariesResponse = z.infer<typeof SourceSummariesResponseSchema>;
824
- export type CreateSourceSummaryBody = z.infer<typeof CreateSourceSummaryBodySchema>;
825
- export type CreateSourceSummaryResponse = z.infer<typeof CreateSourceSummaryResponseSchema>;
826
- export type SourceFetchResponse = z.infer<typeof SourceFetchResponseSchema>;
827
- export type SourceContentHashResponse = z.infer<typeof SourceContentHashResponseSchema>;
828
- export type SourceContentHashBody = z.infer<typeof SourceContentHashBodySchema>;
829
- export type ChangelogTokensResponse = z.infer<typeof ChangelogTokensResponseSchema>;
830
- export type SourceMetadataResponse = z.infer<typeof SourceMetadataResponseSchema>;
831
- export type ChangelogProbeResponse = z.infer<typeof ChangelogProbeResponseSchema>;
832
- export type DeleteSourceResponse = z.infer<typeof DeleteSourceResponseSchema>;
833
- export type DeleteSourceReleasesResponse = z.infer<typeof DeleteSourceReleasesResponseSchema>;
834
- export type InsertReleaseResponse = z.infer<typeof InsertReleaseResponseSchema>;
835
- export type BatchReleasesResponse = z.infer<typeof BatchReleasesResponseSchema>;
836
- export type RawSnapshotResponse = z.infer<typeof RawSnapshotResponseSchema>;
837
- export type OversizedChangelogFileRow = z.infer<typeof OversizedChangelogFileRowSchema>;
838
- export type OversizedChangelogFilesResponse = z.infer<typeof OversizedChangelogFilesResponseSchema>;
839
- export type FetchableSourcesResponse = z.infer<typeof FetchableSourcesResponseSchema>;
840
- export type FeedSourcesResponse = z.infer<typeof FeedSourcesResponseSchema>;
841
- export type ChangedSourcesResponse = z.infer<typeof ChangedSourcesResponseSchema>;
842
-
843
- // ── Admin telemetry: orgs rollup ──
844
-
845
- export interface OrgsRollupRow {
846
- /** Org slug, or "—" for sources without an org. */
847
- orgSlug: string;
848
- sourceCount: number;
849
- /** Sources with no release on file or `latestDate` older than `staleDays`. */
850
- staleCount: number;
851
- /** Most-recent release across all of the org's sources, or null. */
852
- mostRecentRelease: string | null;
853
- mostRecentAgeDays: number | null;
854
- /** True iff every source in the org is stale (and the org has at least one source). */
855
- allStale: boolean;
856
- }
857
-
858
- export interface OrgsRollupResponse extends ListResponse<OrgsRollupRow> {
859
- meta: {
860
- /** Stale cutoff used server-side, in days. */
861
- staleDays: number;
862
- totalOrgs: number;
863
- /** Orgs where every source is stale. */
864
- dormantOrgs: number;
865
- /** Orgs with at least one stale source. */
866
- anyStaleOrgs: number;
867
- };
868
- }
869
-
870
- // ── Admin telemetry: stuck sources ──
871
-
872
- /**
873
- * A source whose recent fetch history is all errors with no reachability — a
874
- * candidate for pausing. "Stuck" means: within the last `window` non-`dry_run`
875
- * fetch attempts, every one was an `error` (zero `success`/`no_change`) and
876
- * there were at least `minAttempts` of them.
877
- *
878
- * This keys off the `fetch_log` error streak rather than
879
- * `sources.consecutive_errors`, because the scrape/agent fetch path never bumps
880
- * that column (a source can fail for days with `consecutive_errors = 0`).
881
- */
882
- export interface StuckSource {
883
- sourceId: string;
884
- sourceSlug: string;
885
- name: string;
886
- type: SourceType;
887
- url: string;
888
- kind: string | null;
889
- orgSlug: string | null;
890
- orgName: string | null;
891
- /** Current fetch tier — `paused` rows only appear when `includePaused`. */
892
- fetchPriority: SourceFetchPriority;
893
- /** True when this is the org's primary changelog (Firebase's was). */
894
- isPrimary: boolean;
895
- isHidden: boolean;
896
- /** Non-`dry_run` attempts examined in the window (all errors when stuck). */
897
- recentAttempts: number;
898
- /**
899
- * Failed or degraded attempts (`error`, `crawl_timeout`, `blocked`) among the
900
- * examined attempts (equals `recentAttempts` when stuck).
901
- */
902
- recentErrors: number;
903
- /** Most-recent fetch attempt timestamp (ISO), or null. */
904
- lastAttemptAt: string | null;
905
- /** Most-recent error message. */
906
- lastError: string | null;
907
- /** Most-recent error category, when the fetcher classified it. */
908
- lastErrorCategory: string | null;
909
- /** Last time the source was reachable (`success`/`no_change`), ISO; null = never. */
910
- lastSuccessAt: string | null;
911
- /** `sources.last_fetched_at` — null when the source has never fetched. */
912
- lastFetchedAt: string | null;
913
- /** When the source row was created (ISO) — proxy for how long it's failed. */
914
- sourceCreatedAt: string | null;
915
- }
916
-
917
- export interface StuckSourcesResponse extends ListResponse<StuckSource> {
918
- meta: {
919
- /** Recent non-`dry_run` attempts examined per source. */
920
- window: number;
921
- /** Minimum attempts in the window required to flag a source. */
922
- minAttempts: number;
923
- /** Whether already-paused sources were included. */
924
- includePaused: boolean;
925
- };
926
- }
927
-
928
- // ── Admin telemetry: provider / ingest health ──
929
-
930
- /**
931
- * A source flagged as "overdue for evaluation" — `sources.last_fetched_at`
932
- * (written on every successful check, including `no_change`) is older than
933
- * the health scan's threshold, or null. This is deliberately independent of
934
- * release recency: a source can be perfectly healthy (actively checked, just
935
- * quiet) while its latest release is months old, and conversely every source
936
- * can look quiet-but-fine by release date while the thing that checks them —
937
- * ingest, extraction, the AI provider — has silently stopped running. See the
938
- * 2026-07-23 spend-cap outage (#2168): `last_fetched_at` froze across every
939
- * affected source for six days while nothing else changed.
940
- */
941
- export interface ProviderHealthSource {
942
- sourceId: string;
943
- sourceSlug: string;
944
- name: string;
945
- type: SourceType;
946
- orgSlug: string | null;
947
- orgName: string | null;
948
- fetchPriority: SourceFetchPriority;
949
- isPrimary: boolean;
950
- /** `sources.last_fetched_at` — null when the source has never been fetched successfully. */
951
- lastFetchedAt: string | null;
952
- /** Days since `lastFetchedAt` (or since the source was created, if never fetched). */
953
- daysSinceFetched: number;
954
- }
955
-
956
- export interface ProviderHealthResponse extends ListResponse<ProviderHealthSource> {
957
- meta: {
958
- /** A source is "overdue" once its last successful check exceeds this many days. */
959
- overdueThresholdDays: number;
960
- /** Active (non-paused, non-deleted) sources considered by the scan. */
961
- totalActiveSources: number;
962
- /** Sources whose last successful check is older than the threshold, or never. */
963
- overdueSources: number;
964
- /** Distinct orgs with at least one overdue source. */
965
- overdueOrgs: number;
966
- /** Distinct orgs represented among active sources. */
967
- totalOrgs: number;
968
- /**
969
- * Active sources that should still be polling but whose SourceActor mirror
970
- * is unmanaged / missing `nextAlarmAt` (#2286). Independent of overdue
971
- * last-check — a freshly fetched source can still have a dead alarm.
972
- */
973
- unmanagedActors: number;
974
- };
975
- }
976
-
977
- // ── Releases ──
978
-
979
- /**
980
- * Release type — mirrors `RELEASE_TYPES` in `@buildinternet/releases-core/schema`.
981
- * Optional on the wire so older API responses (mid-deploy or pinned old workers)
982
- * degrade gracefully — consumers that see `undefined` should treat it as `"feature"`.
983
- */
984
- export type ReleaseType = z.infer<typeof ReleaseTypeSchema>;
985
-
986
- export type ReleaseItem = z.infer<typeof ReleaseItemSchema>;
987
- export type ReleaseComposition = z.infer<typeof ReleaseCompositionSchema>;
988
-
989
- /**
990
- * One entry in a {@link WhatsChangedResponse} — a release in the requested
991
- * upgrade range; a slim, release-derived projection. `breaking`/`migrationNotes`
992
- * come from #1696 (`"unknown"` until classified or for non-dev-facing kinds).
993
- */
994
- export interface WhatsChangedEntry {
995
- version: string | null;
996
- publishedAt: string | null;
997
- /** AI-generated title when present, else the raw release title. */
998
- title: string | null;
999
- summary: string | null;
1000
- breaking: BreakingLevel;
1001
- migrationNotes: string | null;
1002
- /** Original source URL. Primary citation link; prefer this over `webUrl`. */
1003
- url: string | null;
1004
- /**
1005
- * releases.sh detail page — the slugged `/release/<id>-<slug>` form (#1906),
1006
- * built from `WEB_BASE_URL`. Secondary to `url` (the original source).
1007
- */
1008
- webUrl: string | null;
1009
- }
1010
-
1011
- /**
1012
- * Response of `GET /v1/whats-changed` (#1697, upgrade intelligence Phase 1) —
1013
- * the changelog entries in the half-open version range `(from, to]` for a
1014
- * package (`from` exclusive, `to` inclusive). `status: "unknown"` (still
1015
- * HTTP 200 — a valid answer, not an error) when the package can't be resolved
1016
- * read-only from the catalog (e.g. an npm/PyPI name absent until #1345).
1017
- * `entries` are ordered oldest→newest; a range wider than the token budget is
1018
- * truncated (newest entries kept), flagged by `truncated` + `truncatedAtTokens`.
1019
- */
1020
- export interface WhatsChangedResponse {
1021
- status: "resolved" | "unknown";
1022
- package: string;
1023
- ecosystem: "npm" | "pypi" | "github" | null;
1024
- from: string;
1025
- to: string;
1026
- source: { sourceId: string; sourceSlug: string; orgSlug: string } | null;
1027
- entries: WhatsChangedEntry[];
1028
- count: number;
1029
- truncated: boolean;
1030
- truncatedAtTokens?: number;
1031
- }
1032
-
1033
- export interface ReleaseDetail {
1034
- id: string;
1035
- sourceId: string;
1036
- version: string | null;
1037
- title: string;
1038
- content: string;
1039
- /** AI-generated summary (#852, renamed in #860). Nullable — most rows unpopulated. */
1040
- summary: string | null;
1041
- /**
1042
- * AI-generated self-contained news-headline form of the release (#852,
1043
- * renamed in #860). Nullable because most rows are unpopulated — fall
1044
- * back to `title` for display. `.optional()` for the same mid-deploy /
1045
- * pinned-worker reason as `type` on {@link ReleaseItem}.
1046
- */
1047
- titleGenerated?: string | null;
1048
- /** AI-generated smart-brevity headline (#852, renamed in #860). Same fallback as `titleGenerated`. */
1049
- titleShort?: string | null;
1050
- /**
1051
- * Machine-readable breaking-change level (#1696). `.optional()` for mid-deploy
1052
- * / pinned-worker tolerance; absent or `"unknown"` means not classified (the
1053
- * fail-open default). Populated live at ingest for developer-facing source
1054
- * kinds; history is `"unknown"` pending a backfill. Route population + the web
1055
- * chip are #1696 follow-ups.
1056
- */
1057
- breaking?: BreakingLevel;
1058
- /** Explicit upgrade/migration steps lifted from the body (#1696); null when the body gives none. */
1059
- migrationNotes?: string | null;
1060
- /**
1061
- * AI-scored release importance, 1 (housekeeping) to 5 (landmark). Scored at
1062
- * ingest by the release-content pass; fail-open — null/absent means not
1063
- * scored. Additive — older servers omit it.
1064
- */
1065
- importance?: number | null;
1066
- /** Original source URL. Primary citation link; `webUrl` is the releases.sh copy. */
1067
- url: string | null;
1068
- /**
1069
- * releases.sh detail-page URL (friendly form: ID + current title slug).
1070
- * Secondary to `url`. Additive — older servers omit it.
1071
- */
1072
- webUrl?: string;
1073
- media: MediaItem[];
1074
- publishedAt: string | null;
1075
- fetchedAt: string;
1076
- sourceName: string;
1077
- sourceSlug: string;
1078
- sourceType: string;
1079
- /**
1080
- * Owning org. `avatarUrl` is the resolved `organizations.avatar_url`
1081
- * (nullable; `.optional()` for mid-deploy / pinned-worker tolerance).
1082
- * `discovery` and `isHidden` are additive — older servers omit them.
1083
- */
1084
- org: {
1085
- slug: string;
1086
- name: string;
1087
- avatarUrl?: string | null;
1088
- /** How the org was created. Additive — older servers omit it. */
1089
- discovery?: "curated" | "agent" | "on_demand";
1090
- /** Whether the org is hidden from public listings. Additive — older servers omit it. */
1091
- isHidden?: boolean;
1092
- } | null;
1093
- /**
1094
- * Owning product, when the source is grouped under one (`sources.product_id`).
1095
- * `null` when ungrouped; `.optional()` so older servers that omit it still type.
1096
- */
1097
- product?: { slug: string; name: string } | null;
1098
- /** Release type. See {@link ReleaseType}. */
1099
- type?: ReleaseType;
1100
- /** Per-category item counts from the AI release-content pass. See {@link ReleaseComposition}. */
1101
- composition?: ReleaseComposition | null;
1102
- /** App Store platform + icon, present only when `sourceType === "appstore"`. */
1103
- appStore?: { platform: "ios" | "macos"; iconUrl: string | null } | null;
1104
- /** Video provider tag, present only when `sourceType === "video"`. */
1105
- video?: { provider: "youtube" | "vimeo" | "wistia" } | null;
1106
- /**
1107
- * Whether the release's source is hidden from public listings. Additive —
1108
- * older servers omit it; treat `undefined` as `false`.
1109
- */
1110
- sourceIsHidden?: boolean;
1111
- }
1112
-
1113
- export type ReleaseCoverageSibling = z.infer<typeof ReleaseCoverageSiblingSchema>;
1114
- export type ReleaseCoverageRow = z.infer<typeof ReleaseCoverageRowSchema>;
1115
- export type ReleaseCoverageResponse = z.infer<typeof ReleaseCoverageResponseSchema>;
1116
- export type LinkReleaseCoverageBody = z.infer<typeof LinkReleaseCoverageBodySchema>;
1117
- export type LinkReleaseCoverageResponse = z.infer<typeof LinkReleaseCoverageResponseSchema>;
1118
- export type UnlinkReleaseCoverageResponse = z.infer<typeof UnlinkReleaseCoverageResponseSchema>;
1119
-
1120
- export type ReleaseLatestSource = z.infer<typeof ReleaseLatestSourceSchema>;
1121
- export type ReleaseLatestProduct = z.infer<typeof ReleaseLatestProductSchema>;
1122
- export type ReleaseLatestItem = z.infer<typeof ReleaseLatestItemSchema>;
1123
- export type ReleaseLatestResponse = z.infer<typeof ReleaseLatestResponseSchema>;
1124
-
1125
- export type ReleaseWithMediaRow = z.infer<typeof ReleaseWithMediaRowSchema>;
1126
- export type ReleasesWithMediaResponse = z.infer<typeof ReleasesWithMediaResponseSchema>;
1127
-
1128
- export type ReleaseDetailOrg = z.infer<typeof ReleaseDetailOrgSchema>;
1129
- export type ReleaseDetailResponse = z.infer<typeof ReleaseDetailResponseSchema>;
1130
- export type ReleaseUrlConflictDetails = z.infer<typeof ReleaseUrlConflictDetailsSchema>;
1131
- export type UpdateReleaseBody = z.infer<typeof UpdateReleaseBodySchema>;
1132
- export type ReleasePatchResponse = z.infer<typeof ReleasePatchResponseSchema>;
1133
- export type ReleaseDeleteResponse = z.infer<typeof ReleaseDeleteResponseSchema>;
1134
- export type ReleaseBatchDeleteBody = z.infer<typeof ReleaseBatchDeleteBodySchema>;
1135
- export type ReleaseBatchDeleteResponse = z.infer<typeof ReleaseBatchDeleteResponseSchema>;
1136
- export type ReleaseSuppressResponse = z.infer<typeof ReleaseSuppressResponseSchema>;
1137
- export type ReleaseUnsuppressResponse = z.infer<typeof ReleaseUnsuppressResponseSchema>;
1138
- export type ReleaseSuppressBody = z.infer<typeof ReleaseSuppressBodySchema>;
1139
- export type ReleaseBatchSuppressBody = z.infer<typeof ReleaseBatchSuppressBodySchema>;
1140
- export type ReleaseBatchSuppressResponse = z.infer<typeof ReleaseBatchSuppressResponseSchema>;
1141
- export type ReleaseStreamMessage = z.infer<typeof ReleaseStreamMessageSchema>;
1142
-
1143
- export type ReleaseSummaryItem = z.infer<typeof ReleaseSummaryItemSchema>;
1144
-
1145
- // ── Follows ──
1146
-
1147
- /** What a user can follow. */
1148
- export type FollowTarget = "org" | "product";
1149
-
1150
- /** A user's follow, enriched for rendering (returned by GET /v1/me/follows). */
1151
- export interface Follow {
1152
- targetType: FollowTarget;
1153
- targetId: string;
1154
- name: string;
1155
- slug: string;
1156
- avatarUrl: string | null;
1157
- /** Owning org slug for product follows (null for org follows). */
1158
- orgSlug: string | null;
1159
- createdAt: string;
1160
- }
1161
-
1162
- /** GET /v1/me/follows response. */
1163
- export interface FollowsListResponse {
1164
- follows: Follow[];
1165
- }
1166
-
1167
- /** POST /v1/me/follows request body. */
1168
- export interface FollowRequest {
1169
- targetType: FollowTarget;
1170
- targetId: string;
1171
- }
1172
-
1173
- /** POST/DELETE /v1/me/follows response. */
1174
- export interface FollowMutationResponse {
1175
- success: true;
1176
- following: boolean;
1177
- }
1178
-
1179
- /**
1180
- * A user's personalized feed token, including the full re-revealable feed URL.
1181
- * The token is reversible (stored recoverably) because the feed serves only
1182
- * public release data and carries no PII — so the URL can be re-displayed and
1183
- * copied on any visit (see #1519 design, decision 6). One per user.
1184
- */
1185
- export interface FeedToken {
1186
- /** Absolute, tokenized Atom URL — e.g. https://api.releases.sh/v1/feed/relf_…_….atom */
1187
- feedUrl: string;
1188
- /** Non-secret public handle (for masked display). */
1189
- lookupId: string;
1190
- createdAt: string;
1191
- lastUsedAt: string | null;
1192
- }
1193
-
1194
- /** `GET /v1/me/feed/token` — the token, or null if the user has none yet. */
1195
- export interface FeedTokenResponse {
1196
- token: FeedToken | null;
1197
- }
1198
-
1199
- /** Cursor pagination shape for GET /v1/me/feed (same as other release feeds). */
1200
- export type PersonalizedFeedPagination = OrgFeedPagination;
1201
-
1202
- /**
1203
- * GET /v1/me/feed response — the personalized release feed. Reuses the same item
1204
- * shape as /v1/releases/latest (ReleaseLatestItem); cursor-paginated like other
1205
- * feed-shaped surfaces.
1206
- */
1207
- export interface PersonalizedFeedResponse {
1208
- items: ReleaseLatestItem[];
1209
- pagination: PersonalizedFeedPagination;
1210
- }
1211
-
1212
- // ── User webhooks ──
1213
-
1214
- /** High-level delivery posture derived from summary columns (no AE query). */
1215
- export type WebhookDeliveryHealth =
1216
- | "never_delivered"
1217
- | "healthy"
1218
- | "degraded"
1219
- | "failing"
1220
- | "paused"
1221
- | "auto_paused";
1222
-
1223
- /** Self-serve webhook filter scope. */
1224
- export type UserWebhookScope = "org" | "follows";
1225
-
1226
- /** Optional per-event filter on release taxonomy type. */
1227
- export type UserWebhookReleaseTypeFilter = "feature" | "rollup";
1228
-
1229
- /** Webhook delivery output format. */
1230
- export type UserWebhookFormat = "json" | "slack" | "discord";
1231
-
1232
- /** A user-owned webhook subscription row (no signing secret). */
1233
- export interface UserWebhookSubscription {
1234
- id: string;
1235
- userId: string;
1236
- scope: UserWebhookScope;
1237
- orgId: string | null;
1238
- url: string;
1239
- sourceId: string | null;
1240
- productId: string | null;
1241
- releaseType: UserWebhookReleaseTypeFilter | null;
1242
- format: UserWebhookFormat;
1243
- enabled: boolean;
1244
- description: string | null;
1245
- secretVersion: number;
1246
- createdAt: string;
1247
- lastSuccessAt: string | null;
1248
- lastErrorAt: string | null;
1249
- lastErrorMsg: string | null;
1250
- consecutiveFailures: number;
1251
- disabledReason: string | null;
1252
- failureStreakStartedAt: string | null;
1253
- }
1254
-
1255
- /** Delivery health fields returned on user webhook read paths. */
1256
- export interface UserWebhookDeliveryHealth {
1257
- deliveryHealth: WebhookDeliveryHealth;
1258
- deliveryHealthSummary: string;
1259
- }
1260
-
1261
- /** List item returned by GET /v1/me/webhooks — includes org/source display fields. */
1262
- export interface UserWebhookListItem
1263
- extends Omit<UserWebhookSubscription, "userId">, UserWebhookDeliveryHealth {
1264
- orgSlug: string | null;
1265
- orgName: string | null;
1266
- sourceSlug: string | null;
1267
- sourceName: string | null;
1268
- productSlug: string | null;
1269
- productName: string | null;
1270
- }
1271
-
1272
- /** GET /v1/me/webhooks response. */
1273
- export interface UserWebhookListResponse {
1274
- subscriptions: UserWebhookListItem[];
1275
- }
1276
-
1277
- /** POST /v1/me/webhooks response — signing key shown once at creation (omitted for slack/discord). */
1278
- export interface CreateUserWebhookResponse
1279
- extends UserWebhookSubscription, UserWebhookDeliveryHealth {
1280
- orgSlug: string | null;
1281
- orgName: string | null;
1282
- signingKey?: string;
1283
- }
1284
-
1285
- /** POST /v1/me/webhooks/:id/rotate-secret response. */
1286
- export interface RotateUserWebhookSecretResponse {
1287
- secretVersion: number;
1288
- signingKey: string;
1289
- }
1290
-
1291
- /** POST /v1/me/webhooks/:id/test response. */
1292
- export interface TestUserWebhookResponse {
1293
- enqueued: true;
1294
- eventId: string;
1295
- }
1296
-
1297
- // ── Workspace webhooks ──
1298
-
1299
- /** Workspace member role (Better Auth `member.role`, not `user.role`). */
1300
- export type WorkspaceMemberRole = "owner" | "admin" | "member";
1301
-
1302
- /**
1303
- * A workspace-owned webhook subscription row (no signing secret). Workspace
1304
- * webhooks are org-scoped only; there is no workspace follows scope.
1305
- */
1306
- export interface WorkspaceWebhookSubscription extends Omit<
1307
- UserWebhookSubscription,
1308
- "userId" | "scope"
1309
- > {
1310
- workspaceId: string;
1311
- scope: "org";
1312
- }
1313
-
1314
- /** List item returned by GET /v1/workspaces/:workspaceId/webhooks. */
1315
- export interface WorkspaceWebhookListItem extends Omit<UserWebhookListItem, "scope"> {
1316
- workspaceId: string;
1317
- scope: "org";
1318
- }
1319
-
1320
- /** GET /v1/workspaces/:workspaceId/webhooks response. */
1321
- export interface WorkspaceWebhookListResponse {
1322
- subscriptions: WorkspaceWebhookListItem[];
1323
- /** The caller's role in the workspace. */
1324
- role: WorkspaceMemberRole;
1325
- /** True for owners and admins: create, edit, rotate, and delete. Members can view and test. */
1326
- canManage: boolean;
1327
- }
1328
-
1329
- /** POST /v1/workspaces/:workspaceId/webhooks response — signing key shown once (omitted for slack/discord). */
1330
- export interface CreateWorkspaceWebhookResponse
1331
- extends WorkspaceWebhookSubscription, UserWebhookDeliveryHealth {
1332
- orgSlug: string | null;
1333
- orgName: string | null;
1334
- signingKey?: string;
1335
- }
1336
-
1337
- /** One Analytics Engine delivery-attempt row from GET …/webhooks/:id/deliveries. */
1338
- export interface WebhookDeliveryRow {
1339
- timestamp?: string;
1340
- event_id?: string;
1341
- error_message?: string | null;
1342
- error_code?: string | null;
1343
- outcome?: string;
1344
- /** Delivery format — "json" (signed raw event) or a chat card (`slack` / `discord`). Empty on pre-format rows. */
1345
- format?: UserWebhookFormat | "";
1346
- http_status?: number;
1347
- latency_ms?: number;
1348
- attempt?: number;
1349
- }
1350
-
1351
- // ── Digest emails ──
1352
-
1353
- /** How often a user wants a digest email. `off` = no emails. */
1354
- export type DigestCadence = "off" | "daily" | "weekly";
1355
-
1356
- /** GET /v1/me/digest response — the caller's current cadence. */
1357
- export interface DigestPrefsResponse {
1358
- cadence: DigestCadence;
1359
- }
1360
-
1361
- /** PUT /v1/me/digest request body. */
1362
- export interface DigestPrefsRequest {
1363
- cadence: DigestCadence;
1364
- }
1365
-
1366
- /** One collection whose weekly digest the caller gets by email (#2459). */
1367
- export interface CollectionDigestSubscription {
1368
- collectionSlug: string;
1369
- collectionName: string;
1370
- /** ISO-8601. */
1371
- createdAt: string;
1372
- }
1373
-
1374
- /** GET /v1/me/collection-digests response, newest first. */
1375
- export interface CollectionDigestSubscriptionsResponse {
1376
- subscriptions: CollectionDigestSubscription[];
1377
- }
1378
-
1379
- /** PUT / DELETE /v1/me/collection-digests/:slug response. Both are idempotent. */
1380
- export interface CollectionDigestSubscriptionResponse {
1381
- collectionSlug: string;
1382
- subscribed: boolean;
1383
- }
1384
-
1385
- // ── Semantic alerts (#2304 Phase 1) ──
1386
-
1387
- /** Hard cap on saved semantic alerts per account. Enforced on create. */
1388
- export const SEMANTIC_ALERT_MAX_PER_USER = 5;
1389
-
1390
- /** Freeform interest text, after trim. User-private — never an analytics label. */
1391
- export const SEMANTIC_ALERT_QUERY_MAX_CHARS = 500;
1392
-
1393
- /** Default selected-choice probability. Phase 2 matcher uses this unless overridden. */
1394
- export const SEMANTIC_ALERT_THRESHOLD_DEFAULT = 0.8;
1395
-
1396
- export const SEMANTIC_ALERT_THRESHOLD_MIN = 0.5;
1397
- export const SEMANTIC_ALERT_THRESHOLD_MAX = 1;
1398
-
1399
- /**
1400
- * v1 candidate pool. Matching (Phase 2) scores only releases that already hit
1401
- * the caller's follow graph. Not a per-alert setting.
1402
- */
1403
- export const SEMANTIC_ALERT_CANDIDATE_POOL = "follows" as const;
1404
-
1405
- /** One saved semantic alert. Query text is returned only to the owning user. */
1406
- export interface SemanticAlert {
1407
- id: string;
1408
- query: string;
1409
- enabled: boolean;
1410
- /** Inclusive match probability in [0.50, 1.00]. Default 0.80. */
1411
- threshold: number;
1412
- /** Stored preference. Phase 1 does not send email. */
1413
- deliverEmail: boolean;
1414
- /** Stored preference. Phase 1 does not send webhook deliveries. */
1415
- deliverWebhook: boolean;
1416
- /** Optional link to one of the caller's `/v1/me/webhooks` subscriptions. */
1417
- webhookSubscriptionId: string | null;
1418
- createdAt: string;
1419
- updatedAt: string;
1420
- }
1421
-
1422
- /**
1423
- * Claimed-match activity for one alert (#2320). Counts are rows in
1424
- * `semantic_alert_matches` (notified matches only — below-threshold scores
1425
- * are not stored). Present on list and notifications-bootstrap rows.
1426
- */
1427
- export interface SemanticAlertActivity {
1428
- /** Matches in the last 7 days. Included in `matches30d`. */
1429
- matches7d: number;
1430
- /** Matches in the last 30 days. */
1431
- matches30d: number;
1432
- /** Newest claim, or null when the alert has never matched. */
1433
- lastMatchedAt: string | null;
1434
- /** Newest claim's release, when that row still exists. */
1435
- lastMatch: {
1436
- releaseId: string;
1437
- title: string;
1438
- /** Canonical site path, `/release/rel_…`. */
1439
- path: string;
1440
- } | null;
1441
- }
1442
-
1443
- /** A list row: the saved alert plus recent match activity. */
1444
- export interface SemanticAlertListItem extends SemanticAlert {
1445
- activity: SemanticAlertActivity;
1446
- }
1447
-
1448
- /** GET /v1/me/semantic-alerts. `candidatePool` is the locked v1 scope. */
1449
- export interface SemanticAlertListResponse {
1450
- alerts: SemanticAlertListItem[];
1451
- candidatePool: typeof SEMANTIC_ALERT_CANDIDATE_POOL;
1452
- maxAlerts: number;
1453
- }
1454
-
1455
- /**
1456
- * GET /v1/me/settings/notifications — one-shot bootstrap for `/account/notifications`.
1457
- * Composes digest cadence + feed token + webhook list so the settings page can
1458
- * render with a single round-trip instead of three independent mounts.
1459
- * `semanticAlerts` is `null` when `semantic-alerts-enabled` is off (hide the
1460
- * section); an array, possibly empty, when the lane is on.
1461
- */
1462
- export interface NotificationSettingsResponse {
1463
- cadence: DigestCadence;
1464
- feedToken: FeedToken | null;
1465
- webhooks: UserWebhookListItem[];
1466
- semanticAlerts: SemanticAlertListItem[] | null;
1467
- }
1468
-
1469
- /**
1470
- * GET /v1/me/settings/developer — one-shot bootstrap for `/account/webhooks`
1471
- * (Webhooks & API). `apiKeys` is `null` when the user-api-keys feature is off
1472
- * so the UI can hide the keys section without a separate probe.
1473
- */
1474
- export interface DeveloperSettingsResponse {
1475
- webhooks: UserWebhookListItem[];
1476
- apiKeys: UserApiKey[] | null;
1477
- }
1478
-
1479
- /** GET /v1/me/workspaces — one row per workspace the caller belongs to. */
1480
- export interface MeWorkspace {
1481
- /** Better Auth organization id. */
1482
- id: string;
1483
- name: string;
1484
- slug: string;
1485
- logo: string | null;
1486
- /** Workspace membership role (`member.role`, not `user.role`). */
1487
- role: WorkspaceMemberRole;
1488
- /** The caller's active workspace (see docs/architecture/workspaces.md). */
1489
- active: boolean;
1490
- createdAt: string;
1491
- }
1492
-
1493
- export interface MeWorkspacesResponse {
1494
- workspaces: MeWorkspace[];
1495
- }
1496
-
1497
- // ── Search ──
1498
-
1499
- export type SearchOrgHit = z.infer<typeof SearchOrgHitSchema>;
1500
- export type SearchCatalogHit = z.infer<typeof SearchCatalogHitSchema>;
1501
-
1502
- export type SearchSourceHit = z.infer<typeof SearchSourceHitSchema>;
1503
-
1504
- export interface RawSourceHit extends SearchSourceHit {
1505
- productName?: string;
1506
- productCategory?: string;
1507
- /** Owning org's avatar URL — folded onto the catalog hit for the byline avatar. */
1508
- orgAvatarUrl?: string | null;
1509
- /** Entity taxonomy kind from the `sources.kind` column. */
1510
- entityKind?: string | null;
1511
- }
1512
-
1513
- /**
1514
- * Fold source hits into the catalog list. Sources under a matched product
1515
- * are dropped (product wins); orphan sources become `entryType: "source"`.
1516
- */
1517
- export function foldSourcesIntoCatalog(
1518
- existingProducts: SearchCatalogHit[],
1519
- rawSources: RawSourceHit[],
1520
- ): SearchCatalogHit[] {
1521
- const result: SearchCatalogHit[] = existingProducts.map((p) => ({
1522
- ...p,
1523
- entryType: "product" as const,
1524
- }));
1525
- const seen = new Set(result.map((p) => p.slug));
1526
- for (const s of rawSources) {
1527
- if (s.productSlug) {
1528
- if (seen.has(s.productSlug)) continue;
1529
- result.push({
1530
- slug: s.productSlug,
1531
- name: s.productName ?? s.name,
1532
- orgSlug: s.orgSlug,
1533
- orgName: s.orgName,
1534
- orgAvatarUrl: s.orgAvatarUrl ?? null,
1535
- category: s.productCategory ?? null,
1536
- entryType: "product",
1537
- kind: undefined,
1538
- });
1539
- seen.add(s.productSlug);
1540
- } else {
1541
- result.push({
1542
- slug: s.slug,
1543
- name: s.name,
1544
- orgSlug: s.orgSlug,
1545
- orgName: s.orgName,
1546
- orgAvatarUrl: s.orgAvatarUrl ?? null,
1547
- category: null,
1548
- entryType: "source",
1549
- kind: (s.entityKind as SearchCatalogHit["kind"]) ?? undefined,
1550
- sourceSlug: s.slug,
1551
- sourceType: s.type,
1552
- });
1553
- }
1554
- }
1555
- return result;
1556
- }
1557
-
1558
- export type SearchReleaseHit = z.infer<typeof SearchReleaseHitSchema>;
1559
- export type SearchChunkHit = z.infer<typeof SearchChunkHitSchema>;
1560
- export type SearchCollectionHit = z.infer<typeof SearchCollectionHitSchema>;
1561
-
1562
- /**
1563
- * Merge collection hits from three independent sources into one ordered,
1564
- * deduped array on the wire:
1565
- *
1566
- * 1. Direct lexical matches — name/slug/description LIKE.
1567
- * 2. Direct semantic matches — vector hit (hybrid/semantic only).
1568
- * 3. Member rollups — collections containing one of the result orgs.
1569
- *
1570
- * A direct row always wins for a given slug; member rollups attach their
1571
- * `matchedOrgSlugs` to a winning direct row so the UI keeps the "shown
1572
- * because" affordance. Within each `via` bucket, rows order by score desc
1573
- * (missing scores last) then by name.
1574
- *
1575
- * Pure: no DB, no Workers runtime. Used by both `/v1/search` and the MCP
1576
- * `search` tool so the merge stays in lockstep across surfaces.
1577
- */
1578
- export function mergeCollectionHits(
1579
- direct: SearchCollectionHit[],
1580
- semantic: SearchCollectionHit[],
1581
- member: SearchCollectionHit[],
1582
- limit: number,
1583
- ): SearchCollectionHit[] {
1584
- // Pure: never mutate caller-owned objects. Always replace map entries with
1585
- // shallow copies so two callers (e.g. API and MCP merging from the same
1586
- // upstream list) can't see each other's writes.
1587
- const bySlug = new Map<string, SearchCollectionHit>();
1588
- for (const c of direct) bySlug.set(c.slug, { ...c });
1589
- for (const c of semantic) {
1590
- const existing = bySlug.get(c.slug);
1591
- if (existing) {
1592
- if (c.score !== undefined && (existing.score === undefined || c.score > existing.score)) {
1593
- bySlug.set(c.slug, { ...existing, score: c.score });
1594
- }
1595
- } else {
1596
- bySlug.set(c.slug, { ...c });
1597
- }
1598
- }
1599
- for (const c of member) {
1600
- const existing = bySlug.get(c.slug);
1601
- if (existing) {
1602
- bySlug.set(c.slug, { ...existing, matchedOrgSlugs: c.matchedOrgSlugs });
1603
- } else {
1604
- bySlug.set(c.slug, { ...c });
1605
- }
1606
- }
1607
- return [...bySlug.values()]
1608
- .toSorted((a, b) => {
1609
- if (a.via !== b.via) return a.via === "direct" ? -1 : 1;
1610
- const sa = a.score ?? -Infinity;
1611
- const sb = b.score ?? -Infinity;
1612
- if (sa !== sb) return sb - sa;
1613
- return a.name.localeCompare(b.name);
1614
- })
1615
- .slice(0, limit);
1616
- }
1617
-
1618
- // ── Lookups ──
1619
-
1620
- export type LookupStatus = z.infer<typeof LookupStatusSchema>;
1621
- export type LookupBody = z.infer<typeof LookupBodySchema>;
1622
- export type LookupSourceRow = z.infer<typeof LookupSourceSchema>;
1623
- export type LookupReleaseRow = z.infer<typeof LookupReleaseSchema>;
1624
- export type LookupRelatedOrg = z.infer<typeof LookupRelatedOrgSchema>;
1625
- export type LookupResponse = z.infer<typeof LookupResponseSchema>;
1626
- export type LookupSourceBySlugResponse = z.infer<typeof LookupSourceBySlugResponseSchema>;
1627
- export type LookupProductBySlugResponse = z.infer<typeof LookupProductBySlugResponseSchema>;
1628
- export type DomainLookupOrg = z.infer<typeof DomainLookupOrgSchema>;
1629
- export type DomainLookupProduct = z.infer<typeof DomainLookupProductSchema>;
1630
- export type DomainLookupResponse = z.infer<typeof DomainLookupResponseSchema>;
1631
-
1632
- // Slim wire payload embedded in a search response when the query is a GitHub
1633
- // coordinate. `LookupResultPayload` is the search-embedded slim variant;
1634
- // `LookupResponse` (above) is the thicker payload returned by POST /v1/lookups.
1635
- export type LookupResultPayload = z.infer<typeof LookupResultPayloadSchema>;
1636
- export type UnifiedSearchResponse = z.infer<typeof UnifiedSearchResponseSchema>;
1637
-
1638
- // ── Overview Pages ──
1639
-
1640
- export type OverviewPageItem = z.infer<typeof OverviewPageItemSchema>;
1641
- export type OverviewCitation = z.infer<typeof OverviewCitationSchema>;
1642
-
1643
- /** @deprecated Use OverviewPageItem */
1644
- export type KnowledgePageItem = OverviewPageItem;
1645
-
1646
- export type OrgOverviewResponse = z.infer<typeof OrgOverviewResponseSchema>;
1647
- export type IncomingOverviewCitation = z.infer<typeof IncomingOverviewCitationSchema>;
1648
- export type RegenerateOverviewBody = z.infer<typeof RegenerateOverviewBodySchema>;
1649
- export type RegenerateOverviewResponse = z.infer<typeof RegenerateOverviewResponseSchema>;
1650
- export type ProductOverviewResponse = z.infer<typeof ProductOverviewResponseSchema>;
1651
- export type OverviewInputsCheckResponse = z.infer<typeof OverviewInputsCheckResponseSchema>;
1652
- export type OverviewInputsFullResponse = z.infer<typeof OverviewInputsFullResponseSchema>;
1653
- export type OverviewInputsResponse = z.infer<typeof OverviewInputsResponseSchema>;
1654
- export type PlaybookResponse = z.infer<typeof PlaybookResponseSchema>;
1655
- export type UpdatePlaybookNotesBody = z.infer<typeof UpdatePlaybookNotesBodySchema>;
1656
- export type UpdatePlaybookNotesResponse = z.infer<typeof UpdatePlaybookNotesResponseSchema>;
1657
-
1658
- // ── Overview Manifest (admin planning) ──
1659
-
1660
- export type OverviewStaleness = "missing" | "behind" | "fresh";
1661
- /**
1662
- * `opted_out` — the org has `autoGenerateContent=false`, so the overview-regen
1663
- * eligibility filter skips it regardless of staleness. Surfaced so an
1664
- * orchestrator planning a sweep doesn't queue a regen that will never run
1665
- * (#1795).
1666
- */
1667
- export type OverviewPlanAction = "missing" | "refresh" | "skip" | "opted_out";
1668
-
1669
- /**
1670
- * Per-org row returned by GET /v1/admin/overviews. Designed for orchestrators
1671
- * planning a maintenance sweep — `releasesSinceOverview` is the freshness
1672
- * signal that matters, not date diff alone.
1673
- */
1674
- export interface OverviewManifestRow {
1675
- orgSlug: string;
1676
- orgName: string;
1677
- orgCreatedAt: string;
1678
- discovery: "curated" | "agent" | "on_demand";
1679
- overviewUpdatedAt: string | null;
1680
- overviewGeneratedAt: string | null;
1681
- lastContributingReleaseAt: string | null;
1682
- orgLastActivity: string | null;
1683
- releasesSinceOverview: number;
1684
- recentReleaseCount: number;
1685
- staleness: OverviewStaleness;
1686
- /**
1687
- * Whether the org is opted into automatic AI content. When `false`, the
1688
- * overview-regen cron skips it — the staleness signal alone is
1689
- * misleading without this (#1795). Older workers may omit it mid-deploy.
1690
- */
1691
- autoGenerateContent?: boolean;
1692
- /** Only populated when ?format=plan. */
1693
- action?: OverviewPlanAction;
1694
- /** Only populated when ?format=plan. */
1695
- needsFetch?: boolean;
1696
- }
1697
-
1698
- export type OverviewManifestResponse = ListResponse<OverviewManifestRow>;
1699
-
1700
- // ── Overview inputs (?check=true) ──
1701
-
1702
- /**
1703
- * Lightweight pre-flight payload returned by GET /v1/orgs/:slug/overview/inputs?check=true.
1704
- * Skips the heavy release-content hydration so an orchestrator can decide whether
1705
- * to dispatch without paying for the full payload.
1706
- */
1707
- export interface OverviewInputsCheck {
1708
- orgSlug: string;
1709
- selected: number;
1710
- totalAvailable: number;
1711
- hasExistingContent: boolean;
1712
- wouldRegenerate: boolean;
1713
- windowDays: number;
1714
- }
1715
-
1716
- /** @deprecated Use UnifiedSearchResponse */
1717
- export type SearchResult = SearchReleaseHit;
1718
- /** @deprecated Use UnifiedSearchResponse */
1719
- export interface SearchResponse {
1720
- query: string;
1721
- results: SearchResult[];
1722
- }
1723
-
1724
- // ── Activity ──
1725
-
1726
- export interface WeeklyBucket {
1727
- weekStart: string;
1728
- count: number;
1729
- earliestVersion: string | null;
1730
- latestVersion: string | null;
1731
- }
1732
-
1733
- /**
1734
- * @deprecated Use SourceActivityResponse (Zod-derived).
1735
- * The hand-written interface is kept for callsite compatibility — shape is identical.
1736
- */
1737
- export type SourceActivity = SourceActivityResponse;
1738
-
1739
- // ── Org Activity (Zod-derived aliases) ──
1740
- // The old hand-written OrgActivitySource / OrgActivity / OrgSparklines /
1741
- // OrgHeatmap / OrgReleaseItem interfaces have been
1742
- // replaced by Zod-derived types in the Organizations section above. Keeping
1743
- // the interface names as deprecated aliases so callsites don't need an
1744
- // immediate churn.
1745
-
1746
- /** @deprecated Use OrgActivityResponse */
1747
- export type OrgActivity = OrgActivityResponse;
1748
-
1749
- /** @deprecated Use OrgSparklinesResponse */
1750
- export type OrgSparklines = OrgSparklinesResponse;
1751
-
1752
- /** @deprecated Use OrgHeatmapResponse */
1753
- export type OrgHeatmap = OrgHeatmapResponse;
1754
-
1755
- // ── Org Sparklines (per-source/product breakdown) ──
1756
- // (covered above)
1757
-
1758
- // ── Source Heatmap ──
1759
- // (covered by SourceHeatmapResponse above)
1760
-
1761
- /**
1762
- * @deprecated Use SourceHeatmapResponse (Zod-derived).
1763
- * The hand-written interface is kept for callsite compatibility — shape is identical.
1764
- */
1765
- export type SourceHeatmap = SourceHeatmapResponse;
1766
-
1767
- // ── Org Releases ──
1768
- // (covered by OrgReleaseItem / OrgReleasesFeedResponse above)
1769
-
1770
- // Source-scoped release feed — the source identity is encoded in the URL, so
1771
- // items omit the redundant `source` block carried by the org feed.
1772
- export interface SourceReleasesResponse {
1773
- releases: ReleaseItem[];
1774
- pagination: { nextCursor: string | null; limit: number };
1775
- }
1776
-
1777
- // ── Products ──
1778
-
1779
- // `Category` lives in @buildinternet/releases-core/categories — import it from
1780
- // there. CategorySchema is re-exported here for OpenAPI / Zod consumers only.
1781
- export type ProductRow = z.infer<typeof ProductRowSchema>;
1782
- export type ProductCreateResponse = z.infer<typeof ProductCreateResponseSchema>;
1783
- export type ProductListItem = z.infer<typeof ProductListItemSchema>;
1784
- export type ProductListResponse = z.infer<typeof ProductListResponseSchema>;
1785
- export type ProductDetailSource = z.infer<typeof ProductDetailSourceSchema>;
1786
- export type ProductDetail = z.infer<typeof ProductDetailSchema>;
1787
- export type CreateProductBody = z.infer<typeof CreateProductBodySchema>;
1788
- export type UpdateProductBody = z.infer<typeof UpdateProductBodySchema>;
1789
- export type AdoptProductBody = z.infer<typeof AdoptProductBodySchema>;
1790
- export type ProductAdoptResult = z.infer<typeof ProductAdoptResultSchema>;
1791
- export type ProductAdoptDryRun = z.infer<typeof ProductAdoptDryRunSchema>;
1792
- export type ProductAdoptResponse = z.infer<typeof ProductAdoptResponseSchema>;
1793
- export type ProductDeleteResponse = z.infer<typeof ProductDeleteResponseSchema>;
1794
- export type ProductTagsListResponse = z.infer<typeof ProductTagsListResponseSchema>;
1795
- export type ProductTagsBody = z.infer<typeof ProductTagsBodySchema>;
1796
- export type ProductTagsMutationResponse = z.infer<typeof ProductTagsMutationResponseSchema>;
1797
- export type ProductActivityResponse = z.infer<typeof ProductActivityResponseSchema>;
1798
- export type ProductHeatmapResponse = z.infer<typeof ProductHeatmapResponseSchema>;
1799
-
1800
- // ── Taxonomy (categories + tags) ──
1801
-
1802
- export type TaxonomyOrg = z.infer<typeof TaxonomyOrgSchema>;
1803
- export type TaxonomyProduct = z.infer<typeof TaxonomyProductSchema>;
1804
- export type CategoryDetail = z.infer<typeof CategoryDetailSchema>;
1805
- export type CategoryListItem = z.infer<typeof CategoryListItemSchema>;
1806
- export type CategoryListResponse = z.infer<typeof CategoryListResponseSchema>;
1807
- export type UpdateCategoryRequest = z.infer<typeof UpdateCategoryRequestSchema>;
1808
- export type UpdateCategoryResponse = z.infer<typeof UpdateCategoryResponseSchema>;
1809
- export type CategoryFeedPagination = z.infer<typeof CategoryFeedPaginationSchema>;
1810
- export type CategoryReleasesResponse = z.infer<typeof CategoryReleasesResponseSchema>;
1811
- export type TagDetail = z.infer<typeof TagDetailSchema>;
1812
-
1813
- /**
1814
- * Aggregated release feed row for a category rollup — same wire shape as
1815
- * `CollectionReleaseItem` (both surfaces use `formatAggregateReleaseRow` in
1816
- * `apps/api/src/utils.ts`). Aliased rather than duplicated so renderers
1817
- * can treat them as one.
1818
- */
1819
- export type CategoryReleaseItem = CollectionReleaseItem;
1820
-
1821
- // ── Collections ──
1822
- //
1823
- // Curated, named groups of orgs that drive a public "playlist" page (e.g.
1824
- // /collections/frontier-ai-labs). Independent of the fixed `category` taxonomy.
1825
-
1826
- export type CollectionMemberOrg = z.infer<typeof CollectionMemberOrgSchema>;
1827
- export type ProductParentOrg = z.infer<typeof ProductParentOrgSchema>;
1828
- export type CollectionMemberProduct = z.infer<typeof CollectionMemberProductSchema>;
1829
- export type CollectionMember = z.infer<typeof CollectionMemberSchema>;
1830
- export type CollectionListItem = z.infer<typeof CollectionListItemSchema>;
1831
- export type CollectionListResponse = z.infer<typeof CollectionListResponseSchema>;
1832
- export type CollectionDetail = z.infer<typeof CollectionDetailSchema>;
1833
- export type CollectionReleaseItem = z.infer<typeof CollectionReleaseItemSchema>;
1834
- export type CollectionFeedPagination = z.infer<typeof CollectionFeedPaginationSchema>;
1835
- export type CollectionReleasesResponse = z.infer<typeof CollectionReleasesResponseSchema>;
1836
- export type CollectionRow = z.infer<typeof CollectionRowSchema>;
1837
- export type CreateCollectionRequest = z.infer<typeof CreateCollectionRequestSchema>;
1838
- export type UpdateCollectionRequest = z.infer<typeof UpdateCollectionRequestSchema>;
1839
- export type CollectionMemberInput = z.infer<typeof CollectionMemberInputSchema>;
1840
- export type AddCollectionMemberRequest = z.infer<typeof AddCollectionMemberRequestSchema>;
1841
- export type ReplaceCollectionMembersRequest = z.infer<typeof ReplaceCollectionMembersRequestSchema>;
1842
- export type ResolvedCollectionMember = z.infer<typeof ResolvedCollectionMemberSchema>;
1843
- export type ReplaceCollectionMembersResponse = z.infer<
1844
- typeof ReplaceCollectionMembersResponseSchema
1845
- >;
1846
- export type AddCollectionMemberResponse = z.infer<typeof AddCollectionMemberResponseSchema>;
1847
- export type CollectionDailySummary = z.infer<typeof CollectionDailySummarySchema>;
1848
- export type CollectionDailySummariesResponse = z.infer<
1849
- typeof CollectionDailySummariesResponseSchema
1850
- >;
1851
- export type CollectionWeeklyDigestListItem = z.infer<typeof CollectionWeeklyDigestListItemSchema>;
1852
- export type CollectionWeeklyDigestsResponse = z.infer<typeof CollectionWeeklyDigestsResponseSchema>;
1853
- export type DigestCoveredRelease = z.infer<typeof DigestCoveredReleaseSchema>;
1854
- export type DigestSection = z.infer<typeof DigestSectionSchema>;
1855
- export type CollectionWeeklyDigestDetail = z.infer<typeof CollectionWeeklyDigestDetailSchema>;
1856
-
1857
- // ── Releases (enriched) ──
1858
-
1859
- /** Flat release shape returned by GET /v1/releases/:id with source metadata. */
1860
- export interface ReleaseWithSource {
1861
- id: string;
1862
- sourceId: string;
1863
- version: string | null;
1864
- title: string;
1865
- content: string;
1866
- /** AI-generated summary (#852, renamed in #860). Nullable — most rows unpopulated. */
1867
- summary: string | null;
1868
- /** AI-generated headline (#852, renamed in #860). See {@link ReleaseDetail.titleGenerated}. */
1869
- titleGenerated?: string | null;
1870
- /** AI-generated smart-brevity headline (#852, renamed in #860). */
1871
- titleShort?: string | null;
1872
- /** AI-scored importance 1–5. See {@link ReleaseDetail.importance}. */
1873
- importance?: number | null;
1874
- url: string | null;
1875
- contentHash: string | null;
1876
- metadata: string | null;
1877
- publishedAt: string | null;
1878
- suppressed: boolean;
1879
- suppressedReason: string | null;
1880
- fetchedAt: string;
1881
- sourceName: string | null;
1882
- sourceSlug: string | null;
1883
- }
1884
-
1885
- export interface LatestRelease {
1886
- id: string;
1887
- title: string;
1888
- version: string | null;
1889
- publishedAt: string | null;
1890
- sourceName: string;
1891
- sourceSlug: string;
1892
- /**
1893
- * Source type (`github`/`scrape`/`feed`/`agent`/`appstore`/`video`). Lets the
1894
- * live feed render the source-type icon for a freshly-arrived event. Additive —
1895
- * older buffered events / pinned workers omit it.
1896
- */
1897
- sourceType?: string;
1898
- /**
1899
- * Owning-org context, resolved at publish time so the live feed can render an
1900
- * avatar + org name the instant an event arrives. Nested to match
1901
- * {@link ReleaseDetail.org} and the build-event input. Additive/nullable:
1902
- * absent for orphan sources or older buffered events. Avatar fallback chain:
1903
- * `avatarUrl` → `github.com/<githubHandle>.png` → an initial.
1904
- */
1905
- org?: {
1906
- slug: string;
1907
- name: string;
1908
- avatarUrl: string | null;
1909
- githubHandle: string | null;
1910
- } | null;
1911
- /** AI-generated summary (#852, renamed in #860). Nullable — most rows unpopulated. */
1912
- summary: string | null;
1913
- /** AI-generated headline (#852, renamed in #860). See {@link ReleaseDetail.titleGenerated}. */
1914
- titleGenerated?: string | null;
1915
- /** AI-generated smart-brevity headline (#852, renamed in #860). */
1916
- titleShort?: string | null;
1917
- /** AI-scored importance 1–5. See {@link ReleaseDetail.importance}. */
1918
- importance?: number | null;
1919
- media: MediaItem[];
1920
- /**
1921
- * Cached release-body size — `LENGTH(content)` and `countTokensSafe(content)`
1922
- * snapshotted at ingest, so clients can advertise "this release is ~1.5K
1923
- * tokens" without round-tripping the body. Both fields are optional and
1924
- * nullable: pre-existing rows land null until the backfill script
1925
- * populates them. See #958.
1926
- */
1927
- contentChars?: number | null;
1928
- contentTokens?: number | null;
1929
- /**
1930
- * Owning product, when the release's source is grouped under a product.
1931
- * `null` / `undefined` when the source has no `product_id`. Additive — older
1932
- * API responses omit this field; treat `undefined` as `null`. #1217.
1933
- */
1934
- product?: { slug: string; name: string } | null;
1935
- }
1936
-
1937
- // ── Stats ──
1938
- //
1939
- // `Stats` (flat counts) lives near the top of this file alongside the other
1940
- // shared schema-derived aliases. The richer summary shape is the combined
1941
- // hybrid response served at `GET /v1/stats` — flat counts plus per-source
1942
- // rollups.
1943
-
1944
- export type StatsSourceActivity = z.infer<typeof StatsSourceActivitySchema>;
1945
- export type StatsRecentActivity = z.infer<typeof StatsRecentActivitySchema>;
1946
- export type StatsResponse = z.infer<typeof StatsResponseSchema>;
1947
- /**
1948
- * The richer subset of the `GET /v1/stats` response — period + totals +
1949
- * sourceHealth + sourceActivity + recentActivity. The full wire shape
1950
- * (`StatsResponse`) merges these fields with the flat back-compat `Stats`
1951
- * counts.
1952
- */
1953
- export type StatsSummary = Omit<StatsResponse, "orgs" | "sources" | "releases" | "products">;
1954
-
1955
- // ── Feedback ──
1956
- export type FeedbackType = z.infer<typeof FeedbackTypeSchema>;
1957
- export type FeedbackStatus = z.infer<typeof FeedbackStatusSchema>;
1958
- export type FeedbackItem = z.infer<typeof FeedbackItemSchema>;
1959
- export type FeedbackListResponse = z.infer<typeof FeedbackListResponseSchema>;
1960
- export type FeedbackUpdateBody = z.infer<typeof FeedbackUpdateBodySchema>;
1961
- export type FeedbackDeleteResponse = z.infer<typeof FeedbackDeleteResponseSchema>;
1962
-
1963
- // ── Classification analytics ──
1964
- export type ClassificationSummary = z.infer<typeof ClassificationSummarySchema>;
1965
- export type ClassificationRecentResponse = z.infer<typeof ClassificationRecentResponseSchema>;
1966
- export type ClassificationRecentItem = z.infer<typeof ClassificationRecentItemSchema>;
1967
-
1968
- export type SemanticAlertSummary = z.infer<typeof SemanticAlertSummarySchema>;
1969
-
1970
- // ── Recommendations ──
1971
- export type RecommendationNotifyAddedBody = z.infer<typeof RecommendationNotifyAddedBodySchema>;
1972
- export type RecommendationNotifyAddedResult = z.infer<typeof RecommendationNotifyAddedResultSchema>;
1973
-
1974
- // ── Fetch log ──
1975
-
1976
- export interface FetchLogEntry {
1977
- id: string;
1978
- sourceName: string;
1979
- sourceSlug: string;
1980
- status: string;
1981
- releasesFound: number;
1982
- releasesInserted: number;
1983
- durationMs: number | null;
1984
- error: string | null;
1985
- createdAt: string;
1986
- }
1987
-
1988
- /**
1989
- * The managed-agent session currently fetching a source, surfaced read-side on
1990
- * the fetch-log view so an operator/agent can tell "a fetch is in flight" from
1991
- * "stuck/dead" without waiting for a terminal `fetch_log` row (#1360). Only
1992
- * running, non-stale sessions are reported (the StatusHub DO drops sessions idle
1993
- * past its staleness cutoff), so the presence of this object means a fetch is
1994
- * live; `startedAt` says how long it has been running.
1995
- */
1996
- export interface ActiveFetchSession {
1997
- sessionId: string;
1998
- /** Always `running` today — only running sessions are surfaced. */
1999
- status: string;
2000
- /** Session start, epoch ms. */
2001
- startedAt: number;
2002
- /** Last session activity, epoch ms. */
2003
- lastUpdatedAt: number;
2004
- }
2005
-
2006
- // ── Usage ──
2007
-
2008
- export interface UsageBreakdownRow {
2009
- label: string | null;
2010
- totalInput: number;
2011
- totalOutput: number;
2012
- count: number;
2013
- }
2014
-
2015
- export interface UsageStatsResponse {
2016
- totals: { totalInput: number; totalOutput: number; count: number };
2017
- byOperation: UsageBreakdownRow[];
2018
- byModel: UsageBreakdownRow[];
2019
- bySource: UsageBreakdownRow[];
2020
- }
2021
-
2022
- // ── Sessions ──
2023
-
2024
- /**
2025
- * Where the session error originated.
2026
- * - `provider`: managed-agents service / Anthropic-side (e.g. unknown_error, model_overloaded, retries_exhausted)
2027
- * - `us`: this codebase / our agent setup (e.g. parser failure, no tools called, timeout)
2028
- */
2029
- export type SessionErrorSource = "provider" | "us";
2030
-
2031
- export interface Session {
2032
- sessionId: string;
2033
- company: string;
2034
- type: "onboard" | "update";
2035
- /**
2036
- * Sub-agent **role** label that ran this session — `"coordinator"` is the
2037
- * parent orchestrator (typically Sonnet) when a multi-agent session
2038
- * delegates, `"sonnet"` / `"haiku"` are direct single-agent runs.
2039
- * `"deterministic"` marks the #1878/#1881 update path that skips the
2040
- * Managed-Agents (Haiku) session entirely — no Anthropic session runs, so
2041
- * it must never be reported as `"haiku"`. Surfaces on the detail GET.
2042
- *
2043
- * This is a logical role label, not the runtime model identifier. The
2044
- * resolved Anthropic model string (e.g. `claude-sonnet-5-5`,
2045
- * `claude-haiku-5-5`) lives on `usage.model` when the session reported
2046
- * one — consult that field for the concrete model.
2047
- */
2048
- agent?: "sonnet" | "haiku" | "coordinator" | "deterministic";
2049
- /** Identifies the client that started this session (e.g. hostname). */
2050
- runner?: string;
2051
- /** Correlation ID for end-to-end tracing across CLI → API → managed agent. */
2052
- correlationId?: string;
2053
- /** Anthropic session ID for linking to console logs. */
2054
- anthropicSessionId?: string;
2055
- status: "running" | "complete" | "error" | "cancelled";
2056
- step?: string;
2057
- sourcesFound?: number;
2058
- sourcesValidated?: number;
2059
- totalSources?: number;
2060
- sourcesFetched?: number;
2061
- releasesFound?: number;
2062
- releasesInserted?: number;
2063
- currentAction?: string;
2064
- startedAt: number;
2065
- lastUpdatedAt: number;
2066
- error?: string;
2067
- /** Where the error originated. Absent on legacy sessions; treat as `"us"`. */
2068
- errorSource?: SessionErrorSource;
2069
- /** Provider error type (e.g. `unknown_error`, `model_overloaded_error`). */
2070
- errorType?: string;
2071
- /** Stop reason from the final `session.status_idle` event (e.g. `retries_exhausted`). */
2072
- stopReason?: string;
2073
- /** Number of provider `session.error` events observed before terminal. */
2074
- retryCount?: number;
2075
- /** Non-fatal warnings collected during the session. */
2076
- warnings?: string[];
2077
- /**
2078
- * Token usage + estimated cost from the managed-agents session. `estimatedUsd`
2079
- * is a snapshot of Anthropic list prices at session-completion time.
2080
- */
2081
- usage?: {
2082
- inputTokens?: number;
2083
- outputTokens?: number;
2084
- cacheWriteTokens?: number;
2085
- cacheReadTokens?: number;
2086
- model?: string;
2087
- estimatedUsd?: number;
2088
- };
2089
- /**
2090
- * Final agent-reported state for terminal `onboard` sessions — the JSON
2091
- * blob the agent passed to its `releases_report_state` tool, plus an
2092
- * `agentSessionId` field stitched in server-side. Empty on `update`
2093
- * sessions and pre-report errors. Typed as `Record<string, unknown>`
2094
- * because the shape is owned by the discovery system prompt and may
2095
- * grow new fields without a wire bump; the keys produced today are:
2096
- *
2097
- * - `product` (`string`) — company name
2098
- * - `domain` (`string | null`) — discovered domain
2099
- * - `githubOrg` (`string | null`) — discovered GitHub org
2100
- * - `startedAt`, `updatedAt` (ISO strings)
2101
- * - `status` (e.g. `"awaiting_review"`)
2102
- * - `sources` (`Array<{ url, type, slug, label, confidence,
2103
- * validated, validationError?, releaseCount, releasesFetched,
2104
- * fetched, contentDepth }>`)
2105
- * - `agentSessionId` (`string`) — Anthropic session ID, useful for
2106
- * cross-referencing console logs
2107
- */
2108
- result?: Record<string, unknown>;
2109
- activeSources?: string[];
2110
- cancelRequested?: boolean;
2111
- }
2112
-
2113
- export type SessionListResponse = ListResponse<Session>;
2114
-
2115
- // ── Admin URL Lists ──
2116
- // `IgnoredUrlItem` is now the Zod-derived type exported in the Organizations
2117
- // section. The hand-written interface below is removed to avoid a duplicate
2118
- // identifier; callsites that imported it from here continue to work because
2119
- // the Zod-derived alias has the same shape.
2120
-
2121
- export interface BlockedUrlItem {
2122
- id: string;
2123
- pattern: string;
2124
- type: "exact" | "domain";
2125
- reason: string | null;
2126
- createdAt: string;
2127
- }
2128
-
2129
- export type IgnoredUrlListResponse = ListResponse<IgnoredUrlItem>;
2130
- export type BlockedUrlListResponse = ListResponse<BlockedUrlItem>;
2131
-
2132
- // ── Embed (admin) ──
2133
-
2134
- export interface EmbedBackfillResponse {
2135
- processed: number;
2136
- succeeded: number;
2137
- failed: number;
2138
- remaining: number;
2139
- dryRun?: boolean;
2140
- }
2141
-
2142
- /**
2143
- * Cascade-scope preview returned by `GET /v1/admin/orgs/:slug/dependents`.
2144
- * Backs the confirmation prompt in CLI/web before a hard-delete on an org —
2145
- * post-#690 Phase C, hard-deleting an org cascades into every source row
2146
- * tied to it and every per-source dependent table listed below.
2147
- */
2148
- export interface OrgDependentsResponse {
2149
- org: { id: string; slug: string; name: string };
2150
- counts: {
2151
- sources: number;
2152
- releases: number;
2153
- fetchLog: number;
2154
- sourceChangelogFiles: number;
2155
- sourceChangelogChunks: number;
2156
- releaseSummaries: number;
2157
- mediaAssets: number;
2158
- webhookSubscriptions: number;
2159
- };
2160
- }
2161
-
2162
- export interface EmbedStatusResponse {
2163
- releases: { total: number; embedded: number; unembedded: number };
2164
- entities: {
2165
- total: number;
2166
- embedded: number;
2167
- unembedded: number;
2168
- breakdown: {
2169
- org: { total: number; embedded: number; unembedded: number };
2170
- product: { total: number; embedded: number; unembedded: number };
2171
- source: { total: number; embedded: number; unembedded: number };
2172
- };
2173
- };
2174
- chunks: { total: number; embedded: number; unembedded: number };
2175
- }
2176
-
2177
- // ── Evaluate (URL recommendation) ──
2178
-
2179
- /**
2180
- * Returned verbatim by GET /v1/evaluate. Lives in the public api-types package
2181
- * so external consumers (CLI, third-party clients) can import the shape
2182
- * without depending on worker-internal AI helpers.
2183
- */
2184
- export interface EvaluationResult {
2185
- recommendedMethod: "feed" | "github" | "markdown" | "scrape" | "crawl";
2186
- recommendedUrl: string;
2187
- feedUrl?: string;
2188
- feedType?: "rss" | "atom" | "jsonfeed";
2189
- githubRepo?: string;
2190
- pageStructure: "single-page" | "index" | "unknown";
2191
- alternatives: Array<{ url: string; method: string; note: string }>;
2192
- confidence: "high" | "medium" | "low";
2193
- provider?: string;
2194
- notes?: string;
2195
- }
2196
-
2197
- /**
2198
- * Identity returned by `GET /v1/tokens/me` — the caller introspecting its own
2199
- * credential. `kind: "root"` is the static break-glass key (synthetic identity,
2200
- * no DB row); `kind: "token"` is a DB-backed `relk_` token.
2201
- */
2202
- export interface TokenIdentity {
2203
- kind: "root" | "token";
2204
- /** Display label; "root" for the static key, "local-dev" when no secret is bound. */
2205
- name: string;
2206
- /** e.g. ["read","write"] or ["*"] for root. */
2207
- scopes: string[];
2208
- principalType: "internal" | "agent" | "user";
2209
- principalId?: string | null;
2210
- /**
2211
- * Stable internal principal id for consumption telemetry (#1719). Same value the
2212
- * auth middleware attaches (`relk_` row id, `relu_${keyId}`, …) — never the raw
2213
- * secret. Returned on self-introspection so MCP can distinguish `relu_` keys.
2214
- */
2215
- tokenId?: string | null;
2216
- /**
2217
- * Owning user id for a user-scoped principal (`relu_` key) — the Better Auth
2218
- * `apikey.referenceId`. Lets a consumer bucket all of an account's credentials
2219
- * together. Null for the static root key and machine (`relk_`) tokens, which
2220
- * have no owning user. Distinct from `principalId`, which carries an
2221
- * agent/internal id for machine tokens. Used by the MCP worker to bucket
2222
- * `relu_` keys per-account on the rate-limit account tier (#1729).
2223
- */
2224
- userId?: string | null;
2225
- expiresAt?: string | null;
2226
- lastUsedAt?: string | null;
2227
- }
2228
-
2229
- export * from "./schemas/datasets.js";