Skip to content

Commit a7e862d

Browse files
Support connecting to parent process
1 parent 1476801 commit a7e862d

4 files changed

Lines changed: 53 additions & 5 deletions

File tree

nodejs/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
".": {
1313
"import": "./dist/index.js",
1414
"types": "./dist/index.d.ts"
15+
},
16+
"./extension": {
17+
"import": "./dist/extension.js",
18+
"types": "./dist/extension.d.ts"
1519
}
1620
},
1721
"type": "module",

nodejs/src/client.ts

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ import type {
4242
SessionListFilter,
4343
SessionMetadata,
4444
Tool,
45-
ToolHandler,
4645
TypedSessionLifecycleHandler,
4746
} from "./types.js";
4847

@@ -192,6 +191,12 @@ export class CopilotClient {
192191
throw new Error("cliUrl is mutually exclusive with useStdio and cliPath");
193192
}
194193

194+
if (options.isChildProcess && (options.cliUrl || options.useStdio === false)) {
195+
throw new Error(
196+
"isChildProcess must be used in conjunction with useStdio and not with cliUrl"
197+
);
198+
}
199+
195200
// Validate auth options with external server
196201
if (options.cliUrl && (options.githubToken || options.useLoggedInUser !== undefined)) {
197202
throw new Error(
@@ -207,12 +212,17 @@ export class CopilotClient {
207212
this.isExternalServer = true;
208213
}
209214

215+
if (options.isChildProcess) {
216+
this.isExternalServer = true;
217+
}
218+
210219
this.options = {
211220
cliPath: options.cliPath || getBundledCliPath(),
212221
cliArgs: options.cliArgs ?? [],
213222
cwd: options.cwd ?? process.cwd(),
214223
port: options.port || 0,
215224
useStdio: options.cliUrl ? false : (options.useStdio ?? true), // Default to stdio unless cliUrl is provided
225+
isChildProcess: options.isChildProcess ?? false,
216226
cliUrl: options.cliUrl,
217227
logLevel: options.logLevel || "debug",
218228
autoStart: options.autoStart ?? true,
@@ -1200,17 +1210,19 @@ export class CopilotClient {
12001210
* Connect to the CLI server (via socket or stdio)
12011211
*/
12021212
private async connectToServer(): Promise<void> {
1203-
if (this.options.useStdio) {
1204-
return this.connectViaStdio();
1213+
if (this.options.isChildProcess) {
1214+
return this.connectToParentProcessViaStdio();
1215+
} else if (this.options.useStdio) {
1216+
return this.connectToChildProcessViaStdio();
12051217
} else {
12061218
return this.connectViaTcp();
12071219
}
12081220
}
12091221

12101222
/**
1211-
* Connect via stdio pipes
1223+
* Connect to child via stdio pipes
12121224
*/
1213-
private async connectViaStdio(): Promise<void> {
1225+
private async connectToChildProcessViaStdio(): Promise<void> {
12141226
if (!this.cliProcess) {
12151227
throw new Error("CLI process not started");
12161228
}
@@ -1232,6 +1244,24 @@ export class CopilotClient {
12321244
this.connection.listen();
12331245
}
12341246

1247+
/**
1248+
* Connect to parent via stdio pipes
1249+
*/
1250+
private async connectToParentProcessViaStdio(): Promise<void> {
1251+
if (this.cliProcess) {
1252+
throw new Error("CLI child process was unexpectedly started in parent process mode");
1253+
}
1254+
1255+
// Create JSON-RPC connection over stdin/stdout
1256+
this.connection = createMessageConnection(
1257+
new StreamMessageReader(process.stdin),
1258+
new StreamMessageWriter(process.stdout)
1259+
);
1260+
1261+
this.attachConnectionHandlers();
1262+
this.connection.listen();
1263+
}
1264+
12351265
/**
12361266
* Connect to the CLI server via TCP socket
12371267
*/

nodejs/src/extension.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
*--------------------------------------------------------------------------------------------*/
4+
5+
import { CopilotClient } from "./client.js";
6+
7+
export const extension = new CopilotClient({ isChildProcess: true });

nodejs/src/types.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ export interface CopilotClientOptions {
4444
*/
4545
useStdio?: boolean;
4646

47+
/**
48+
* When true, indicates the SDK is running as a child process of the Copilot CLI server, and should
49+
* use its own stdio for communicating with the existing parent process. Can only be used in combination
50+
* with useStdio: true.
51+
*/
52+
isChildProcess?: boolean;
53+
4754
/**
4855
* URL of an existing Copilot CLI server to connect to over TCP
4956
* When provided, the client will not spawn a CLI process

0 commit comments

Comments
 (0)