@cat-factory/app 0.36.0 → 0.37.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.
- package/app/components/auth/UserMenu.vue +11 -1
- package/app/components/brainstorm/BrainstormWindow.vue +2 -1
- package/app/components/clarity/ClarityReviewWindow.vue +2 -1
- package/app/components/layout/IntegrationBackTitle.vue +12 -7
- package/app/components/layout/IntegrationsHub.vue +191 -43
- package/app/components/layout/PersonalSetupModal.vue +141 -0
- package/app/components/pipeline/PipelineBuilder.vue +1 -1
- package/app/components/providers/VendorCredentialsModal.vue +7 -2
- package/app/composables/api/accounts.ts +36 -51
- package/app/composables/api/auth.ts +20 -19
- package/app/composables/api/board.ts +60 -40
- package/app/composables/api/bootstrap.ts +25 -22
- package/app/composables/api/client.ts +102 -0
- package/app/composables/api/context.ts +25 -6
- package/app/composables/api/documents.ts +36 -34
- package/app/composables/api/execution.ts +65 -48
- package/app/composables/api/followUps.ts +26 -26
- package/app/composables/api/fragments.ts +47 -34
- package/app/composables/api/github.ts +65 -45
- package/app/composables/api/humanReview.ts +7 -6
- package/app/composables/api/humanTest.ts +15 -11
- package/app/composables/api/kaizen.ts +8 -6
- package/app/composables/api/localSettings.ts +5 -4
- package/app/composables/api/models.ts +58 -51
- package/app/composables/api/notifications.ts +13 -7
- package/app/composables/api/presets.ts +34 -28
- package/app/composables/api/providerConnections.ts +68 -26
- package/app/composables/api/recurring.ts +40 -30
- package/app/composables/api/releaseHealth.ts +28 -26
- package/app/composables/api/reviews.ts +136 -114
- package/app/composables/api/sandbox.ts +52 -34
- package/app/composables/api/slack.ts +22 -25
- package/app/composables/api/spec.ts +3 -3
- package/app/composables/api/tasks.ts +42 -41
- package/app/composables/api/userSecrets.ts +12 -17
- package/app/composables/api/workspaces.ts +21 -15
- package/app/composables/useApi.ts +9 -1
- package/app/composables/useIntegrationBack.ts +9 -3
- package/app/pages/index.vue +2 -0
- package/app/stores/auth.ts +2 -1
- package/app/stores/board.ts +2 -1
- package/app/stores/brainstorm.ts +2 -2
- package/app/stores/clarity.ts +6 -2
- package/app/stores/execution.ts +3 -2
- package/app/stores/github.ts +1 -2
- package/app/stores/mergePresets.ts +2 -6
- package/app/stores/pipelines.ts +1 -1
- package/app/stores/recurringPipelines.ts +2 -7
- package/app/stores/sandbox.ts +1 -2
- package/app/stores/ui.ts +62 -19
- package/app/types/accountSettings.ts +11 -36
- package/app/types/accounts.ts +16 -71
- package/app/types/bootstrap.ts +13 -75
- package/app/types/brainstorm.ts +13 -38
- package/app/types/clarity.ts +12 -43
- package/app/types/consensus.ts +16 -89
- package/app/types/documents.ts +19 -94
- package/app/types/domain.ts +54 -586
- package/app/types/execution.ts +48 -515
- package/app/types/fragments.ts +15 -83
- package/app/types/github.ts +25 -161
- package/app/types/incidentEnrichment.ts +10 -25
- package/app/types/localModels.ts +11 -61
- package/app/types/localSettings.ts +9 -26
- package/app/types/merge.ts +10 -68
- package/app/types/model-presets.ts +7 -28
- package/app/types/models.ts +16 -164
- package/app/types/notifications.ts +18 -77
- package/app/types/openrouter.ts +8 -34
- package/app/types/providerConnections.ts +21 -41
- package/app/types/provisioningLogs.ts +9 -29
- package/app/types/recurring.ts +10 -63
- package/app/types/releaseHealth.ts +15 -39
- package/app/types/requirements.ts +14 -84
- package/app/types/sandbox.ts +45 -161
- package/app/types/services.ts +3 -22
- package/app/types/slack.ts +10 -47
- package/app/types/spec.ts +15 -68
- package/app/types/tasks.ts +15 -111
- package/app/types/tracker.ts +9 -24
- package/app/types/userSecrets.ts +12 -47
- package/package.json +9 -2
|
@@ -1,44 +1,69 @@
|
|
|
1
|
-
import
|
|
1
|
+
import {
|
|
2
|
+
acceptRequirementRecommendationContract,
|
|
3
|
+
getBrainstormContract,
|
|
4
|
+
getClarityReviewContract,
|
|
5
|
+
getConsensusSessionContract,
|
|
6
|
+
getRequirementReviewContract,
|
|
7
|
+
incorporateBrainstormContract,
|
|
8
|
+
incorporateClarityContract,
|
|
9
|
+
incorporateRequirementsContract,
|
|
10
|
+
proceedBrainstormContract,
|
|
11
|
+
proceedClarityContract,
|
|
12
|
+
proceedRequirementsContract,
|
|
13
|
+
reRequestRequirementRecommendationContract,
|
|
14
|
+
reReviewBrainstormContract,
|
|
15
|
+
reReviewClarityContract,
|
|
16
|
+
reReviewRequirementsContract,
|
|
17
|
+
rejectRequirementRecommendationContract,
|
|
18
|
+
replyBrainstormItemContract,
|
|
19
|
+
replyClarityItemContract,
|
|
20
|
+
replyRequirementItemContract,
|
|
21
|
+
requestRequirementRecommendationsContract,
|
|
22
|
+
resolveBrainstormExceededContract,
|
|
23
|
+
resolveClarityExceededContract,
|
|
24
|
+
resolveRequirementsExceededContract,
|
|
25
|
+
updateBrainstormItemStatusContract,
|
|
26
|
+
updateClarityItemStatusContract,
|
|
27
|
+
updateRequirementItemStatusContract,
|
|
28
|
+
} from '@cat-factory/contracts'
|
|
2
29
|
import type {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
} from '~/types/
|
|
7
|
-
import type {
|
|
8
|
-
import type {
|
|
9
|
-
RequirementReview,
|
|
10
|
-
ResolveRequirementsExceededChoice,
|
|
11
|
-
ReviewItemStatus,
|
|
12
|
-
} from '~/types/requirements'
|
|
30
|
+
UpdateBrainstormItemStatusInput,
|
|
31
|
+
UpdateClarityItemStatusInput,
|
|
32
|
+
} from '@cat-factory/contracts'
|
|
33
|
+
import type { ResolveClarityExceededChoice } from '~/types/clarity'
|
|
34
|
+
import type { BrainstormStage, ResolveBrainstormExceededChoice } from '~/types/brainstorm'
|
|
35
|
+
import type { ResolveRequirementsExceededChoice, ReviewItemStatus } from '~/types/requirements'
|
|
13
36
|
import type { ApiContext } from './context'
|
|
14
37
|
|
|
38
|
+
// The clarity/brainstorm item-status routes accept a narrower set than the full
|
|
39
|
+
// requirements `ReviewItemStatus` (no `recommend_requested`).
|
|
40
|
+
type ClarityItemStatus = UpdateClarityItemStatusInput['status']
|
|
41
|
+
type BrainstormItemStatus = UpdateBrainstormItemStatusInput['status']
|
|
42
|
+
|
|
15
43
|
/**
|
|
16
44
|
* The two iterative gate reviewers (requirements + clarity) and the consensus
|
|
17
45
|
* session read. Each reviewer follows the same answer → incorporate → re-review
|
|
18
46
|
* → proceed/resolve-exceeded loop.
|
|
19
47
|
*/
|
|
20
|
-
export function reviewsApi({
|
|
48
|
+
export function reviewsApi({ send, ws }: ApiContext) {
|
|
21
49
|
return {
|
|
22
50
|
// ---- requirements review (stateless reviewer agent) ------------------
|
|
23
51
|
// The current review for a block (null when none has been run). A 503 means
|
|
24
52
|
// the feature is unconfigured (the panel hides on any error here).
|
|
25
53
|
getRequirementReview: (workspaceId: string, blockId: string) =>
|
|
26
|
-
|
|
27
|
-
`${ws(workspaceId)}/blocks/${encodeURIComponent(blockId)}/requirement-review`,
|
|
28
|
-
),
|
|
54
|
+
send(getRequirementReviewContract, { pathPrefix: ws(workspaceId), pathParams: { blockId } }),
|
|
29
55
|
|
|
30
56
|
// The latest consensus session for a block (`{ session: null }` when none / consensus
|
|
31
57
|
// off). The live transcript also arrives via the `consensus` stream event.
|
|
32
58
|
getConsensusSession: (workspaceId: string, blockId: string) =>
|
|
33
|
-
|
|
34
|
-
`${ws(workspaceId)}/blocks/${encodeURIComponent(blockId)}/consensus-session`,
|
|
35
|
-
),
|
|
59
|
+
send(getConsensusSessionContract, { pathPrefix: ws(workspaceId), pathParams: { blockId } }),
|
|
36
60
|
|
|
37
61
|
replyRequirementItem: (workspaceId: string, reviewId: string, itemId: string, reply: string) =>
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
62
|
+
send(replyRequirementItemContract, {
|
|
63
|
+
pathPrefix: ws(workspaceId),
|
|
64
|
+
pathParams: { reviewId, itemId },
|
|
65
|
+
body: { reply },
|
|
66
|
+
}),
|
|
42
67
|
|
|
43
68
|
setRequirementItemStatus: (
|
|
44
69
|
workspaceId: string,
|
|
@@ -46,35 +71,31 @@ export function reviewsApi({ http, ws }: ApiContext) {
|
|
|
46
71
|
itemId: string,
|
|
47
72
|
status: ReviewItemStatus,
|
|
48
73
|
) =>
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
74
|
+
send(updateRequirementItemStatusContract, {
|
|
75
|
+
pathPrefix: ws(workspaceId),
|
|
76
|
+
pathParams: { reviewId, itemId },
|
|
77
|
+
body: { status },
|
|
78
|
+
}),
|
|
53
79
|
|
|
54
80
|
// Incorporate the answers ASYNCHRONOUSLY (every finding must be answered or dismissed).
|
|
55
81
|
// The durable driver folds them and re-reviews in the background. Optional `feedback` is
|
|
56
82
|
// the "do it differently" lever when redoing a merge. Returns the `incorporating` review
|
|
57
83
|
// at once; a notification calls the user back only if the re-review needs input.
|
|
58
84
|
incorporateRequirements: (workspaceId: string, blockId: string, feedback?: string) =>
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
85
|
+
send(incorporateRequirementsContract, {
|
|
86
|
+
pathPrefix: ws(workspaceId),
|
|
87
|
+
pathParams: { blockId },
|
|
88
|
+
body: feedback ? { feedback } : {},
|
|
89
|
+
}),
|
|
63
90
|
|
|
64
91
|
// Re-review the incorporated document (one more reviewer pass). On convergence the
|
|
65
92
|
// parked run advances; otherwise the response carries the next cycle / cap state.
|
|
66
93
|
reReviewRequirements: (workspaceId: string, blockId: string) =>
|
|
67
|
-
|
|
68
|
-
`${ws(workspaceId)}/blocks/${encodeURIComponent(blockId)}/requirement-review/re-review`,
|
|
69
|
-
{ method: 'POST' },
|
|
70
|
-
),
|
|
94
|
+
send(reReviewRequirementsContract, { pathPrefix: ws(workspaceId), pathParams: { blockId } }),
|
|
71
95
|
|
|
72
96
|
// Proceed: settle the requirements and advance the parked run (all findings dismissed).
|
|
73
97
|
proceedRequirements: (workspaceId: string, blockId: string) =>
|
|
74
|
-
|
|
75
|
-
`${ws(workspaceId)}/blocks/${encodeURIComponent(blockId)}/requirement-review/proceed`,
|
|
76
|
-
{ method: 'POST' },
|
|
77
|
-
),
|
|
98
|
+
send(proceedRequirementsContract, { pathPrefix: ws(workspaceId), pathParams: { blockId } }),
|
|
78
99
|
|
|
79
100
|
// Resolve a review that hit its iteration cap: extra-round / proceed / stop-reset.
|
|
80
101
|
resolveRequirementsExceeded: (
|
|
@@ -82,10 +103,11 @@ export function reviewsApi({ http, ws }: ApiContext) {
|
|
|
82
103
|
blockId: string,
|
|
83
104
|
choice: ResolveRequirementsExceededChoice,
|
|
84
105
|
) =>
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
106
|
+
send(resolveRequirementsExceededContract, {
|
|
107
|
+
pathPrefix: ws(workspaceId),
|
|
108
|
+
pathParams: { blockId },
|
|
109
|
+
body: { choice },
|
|
110
|
+
}),
|
|
89
111
|
|
|
90
112
|
// Ask the Requirement Writer to recommend grounded answers for a batch of findings (by
|
|
91
113
|
// item id). Returns the review with `pending` placeholder recommendations; they fill in
|
|
@@ -96,80 +118,77 @@ export function reviewsApi({ http, ws }: ApiContext) {
|
|
|
96
118
|
itemIds: string[],
|
|
97
119
|
note?: string,
|
|
98
120
|
) =>
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
121
|
+
send(requestRequirementRecommendationsContract, {
|
|
122
|
+
pathPrefix: ws(workspaceId),
|
|
123
|
+
pathParams: { blockId },
|
|
124
|
+
body: { itemIds, ...(note ? { note } : {}) },
|
|
125
|
+
}),
|
|
103
126
|
|
|
104
127
|
// Accept a recommendation (becomes the finding's answer), reject it, or re-request it
|
|
105
128
|
// with a "do it differently" note.
|
|
106
129
|
acceptRecommendation: (workspaceId: string, reviewId: string, recId: string) =>
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
{
|
|
110
|
-
),
|
|
130
|
+
send(acceptRequirementRecommendationContract, {
|
|
131
|
+
pathPrefix: ws(workspaceId),
|
|
132
|
+
pathParams: { reviewId, recId },
|
|
133
|
+
}),
|
|
111
134
|
|
|
112
135
|
rejectRecommendation: (workspaceId: string, reviewId: string, recId: string) =>
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
{
|
|
116
|
-
),
|
|
136
|
+
send(rejectRequirementRecommendationContract, {
|
|
137
|
+
pathPrefix: ws(workspaceId),
|
|
138
|
+
pathParams: { reviewId, recId },
|
|
139
|
+
}),
|
|
117
140
|
|
|
118
141
|
reRequestRecommendation: (workspaceId: string, reviewId: string, recId: string, note: string) =>
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
142
|
+
send(reRequestRequirementRecommendationContract, {
|
|
143
|
+
pathPrefix: ws(workspaceId),
|
|
144
|
+
pathParams: { reviewId, recId },
|
|
145
|
+
body: { note },
|
|
146
|
+
}),
|
|
123
147
|
|
|
124
148
|
// ---- clarity review (bug-report triage reviewer agent) ---------------
|
|
125
149
|
// The current review for a block (null when none has been run). A 503 means
|
|
126
150
|
// the feature is unconfigured (the panel hides on any error here).
|
|
127
151
|
getClarityReview: (workspaceId: string, blockId: string) =>
|
|
128
|
-
|
|
129
|
-
`${ws(workspaceId)}/blocks/${encodeURIComponent(blockId)}/clarity-review`,
|
|
130
|
-
),
|
|
152
|
+
send(getClarityReviewContract, { pathPrefix: ws(workspaceId), pathParams: { blockId } }),
|
|
131
153
|
|
|
132
154
|
replyClarityItem: (workspaceId: string, reviewId: string, itemId: string, reply: string) =>
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
155
|
+
send(replyClarityItemContract, {
|
|
156
|
+
pathPrefix: ws(workspaceId),
|
|
157
|
+
pathParams: { reviewId, itemId },
|
|
158
|
+
body: { reply },
|
|
159
|
+
}),
|
|
137
160
|
|
|
138
161
|
setClarityItemStatus: (
|
|
139
162
|
workspaceId: string,
|
|
140
163
|
reviewId: string,
|
|
141
164
|
itemId: string,
|
|
142
|
-
status:
|
|
165
|
+
status: ClarityItemStatus,
|
|
143
166
|
) =>
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
167
|
+
send(updateClarityItemStatusContract, {
|
|
168
|
+
pathPrefix: ws(workspaceId),
|
|
169
|
+
pathParams: { reviewId, itemId },
|
|
170
|
+
body: { status },
|
|
171
|
+
}),
|
|
148
172
|
|
|
149
173
|
// Incorporate the answers ASYNCHRONOUSLY (every finding must be answered or dismissed).
|
|
150
174
|
// The durable driver folds them and re-reviews in the background. Optional `feedback` is
|
|
151
175
|
// the "do it differently" lever when redoing a merge. Returns the `incorporating` review
|
|
152
176
|
// at once; a notification calls the user back only if the re-review needs input.
|
|
153
177
|
incorporateClarity: (workspaceId: string, blockId: string, feedback?: string) =>
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
178
|
+
send(incorporateClarityContract, {
|
|
179
|
+
pathPrefix: ws(workspaceId),
|
|
180
|
+
pathParams: { blockId },
|
|
181
|
+
body: feedback ? { feedback } : {},
|
|
182
|
+
}),
|
|
158
183
|
|
|
159
184
|
// Re-review the clarified report (one more reviewer pass). On convergence the parked run
|
|
160
185
|
// advances; otherwise the response carries the next cycle / cap state.
|
|
161
186
|
reReviewClarity: (workspaceId: string, blockId: string) =>
|
|
162
|
-
|
|
163
|
-
`${ws(workspaceId)}/blocks/${encodeURIComponent(blockId)}/clarity-review/re-review`,
|
|
164
|
-
{ method: 'POST' },
|
|
165
|
-
),
|
|
187
|
+
send(reReviewClarityContract, { pathPrefix: ws(workspaceId), pathParams: { blockId } }),
|
|
166
188
|
|
|
167
189
|
// Proceed: settle the clarity review and advance the parked run (all findings dismissed).
|
|
168
190
|
proceedClarity: (workspaceId: string, blockId: string) =>
|
|
169
|
-
|
|
170
|
-
`${ws(workspaceId)}/blocks/${encodeURIComponent(blockId)}/clarity-review/proceed`,
|
|
171
|
-
{ method: 'POST' },
|
|
172
|
-
),
|
|
191
|
+
send(proceedClarityContract, { pathPrefix: ws(workspaceId), pathParams: { blockId } }),
|
|
173
192
|
|
|
174
193
|
// Resolve a review that hit its iteration cap: extra-round / proceed / stop-reset.
|
|
175
194
|
resolveClarityExceeded: (
|
|
@@ -177,35 +196,36 @@ export function reviewsApi({ http, ws }: ApiContext) {
|
|
|
177
196
|
blockId: string,
|
|
178
197
|
choice: ResolveClarityExceededChoice,
|
|
179
198
|
) =>
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
199
|
+
send(resolveClarityExceededContract, {
|
|
200
|
+
pathPrefix: ws(workspaceId),
|
|
201
|
+
pathParams: { blockId },
|
|
202
|
+
body: { choice },
|
|
203
|
+
}),
|
|
184
204
|
|
|
185
205
|
// ---- brainstorm (structured-dialogue agent, stage-scoped) ------------
|
|
186
206
|
// The current session for a block + stage (null when none has been run). A 503 means
|
|
187
207
|
// the feature is unconfigured (the panel hides on any error here).
|
|
188
208
|
getBrainstorm: (workspaceId: string, blockId: string, stage: BrainstormStage) =>
|
|
189
|
-
|
|
190
|
-
`${ws(workspaceId)}/blocks/${encodeURIComponent(blockId)}/brainstorm/${stage}`,
|
|
191
|
-
),
|
|
209
|
+
send(getBrainstormContract, { pathPrefix: ws(workspaceId), pathParams: { blockId, stage } }),
|
|
192
210
|
|
|
193
211
|
replyBrainstormItem: (workspaceId: string, sessionId: string, itemId: string, reply: string) =>
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
212
|
+
send(replyBrainstormItemContract, {
|
|
213
|
+
pathPrefix: ws(workspaceId),
|
|
214
|
+
pathParams: { sessionId, itemId },
|
|
215
|
+
body: { reply },
|
|
216
|
+
}),
|
|
198
217
|
|
|
199
218
|
setBrainstormItemStatus: (
|
|
200
219
|
workspaceId: string,
|
|
201
220
|
sessionId: string,
|
|
202
221
|
itemId: string,
|
|
203
|
-
status:
|
|
222
|
+
status: BrainstormItemStatus,
|
|
204
223
|
) =>
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
224
|
+
send(updateBrainstormItemStatusContract, {
|
|
225
|
+
pathPrefix: ws(workspaceId),
|
|
226
|
+
pathParams: { sessionId, itemId },
|
|
227
|
+
body: { status },
|
|
228
|
+
}),
|
|
209
229
|
|
|
210
230
|
// Incorporate the picks ASYNCHRONOUSLY (the durable driver folds + re-runs).
|
|
211
231
|
incorporateBrainstorm: (
|
|
@@ -214,24 +234,25 @@ export function reviewsApi({ http, ws }: ApiContext) {
|
|
|
214
234
|
stage: BrainstormStage,
|
|
215
235
|
feedback?: string,
|
|
216
236
|
) =>
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
237
|
+
send(incorporateBrainstormContract, {
|
|
238
|
+
pathPrefix: ws(workspaceId),
|
|
239
|
+
pathParams: { blockId, stage },
|
|
240
|
+
body: feedback ? { feedback } : {},
|
|
241
|
+
}),
|
|
221
242
|
|
|
222
243
|
// Re-run the brainstorm against the converged direction (one more pass).
|
|
223
244
|
reReviewBrainstorm: (workspaceId: string, blockId: string, stage: BrainstormStage) =>
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
{
|
|
227
|
-
),
|
|
245
|
+
send(reReviewBrainstormContract, {
|
|
246
|
+
pathPrefix: ws(workspaceId),
|
|
247
|
+
pathParams: { blockId, stage },
|
|
248
|
+
}),
|
|
228
249
|
|
|
229
250
|
// Proceed: settle the brainstorm and advance the parked run (all options dismissed).
|
|
230
251
|
proceedBrainstorm: (workspaceId: string, blockId: string, stage: BrainstormStage) =>
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
{
|
|
234
|
-
),
|
|
252
|
+
send(proceedBrainstormContract, {
|
|
253
|
+
pathPrefix: ws(workspaceId),
|
|
254
|
+
pathParams: { blockId, stage },
|
|
255
|
+
}),
|
|
235
256
|
|
|
236
257
|
// Resolve a session that hit its iteration cap: extra-round / proceed / stop-reset.
|
|
237
258
|
resolveBrainstormExceeded: (
|
|
@@ -240,9 +261,10 @@ export function reviewsApi({ http, ws }: ApiContext) {
|
|
|
240
261
|
stage: BrainstormStage,
|
|
241
262
|
choice: ResolveBrainstormExceededChoice,
|
|
242
263
|
) =>
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
264
|
+
send(resolveBrainstormExceededContract, {
|
|
265
|
+
pathPrefix: ws(workspaceId),
|
|
266
|
+
pathParams: { blockId, stage },
|
|
267
|
+
body: { choice },
|
|
268
|
+
}),
|
|
247
269
|
}
|
|
248
270
|
}
|
|
@@ -1,57 +1,75 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import {
|
|
2
|
+
archiveSandboxPromptContract,
|
|
3
|
+
cloneSandboxPromptContract,
|
|
4
|
+
createSandboxExperimentContract,
|
|
5
|
+
createSandboxFixtureContract,
|
|
6
|
+
getSandboxExperimentContract,
|
|
7
|
+
launchSandboxExperimentContract,
|
|
8
|
+
removeSandboxFixtureContract,
|
|
9
|
+
sandboxOverviewContract,
|
|
10
|
+
saveSandboxPromptContract,
|
|
11
|
+
setSandboxPromptLabelsContract,
|
|
12
|
+
} from '@cat-factory/contracts'
|
|
13
|
+
import type { SendParams } from './client'
|
|
11
14
|
import type { ApiContext } from './context'
|
|
12
15
|
|
|
16
|
+
// Request bodies are typed from the contract's INPUT shape (`SendParams[...]['body']`),
|
|
17
|
+
// so valibot-defaulted fields (labels / repeats / budgetTokens) stay optional for callers —
|
|
18
|
+
// the contract's exported `*Input` types are the post-default OUTPUT shape and would force
|
|
19
|
+
// callers to supply them.
|
|
20
|
+
type CloneSandboxPromptBody = NonNullable<SendParams<typeof cloneSandboxPromptContract>['body']>
|
|
21
|
+
type SaveSandboxVersionBody = NonNullable<SendParams<typeof saveSandboxPromptContract>['body']>
|
|
22
|
+
type CreateSandboxFixtureBody = NonNullable<SendParams<typeof createSandboxFixtureContract>['body']>
|
|
23
|
+
type CreateSandboxExperimentBody = NonNullable<
|
|
24
|
+
SendParams<typeof createSandboxExperimentContract>['body']
|
|
25
|
+
>
|
|
26
|
+
|
|
13
27
|
/**
|
|
14
28
|
* The Sandbox API (the parallel prompt/model testing surface): manage versioned prompt
|
|
15
29
|
* candidates + the fixture library, define experiments (prompt × model × fixture), and
|
|
16
30
|
* launch one to run + grade every cell. Opt-in: every endpoint 503s when the deployment
|
|
17
31
|
* hasn't wired the Sandbox (its dedicated DB / schema).
|
|
18
32
|
*/
|
|
19
|
-
export function sandboxApi({
|
|
20
|
-
const base = (workspaceId: string) => `${ws(workspaceId)}/sandbox`
|
|
33
|
+
export function sandboxApi({ send, ws }: ApiContext) {
|
|
21
34
|
return {
|
|
22
35
|
getSandboxOverview: (workspaceId: string) =>
|
|
23
|
-
|
|
36
|
+
send(sandboxOverviewContract, { pathPrefix: ws(workspaceId) }),
|
|
24
37
|
|
|
25
38
|
// ---- prompt versions -------------------------------------------------
|
|
26
|
-
cloneSandboxPrompt: (workspaceId: string, body:
|
|
27
|
-
|
|
28
|
-
saveSandboxVersion: (workspaceId: string, body:
|
|
29
|
-
|
|
39
|
+
cloneSandboxPrompt: (workspaceId: string, body: CloneSandboxPromptBody) =>
|
|
40
|
+
send(cloneSandboxPromptContract, { pathPrefix: ws(workspaceId), body }),
|
|
41
|
+
saveSandboxVersion: (workspaceId: string, body: SaveSandboxVersionBody) =>
|
|
42
|
+
send(saveSandboxPromptContract, { pathPrefix: ws(workspaceId), body }),
|
|
30
43
|
setSandboxPromptLabels: (workspaceId: string, promptId: string, labels: string[]) =>
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
44
|
+
send(setSandboxPromptLabelsContract, {
|
|
45
|
+
pathPrefix: ws(workspaceId),
|
|
46
|
+
pathParams: { promptId },
|
|
47
|
+
body: { labels },
|
|
48
|
+
}),
|
|
35
49
|
archiveSandboxPrompt: (workspaceId: string, promptId: string) =>
|
|
36
|
-
|
|
50
|
+
send(archiveSandboxPromptContract, { pathPrefix: ws(workspaceId), pathParams: { promptId } }),
|
|
37
51
|
|
|
38
52
|
// ---- fixtures --------------------------------------------------------
|
|
39
|
-
createSandboxFixture: (workspaceId: string, body:
|
|
40
|
-
|
|
53
|
+
createSandboxFixture: (workspaceId: string, body: CreateSandboxFixtureBody) =>
|
|
54
|
+
send(createSandboxFixtureContract, { pathPrefix: ws(workspaceId), body }),
|
|
41
55
|
deleteSandboxFixture: (workspaceId: string, fixtureId: string) =>
|
|
42
|
-
|
|
56
|
+
send(removeSandboxFixtureContract, {
|
|
57
|
+
pathPrefix: ws(workspaceId),
|
|
58
|
+
pathParams: { fixtureId },
|
|
59
|
+
}),
|
|
43
60
|
|
|
44
61
|
// ---- experiments -----------------------------------------------------
|
|
45
|
-
createSandboxExperiment: (workspaceId: string, body:
|
|
46
|
-
|
|
62
|
+
createSandboxExperiment: (workspaceId: string, body: CreateSandboxExperimentBody) =>
|
|
63
|
+
send(createSandboxExperimentContract, { pathPrefix: ws(workspaceId), body }),
|
|
47
64
|
getSandboxExperiment: (workspaceId: string, experimentId: string) =>
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
65
|
+
send(getSandboxExperimentContract, {
|
|
66
|
+
pathPrefix: ws(workspaceId),
|
|
67
|
+
pathParams: { experimentId },
|
|
68
|
+
}),
|
|
51
69
|
launchSandboxExperiment: (workspaceId: string, experimentId: string) =>
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
{
|
|
55
|
-
),
|
|
70
|
+
send(launchSandboxExperimentContract, {
|
|
71
|
+
pathPrefix: ws(workspaceId),
|
|
72
|
+
pathParams: { experimentId },
|
|
73
|
+
}),
|
|
56
74
|
}
|
|
57
75
|
}
|
|
@@ -1,54 +1,51 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import {
|
|
2
|
+
connectSlackContract,
|
|
3
|
+
disconnectSlackContract,
|
|
4
|
+
getSlackConnectionContract,
|
|
5
|
+
getSlackInstallUrlContract,
|
|
6
|
+
getSlackMemberMappingContract,
|
|
7
|
+
getSlackSettingsContract,
|
|
8
|
+
listSlackChannelsContract,
|
|
9
|
+
updateSlackMemberMappingContract,
|
|
10
|
+
updateSlackSettingsContract,
|
|
11
|
+
} from '@cat-factory/contracts'
|
|
12
|
+
import type { SlackMemberMappingEntry, SlackNotificationSettings } from '~/types/slack'
|
|
7
13
|
import type { ApiContext } from './context'
|
|
8
14
|
|
|
9
15
|
/** Slack integration: per-account connection, per-workspace routing + member map. */
|
|
10
|
-
export function slackApi({
|
|
16
|
+
export function slackApi({ send, ws }: ApiContext) {
|
|
11
17
|
return {
|
|
12
18
|
// ---- slack integration (extra notification transport) -----------------
|
|
13
19
|
// Per-account connection (manual bot-token paste + the OAuth "Add to Slack"
|
|
14
20
|
// URL), per-workspace routing, and the per-account member map. A 503 from
|
|
15
21
|
// `getSlackConnection` means the integration is off (the store hides its UI).
|
|
16
22
|
getSlackConnection: (workspaceId: string) =>
|
|
17
|
-
|
|
18
|
-
`${ws(workspaceId)}/slack/connection`,
|
|
19
|
-
),
|
|
23
|
+
send(getSlackConnectionContract, { pathPrefix: ws(workspaceId) }),
|
|
20
24
|
|
|
21
25
|
getSlackInstallUrl: (workspaceId: string) =>
|
|
22
|
-
|
|
26
|
+
send(getSlackInstallUrlContract, { pathPrefix: ws(workspaceId) }),
|
|
23
27
|
|
|
24
28
|
connectSlack: (workspaceId: string, token: string) =>
|
|
25
|
-
|
|
26
|
-
method: 'POST',
|
|
27
|
-
body: { token },
|
|
28
|
-
}),
|
|
29
|
+
send(connectSlackContract, { pathPrefix: ws(workspaceId), body: { token } }),
|
|
29
30
|
|
|
30
31
|
disconnectSlack: (workspaceId: string) =>
|
|
31
|
-
|
|
32
|
+
send(disconnectSlackContract, { pathPrefix: ws(workspaceId) }),
|
|
32
33
|
|
|
33
34
|
listSlackChannels: (workspaceId: string) =>
|
|
34
|
-
|
|
35
|
+
send(listSlackChannelsContract, { pathPrefix: ws(workspaceId) }),
|
|
35
36
|
|
|
36
37
|
getSlackSettings: (workspaceId: string) =>
|
|
37
|
-
|
|
38
|
+
send(getSlackSettingsContract, { pathPrefix: ws(workspaceId) }),
|
|
38
39
|
|
|
39
40
|
updateSlackSettings: (
|
|
40
41
|
workspaceId: string,
|
|
41
42
|
body: { routes: SlackNotificationSettings['routes']; mentionsEnabled: boolean },
|
|
42
|
-
) =>
|
|
43
|
-
http<SlackNotificationSettings>(`${ws(workspaceId)}/slack/settings`, { method: 'PUT', body }),
|
|
43
|
+
) => send(updateSlackSettingsContract, { pathPrefix: ws(workspaceId), body }),
|
|
44
44
|
|
|
45
45
|
getSlackMemberMapping: (workspaceId: string) =>
|
|
46
|
-
|
|
46
|
+
send(getSlackMemberMappingContract, { pathPrefix: ws(workspaceId) }),
|
|
47
47
|
|
|
48
48
|
updateSlackMemberMapping: (workspaceId: string, entries: SlackMemberMappingEntry[]) =>
|
|
49
|
-
|
|
50
|
-
method: 'PUT',
|
|
51
|
-
body: { entries },
|
|
52
|
-
}),
|
|
49
|
+
send(updateSlackMemberMappingContract, { pathPrefix: ws(workspaceId), body: { entries } }),
|
|
53
50
|
}
|
|
54
51
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { getServiceSpecContract } from '@cat-factory/contracts'
|
|
2
2
|
import type { ApiContext } from './context'
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -6,9 +6,9 @@ import type { ApiContext } from './context'
|
|
|
6
6
|
* sharded `spec/` artifact from the service repo's default branch. Always 200: a service
|
|
7
7
|
* with no spec on main (or no GitHub connected) returns `{ present: false }`.
|
|
8
8
|
*/
|
|
9
|
-
export function specApi({
|
|
9
|
+
export function specApi({ send, ws }: ApiContext) {
|
|
10
10
|
return {
|
|
11
11
|
getServiceSpec: (workspaceId: string, blockId: string) =>
|
|
12
|
-
|
|
12
|
+
send(getServiceSpecContract, { pathPrefix: ws(workspaceId), pathParams: { blockId } }),
|
|
13
13
|
}
|
|
14
14
|
}
|