@cat-factory/server 0.30.0 → 0.32.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 (166) hide show
  1. package/dist/app.d.ts.map +1 -1
  2. package/dist/app.js +2 -0
  3. package/dist/app.js.map +1 -1
  4. package/dist/config/types.d.ts +1 -15
  5. package/dist/config/types.d.ts.map +1 -1
  6. package/dist/github/FetchGitHubClient.d.ts +15 -1
  7. package/dist/github/FetchGitHubClient.d.ts.map +1 -1
  8. package/dist/github/FetchGitHubClient.js +128 -7
  9. package/dist/github/FetchGitHubClient.js.map +1 -1
  10. package/dist/github/GitHubPullRequestReviewProvider.d.ts +25 -0
  11. package/dist/github/GitHubPullRequestReviewProvider.d.ts.map +1 -0
  12. package/dist/github/GitHubPullRequestReviewProvider.js +170 -0
  13. package/dist/github/GitHubPullRequestReviewProvider.js.map +1 -0
  14. package/dist/http/errorHandler.d.ts.map +1 -1
  15. package/dist/http/errorHandler.js +20 -0
  16. package/dist/http/errorHandler.js.map +1 -1
  17. package/dist/index.d.ts +1 -1
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +1 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/modules/accounts/AccountController.d.ts +4 -0
  22. package/dist/modules/accounts/AccountController.d.ts.map +1 -1
  23. package/dist/modules/accounts/AccountController.js +78 -58
  24. package/dist/modules/accounts/AccountController.js.map +1 -1
  25. package/dist/modules/agentRuns/AgentRunController.d.ts.map +1 -1
  26. package/dist/modules/agentRuns/AgentRunController.js +8 -6
  27. package/dist/modules/agentRuns/AgentRunController.js.map +1 -1
  28. package/dist/modules/auth/AuthController.d.ts.map +1 -1
  29. package/dist/modules/auth/AuthController.js +23 -23
  30. package/dist/modules/auth/AuthController.js.map +1 -1
  31. package/dist/modules/board/BoardController.d.ts.map +1 -1
  32. package/dist/modules/board/BoardController.js +26 -26
  33. package/dist/modules/board/BoardController.js.map +1 -1
  34. package/dist/modules/bootstrap/BootstrapController.d.ts.map +1 -1
  35. package/dist/modules/bootstrap/BootstrapController.js +15 -15
  36. package/dist/modules/bootstrap/BootstrapController.js.map +1 -1
  37. package/dist/modules/brainstorm/BrainstormController.d.ts +3 -2
  38. package/dist/modules/brainstorm/BrainstormController.d.ts.map +1 -1
  39. package/dist/modules/brainstorm/BrainstormController.js +36 -52
  40. package/dist/modules/brainstorm/BrainstormController.js.map +1 -1
  41. package/dist/modules/clarity/ClarityReviewController.d.ts.map +1 -1
  42. package/dist/modules/clarity/ClarityReviewController.js +27 -25
  43. package/dist/modules/clarity/ClarityReviewController.js.map +1 -1
  44. package/dist/modules/consensus/ConsensusController.d.ts.map +1 -1
  45. package/dist/modules/consensus/ConsensusController.js +6 -4
  46. package/dist/modules/consensus/ConsensusController.js.map +1 -1
  47. package/dist/modules/documents/DocumentSourceController.d.ts.map +1 -1
  48. package/dist/modules/documents/DocumentSourceController.js +17 -17
  49. package/dist/modules/documents/DocumentSourceController.js.map +1 -1
  50. package/dist/modules/environments/EnvironmentController.d.ts.map +1 -1
  51. package/dist/modules/environments/EnvironmentController.js +24 -24
  52. package/dist/modules/environments/EnvironmentController.js.map +1 -1
  53. package/dist/modules/execution/ExecutionController.d.ts.map +1 -1
  54. package/dist/modules/execution/ExecutionController.js +57 -45
  55. package/dist/modules/execution/ExecutionController.js.map +1 -1
  56. package/dist/modules/followUp/FollowUpController.d.ts.map +1 -1
  57. package/dist/modules/followUp/FollowUpController.js +21 -17
  58. package/dist/modules/followUp/FollowUpController.js.map +1 -1
  59. package/dist/modules/fragmentLibrary/FragmentLibraryController.d.ts.map +1 -1
  60. package/dist/modules/fragmentLibrary/FragmentLibraryController.js +26 -26
  61. package/dist/modules/fragmentLibrary/FragmentLibraryController.js.map +1 -1
  62. package/dist/modules/github/GitHubController.d.ts.map +1 -1
  63. package/dist/modules/github/GitHubController.js +44 -44
  64. package/dist/modules/github/GitHubController.js.map +1 -1
  65. package/dist/modules/humanReview/HumanReviewController.d.ts +11 -0
  66. package/dist/modules/humanReview/HumanReviewController.d.ts.map +1 -0
  67. package/dist/modules/humanReview/HumanReviewController.js +22 -0
  68. package/dist/modules/humanReview/HumanReviewController.js.map +1 -0
  69. package/dist/modules/humanTest/HumanTestController.d.ts.map +1 -1
  70. package/dist/modules/humanTest/HumanTestController.js +17 -17
  71. package/dist/modules/humanTest/HumanTestController.js.map +1 -1
  72. package/dist/modules/incidentEnrichment/IncidentEnrichmentController.d.ts.map +1 -1
  73. package/dist/modules/incidentEnrichment/IncidentEnrichmentController.js +7 -7
  74. package/dist/modules/incidentEnrichment/IncidentEnrichmentController.js.map +1 -1
  75. package/dist/modules/kaizen/KaizenController.d.ts.map +1 -1
  76. package/dist/modules/kaizen/KaizenController.js +7 -5
  77. package/dist/modules/kaizen/KaizenController.js.map +1 -1
  78. package/dist/modules/localModels/LocalModelEndpointController.d.ts.map +1 -1
  79. package/dist/modules/localModels/LocalModelEndpointController.js +10 -11
  80. package/dist/modules/localModels/LocalModelEndpointController.js.map +1 -1
  81. package/dist/modules/localSettings/LocalSettingsController.d.ts.map +1 -1
  82. package/dist/modules/localSettings/LocalSettingsController.js +6 -6
  83. package/dist/modules/localSettings/LocalSettingsController.js.map +1 -1
  84. package/dist/modules/merge/MergePresetController.d.ts.map +1 -1
  85. package/dist/modules/merge/MergePresetController.js +10 -10
  86. package/dist/modules/merge/MergePresetController.js.map +1 -1
  87. package/dist/modules/modelPresets/ModelPresetController.d.ts.map +1 -1
  88. package/dist/modules/modelPresets/ModelPresetController.js +10 -10
  89. package/dist/modules/modelPresets/ModelPresetController.js.map +1 -1
  90. package/dist/modules/models/ModelController.d.ts.map +1 -1
  91. package/dist/modules/models/ModelController.js +6 -4
  92. package/dist/modules/models/ModelController.js.map +1 -1
  93. package/dist/modules/notifications/NotificationController.d.ts.map +1 -1
  94. package/dist/modules/notifications/NotificationController.js +11 -9
  95. package/dist/modules/notifications/NotificationController.js.map +1 -1
  96. package/dist/modules/openrouter/OpenRouterCatalogController.d.ts.map +1 -1
  97. package/dist/modules/openrouter/OpenRouterCatalogController.js +9 -10
  98. package/dist/modules/openrouter/OpenRouterCatalogController.js.map +1 -1
  99. package/dist/modules/pipelines/PipelineController.d.ts.map +1 -1
  100. package/dist/modules/pipelines/PipelineController.js +17 -15
  101. package/dist/modules/pipelines/PipelineController.js.map +1 -1
  102. package/dist/modules/promptFragments/PromptFragmentController.d.ts.map +1 -1
  103. package/dist/modules/promptFragments/PromptFragmentController.js +4 -2
  104. package/dist/modules/promptFragments/PromptFragmentController.js.map +1 -1
  105. package/dist/modules/providers/ApiKeyController.d.ts.map +1 -1
  106. package/dist/modules/providers/ApiKeyController.js +12 -12
  107. package/dist/modules/providers/ApiKeyController.js.map +1 -1
  108. package/dist/modules/providers/PersonalSubscriptionController.d.ts.map +1 -1
  109. package/dist/modules/providers/PersonalSubscriptionController.js +7 -8
  110. package/dist/modules/providers/PersonalSubscriptionController.js.map +1 -1
  111. package/dist/modules/providers/UserSecretController.d.ts.map +1 -1
  112. package/dist/modules/providers/UserSecretController.js +14 -15
  113. package/dist/modules/providers/UserSecretController.js.map +1 -1
  114. package/dist/modules/providers/VendorCredentialController.d.ts.map +1 -1
  115. package/dist/modules/providers/VendorCredentialController.js +7 -7
  116. package/dist/modules/providers/VendorCredentialController.js.map +1 -1
  117. package/dist/modules/providers/personalCredentialGate.d.ts +2 -2
  118. package/dist/modules/providers/personalCredentialGate.d.ts.map +1 -1
  119. package/dist/modules/providers/personalCredentialGate.js.map +1 -1
  120. package/dist/modules/provisioningLogs/ProvisioningLogController.d.ts.map +1 -1
  121. package/dist/modules/provisioningLogs/ProvisioningLogController.js +4 -3
  122. package/dist/modules/provisioningLogs/ProvisioningLogController.js.map +1 -1
  123. package/dist/modules/recurring/RecurringPipelineController.d.ts.map +1 -1
  124. package/dist/modules/recurring/RecurringPipelineController.js +15 -15
  125. package/dist/modules/recurring/RecurringPipelineController.js.map +1 -1
  126. package/dist/modules/recurring/TrackerSettingsController.d.ts.map +1 -1
  127. package/dist/modules/recurring/TrackerSettingsController.js +6 -6
  128. package/dist/modules/recurring/TrackerSettingsController.js.map +1 -1
  129. package/dist/modules/releaseHealth/ReleaseHealthController.d.ts.map +1 -1
  130. package/dist/modules/releaseHealth/ReleaseHealthController.js +14 -14
  131. package/dist/modules/releaseHealth/ReleaseHealthController.js.map +1 -1
  132. package/dist/modules/requirements/RequirementReviewController.d.ts.map +1 -1
  133. package/dist/modules/requirements/RequirementReviewController.js +43 -38
  134. package/dist/modules/requirements/RequirementReviewController.js.map +1 -1
  135. package/dist/modules/runners/RunnerPoolController.d.ts.map +1 -1
  136. package/dist/modules/runners/RunnerPoolController.js +12 -12
  137. package/dist/modules/runners/RunnerPoolController.js.map +1 -1
  138. package/dist/modules/sandbox/SandboxController.d.ts.map +1 -1
  139. package/dist/modules/sandbox/SandboxController.js +35 -26
  140. package/dist/modules/sandbox/SandboxController.js.map +1 -1
  141. package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsController.d.ts.map +1 -1
  142. package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsController.js +6 -6
  143. package/dist/modules/serviceFragmentDefaults/ServiceFragmentDefaultsController.js.map +1 -1
  144. package/dist/modules/serviceSpec/ServiceSpecController.d.ts.map +1 -1
  145. package/dist/modules/serviceSpec/ServiceSpecController.js +9 -8
  146. package/dist/modules/serviceSpec/ServiceSpecController.js.map +1 -1
  147. package/dist/modules/services/ServiceMountController.d.ts.map +1 -1
  148. package/dist/modules/services/ServiceMountController.js +14 -14
  149. package/dist/modules/services/ServiceMountController.js.map +1 -1
  150. package/dist/modules/settings/WorkspaceSettingsController.d.ts.map +1 -1
  151. package/dist/modules/settings/WorkspaceSettingsController.js +6 -6
  152. package/dist/modules/settings/WorkspaceSettingsController.js.map +1 -1
  153. package/dist/modules/slack/SlackController.d.ts.map +1 -1
  154. package/dist/modules/slack/SlackController.js +18 -18
  155. package/dist/modules/slack/SlackController.js.map +1 -1
  156. package/dist/modules/tasks/TaskSourceController.d.ts.map +1 -1
  157. package/dist/modules/tasks/TaskSourceController.js +19 -19
  158. package/dist/modules/tasks/TaskSourceController.js.map +1 -1
  159. package/dist/modules/workspaces/WorkspaceController.d.ts.map +1 -1
  160. package/dist/modules/workspaces/WorkspaceController.js +11 -11
  161. package/dist/modules/workspaces/WorkspaceController.js.map +1 -1
  162. package/package.json +11 -9
  163. package/dist/http/validation.d.ts +0 -21
  164. package/dist/http/validation.d.ts.map +0 -1
  165. package/dist/http/validation.js +0 -21
  166. package/dist/http/validation.js.map +0 -1
@@ -0,0 +1,170 @@
1
+ const EMPTY = {
2
+ headSha: null,
3
+ requiredApprovingReviewCount: 1,
4
+ assignedReviewers: [],
5
+ approvals: 0,
6
+ unresolvedThreads: [],
7
+ comments: [],
8
+ };
9
+ /** A GitHub App's own comments/reviews show as `<app-slug>[bot]`; treat those as the bot. */
10
+ function isBotLogin(login) {
11
+ return login.endsWith('[bot]');
12
+ }
13
+ /** The standing review states that determine approval (a later COMMENTED/PENDING doesn't change it). */
14
+ const STANDING = new Set(['APPROVED', 'CHANGES_REQUESTED', 'DISMISSED']);
15
+ /**
16
+ * Reduce a PR's review event log to the count of distinct reviewers whose LATEST standing review
17
+ * is APPROVED. Mirrors GitHub's own rule: a `COMMENTED`/`PENDING` review after an approval does
18
+ * not dismiss it (only an explicit CHANGES_REQUESTED / DISMISSED does). Approvers are NOT filtered
19
+ * to the current requested-reviewer list — GitHub removes a reviewer from "requested" once they
20
+ * approve, so filtering there would never count an approval.
21
+ */
22
+ function countApprovals(reviews) {
23
+ const latestByAuthor = new Map();
24
+ for (const r of reviews) {
25
+ if (!r.author || isBotLogin(r.author))
26
+ continue;
27
+ if (!STANDING.has(r.state))
28
+ continue;
29
+ latestByAuthor.set(r.author, r.state);
30
+ }
31
+ let approvals = 0;
32
+ for (const state of latestByAuthor.values())
33
+ if (state === 'APPROVED')
34
+ approvals++;
35
+ return approvals;
36
+ }
37
+ function toReviewThread(t) {
38
+ const first = t.comments[0];
39
+ const last = t.comments[t.comments.length - 1];
40
+ const body = (last?.body ?? '').trim();
41
+ return {
42
+ threadId: t.id,
43
+ author: first?.author ?? '',
44
+ bodyExcerpt: body.length > 280 ? `${body.slice(0, 277)}…` : body,
45
+ path: t.path,
46
+ line: t.line,
47
+ isBot: isBotLogin(last?.author ?? ''),
48
+ latestCommentAt: t.comments.reduce((m, c) => Math.max(m, c.createdAt), 0),
49
+ };
50
+ }
51
+ /**
52
+ * Reads a block's PR human-review state from GitHub for the `human-review` gate: assigned
53
+ * reviewers, the approval count (vs branch-protection's required count), the unresolved review
54
+ * threads and the plain PR comments. Reads LIVE each poll (no projection table), mirroring
55
+ * {@link GitHubCiStatusProvider}. Returns the empty snapshot (`headSha: null`) when there is no
56
+ * resolvable PR branch + number yet (the engine treats that as "nothing to gate").
57
+ */
58
+ export class GitHubPullRequestReviewProvider {
59
+ deps;
60
+ constructor(deps) {
61
+ this.deps = deps;
62
+ }
63
+ async getReview(workspaceId, blockId, cachedRequiredApprovingReviewCount) {
64
+ const block = await this.deps.blockRepository.get(workspaceId, blockId);
65
+ const branch = block?.pullRequest?.branch;
66
+ const number = block?.pullRequest?.number;
67
+ if (!branch || number == null)
68
+ return EMPTY;
69
+ const target = await this.deps.resolveRepoTarget(workspaceId, blockId);
70
+ if (!target)
71
+ return EMPTY;
72
+ const ref = { owner: target.owner, repo: target.name };
73
+ const gh = this.deps.githubClient;
74
+ // Head commit of the PR branch (the latest commit on the ref), for the GateProbe. This gate
75
+ // polls indefinitely, so use the exact single-ref lookup (one API call, correctly 404→null on
76
+ // a deleted branch) rather than paginating the whole branch history just to read its tip.
77
+ const headSha = await gh.branchHeadSha(target.installationId, ref, branch);
78
+ if (!headSha)
79
+ return EMPTY;
80
+ // The required-approval count is static repo config (branch protection), so the gate caches
81
+ // it after the first probe and passes it back here — skip BOTH the base-branch lookup and the
82
+ // protection read on every subsequent poll. On the first probe (no cache) read protection
83
+ // against the PR's ACTUAL base branch (`pulls/{n}.base.ref`), not the repo default: a PR into
84
+ // a stricter protected branch (e.g. a release branch requiring 2 approvals) must be gated
85
+ // against its own rule. Fall back to the resolved repo default when the base ref is unreadable.
86
+ const requiredCount = cachedRequiredApprovingReviewCount != null
87
+ ? cachedRequiredApprovingReviewCount
88
+ : await this.resolveRequiredApprovingReviewCount(target, ref, number);
89
+ // The reviews (approval) + unresolved threads are needed on EVERY poll. The plain issue
90
+ // comments and the assigned-reviewer list are consulted by the gate ONLY while the PR is
91
+ // not yet approved — `classifyHumanReview` discards comments once approved, and the
92
+ // assigned-reviewer list only feeds the "assign a reviewer" awaiting-approval card — so
93
+ // skip those two reads once the PR is approved. Over an indefinite review wait that trims
94
+ // the per-poll GitHub reads in the approved-with-open-threads window. (The dominant
95
+ // not-yet-approved wait still needs all four; the GraphQL thread read has no etag, so it
96
+ // can't be made conditional.) `approved` MUST mirror the gate's `isApproved` floor
97
+ // (`max(1, requiredApprovingReviewCount)` — see review.logic.ts) so the provider never
98
+ // skips a read the gate would have consulted.
99
+ const [reviews, threads] = await Promise.all([
100
+ gh.listPullRequestReviews?.(target.installationId, ref, number) ?? Promise.resolve([]),
101
+ gh.listReviewThreads?.(target.installationId, ref, number) ?? Promise.resolve([]),
102
+ ]);
103
+ const approvals = countApprovals(reviews);
104
+ const approved = approvals >= Math.max(1, requiredCount);
105
+ const [assignedReviewers, comments] = approved
106
+ ? [[], []]
107
+ : await Promise.all([
108
+ gh.listRequestedReviewers?.(target.installationId, ref, number) ?? Promise.resolve([]),
109
+ gh.listIssueComments?.(target.installationId, ref, number) ?? Promise.resolve([]),
110
+ ]);
111
+ return {
112
+ headSha,
113
+ requiredApprovingReviewCount: requiredCount,
114
+ assignedReviewers,
115
+ approvals,
116
+ unresolvedThreads: threads.filter((t) => !t.isResolved).map(toReviewThread),
117
+ comments: comments.map((c) => ({
118
+ id: c.id,
119
+ author: c.author,
120
+ body: c.body,
121
+ createdAt: c.createdAt,
122
+ isBot: isBotLogin(c.author),
123
+ })),
124
+ };
125
+ }
126
+ /** Read branch-protection's required-approval count against the PR's actual base branch. */
127
+ async resolveRequiredApprovingReviewCount(target, ref, number) {
128
+ const gh = this.deps.githubClient;
129
+ if (!gh.getRequiredApprovingReviewCount)
130
+ return 1;
131
+ const baseRef = (await gh.getPullRequestBaseRef?.(target.installationId, ref, number)) ?? target.baseBranch;
132
+ return gh.getRequiredApprovingReviewCount(target.installationId, ref, baseRef);
133
+ }
134
+ async resolveThreads(workspaceId, blockId, threadIds, reply) {
135
+ if (threadIds.length === 0)
136
+ return;
137
+ const target = await this.deps.resolveRepoTarget(workspaceId, blockId);
138
+ if (!target)
139
+ return;
140
+ const ref = { owner: target.owner, repo: target.name };
141
+ const gh = this.deps.githubClient;
142
+ const wantsReply = reply.trim().length > 0;
143
+ const failed = [];
144
+ for (const threadId of threadIds) {
145
+ try {
146
+ // RESOLVE first, then (only if a reply was requested) post the courtesy reply. Doing the
147
+ // state-changing resolve before the cosmetic reply guarantees we never leave a bot reply
148
+ // as a thread's latest comment while it is still unresolved — that combination would hide
149
+ // the thread from the gate's outstanding set (bot-latest is treated as "addressed") yet
150
+ // leave it open forever. An empty `reply` means "resolve only" (the probe's reconcile
151
+ // retry passes ''), so a retry never double-posts the reply.
152
+ await gh.resolveReviewThread?.(target.installationId, ref, threadId);
153
+ if (wantsReply)
154
+ await gh.replyToReviewThread?.(target.installationId, ref, threadId, reply);
155
+ }
156
+ catch {
157
+ // Best-effort per thread: keep going so a single bad thread doesn't strand the rest.
158
+ failed.push(threadId);
159
+ }
160
+ }
161
+ // Surface a partial failure to the caller. The gate's onHelperComplete RETAINS the handed
162
+ // thread ids when this throws so the next probe's reconcile retries exactly those (a
163
+ // swallowed failure here would let the gate clear its stash and re-dispatch a whole fixer
164
+ // round for an already-fixed thread instead of the cheap resolve-only reconcile).
165
+ if (failed.length > 0) {
166
+ throw new Error(`Failed to resolve ${failed.length} review thread(s): ${failed.join(', ')}`);
167
+ }
168
+ }
169
+ }
170
+ //# sourceMappingURL=GitHubPullRequestReviewProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GitHubPullRequestReviewProvider.js","sourceRoot":"","sources":["../../src/github/GitHubPullRequestReviewProvider.ts"],"names":[],"mappings":"AAmBA,MAAM,KAAK,GAA8B;IACvC,OAAO,EAAE,IAAI;IACb,4BAA4B,EAAE,CAAC;IAC/B,iBAAiB,EAAE,EAAE;IACrB,SAAS,EAAE,CAAC;IACZ,iBAAiB,EAAE,EAAE;IACrB,QAAQ,EAAE,EAAE;CACb,CAAA;AAED,6FAA6F;AAC7F,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;AAChC,CAAC;AAED,wGAAwG;AACxG,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,mBAAmB,EAAE,WAAW,CAAC,CAAC,CAAA;AAExE;;;;;;GAMG;AACH,SAAS,cAAc,CAAC,OAAkC;IACxD,MAAM,cAAc,GAAG,IAAI,GAAG,EAAkB,CAAA;IAChD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC;YAAE,SAAQ;QAC/C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;YAAE,SAAQ;QACpC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,CAAA;IACvC,CAAC;IACD,IAAI,SAAS,GAAG,CAAC,CAAA;IACjB,KAAK,MAAM,KAAK,IAAI,cAAc,CAAC,MAAM,EAAE;QAAE,IAAI,KAAK,KAAK,UAAU;YAAE,SAAS,EAAE,CAAA;IAClF,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAS,cAAc,CAAC,CAMvB;IACC,MAAM,KAAK,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;IAC3B,MAAM,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAC9C,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAA;IACtC,OAAO;QACL,QAAQ,EAAE,CAAC,CAAC,EAAE;QACd,MAAM,EAAE,KAAK,EAAE,MAAM,IAAI,EAAE;QAC3B,WAAW,EAAE,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI;QAChE,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,KAAK,EAAE,UAAU,CAAC,IAAI,EAAE,MAAM,IAAI,EAAE,CAAC;QACrC,eAAe,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;KAC1E,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,OAAO,+BAA+B;IACb,IAAI;IAAjC,YAA6B,IAAiD;oBAAjD,IAAI;IAAgD,CAAC;IAElF,KAAK,CAAC,SAAS,CACb,WAAmB,EACnB,OAAe,EACf,kCAAkD;QAElD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QACvE,MAAM,MAAM,GAAG,KAAK,EAAE,WAAW,EAAE,MAAM,CAAA;QACzC,MAAM,MAAM,GAAG,KAAK,EAAE,WAAW,EAAE,MAAM,CAAA;QACzC,IAAI,CAAC,MAAM,IAAI,MAAM,IAAI,IAAI;YAAE,OAAO,KAAK,CAAA;QAE3C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QACtE,IAAI,CAAC,MAAM;YAAE,OAAO,KAAK,CAAA;QACzB,MAAM,GAAG,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAA;QACtD,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAA;QAEjC,4FAA4F;QAC5F,8FAA8F;QAC9F,0FAA0F;QAC1F,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,aAAa,CAAC,MAAM,CAAC,cAAc,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;QAC1E,IAAI,CAAC,OAAO;YAAE,OAAO,KAAK,CAAA;QAE1B,4FAA4F;QAC5F,8FAA8F;QAC9F,0FAA0F;QAC1F,8FAA8F;QAC9F,0FAA0F;QAC1F,gGAAgG;QAChG,MAAM,aAAa,GACjB,kCAAkC,IAAI,IAAI;YACxC,CAAC,CAAC,kCAAkC;YACpC,CAAC,CAAC,MAAM,IAAI,CAAC,mCAAmC,CAAC,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;QAEzE,wFAAwF;QACxF,yFAAyF;QACzF,oFAAoF;QACpF,wFAAwF;QACxF,0FAA0F;QAC1F,oFAAoF;QACpF,yFAAyF;QACzF,mFAAmF;QACnF,uFAAuF;QACvF,8CAA8C;QAC9C,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC3C,EAAE,CAAC,sBAAsB,EAAE,CAAC,MAAM,CAAC,cAAc,EAAE,GAAG,EAAE,MAAM,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACtF,EAAE,CAAC,iBAAiB,EAAE,CAAC,MAAM,CAAC,cAAc,EAAE,GAAG,EAAE,MAAM,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;SAClF,CAAC,CAAA;QACF,MAAM,SAAS,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;QACzC,MAAM,QAAQ,GAAG,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,aAAa,CAAC,CAAA;QACxD,MAAM,CAAC,iBAAiB,EAAE,QAAQ,CAAC,GAAG,QAAQ;YAC5C,CAAC,CAAC,CAAC,EAAc,EAAE,EAAgC,CAAC;YACpD,CAAC,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC;gBAChB,EAAE,CAAC,sBAAsB,EAAE,CAAC,MAAM,CAAC,cAAc,EAAE,GAAG,EAAE,MAAM,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBACtF,EAAE,CAAC,iBAAiB,EAAE,CAAC,MAAM,CAAC,cAAc,EAAE,GAAG,EAAE,MAAM,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;aAClF,CAAC,CAAA;QAEN,OAAO;YACL,OAAO;YACP,4BAA4B,EAAE,aAAa;YAC3C,iBAAiB;YACjB,SAAS;YACT,iBAAiB,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC;YAC3E,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC7B,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,SAAS,EAAE,CAAC,CAAC,SAAS;gBACtB,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC;aAC5B,CAAC,CAAC;SACJ,CAAA;IACH,CAAC;IAED,4FAA4F;IACpF,KAAK,CAAC,mCAAmC,CAC/C,MAAsD,EACtD,GAAoC,EACpC,MAAc;QAEd,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAA;QACjC,IAAI,CAAC,EAAE,CAAC,+BAA+B;YAAE,OAAO,CAAC,CAAA;QACjD,MAAM,OAAO,GACX,CAAC,MAAM,EAAE,CAAC,qBAAqB,EAAE,CAAC,MAAM,CAAC,cAAc,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC,UAAU,CAAA;QAC7F,OAAO,EAAE,CAAC,+BAA+B,CAAC,MAAM,CAAC,cAAc,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;IAChF,CAAC;IAED,KAAK,CAAC,cAAc,CAClB,WAAmB,EACnB,OAAe,EACf,SAAmB,EACnB,KAAa;QAEb,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,OAAM;QAClC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;QACtE,IAAI,CAAC,MAAM;YAAE,OAAM;QACnB,MAAM,GAAG,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAA;QACtD,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAA;QACjC,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAA;QAC1C,MAAM,MAAM,GAAa,EAAE,CAAA;QAC3B,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC;gBACH,yFAAyF;gBACzF,yFAAyF;gBACzF,0FAA0F;gBAC1F,wFAAwF;gBACxF,sFAAsF;gBACtF,6DAA6D;gBAC7D,MAAM,EAAE,CAAC,mBAAmB,EAAE,CAAC,MAAM,CAAC,cAAc,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAA;gBACpE,IAAI,UAAU;oBAAE,MAAM,EAAE,CAAC,mBAAmB,EAAE,CAAC,MAAM,CAAC,cAAc,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAA;YAC7F,CAAC;YAAC,MAAM,CAAC;gBACP,qFAAqF;gBACrF,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YACvB,CAAC;QACH,CAAC;QACD,0FAA0F;QAC1F,qFAAqF;QACrF,0FAA0F;QAC1F,kFAAkF;QAClF,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,qBAAqB,MAAM,CAAC,MAAM,sBAAsB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAC9F,CAAC;IACH,CAAC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../src/http/errorHandler.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAanC,oEAAoE;AACpE,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,QAAQ,CA2BhE"}
1
+ {"version":3,"file":"errorHandler.d.ts","sourceRoot":"","sources":["../../src/http/errorHandler.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAanC,oEAAoE;AACpE,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,QAAQ,CAmDhE"}
@@ -1,4 +1,5 @@
1
1
  import { DomainError } from '@cat-factory/kernel';
2
+ import { SchemaValidationError } from '@toad-contracts/core';
2
3
  import { logger } from '../observability/logger.js';
3
4
  const STATUS_BY_CODE = {
4
5
  not_found: 404,
@@ -10,6 +11,25 @@ const STATUS_BY_CODE = {
10
11
  };
11
12
  /** Maps domain errors to HTTP responses; anything else is a 500. */
12
13
  export function handleError(error, c) {
14
+ // A contract request schema (path/query/header/body) rejected the input. Surface the
15
+ // same `{ error: { code: 'validation', ... } }` envelope the old @hono/valibot-validator
16
+ // `jsonBody` middleware produced, so the wire shape is unchanged after the contract migration.
17
+ if (error instanceof SchemaValidationError) {
18
+ return c.json({
19
+ error: {
20
+ code: 'validation',
21
+ message: 'Request failed validation',
22
+ issues: error.issues.map((issue) => ({
23
+ path: issue.path
24
+ ?.map((segment) => typeof segment === 'object' && segment !== null && 'key' in segment
25
+ ? String(segment.key)
26
+ : String(segment))
27
+ .join('.'),
28
+ message: issue.message,
29
+ })),
30
+ },
31
+ }, 400);
32
+ }
13
33
  if (error instanceof DomainError) {
14
34
  return c.json({
15
35
  error: {
@@ -1 +1 @@
1
- {"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../../src/http/errorHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAGjD,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AAEnD,MAAM,cAAc,GAAsD;IACxE,SAAS,EAAE,GAAG;IACd,UAAU,EAAE,GAAG;IACf,QAAQ,EAAE,GAAG;IACb,mFAAmF;IACnF,qFAAqF;IACrF,mBAAmB,EAAE,GAAG;CACzB,CAAA;AAED,oEAAoE;AACpE,MAAM,UAAU,WAAW,CAAC,KAAc,EAAE,CAAU;IACpD,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;QACjC,OAAO,CAAC,CAAC,IAAI,CACX;YACE,KAAK,EAAE;gBACL,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACrD;SACF,EACD,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAC3B,CAAA;IACH,CAAC;IACD,6EAA6E;IAC7E,gCAAgC;IAChC,MAAM,CAAC,KAAK,CACV;QACE,GAAG,EACD,KAAK,YAAY,KAAK;YACpB,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE;YAChD,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE;QAChC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM;QACpB,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ;KAClC,EACD,yBAAyB,CAC1B,CAAA;IACD,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,uBAAuB,EAAE,EAAE,EAAE,GAAG,CAAC,CAAA;AACvF,CAAC"}
1
+ {"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../../src/http/errorHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAG5D,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AAEnD,MAAM,cAAc,GAAsD;IACxE,SAAS,EAAE,GAAG;IACd,UAAU,EAAE,GAAG;IACf,QAAQ,EAAE,GAAG;IACb,mFAAmF;IACnF,qFAAqF;IACrF,mBAAmB,EAAE,GAAG;CACzB,CAAA;AAED,oEAAoE;AACpE,MAAM,UAAU,WAAW,CAAC,KAAc,EAAE,CAAU;IACpD,qFAAqF;IACrF,yFAAyF;IACzF,+FAA+F;IAC/F,IAAI,KAAK,YAAY,qBAAqB,EAAE,CAAC;QAC3C,OAAO,CAAC,CAAC,IAAI,CACX;YACE,KAAK,EAAE;gBACL,IAAI,EAAE,YAAY;gBAClB,OAAO,EAAE,2BAA2B;gBACpC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;oBACnC,IAAI,EAAE,KAAK,CAAC,IAAI;wBACd,EAAE,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAChB,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,KAAK,IAAI,OAAO;wBACjE,CAAC,CAAC,MAAM,CAAE,OAAgC,CAAC,GAAG,CAAC;wBAC/C,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CACpB;yBACA,IAAI,CAAC,GAAG,CAAC;oBACZ,OAAO,EAAE,KAAK,CAAC,OAAO;iBACvB,CAAC,CAAC;aACJ;SACF,EACD,GAAG,CACJ,CAAA;IACH,CAAC;IACD,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;QACjC,OAAO,CAAC,CAAC,IAAI,CACX;YACE,KAAK,EAAE;gBACL,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACrD;SACF,EACD,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAC3B,CAAA;IACH,CAAC;IACD,6EAA6E;IAC7E,gCAAgC;IAChC,MAAM,CAAC,KAAK,CACV;QACE,GAAG,EACD,KAAK,YAAY,KAAK;YACpB,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE;YAChD,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE;QAChC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM;QACpB,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ;KAClC,EACD,yBAAyB,CAC1B,CAAA;IACD,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,uBAAuB,EAAE,EAAE,EAAE,GAAG,CAAC,CAAA;AACvF,CAAC"}
package/dist/index.d.ts CHANGED
@@ -25,7 +25,6 @@ export { FanOutEventPublisher, type FanOutEventPublisherDependencies, } from './
25
25
  export { InAppNotificationChannel } from './events/InAppNotificationChannel.js';
26
26
  export { mountAuthGate } from './http/authGate.js';
27
27
  export { param } from './http/params.js';
28
- export { jsonBody } from './http/validation.js';
29
28
  export { handleError } from './http/errorHandler.js';
30
29
  export { parseAllowedOrigins, resolveCorsOrigin } from './http/cors.js';
31
30
  export { base64url, base64urlToBytes, pkcs8PemToDer, timingSafeEqual } from './crypto/encoding.js';
@@ -39,6 +38,7 @@ export { FetchGitHubClient, GitHubApiError, type FetchGitHubClientDependencies,
39
38
  export { FetchGitHubProvisioningClient, type FetchGitHubProvisioningClientDependencies, } from './github/FetchGitHubProvisioningClient.js';
40
39
  export { WebCryptoWebhookVerifier } from './github/WebCryptoWebhookVerifier.js';
41
40
  export { GitHubCiStatusProvider, type GitHubCiStatusProviderDependencies, } from './github/GitHubCiStatusProvider.js';
41
+ export { GitHubPullRequestReviewProvider, type GitHubPullRequestReviewProviderDependencies, } from './github/GitHubPullRequestReviewProvider.js';
42
42
  export { GitHubMergeabilityProvider, classifyMergeability, type GitHubMergeabilityProviderDependencies, } from './github/GitHubMergeabilityProvider.js';
43
43
  export { GitHubBranchUpdater, type GitHubBranchUpdaterDependencies, } from './github/GitHubBranchUpdater.js';
44
44
  export { GitHubPullRequestMerger, type GitHubPullRequestMergerDependencies, } from './github/GitHubPullRequestMerger.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -34,7 +34,6 @@ export { FanOutEventPublisher, } from './events/FanOutEventPublisher.js';
34
34
  export { InAppNotificationChannel } from './events/InAppNotificationChannel.js';
35
35
  export { mountAuthGate } from './http/authGate.js';
36
36
  export { param } from './http/params.js';
37
- export { jsonBody } from './http/validation.js';
38
37
  export { handleError } from './http/errorHandler.js';
39
38
  export { parseAllowedOrigins, resolveCorsOrigin } from './http/cors.js';
40
39
  export { base64url, base64urlToBytes, pkcs8PemToDer, timingSafeEqual } from './crypto/encoding.js';
@@ -57,6 +56,7 @@ export { FetchGitHubClient, GitHubApiError, } from './github/FetchGitHubClient.j
57
56
  export { FetchGitHubProvisioningClient, } from './github/FetchGitHubProvisioningClient.js';
58
57
  export { WebCryptoWebhookVerifier } from './github/WebCryptoWebhookVerifier.js';
59
58
  export { GitHubCiStatusProvider, } from './github/GitHubCiStatusProvider.js';
59
+ export { GitHubPullRequestReviewProvider, } from './github/GitHubPullRequestReviewProvider.js';
60
60
  export { GitHubMergeabilityProvider, classifyMergeability, } from './github/GitHubMergeabilityProvider.js';
61
61
  export { GitHubBranchUpdater, } from './github/GitHubBranchUpdater.js';
62
62
  export { GitHubPullRequestMerger, } from './github/GitHubPullRequestMerger.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,gFAAgF;AAChF,8EAA8E;AAC9E,qEAAqE;AACrE,OAAO,EAAE,MAAM,EAAe,MAAM,2BAA2B,CAAA;AAC/D,OAAO,EAAqC,MAAM,eAAe,CAAA;AACjE,OAAO,EAYN,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,sBAAsB,EACtB,wBAAwB,EACxB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,kCAAkC,CAAA;AACzC,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAA;AAC/E,OAAO,EAAE,WAAW,EAAqB,MAAM,mBAAmB,CAAA;AAClE,OAAO,EACL,WAAW,GAGZ,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACL,WAAW,GAGZ,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAA;AAC7E,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAA;AACxF,OAAO,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAA;AAC7E,OAAO,EACL,uBAAuB,EACvB,sBAAsB,GAGvB,MAAM,yCAAyC,CAAA;AAChD,mFAAmF;AACnF,kFAAkF;AAClF,oFAAoF;AACpF,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAA;AAC3E,OAAO,EACL,sBAAsB,GAMvB,MAAM,oCAAoC,CAAA;AAC3C,OAAO,EAAE,uBAAuB,EAA8B,MAAM,8BAA8B,CAAA;AAClG,OAAO,EAAE,eAAe,EAA+B,MAAM,6BAA6B,CAAA;AAC1F,OAAO,EACL,iCAAiC,GAElC,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EACL,4BAA4B,GAE7B,MAAM,kCAAkC,CAAA;AACzC,OAAO,EACL,yBAAyB,GAE1B,MAAM,uCAAuC,CAAA;AAC9C,OAAO,EACL,sBAAsB,GAEvB,MAAM,+BAA+B,CAAA;AACtC,qFAAqF;AACrF,4FAA4F;AAC5F,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,yBAAyB,EACzB,UAAU,GACX,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAC9E,OAAO,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAA;AAClD,OAAO,EACL,oBAAoB,GAErB,MAAM,kCAAkC,CAAA;AACzC,OAAO,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAA;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACpD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AACvE,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAClG,kFAAkF;AAClF,8EAA8E;AAC9E,kEAAkE;AAClE,OAAO,EACL,qBAAqB,GAEtB,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EAAE,6BAA6B,EAAE,MAAM,2CAA2C,CAAA;AACzF,OAAO,EAAE,aAAa,EAAkC,MAAM,2BAA2B,CAAA;AACzF,OAAO,EACL,iBAAiB,GAIlB,MAAM,+BAA+B,CAAA;AACtC,OAAO,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAA;AAC/E,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAA;AACpF,gFAAgF;AAChF,kFAAkF;AAClF,qFAAqF;AACrF,6BAA6B;AAC7B,OAAO,EACL,iBAAiB,EACjB,cAAc,GAEf,MAAM,+BAA+B,CAAA;AACtC,oFAAoF;AACpF,qEAAqE;AACrE,OAAO,EACL,6BAA6B,GAE9B,MAAM,2CAA2C,CAAA;AAClD,OAAO,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAA;AAC/E,OAAO,EACL,sBAAsB,GAEvB,MAAM,oCAAoC,CAAA;AAC3C,OAAO,EACL,0BAA0B,EAC1B,oBAAoB,GAErB,MAAM,wCAAwC,CAAA;AAC/C,OAAO,EACL,mBAAmB,GAEpB,MAAM,iCAAiC,CAAA;AACxC,OAAO,EACL,uBAAuB,GAExB,MAAM,qCAAqC,CAAA;AAC5C,OAAO,EACL,UAAU,EACV,cAAc,GAIf,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,YAAY,GAGb,MAAM,oBAAoB,CAAA;AAqB3B,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;AAE/D,mFAAmF;AACnF,iEAAiE;AACjE,cAAc,0BAA0B,CAAA;AACxC,cAAc,kCAAkC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,10 @@ import type { AppEnv } from '../../http/env.js';
5
5
  * plus any orgs they belong to), org creation, and membership management. Accounts
6
6
  * are an authenticated concept; with auth disabled (no signed-in user) there is a
7
7
  * single implicit dev context, so the list is empty and mutations are refused.
8
+ *
9
+ * Every route is mounted from its `@cat-factory/contracts` contract via
10
+ * `buildHonoRoute`: the method/path and request validation come from the contract,
11
+ * and `c.req.valid(...)` + the `c.json(body, status)` return are typed from it.
8
12
  */
9
13
  export declare function accountController(): Hono<AppEnv>;
10
14
  //# sourceMappingURL=AccountController.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AccountController.d.ts","sourceRoot":"","sources":["../../../src/modules/accounts/AccountController.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAc/C;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAAC,MAAM,CAAC,CAuOhD"}
1
+ {"version":3,"file":"AccountController.d.ts","sourceRoot":"","sources":["../../../src/modules/accounts/AccountController.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAE3B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAgB/C;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAAC,MAAM,CAAC,CAwOhD"}
@@ -1,9 +1,12 @@
1
- import { addApiKeySchema, addMemberSchema, connectEmailSchema, createAccountSchema, createInvitationSchema, setMemberRolesSchema, testEmailSchema, updateAccountSchema, updateAccountSettingsSchema, } from '@cat-factory/contracts';
1
+ import { addAccountApiKeyContract, addAccountMemberContract, connectEmailContract, createAccountContract, createInvitationContract, disconnectEmailContract, getAccountSettingsContract, getEmailConnectionContract, listAccountApiKeysContract, listAccountMembersContract, listAccountsContract, listInvitationsContract, removeAccountApiKeyContract, revokeInvitationContract, setMemberRolesContract, testEmailContract, updateAccountContract, updateAccountSettingsContract, } from '@cat-factory/contracts';
2
+ import { buildHonoRoute } from '@toad-contracts/hono';
2
3
  import { Hono } from 'hono';
3
- import { param } from '../../http/params.js';
4
- import { jsonBody } from '../../http/validation.js';
5
4
  import { apiKeyToWire } from '../providers/ApiKeyController.js';
6
- /** The signed-in user, narrowed to what the tenancy layer needs. */
5
+ /**
6
+ * The signed-in user, narrowed to what the tenancy layer needs. Generic over the
7
+ * env so it accepts a contract-typed handler context (`ContractEnv<T> & AppEnv`),
8
+ * which Hono treats as a distinct, non-assignable env from the bare `AppEnv`.
9
+ */
7
10
  function accountUser(c) {
8
11
  const user = c.get('user');
9
12
  return user ? { id: user.id, login: user.login, name: user.name } : null;
@@ -14,74 +17,81 @@ const signInRequired = (c) => c.json({ error: { code: 'unauthorized', message: '
14
17
  * plus any orgs they belong to), org creation, and membership management. Accounts
15
18
  * are an authenticated concept; with auth disabled (no signed-in user) there is a
16
19
  * single implicit dev context, so the list is empty and mutations are refused.
20
+ *
21
+ * Every route is mounted from its `@cat-factory/contracts` contract via
22
+ * `buildHonoRoute`: the method/path and request validation come from the contract,
23
+ * and `c.req.valid(...)` + the `c.json(body, status)` return are typed from it.
17
24
  */
18
25
  export function accountController() {
19
26
  const app = new Hono();
20
- app.get('/accounts', async (c) => {
27
+ buildHonoRoute(app, listAccountsContract, async (c) => {
21
28
  const user = accountUser(c);
22
29
  if (!user)
23
- return c.json([]);
24
- return c.json(await c.get('container').accountService.listForUser(user));
30
+ return c.json([], 200);
31
+ return c.json(await c.get('container').accountService.listForUser(user), 200);
25
32
  });
26
- app.post('/accounts', jsonBody(createAccountSchema), async (c) => {
33
+ buildHonoRoute(app, createAccountContract, async (c) => {
27
34
  const user = accountUser(c);
28
35
  if (!user)
29
36
  return signInRequired(c);
30
37
  const account = await c.get('container').accountService.createOrg(user, c.req.valid('json'));
31
38
  return c.json(account, 201);
32
39
  });
33
- app.patch('/accounts/:accountId', jsonBody(updateAccountSchema), async (c) => {
40
+ buildHonoRoute(app, updateAccountContract, async (c) => {
34
41
  const user = accountUser(c);
35
42
  if (!user)
36
43
  return signInRequired(c);
37
44
  const account = await c
38
45
  .get('container')
39
- .accountService.updateSettings(param(c, 'accountId'), user.id, c.req.valid('json'));
40
- return c.json(account);
46
+ .accountService.updateSettings(c.req.valid('param').accountId, user.id, c.req.valid('json'));
47
+ return c.json(account, 200);
41
48
  });
42
- app.get('/accounts/:accountId/members', async (c) => {
49
+ buildHonoRoute(app, listAccountMembersContract, async (c) => {
43
50
  const user = accountUser(c);
44
51
  if (!user)
45
52
  return signInRequired(c);
46
53
  const accounts = c.get('container').accountService;
54
+ const { accountId } = c.req.valid('param');
47
55
  // Membership in the account is required to see its roster (404 otherwise).
48
- await accounts.requireMember(param(c, 'accountId'), user.id);
49
- return c.json(await accounts.members(param(c, 'accountId')));
56
+ await accounts.requireMember(accountId, user.id);
57
+ return c.json(await accounts.members(accountId), 200);
50
58
  });
51
- app.post('/accounts/:accountId/members', jsonBody(addMemberSchema), async (c) => {
59
+ buildHonoRoute(app, addAccountMemberContract, async (c) => {
52
60
  const user = accountUser(c);
53
61
  if (!user)
54
62
  return signInRequired(c);
55
63
  const body = c.req.valid('json');
56
64
  const member = await c
57
65
  .get('container')
58
- .accountService.addMember(param(c, 'accountId'), user.id, body.userId, body.roles);
66
+ .accountService.addMember(c.req.valid('param').accountId, user.id, body.userId, body.roles);
59
67
  return c.json(member, 201);
60
68
  });
61
69
  // Set a member's role set (admin-only). The acting admin can't drop their own admin.
62
- app.patch('/accounts/:accountId/members/:userId/roles', jsonBody(setMemberRolesSchema), async (c) => {
70
+ buildHonoRoute(app, setMemberRolesContract, async (c) => {
63
71
  const user = accountUser(c);
64
72
  if (!user)
65
73
  return signInRequired(c);
74
+ const { accountId, userId } = c.req.valid('param');
66
75
  const member = await c
67
76
  .get('container')
68
- .accountService.setMemberRoles(param(c, 'accountId'), user.id, param(c, 'userId'), c.req.valid('json').roles);
69
- return c.json(member);
77
+ .accountService.setMemberRoles(accountId, user.id, userId, c.req.valid('json').roles);
78
+ return c.json(member, 200);
70
79
  });
71
80
  // ---- Invitations (email-based org onboarding) ---------------------------
72
81
  // Available only when the invitation repository is wired (opt-in feature).
73
- app.get('/accounts/:accountId/invitations', async (c) => {
82
+ buildHonoRoute(app, listInvitationsContract, async (c) => {
74
83
  const user = accountUser(c);
75
84
  if (!user)
76
85
  return signInRequired(c);
77
86
  const container = c.get('container');
78
87
  if (!container.invitations)
79
- return c.json([]);
88
+ return c.json([], 200);
89
+ const { accountId } = c.req.valid('param');
80
90
  // Membership is required to view the account's pending invitations.
81
- await container.accountService.requireMember(param(c, 'accountId'), user.id);
82
- return c.json(await container.invitations.list(param(c, 'accountId')));
91
+ await container.accountService.requireMember(accountId, user.id);
92
+ return c.json(await container.invitations.list(accountId), 200);
83
93
  });
84
- app.post('/accounts/:accountId/invitations', jsonBody(createInvitationSchema), async (c) => {
94
+ buildHonoRoute(app, createInvitationContract, async (c) => {
85
95
  const user = accountUser(c);
86
96
  if (!user)
87
97
  return signInRequired(c);
@@ -90,19 +100,20 @@ export function accountController() {
90
100
  return c.json({ error: { code: 'unavailable', message: 'Invitations are not configured' } }, 503);
91
101
  }
92
102
  const body = c.req.valid('json');
93
- const created = await container.invitations.invite(param(c, 'accountId'), user.id, body.email, body.roles);
103
+ const created = await container.invitations.invite(c.req.valid('param').accountId, user.id, body.email, body.roles);
94
104
  // The raw accept link is returned so an operator can share it manually when no
95
105
  // email transport is configured; never re-derivable afterwards.
96
106
  return c.json({ invitation: created.invitation, acceptUrl: created.acceptUrl }, 201);
97
107
  });
98
- app.delete('/accounts/:accountId/invitations/:invitationId', async (c) => {
108
+ buildHonoRoute(app, revokeInvitationContract, async (c) => {
99
109
  const user = accountUser(c);
100
110
  if (!user)
101
111
  return signInRequired(c);
102
112
  const container = c.get('container');
103
113
  if (!container.invitations)
104
114
  return c.body(null, 204);
105
- await container.invitations.revoke(param(c, 'accountId'), user.id, param(c, 'invitationId'));
115
+ const { accountId, invitationId } = c.req.valid('param');
116
+ await container.invitations.revoke(accountId, user.id, invitationId);
106
117
  return c.body(null, 204);
107
118
  });
108
119
  // ---- Account-scoped provider API keys (admin-onboarded, shared org pool) ----
@@ -111,53 +122,57 @@ export function accountController() {
111
122
  // the raw key is write-only — only secret-free metadata is ever returned. Available
112
123
  // only when the API-key store is wired (ENCRYPTION_KEY).
113
124
  const apiKeysUnavailable = (c) => c.json({ error: { code: 'unavailable', message: 'API key storage is not configured' } }, 503);
114
- app.get('/accounts/:accountId/api-keys', async (c) => {
125
+ buildHonoRoute(app, listAccountApiKeysContract, async (c) => {
115
126
  const user = accountUser(c);
116
127
  if (!user)
117
128
  return signInRequired(c);
118
129
  const container = c.get('container');
119
130
  if (!container.apiKeys)
120
131
  return apiKeysUnavailable(c);
121
- await container.accountService.requireAdmin(param(c, 'accountId'), user.id);
122
- const keys = await container.apiKeys.listKeys('account', param(c, 'accountId'));
123
- return c.json({ keys: keys.map(apiKeyToWire) });
132
+ const { accountId } = c.req.valid('param');
133
+ await container.accountService.requireAdmin(accountId, user.id);
134
+ const keys = await container.apiKeys.listKeys('account', accountId);
135
+ return c.json({ keys: keys.map(apiKeyToWire) }, 200);
124
136
  });
125
- app.post('/accounts/:accountId/api-keys', jsonBody(addApiKeySchema), async (c) => {
137
+ buildHonoRoute(app, addAccountApiKeyContract, async (c) => {
126
138
  const user = accountUser(c);
127
139
  if (!user)
128
140
  return signInRequired(c);
129
141
  const container = c.get('container');
130
142
  if (!container.apiKeys)
131
143
  return apiKeysUnavailable(c);
132
- await container.accountService.requireAdmin(param(c, 'accountId'), user.id);
133
- const summary = await container.apiKeys.addKey('account', param(c, 'accountId'), c.req.valid('json'));
144
+ const { accountId } = c.req.valid('param');
145
+ await container.accountService.requireAdmin(accountId, user.id);
146
+ const summary = await container.apiKeys.addKey('account', accountId, c.req.valid('json'));
134
147
  return c.json(apiKeyToWire(summary), 201);
135
148
  });
136
- app.delete('/accounts/:accountId/api-keys/:id', async (c) => {
149
+ buildHonoRoute(app, removeAccountApiKeyContract, async (c) => {
137
150
  const user = accountUser(c);
138
151
  if (!user)
139
152
  return signInRequired(c);
140
153
  const container = c.get('container');
141
154
  if (!container.apiKeys)
142
155
  return apiKeysUnavailable(c);
143
- await container.accountService.requireAdmin(param(c, 'accountId'), user.id);
144
- await container.apiKeys.removeKey('account', param(c, 'accountId'), param(c, 'id'));
156
+ const { accountId, id } = c.req.valid('param');
157
+ await container.accountService.requireAdmin(accountId, user.id);
158
+ await container.apiKeys.removeKey('account', accountId, id);
145
159
  return c.body(null, 204);
146
160
  });
147
161
  // ---- Email sender connection (per-account, UI-onboarded) ----------------
148
162
  // Owner-only mutations; available only when the email module is wired.
149
- app.get('/accounts/:accountId/email-connection', async (c) => {
163
+ buildHonoRoute(app, getEmailConnectionContract, async (c) => {
150
164
  const user = accountUser(c);
151
165
  if (!user)
152
166
  return signInRequired(c);
153
167
  const container = c.get('container');
154
168
  if (!container.email)
155
- return c.json({ connection: null, configured: false });
156
- await container.accountService.requireMember(param(c, 'accountId'), user.id);
157
- const connection = await container.email.getConnection(param(c, 'accountId'));
158
- return c.json({ connection, configured: true });
169
+ return c.json({ connection: null, configured: false }, 200);
170
+ const { accountId } = c.req.valid('param');
171
+ await container.accountService.requireMember(accountId, user.id);
172
+ const connection = await container.email.getConnection(accountId);
173
+ return c.json({ connection, configured: true }, 200);
159
174
  });
160
- app.post('/accounts/:accountId/email-connection', jsonBody(connectEmailSchema), async (c) => {
175
+ buildHonoRoute(app, connectEmailContract, async (c) => {
161
176
  const user = accountUser(c);
162
177
  if (!user)
163
178
  return signInRequired(c);
@@ -165,22 +180,24 @@ export function accountController() {
165
180
  if (!container.email) {
166
181
  return c.json({ error: { code: 'unavailable', message: 'Email is not configured' } }, 503);
167
182
  }
168
- await c.get('container').accountService.requireAdmin(param(c, 'accountId'), user.id);
169
- const connection = await container.email.connect(param(c, 'accountId'), c.req.valid('json'));
183
+ const { accountId } = c.req.valid('param');
184
+ await container.accountService.requireAdmin(accountId, user.id);
185
+ const connection = await container.email.connect(accountId, c.req.valid('json'));
170
186
  return c.json(connection, 201);
171
187
  });
172
- app.delete('/accounts/:accountId/email-connection', async (c) => {
188
+ buildHonoRoute(app, disconnectEmailContract, async (c) => {
173
189
  const user = accountUser(c);
174
190
  if (!user)
175
191
  return signInRequired(c);
176
192
  const container = c.get('container');
177
193
  if (!container.email)
178
194
  return c.body(null, 204);
179
- await c.get('container').accountService.requireAdmin(param(c, 'accountId'), user.id);
180
- await container.email.disconnect(param(c, 'accountId'));
195
+ const { accountId } = c.req.valid('param');
196
+ await container.accountService.requireAdmin(accountId, user.id);
197
+ await container.email.disconnect(accountId);
181
198
  return c.body(null, 204);
182
199
  });
183
- app.post('/accounts/:accountId/email-connection/test', jsonBody(testEmailSchema), async (c) => {
200
+ buildHonoRoute(app, testEmailContract, async (c) => {
184
201
  const user = accountUser(c);
185
202
  if (!user)
186
203
  return signInRequired(c);
@@ -188,9 +205,10 @@ export function accountController() {
188
205
  if (!container.email) {
189
206
  return c.json({ error: { code: 'unavailable', message: 'Email is not configured' } }, 503);
190
207
  }
191
- await c.get('container').accountService.requireAdmin(param(c, 'accountId'), user.id);
192
- await container.email.sendTest(param(c, 'accountId'), c.req.valid('json').to);
193
- return c.json({ ok: true });
208
+ const { accountId } = c.req.valid('param');
209
+ await container.accountService.requireAdmin(accountId, user.id);
210
+ await container.email.sendTest(accountId, c.req.valid('json').to);
211
+ return c.json({ ok: true }, 200);
194
212
  });
195
213
  // ---- Deployment settings (per-account, admin-only) ----------------------
196
214
  // The integration secrets (Slack OAuth / web-search / Langfuse) + tuning (retention,
@@ -199,25 +217,27 @@ export function accountController() {
199
217
  // settings store is wired (ENCRYPTION_KEY). Admin-gated for BOTH read and write —
200
218
  // these are sensitive deployment knobs.
201
219
  const settingsUnavailable = (c) => c.json({ error: { code: 'unavailable', message: 'Account settings storage is not configured' } }, 503);
202
- app.get('/accounts/:accountId/settings', async (c) => {
220
+ buildHonoRoute(app, getAccountSettingsContract, async (c) => {
203
221
  const user = accountUser(c);
204
222
  if (!user)
205
223
  return signInRequired(c);
206
224
  const container = c.get('container');
207
225
  if (!container.accountSettings)
208
226
  return settingsUnavailable(c);
209
- await container.accountService.requireAdmin(param(c, 'accountId'), user.id);
210
- return c.json(await container.accountSettings.service.read(param(c, 'accountId')));
227
+ const { accountId } = c.req.valid('param');
228
+ await container.accountService.requireAdmin(accountId, user.id);
229
+ return c.json(await container.accountSettings.service.read(accountId), 200);
211
230
  });
212
- app.put('/accounts/:accountId/settings', jsonBody(updateAccountSettingsSchema), async (c) => {
231
+ buildHonoRoute(app, updateAccountSettingsContract, async (c) => {
213
232
  const user = accountUser(c);
214
233
  if (!user)
215
234
  return signInRequired(c);
216
235
  const container = c.get('container');
217
236
  if (!container.accountSettings)
218
237
  return settingsUnavailable(c);
219
- await container.accountService.requireAdmin(param(c, 'accountId'), user.id);
220
- return c.json(await container.accountSettings.service.write(param(c, 'accountId'), c.req.valid('json')));
238
+ const { accountId } = c.req.valid('param');
239
+ await container.accountService.requireAdmin(accountId, user.id);
240
+ return c.json(await container.accountSettings.service.write(accountId, c.req.valid('json')), 200);
221
241
  });
222
242
  return app;
223
243
  }