Skip to content

Commit 7ac77be

Browse files
feat: Add more informative permissions approval (#180)
* feat: Add more informative permissions approval Uses the info we have to construct nicer menu items (translation of similar behavior on the Rust one) * feat: ensure permission rule is rendered in new line * Update tests --------- Co-authored-by: Alexandr Suhinin <alexandr.suhinin@jetbrains.com>
1 parent 989fc18 commit 7ac77be

9 files changed

Lines changed: 813 additions & 37 deletions

src/ApprovalOptionId.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@ export const ApprovalOptionId = {
22
AllowOnce: "allow_once",
33
AllowAlways: "allow_always",
44
RejectOnce: "reject_once",
5+
AcceptWithExecpolicyAmendment: "accept_execpolicy_amendment",
6+
ApplyNetworkPolicyAmendment: "apply_network_policy_amendment",
7+
AllowPermissionsForTurn: "allow_permissions_turn",
8+
AllowPermissionsForSession: "allow_permissions_session",
9+
RejectPermissions: "reject_permissions",
510
} as const;
611

712
export type ApprovalOptionId = typeof ApprovalOptionId[keyof typeof ApprovalOptionId];

src/CodexAcpClient.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,10 @@ export class CodexAcpClient {
440440
await this.waitForSessionNotifications(sessionId);
441441
return await approvalHandler.handleFileChange(params);
442442
},
443+
handlePermissionsRequest: async (params) => {
444+
await this.waitForSessionNotifications(sessionId);
445+
return await approvalHandler.handlePermissionsRequest(params);
446+
},
443447
});
444448
this.codexClient.onElicitationRequest(sessionId, {
445449
handleElicitation: async (params) => {

src/CodexAppServerClient.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,15 @@ import type {
5151
CommandExecutionRequestApprovalResponse,
5252
FileChangeRequestApprovalParams,
5353
FileChangeRequestApprovalResponse,
54+
PermissionsRequestApprovalParams,
55+
PermissionsRequestApprovalResponse,
5456
ItemCompletedNotification,
5557
} from "./app-server/v2";
5658

5759
export interface ApprovalHandler {
5860
handleCommandExecution(params: CommandExecutionRequestApprovalParams): Promise<CommandExecutionRequestApprovalResponse>;
5961
handleFileChange(params: FileChangeRequestApprovalParams): Promise<FileChangeRequestApprovalResponse>;
62+
handlePermissionsRequest(params: PermissionsRequestApprovalParams): Promise<PermissionsRequestApprovalResponse>;
6063
}
6164

6265
export interface ElicitationHandler {
@@ -86,6 +89,12 @@ const FileChangeApprovalRequest = new RequestType<
8689
void
8790
>('item/fileChange/requestApproval');
8891

92+
const PermissionsApprovalRequest = new RequestType<
93+
PermissionsRequestApprovalParams,
94+
PermissionsRequestApprovalResponse,
95+
void
96+
>('item/permissions/requestApproval');
97+
8998
const McpServerElicitationRequest = new RequestType<
9099
McpServerElicitationRequestParams,
91100
McpServerElicitationRequestResponse,
@@ -166,6 +175,17 @@ export class CodexAppServerClient {
166175
return await handler.handleFileChange(params);
167176
});
168177

178+
this.connection.onRequest(PermissionsApprovalRequest, async (params) => {
179+
if (this.isStaleTurn(params.threadId, params.turnId)) {
180+
return { permissions: {}, scope: "turn", strictAutoReview: true };
181+
}
182+
const handler = this.approvalHandlers.get(params.threadId);
183+
if (!handler) {
184+
return { permissions: {}, scope: "turn", strictAutoReview: true };
185+
}
186+
return await handler.handlePermissionsRequest(params);
187+
});
188+
169189
this.connection.onRequest(McpServerElicitationRequest, async (params) => {
170190
if (this.isStaleTurn(params.threadId, params.turnId)) {
171191
return { action: "cancel", content: null, _meta: null };

0 commit comments

Comments
 (0)