@github/copilot-sdk 0.1.21 → 0.1.23-preview.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.d.ts CHANGED
@@ -1,38 +1,5 @@
1
1
  import { CopilotSession } from "./session.js";
2
2
  import type { ConnectionState, CopilotClientOptions, GetAuthStatusResponse, GetStatusResponse, ModelInfo, ResumeSessionConfig, SessionConfig, SessionLifecycleEventType, SessionLifecycleHandler, SessionMetadata, TypedSessionLifecycleHandler } from "./types.js";
3
- /**
4
- * Main client for interacting with the Copilot CLI.
5
- *
6
- * The CopilotClient manages the connection to the Copilot CLI server and provides
7
- * methods to create and manage conversation sessions. It can either spawn a CLI
8
- * server process or connect to an existing server.
9
- *
10
- * @example
11
- * ```typescript
12
- * import { CopilotClient } from "@github/copilot-sdk";
13
- *
14
- * // Create a client with default options (spawns CLI server)
15
- * const client = new CopilotClient();
16
- *
17
- * // Or connect to an existing server
18
- * const client = new CopilotClient({ cliUrl: "localhost:3000" });
19
- *
20
- * // Create a session
21
- * const session = await client.createSession({ model: "gpt-4" });
22
- *
23
- * // Send messages and handle responses
24
- * session.on((event) => {
25
- * if (event.type === "assistant.message") {
26
- * console.log(event.data.content);
27
- * }
28
- * });
29
- * await session.send({ prompt: "Hello!" });
30
- *
31
- * // Clean up
32
- * await session.destroy();
33
- * await client.stop();
34
- * ```
35
- */
36
3
  export declare class CopilotClient {
37
4
  private cliProcess;
38
5
  private connection;
package/dist/client.js CHANGED
@@ -1,5 +1,8 @@
1
1
  import { spawn } from "node:child_process";
2
+ import { existsSync } from "node:fs";
2
3
  import { Socket } from "node:net";
4
+ import { dirname, join } from "node:path";
5
+ import { fileURLToPath } from "node:url";
3
6
  import {
4
7
  createMessageConnection,
5
8
  StreamMessageReader,
@@ -17,6 +20,11 @@ function toJsonSchema(parameters) {
17
20
  }
18
21
  return parameters;
19
22
  }
23
+ function getBundledCliPath() {
24
+ const sdkUrl = import.meta.resolve("@github/copilot/sdk");
25
+ const sdkPath = fileURLToPath(sdkUrl);
26
+ return join(dirname(dirname(sdkPath)), "index.js");
27
+ }
20
28
  class CopilotClient {
21
29
  cliProcess = null;
22
30
  connection = null;
@@ -69,7 +77,7 @@ class CopilotClient {
69
77
  this.isExternalServer = true;
70
78
  }
71
79
  this.options = {
72
- cliPath: options.cliPath || "copilot",
80
+ cliPath: options.cliPath || getBundledCliPath(),
73
81
  cliArgs: options.cliArgs ?? [],
74
82
  cwd: options.cwd ?? process.cwd(),
75
83
  port: options.port || 0,
@@ -391,7 +399,11 @@ class CopilotClient {
391
399
  }
392
400
  const response = await this.connection.sendRequest("session.resume", {
393
401
  sessionId,
402
+ model: config.model,
394
403
  reasoningEffort: config.reasoningEffort,
404
+ systemMessage: config.systemMessage,
405
+ availableTools: config.availableTools,
406
+ excludedTools: config.excludedTools,
395
407
  tools: config.tools?.map((tool) => ({
396
408
  name: tool.name,
397
409
  description: tool.description,
@@ -402,11 +414,13 @@ class CopilotClient {
402
414
  requestUserInput: !!config.onUserInputRequest,
403
415
  hooks: !!(config.hooks && Object.values(config.hooks).some(Boolean)),
404
416
  workingDirectory: config.workingDirectory,
417
+ configDir: config.configDir,
405
418
  streaming: config.streaming,
406
419
  mcpServers: config.mcpServers,
407
420
  customAgents: config.customAgents,
408
421
  skillDirectories: config.skillDirectories,
409
422
  disabledSkills: config.disabledSkills,
423
+ infiniteSessions: config.infiniteSessions,
410
424
  disableResume: config.disableResume
411
425
  });
412
426
  const { sessionId: resumedSessionId, workspacePath } = response;
@@ -707,25 +721,26 @@ class CopilotClient {
707
721
  if (this.options.githubToken) {
708
722
  envWithoutNodeDebug.COPILOT_SDK_AUTH_TOKEN = this.options.githubToken;
709
723
  }
724
+ if (!existsSync(this.options.cliPath)) {
725
+ throw new Error(
726
+ `Copilot CLI not found at ${this.options.cliPath}. Ensure @github/copilot is installed.`
727
+ );
728
+ }
729
+ const stdioConfig = this.options.useStdio ? ["pipe", "pipe", "pipe"] : ["ignore", "pipe", "pipe"];
710
730
  const isJsFile = this.options.cliPath.endsWith(".js");
711
- const isAbsolutePath = this.options.cliPath.startsWith("/") || /^[a-zA-Z]:/.test(this.options.cliPath);
712
- let command;
713
- let spawnArgs;
714
731
  if (isJsFile) {
715
- command = "node";
716
- spawnArgs = [this.options.cliPath, ...args];
717
- } else if (process.platform === "win32" && !isAbsolutePath) {
718
- command = "cmd";
719
- spawnArgs = ["/c", `${this.options.cliPath}`, ...args];
732
+ this.cliProcess = spawn(process.execPath, [this.options.cliPath, ...args], {
733
+ stdio: stdioConfig,
734
+ cwd: this.options.cwd,
735
+ env: envWithoutNodeDebug
736
+ });
720
737
  } else {
721
- command = this.options.cliPath;
722
- spawnArgs = args;
738
+ this.cliProcess = spawn(this.options.cliPath, args, {
739
+ stdio: stdioConfig,
740
+ cwd: this.options.cwd,
741
+ env: envWithoutNodeDebug
742
+ });
723
743
  }
724
- this.cliProcess = spawn(command, spawnArgs, {
725
- stdio: this.options.useStdio ? ["pipe", "pipe", "pipe"] : ["ignore", "pipe", "pipe"],
726
- cwd: this.options.cwd,
727
- env: envWithoutNodeDebug
728
- });
729
744
  let stdout = "";
730
745
  let resolved = false;
731
746
  if (this.options.useStdio) {
package/dist/session.js CHANGED
@@ -96,10 +96,11 @@ class CopilotSession {
96
96
  rejectWithError(error);
97
97
  }
98
98
  });
99
+ let timeoutId;
99
100
  try {
100
101
  await this.send(options);
101
102
  const timeoutPromise = new Promise((_, reject) => {
102
- setTimeout(
103
+ timeoutId = setTimeout(
103
104
  () => reject(
104
105
  new Error(
105
106
  `Timeout after ${effectiveTimeout}ms waiting for session.idle`
@@ -111,6 +112,9 @@ class CopilotSession {
111
112
  await Promise.race([idlePromise, timeoutPromise]);
112
113
  return lastAssistantMessage;
113
114
  } finally {
115
+ if (timeoutId !== void 0) {
116
+ clearTimeout(timeoutId);
117
+ }
114
118
  unsubscribe();
115
119
  }
116
120
  }
package/dist/types.d.ts CHANGED
@@ -8,8 +8,8 @@ export type SessionEvent = GeneratedSessionEvent;
8
8
  */
9
9
  export interface CopilotClientOptions {
10
10
  /**
11
- * Path to the Copilot CLI executable
12
- * @default "copilot" (searches PATH)
11
+ * Path to the CLI executable or JavaScript entry point.
12
+ * If not specified, uses the bundled CLI from the @github/copilot package.
13
13
  */
14
14
  cliPath?: string;
15
15
  /**
@@ -587,7 +587,7 @@ export interface SessionConfig {
587
587
  /**
588
588
  * Configuration for resuming a session
589
589
  */
590
- export type ResumeSessionConfig = Pick<SessionConfig, "tools" | "provider" | "streaming" | "reasoningEffort" | "onPermissionRequest" | "onUserInputRequest" | "hooks" | "workingDirectory" | "mcpServers" | "customAgents" | "skillDirectories" | "disabledSkills"> & {
590
+ export type ResumeSessionConfig = Pick<SessionConfig, "model" | "tools" | "systemMessage" | "availableTools" | "excludedTools" | "provider" | "streaming" | "reasoningEffort" | "onPermissionRequest" | "onUserInputRequest" | "hooks" | "workingDirectory" | "configDir" | "mcpServers" | "customAgents" | "skillDirectories" | "disabledSkills" | "infiniteSessions"> & {
591
591
  /**
592
592
  * When true, skips emitting the session.resume event.
593
593
  * Useful for reconnecting to a session without triggering resume-related side effects.
@@ -640,12 +640,31 @@ export interface MessageOptions {
640
640
  */
641
641
  prompt: string;
642
642
  /**
643
- * File or directory attachments
643
+ * File, directory, or selection attachments
644
644
  */
645
645
  attachments?: Array<{
646
- type: "file" | "directory";
646
+ type: "file";
647
647
  path: string;
648
648
  displayName?: string;
649
+ } | {
650
+ type: "directory";
651
+ path: string;
652
+ displayName?: string;
653
+ } | {
654
+ type: "selection";
655
+ filePath: string;
656
+ displayName: string;
657
+ selection?: {
658
+ start: {
659
+ line: number;
660
+ character: number;
661
+ };
662
+ end: {
663
+ line: number;
664
+ character: number;
665
+ };
666
+ };
667
+ text?: string;
649
668
  }>;
650
669
  /**
651
670
  * Message delivery mode
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "type": "git",
5
5
  "url": "https://github.com/github/copilot-sdk.git"
6
6
  },
7
- "version": "0.1.21",
7
+ "version": "0.1.23-preview.0",
8
8
  "description": "TypeScript SDK for programmatic control of GitHub Copilot CLI via JSON-RPC",
9
9
  "main": "./dist/index.js",
10
10
  "types": "./dist/index.d.ts",
@@ -40,9 +40,9 @@
40
40
  "author": "GitHub",
41
41
  "license": "MIT",
42
42
  "dependencies": {
43
- "@github/copilot": "^0.0.402",
43
+ "@github/copilot": "^0.0.403",
44
44
  "vscode-jsonrpc": "^8.2.1",
45
- "zod": "^4.3.5"
45
+ "zod": "^4.3.6"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@types/node": "^25.2.0",
@@ -50,10 +50,10 @@
50
50
  "@typescript-eslint/parser": "^8.54.0",
51
51
  "esbuild": "^0.27.2",
52
52
  "eslint": "^9.0.0",
53
- "glob": "^11.0.0",
53
+ "glob": "^13.0.1",
54
54
  "json-schema": "^0.4.0",
55
55
  "json-schema-to-typescript": "^15.0.4",
56
- "prettier": "^3.4.0",
56
+ "prettier": "^3.8.1",
57
57
  "quicktype-core": "^23.2.6",
58
58
  "rimraf": "^6.1.2",
59
59
  "semver": "^7.7.3",
@@ -62,7 +62,7 @@
62
62
  "vitest": "^4.0.18"
63
63
  },
64
64
  "engines": {
65
- "node": ">=18.0.0"
65
+ "node": ">=24.0.0"
66
66
  },
67
67
  "files": [
68
68
  "dist/**/*",