Skip to content

Commit 7fc03d2

Browse files
[Node] Set requestPermission False If Using Default Permission Handler (#1056)
* [Node] Set requestPermission False If Using Default Permission Handler * Add joinSession permission tests * Format joinSession changes
1 parent 9a38945 commit 7fc03d2

File tree

5 files changed

+70
-6
lines changed

5 files changed

+70
-6
lines changed

nodejs/src/client.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import type {
5555
TraceContextProvider,
5656
TypedSessionLifecycleHandler,
5757
} from "./types.js";
58+
import { defaultJoinSessionPermissionHandler } from "./types.js";
5859

5960
/**
6061
* Minimum protocol version this SDK can communicate with.
@@ -868,7 +869,8 @@ export class CopilotClient {
868869
})),
869870
provider: config.provider,
870871
modelCapabilities: config.modelCapabilities,
871-
requestPermission: true,
872+
requestPermission:
873+
config.onPermissionRequest !== defaultJoinSessionPermissionHandler,
872874
requestUserInput: !!config.onUserInputRequest,
873875
requestElicitation: !!config.onElicitationRequest,
874876
hooks: !!(config.hooks && Object.values(config.hooks).some(Boolean)),

nodejs/src/extension.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44

55
import { CopilotClient } from "./client.js";
66
import type { CopilotSession } from "./session.js";
7-
import type { PermissionHandler, PermissionRequestResult, ResumeSessionConfig } from "./types.js";
8-
9-
const defaultJoinSessionPermissionHandler: PermissionHandler = (): PermissionRequestResult => ({
10-
kind: "no-result",
11-
});
7+
import {
8+
defaultJoinSessionPermissionHandler,
9+
type PermissionHandler,
10+
type ResumeSessionConfig,
11+
} from "./types.js";
1212

1313
export type JoinSessionConfig = Omit<ResumeSessionConfig, "onPermissionRequest"> & {
1414
onPermissionRequest?: PermissionHandler;

nodejs/src/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,11 @@ export type PermissionHandler = (
757757

758758
export const approveAll: PermissionHandler = () => ({ kind: "approved" });
759759

760+
export const defaultJoinSessionPermissionHandler: PermissionHandler =
761+
(): PermissionRequestResult => ({
762+
kind: "no-result",
763+
});
764+
760765
// ============================================================================
761766
// User Input Request Types
762767
// ============================================================================

nodejs/test/client.test.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* eslint-disable @typescript-eslint/no-explicit-any */
22
import { describe, expect, it, onTestFinished, vi } from "vitest";
33
import { approveAll, CopilotClient, type ModelInfo } from "../src/index.js";
4+
import { defaultJoinSessionPermissionHandler } from "../src/types.js";
45

56
// This file is for unit tests. Where relevant, prefer to add e2e tests in e2e/*.test.ts instead
67

@@ -97,6 +98,60 @@ describe("CopilotClient", () => {
9798
spy.mockRestore();
9899
});
99100

101+
it("does not request permissions on session.resume when using the default joinSession handler", async () => {
102+
const client = new CopilotClient();
103+
await client.start();
104+
onTestFinished(() => client.forceStop());
105+
106+
const session = await client.createSession({ onPermissionRequest: approveAll });
107+
const spy = vi
108+
.spyOn((client as any).connection!, "sendRequest")
109+
.mockImplementation(async (method: string, params: any) => {
110+
if (method === "session.resume") return { sessionId: params.sessionId };
111+
throw new Error(`Unexpected method: ${method}`);
112+
});
113+
114+
await client.resumeSession(session.sessionId, {
115+
onPermissionRequest: defaultJoinSessionPermissionHandler,
116+
});
117+
118+
expect(spy).toHaveBeenCalledWith(
119+
"session.resume",
120+
expect.objectContaining({
121+
sessionId: session.sessionId,
122+
requestPermission: false,
123+
})
124+
);
125+
spy.mockRestore();
126+
});
127+
128+
it("requests permissions on session.resume when using an explicit handler", async () => {
129+
const client = new CopilotClient();
130+
await client.start();
131+
onTestFinished(() => client.forceStop());
132+
133+
const session = await client.createSession({ onPermissionRequest: approveAll });
134+
const spy = vi
135+
.spyOn((client as any).connection!, "sendRequest")
136+
.mockImplementation(async (method: string, params: any) => {
137+
if (method === "session.resume") return { sessionId: params.sessionId };
138+
throw new Error(`Unexpected method: ${method}`);
139+
});
140+
141+
await client.resumeSession(session.sessionId, {
142+
onPermissionRequest: approveAll,
143+
});
144+
145+
expect(spy).toHaveBeenCalledWith(
146+
"session.resume",
147+
expect.objectContaining({
148+
sessionId: session.sessionId,
149+
requestPermission: true,
150+
})
151+
);
152+
spy.mockRestore();
153+
});
154+
100155
it("sends session.model.switchTo RPC with correct params", async () => {
101156
const client = new CopilotClient();
102157
await client.start();

nodejs/test/extension.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { afterEach, describe, expect, it, vi } from "vitest";
22
import { CopilotClient } from "../src/client.js";
33
import { approveAll } from "../src/index.js";
44
import { joinSession } from "../src/extension.js";
5+
import { defaultJoinSessionPermissionHandler } from "../src/types.js";
56

67
describe("joinSession", () => {
78
const originalSessionId = process.env.SESSION_ID;
@@ -25,6 +26,7 @@ describe("joinSession", () => {
2526

2627
const [, config] = resumeSession.mock.calls[0]!;
2728
expect(config.onPermissionRequest).toBeDefined();
29+
expect(config.onPermissionRequest).toBe(defaultJoinSessionPermissionHandler);
2830
const result = await Promise.resolve(
2931
config.onPermissionRequest!({ kind: "write" }, { sessionId: "session-123" })
3032
);

0 commit comments

Comments
 (0)