Skip to content

Commit 0c5dbfb

Browse files
authored
feat(sim-cli): publish which CLI commands Mothership is refused, from the route admission rule (#8838)
* feat(sim-cli): publish which CLI commands Mothership is refused, from the route admission rule * fix(sim-cli): inventory raw-route admission so chat is flagged too
1 parent 13461e3 commit 0c5dbfb

10 files changed

Lines changed: 477 additions & 381 deletions

File tree

Lines changed: 297 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,297 @@
1+
[
2+
{
3+
"method": "POST",
4+
"path": "/api/v2/chat",
5+
"operation": "chat.send"
6+
},
7+
{
8+
"method": "GET",
9+
"path": "/api/v2/credentials/[credentialId]/members",
10+
"operation": "credentials.members.list"
11+
},
12+
{
13+
"method": "POST",
14+
"path": "/api/v2/credentials/[credentialId]/members",
15+
"operation": "credentials.members.upsert"
16+
},
17+
{
18+
"method": "DELETE",
19+
"path": "/api/v2/credentials/[credentialId]/members/[userId]",
20+
"operation": "credentials.members.remove"
21+
},
22+
{
23+
"method": "GET",
24+
"path": "/api/v2/files/[fileId]/versions",
25+
"operation": "files.versions.list"
26+
},
27+
{
28+
"method": "GET",
29+
"path": "/api/v2/files/[fileId]/versions/[version]",
30+
"operation": "files.versions.read"
31+
},
32+
{
33+
"method": "DELETE",
34+
"path": "/api/v2/files/[fileId]/versions/[version]",
35+
"operation": "files.versions.delete"
36+
},
37+
{
38+
"method": "GET",
39+
"path": "/api/v2/files/[fileId]/versions/[version]/content",
40+
"operation": "files.versions.download"
41+
},
42+
{
43+
"method": "POST",
44+
"path": "/api/v2/files/[fileId]/versions/[version]/revert",
45+
"operation": "files.versions.revert"
46+
},
47+
{
48+
"method": "GET",
49+
"path": "/api/v2/files/[fileId]/versions/[version]/text",
50+
"operation": "files.versions.read_content"
51+
},
52+
{
53+
"method": "GET",
54+
"path": "/api/v2/meta",
55+
"operation": "meta.capabilities.read"
56+
},
57+
{
58+
"method": "GET",
59+
"path": "/api/v2/organizations",
60+
"operation": "organizations.list"
61+
},
62+
{
63+
"method": "GET",
64+
"path": "/api/v2/organizations/[organizationId]",
65+
"operation": "organizations.read"
66+
},
67+
{
68+
"method": "POST",
69+
"path": "/api/v2/organizations/[organizationId]/access-requests",
70+
"operation": "access_requests.create"
71+
},
72+
{
73+
"method": "GET",
74+
"path": "/api/v2/organizations/[organizationId]/access-requests",
75+
"operation": "access_requests.list_organization"
76+
},
77+
{
78+
"method": "POST",
79+
"path": "/api/v2/organizations/[organizationId]/access-requests/[requestId]/cancel",
80+
"operation": "access_requests.cancel"
81+
},
82+
{
83+
"method": "GET",
84+
"path": "/api/v2/organizations/[organizationId]/access-requests/[requestId]/preview",
85+
"operation": "access_requests.preview"
86+
},
87+
{
88+
"method": "POST",
89+
"path": "/api/v2/organizations/[organizationId]/access-requests/[requestId]/resolve",
90+
"operation": "access_requests.resolve"
91+
},
92+
{
93+
"method": "GET",
94+
"path": "/api/v2/organizations/[organizationId]/access-requests/discovery",
95+
"operation": "access_requests.discover"
96+
},
97+
{
98+
"method": "GET",
99+
"path": "/api/v2/organizations/[organizationId]/access-requests/mine",
100+
"operation": "access_requests.list_mine"
101+
},
102+
{
103+
"method": "GET",
104+
"path": "/api/v2/organizations/[organizationId]/access-requests/settings",
105+
"operation": "access_requests.get_settings"
106+
},
107+
{
108+
"method": "PATCH",
109+
"path": "/api/v2/organizations/[organizationId]/access-requests/settings",
110+
"operation": "access_requests.update_settings"
111+
},
112+
{
113+
"method": "GET",
114+
"path": "/api/v2/organizations/[organizationId]/invitations",
115+
"operation": "organizations.invitations.list"
116+
},
117+
{
118+
"method": "POST",
119+
"path": "/api/v2/organizations/[organizationId]/invitations",
120+
"operation": "organizations.invitations.create"
121+
},
122+
{
123+
"method": "GET",
124+
"path": "/api/v2/organizations/[organizationId]/invitations/[invitationId]",
125+
"operation": "organizations.invitations.read"
126+
},
127+
{
128+
"method": "DELETE",
129+
"path": "/api/v2/organizations/[organizationId]/invitations/[invitationId]",
130+
"operation": "invitations.revoke"
131+
},
132+
{
133+
"method": "POST",
134+
"path": "/api/v2/organizations/[organizationId]/invitations/[invitationId]/resend",
135+
"operation": "invitations.resend"
136+
},
137+
{
138+
"method": "GET",
139+
"path": "/api/v2/organizations/[organizationId]/invitations/[invitationId]/workspaces",
140+
"operation": "organizations.invitations.workspaces.list"
141+
},
142+
{
143+
"method": "GET",
144+
"path": "/api/v2/organizations/[organizationId]/members",
145+
"operation": "organizations.members.list"
146+
},
147+
{
148+
"method": "PATCH",
149+
"path": "/api/v2/organizations/[organizationId]/members/[userId]",
150+
"operation": "organizations.members.update"
151+
},
152+
{
153+
"method": "DELETE",
154+
"path": "/api/v2/organizations/[organizationId]/members/[userId]",
155+
"operation": "organizations.members.remove"
156+
},
157+
{
158+
"method": "GET",
159+
"path": "/api/v2/organizations/[organizationId]/members/[userId]/usage-limit",
160+
"operation": "organization_member_usage_limits.read"
161+
},
162+
{
163+
"method": "PATCH",
164+
"path": "/api/v2/organizations/[organizationId]/members/[userId]/usage-limit",
165+
"operation": "organization_member_usage_limits.update"
166+
},
167+
{
168+
"method": "GET",
169+
"path": "/api/v2/organizations/[organizationId]/permission-groups",
170+
"operation": "permission_groups.list"
171+
},
172+
{
173+
"method": "POST",
174+
"path": "/api/v2/organizations/[organizationId]/permission-groups",
175+
"operation": "permission_groups.create"
176+
},
177+
{
178+
"method": "GET",
179+
"path": "/api/v2/organizations/[organizationId]/permission-groups/[groupId]",
180+
"operation": "permission_groups.read"
181+
},
182+
{
183+
"method": "PATCH",
184+
"path": "/api/v2/organizations/[organizationId]/permission-groups/[groupId]",
185+
"operation": "permission_groups.update"
186+
},
187+
{
188+
"method": "DELETE",
189+
"path": "/api/v2/organizations/[organizationId]/permission-groups/[groupId]",
190+
"operation": "permission_groups.delete"
191+
},
192+
{
193+
"method": "GET",
194+
"path": "/api/v2/organizations/[organizationId]/permission-groups/[groupId]/members",
195+
"operation": "permission_groups.members.list"
196+
},
197+
{
198+
"method": "POST",
199+
"path": "/api/v2/organizations/[organizationId]/permission-groups/[groupId]/members",
200+
"operation": "permission_groups.members.add"
201+
},
202+
{
203+
"method": "DELETE",
204+
"path": "/api/v2/organizations/[organizationId]/permission-groups/[groupId]/members/[userId]",
205+
"operation": "permission_groups.members.remove"
206+
},
207+
{
208+
"method": "POST",
209+
"path": "/api/v2/organizations/[organizationId]/permission-groups/[groupId]/members/bulk",
210+
"operation": "permission_groups.members.bulk_add"
211+
},
212+
{
213+
"method": "GET",
214+
"path": "/api/v2/organizations/[organizationId]/sso/policy",
215+
"operation": "organization.sso.read_requirement"
216+
},
217+
{
218+
"method": "PATCH",
219+
"path": "/api/v2/organizations/[organizationId]/sso/policy",
220+
"operation": "organization.sso.set_requirement"
221+
},
222+
{
223+
"method": "GET",
224+
"path": "/api/v2/organizations/[organizationId]/sso/providers",
225+
"operation": "organization.sso.providers.list"
226+
},
227+
{
228+
"method": "POST",
229+
"path": "/api/v2/organizations/[organizationId]/sso/providers",
230+
"operation": "organization.sso.providers.save"
231+
},
232+
{
233+
"method": "GET",
234+
"path": "/api/v2/organizations/[organizationId]/sso/providers/[providerId]",
235+
"operation": "organization.sso.providers.list"
236+
},
237+
{
238+
"method": "DELETE",
239+
"path": "/api/v2/organizations/[organizationId]/sso/providers/[providerId]",
240+
"operation": "organization.sso.providers.delete"
241+
},
242+
{
243+
"method": "POST",
244+
"path": "/api/v2/organizations/[organizationId]/sso/providers/[providerId]/primary",
245+
"operation": "organization.sso.set_primary_provider"
246+
},
247+
{
248+
"method": "GET",
249+
"path": "/api/v2/organizations/[organizationId]/usage/breakdown",
250+
"operation": "organization_usage.breakdown.read"
251+
},
252+
{
253+
"method": "GET",
254+
"path": "/api/v2/organizations/[organizationId]/usage/events",
255+
"operation": "organization_usage.events.list"
256+
},
257+
{
258+
"method": "GET",
259+
"path": "/api/v2/organizations/[organizationId]/usage/summary",
260+
"operation": "organization_usage.summary.read"
261+
},
262+
{
263+
"method": "GET",
264+
"path": "/api/v2/organizations/[organizationId]/workspaces",
265+
"operation": "organizations.workspaces.list"
266+
},
267+
{
268+
"method": "GET",
269+
"path": "/api/v2/workspaces",
270+
"operation": "workspaces.list_public"
271+
},
272+
{
273+
"method": "GET",
274+
"path": "/api/v2/workspaces/[workspaceId]/access-requests",
275+
"operation": "access_requests.list_mine"
276+
},
277+
{
278+
"method": "POST",
279+
"path": "/api/v2/workspaces/[workspaceId]/access-requests",
280+
"operation": "access_requests.create"
281+
},
282+
{
283+
"method": "POST",
284+
"path": "/api/v2/workspaces/[workspaceId]/access-requests/[requestId]/cancel",
285+
"operation": "access_requests.cancel"
286+
},
287+
{
288+
"method": "GET",
289+
"path": "/api/v2/workspaces/[workspaceId]/access-requests/discovery",
290+
"operation": "access_requests.discover"
291+
},
292+
{
293+
"method": "GET",
294+
"path": "/api/v2/workspaces/[workspaceId]/permission-config",
295+
"operation": "permission_groups.read_user_config"
296+
}
297+
]

‎apps/sim/lib/api/server/routes/copilot-request.ts‎

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,33 @@ export function isCopilotRequest(request: Request): boolean {
2020
return INVOCATIONS.has(request)
2121
}
2222

23-
/** The code-owned use case must explicitly admit Copilot and declare its domain audience. */
23+
export type CopilotRouteUseCase = Pick<
24+
OperationUseCase<ApplicationOperation, unknown, unknown>,
25+
'operation' | 'delegationAudience'
26+
>
27+
28+
/**
29+
* The audience a route admits Copilot under, or none when Mothership is refused. The
30+
* code-owned use case must explicitly admit Copilot and declare its domain audience. The
31+
* route inventory evaluates this same rule to publish which CLI commands chat can run.
32+
*/
33+
export function copilotRouteAudience(
34+
operation: ApplicationOperation,
35+
useCase?: CopilotRouteUseCase
36+
): string | undefined {
37+
return useCase?.operation === operation ? useCase.delegationAudience || undefined : undefined
38+
}
39+
2440
export function copilotRequestPrincipal(
2541
request: Request,
2642
operation: ApplicationOperation,
27-
useCase?: Pick<
28-
OperationUseCase<ApplicationOperation, unknown, unknown>,
29-
'operation' | 'delegationAudience'
30-
>
43+
useCase?: CopilotRouteUseCase
3144
): DelegatedPrincipal | undefined {
3245
const invocation = INVOCATIONS.get(request)
3346
if (!invocation) return undefined
34-
if (useCase?.operation !== operation || !useCase.delegationAudience) return undefined
35-
const principal = createCopilotChatPrincipal(invocation, useCase.delegationAudience)
47+
const audience = copilotRouteAudience(operation, useCase)
48+
if (!audience) return undefined
49+
const principal = createCopilotChatPrincipal(invocation, audience)
3650
markCopilotWorkspaceInvocation(principal)
3751
return principal
3852
}

0 commit comments

Comments
 (0)