1import * as Schema from "effect/Schema";
2import { GitPreparePullRequestThreadInput } from "./git.ts";
3import {
4 AuthOrchestrationOperateScope,
5 AuthTerminalOperateScope,
6 AuthFilesystemReadScope,
7 AuthOrchestrationReadScope,
8 AuthSettingsWriteScope,
9 AuthSourceControlWriteScope,
10 type AuthEnvironmentScope,
11} from "./auth.ts";
12import { ORCHESTRATION_V2_WS_METHODS } from "./orchestrationV2.ts";
13import { WS_METHODS } from "./rpc.ts";
14
15/** Incremental client enforcement; the server still authorizes every request. */
16export const CLIENT_GUARDED_RPC_SCOPES = {
17 [WS_METHODS.uiSettingsPatch]: AuthSettingsWriteScope,
18 [WS_METHODS.devServerStatus]: AuthFilesystemReadScope,
19 [WS_METHODS.devServerStart]: AuthTerminalOperateScope,
20 [WS_METHODS.managedWorkspacesCreate]: AuthOrchestrationOperateScope,
21 [WS_METHODS.managedWorkspacesArchiveCompleted]: AuthOrchestrationOperateScope,
22 [WS_METHODS.serverRunStorageCleanup]: AuthSettingsWriteScope,
23 // Endpoint checks exist to configure exports, so they need the same grant as saving them.
24 [WS_METHODS.serverCheckOtlpEndpoint]: AuthSettingsWriteScope,
25 [WS_METHODS.pullRequestsRunAction]: AuthSourceControlWriteScope,
26 [WS_METHODS.mergebotOpenPullRequest]: AuthSourceControlWriteScope,
27 [WS_METHODS.mergebotSetAutoMerge]: AuthSourceControlWriteScope,
28 [WS_METHODS.mergebotUpdatePullRequest]: AuthSourceControlWriteScope,
29 [WS_METHODS.mergebotDeployProduction]: AuthSourceControlWriteScope,
30 [WS_METHODS.jjDescribe]: AuthSourceControlWriteScope,
31 [WS_METHODS.jjSquash]: AuthSourceControlWriteScope,
32 [WS_METHODS.jjPush]: AuthSourceControlWriteScope,
33 [WS_METHODS.pullRequestsUpdate]: AuthSourceControlWriteScope,
34 [WS_METHODS.pullRequestsComment]: AuthSourceControlWriteScope,
35 [WS_METHODS.pullRequestsUpdateComment]: AuthSourceControlWriteScope,
36 [WS_METHODS.pullRequestsSubmitReview]: AuthSourceControlWriteScope,
37 [WS_METHODS.pullRequestsReplyToThread]: AuthSourceControlWriteScope,
38 [WS_METHODS.pullRequestsSetThreadResolution]: AuthSourceControlWriteScope,
39 [WS_METHODS.pullRequestsSetReaction]: AuthSourceControlWriteScope,
40 [WS_METHODS.pullRequestsSetFilesViewed]: AuthSourceControlWriteScope,
41 [WS_METHODS.pullRequestsRequestReviewers]: AuthSourceControlWriteScope,
42 [WS_METHODS.pullRequestsSetLabels]: AuthSourceControlWriteScope,
43 // Writing a guide runs a model on this environment's providers, which reading one does not.
44 [WS_METHODS.pullRequestsGenerateReviewGuide]: AuthOrchestrationOperateScope,
45 [WS_METHODS.sourceControlCloneRepository]: AuthSourceControlWriteScope,
46 [WS_METHODS.sourceControlPublishRepository]: AuthSourceControlWriteScope,
47 [WS_METHODS.projectCloneStart]: AuthSourceControlWriteScope,
48 [WS_METHODS.projectCloneCancel]: AuthSourceControlWriteScope,
49 [WS_METHODS.projectCloneRetry]: AuthSourceControlWriteScope,
50 [WS_METHODS.vcsPull]: AuthSourceControlWriteScope,
51 [WS_METHODS.gitRunStackedAction]: AuthSourceControlWriteScope,
52 [WS_METHODS.gitPreparePullRequestThread]: AuthSourceControlWriteScope,
53 [WS_METHODS.vcsCreateWorktree]: AuthSourceControlWriteScope,
54 [WS_METHODS.vcsRemoveWorktree]: AuthSourceControlWriteScope,
55 [WS_METHODS.vcsCreateRef]: AuthSourceControlWriteScope,
56 [WS_METHODS.vcsSwitchRef]: AuthSourceControlWriteScope,
57 [WS_METHODS.vcsInit]: AuthSourceControlWriteScope,
58
59 [WS_METHODS.scheduledTasksUpsert]: AuthOrchestrationOperateScope,
60 [WS_METHODS.scheduledTasksSetEnabled]: AuthOrchestrationOperateScope,
61 [WS_METHODS.scheduledTasksDelete]: AuthOrchestrationOperateScope,
62 [WS_METHODS.scheduledTasksRunNow]: AuthOrchestrationOperateScope,
63 [WS_METHODS.scheduledTasksRotateWebhookToken]: AuthOrchestrationOperateScope,
64 [ORCHESTRATION_V2_WS_METHODS.stopWorkflow]: AuthOrchestrationOperateScope,
65} as const;
66export type ClientGuardedRpcTag = keyof typeof CLIENT_GUARDED_RPC_SCOPES;
67
68const decodePrepareThread = Schema.decodeUnknownSync(GitPreparePullRequestThreadInput);
69
70export function clientRpcRequiredScopes(
71 method: string,
72 input: unknown,
73): readonly AuthEnvironmentScope[] {
74 if (method === WS_METHODS.devServerStatus)
75 return [AuthFilesystemReadScope, AuthOrchestrationReadScope];
76 if (method === WS_METHODS.gitPreparePullRequestThread && input !== undefined) {
77 const payload = decodePrepareThread(input);
78 if (payload.mode === "worktree" && payload.threadId !== undefined)
79 return [AuthSourceControlWriteScope, AuthOrchestrationOperateScope];
80 }
81 return Object.hasOwn(CLIENT_GUARDED_RPC_SCOPES, method)
82 ? [CLIENT_GUARDED_RPC_SCOPES[method as ClientGuardedRpcTag]]
83 : [];
84}