🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@github/copilot-sdk

Package Overview
Dependencies
Maintainers
21
Versions
71
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@github/copilot-sdk - npm Package Compare versions

Comparing version
0.1.20
to
0.1.21
+92
-2
dist/client.d.ts
import { CopilotSession } from "./session.js";
import type { ConnectionState, CopilotClientOptions, GetAuthStatusResponse, GetStatusResponse, ModelInfo, ResumeSessionConfig, SessionConfig, SessionMetadata } from "./types.js";
import type { ConnectionState, CopilotClientOptions, GetAuthStatusResponse, GetStatusResponse, ModelInfo, ResumeSessionConfig, SessionConfig, SessionLifecycleEventType, SessionLifecycleHandler, SessionMetadata, TypedSessionLifecycleHandler } from "./types.js";
/**

@@ -47,2 +47,6 @@ * Main client for interacting with the Copilot CLI.

private forceStopping;
private modelsCache;
private modelsCacheLock;
private sessionLifecycleHandlers;
private typedLifecycleHandlers;
/**

@@ -233,3 +237,7 @@ * Creates a new CopilotClient instance.

/**
* List available models with their metadata
* List available models with their metadata.
*
* Results are cached after the first successful call to avoid rate limiting.
* The cache is cleared when the client disconnects.
*
* @throws Error if not authenticated

@@ -294,2 +302,83 @@ */

/**
* Gets the foreground session ID in TUI+server mode.
*
* This returns the ID of the session currently displayed in the TUI.
* Only available when connecting to a server running in TUI+server mode (--ui-server).
*
* @returns A promise that resolves with the foreground session ID, or undefined if none
* @throws Error if the client is not connected
*
* @example
* ```typescript
* const sessionId = await client.getForegroundSessionId();
* if (sessionId) {
* console.log(`TUI is displaying session: ${sessionId}`);
* }
* ```
*/
getForegroundSessionId(): Promise<string | undefined>;
/**
* Sets the foreground session in TUI+server mode.
*
* This requests the TUI to switch to displaying the specified session.
* Only available when connecting to a server running in TUI+server mode (--ui-server).
*
* @param sessionId - The ID of the session to display in the TUI
* @returns A promise that resolves when the session is switched
* @throws Error if the client is not connected or if the operation fails
*
* @example
* ```typescript
* // Switch the TUI to display a specific session
* await client.setForegroundSessionId("session-123");
* ```
*/
setForegroundSessionId(sessionId: string): Promise<void>;
/**
* Subscribes to a specific session lifecycle event type.
*
* Lifecycle events are emitted when sessions are created, deleted, updated,
* or change foreground/background state (in TUI+server mode).
*
* @param eventType - The specific event type to listen for
* @param handler - A callback function that receives events of the specified type
* @returns A function that, when called, unsubscribes the handler
*
* @example
* ```typescript
* // Listen for when a session becomes foreground in TUI
* const unsubscribe = client.on("session.foreground", (event) => {
* console.log(`Session ${event.sessionId} is now displayed in TUI`);
* });
*
* // Later, to stop receiving events:
* unsubscribe();
* ```
*/
on<K extends SessionLifecycleEventType>(eventType: K, handler: TypedSessionLifecycleHandler<K>): () => void;
/**
* Subscribes to all session lifecycle events.
*
* @param handler - A callback function that receives all lifecycle events
* @returns A function that, when called, unsubscribes the handler
*
* @example
* ```typescript
* const unsubscribe = client.on((event) => {
* switch (event.type) {
* case "session.foreground":
* console.log(`Session ${event.sessionId} is now in foreground`);
* break;
* case "session.created":
* console.log(`New session created: ${event.sessionId}`);
* break;
* }
* });
*
* // Later, to stop receiving events:
* unsubscribe();
* ```
*/
on(handler: SessionLifecycleHandler): () => void;
/**
* Start the CLI server process

@@ -312,2 +401,3 @@ */

private handleSessionEventNotification;
private handleSessionLifecycleNotification;
private handleToolCallRequest;

@@ -314,0 +404,0 @@ private executeToolCall;

@@ -31,2 +31,6 @@ import { spawn } from "node:child_process";

forceStopping = false;
modelsCache = null;
modelsCacheLock = Promise.resolve();
sessionLifecycleHandlers = /* @__PURE__ */ new Set();
typedLifecycleHandlers = /* @__PURE__ */ new Map();
/**

@@ -200,2 +204,3 @@ * Creates a new CopilotClient instance.

}
this.modelsCache = null;
if (this.socket) {

@@ -264,2 +269,3 @@ try {

}
this.modelsCache = null;
if (this.socket) {

@@ -321,2 +327,3 @@ try {

sessionId: config.sessionId,
reasoningEffort: config.reasoningEffort,
tools: config.tools?.map((tool) => ({

@@ -391,2 +398,3 @@ name: tool.name,

sessionId,
reasoningEffort: config.reasoningEffort,
tools: config.tools?.map((tool) => ({

@@ -480,3 +488,7 @@ name: tool.name,

/**
* List available models with their metadata
* List available models with their metadata.
*
* Results are cached after the first successful call to avoid rate limiting.
* The cache is cleared when the client disconnects.
*
* @throws Error if not authenticated

@@ -488,5 +500,19 @@ */

}
const result = await this.connection.sendRequest("models.list", {});
const response = result;
return response.models;
await this.modelsCacheLock;
let resolveLock;
this.modelsCacheLock = new Promise((resolve) => {
resolveLock = resolve;
});
try {
if (this.modelsCache !== null) {
return [...this.modelsCache];
}
const result = await this.connection.sendRequest("models.list", {});
const response = result;
const models = response.models;
this.modelsCache = models;
return [...models];
} finally {
resolveLock();
}
}

@@ -594,2 +620,73 @@ /**

/**
* Gets the foreground session ID in TUI+server mode.
*
* This returns the ID of the session currently displayed in the TUI.
* Only available when connecting to a server running in TUI+server mode (--ui-server).
*
* @returns A promise that resolves with the foreground session ID, or undefined if none
* @throws Error if the client is not connected
*
* @example
* ```typescript
* const sessionId = await client.getForegroundSessionId();
* if (sessionId) {
* console.log(`TUI is displaying session: ${sessionId}`);
* }
* ```
*/
async getForegroundSessionId() {
if (!this.connection) {
throw new Error("Client not connected");
}
const response = await this.connection.sendRequest("session.getForeground", {});
return response.sessionId;
}
/**
* Sets the foreground session in TUI+server mode.
*
* This requests the TUI to switch to displaying the specified session.
* Only available when connecting to a server running in TUI+server mode (--ui-server).
*
* @param sessionId - The ID of the session to display in the TUI
* @returns A promise that resolves when the session is switched
* @throws Error if the client is not connected or if the operation fails
*
* @example
* ```typescript
* // Switch the TUI to display a specific session
* await client.setForegroundSessionId("session-123");
* ```
*/
async setForegroundSessionId(sessionId) {
if (!this.connection) {
throw new Error("Client not connected");
}
const response = await this.connection.sendRequest("session.setForeground", { sessionId });
const result = response;
if (!result.success) {
throw new Error(result.error || "Failed to set foreground session");
}
}
on(eventTypeOrHandler, handler) {
if (typeof eventTypeOrHandler === "string" && handler) {
const eventType = eventTypeOrHandler;
if (!this.typedLifecycleHandlers.has(eventType)) {
this.typedLifecycleHandlers.set(eventType, /* @__PURE__ */ new Set());
}
const storedHandler = handler;
this.typedLifecycleHandlers.get(eventType).add(storedHandler);
return () => {
const handlers = this.typedLifecycleHandlers.get(eventType);
if (handlers) {
handlers.delete(storedHandler);
}
};
}
const wildcardHandler = eventTypeOrHandler;
this.sessionLifecycleHandlers.add(wildcardHandler);
return () => {
this.sessionLifecycleHandlers.delete(wildcardHandler);
};
}
/**
* Start the CLI server process

@@ -601,3 +698,3 @@ */

...this.options.cliArgs,
"--server",
"--headless",
"--log-level",

@@ -747,2 +844,5 @@ this.options.logLevel

});
this.connection.onNotification("session.lifecycle", (notification) => {
this.handleSessionLifecycleNotification(notification);
});
this.connection.onRequest(

@@ -781,2 +881,23 @@ "tool.call",

}
handleSessionLifecycleNotification(notification) {
if (typeof notification !== "object" || !notification || !("type" in notification) || typeof notification.type !== "string" || !("sessionId" in notification) || typeof notification.sessionId !== "string") {
return;
}
const event = notification;
const typedHandlers = this.typedLifecycleHandlers.get(event.type);
if (typedHandlers) {
for (const handler of typedHandlers) {
try {
handler(event);
} catch {
}
}
}
for (const handler of this.sessionLifecycleHandlers) {
try {
handler(event);
} catch {
}
}
}
async handleToolCallRequest(params) {

@@ -783,0 +904,0 @@ if (!params || typeof params.sessionId !== "string" || typeof params.toolCallId !== "string" || typeof params.toolName !== "string") {

@@ -6,3 +6,3 @@ /**

* Generated by: scripts/generate-session-types.ts
* Generated at: 2026-01-26T18:08:33.710Z
* Generated at: 2026-02-03T20:40:49.167Z
*

@@ -59,2 +59,4 @@ * To update these types:

stack?: string;
statusCode?: number;
providerCallId?: string;
};

@@ -137,2 +139,35 @@ } | {

ephemeral: true;
type: "session.shutdown";
data: {
shutdownType: "routine" | "error";
errorReason?: string;
totalPremiumRequests: number;
totalApiDurationMs: number;
sessionStartTime: number;
codeChanges: {
linesAdded: number;
linesRemoved: number;
filesModified: string[];
};
modelMetrics: {
[k: string]: {
requests: {
count: number;
cost: number;
};
usage: {
inputTokens: number;
outputTokens: number;
cacheReadTokens: number;
cacheWriteTokens: number;
};
};
};
currentModel?: string;
};
} | {
id: string;
timestamp: string;
parentId: string | null;
ephemeral: true;
type: "session.usage_info";

@@ -166,2 +201,4 @@ data: {

summaryContent?: string;
checkpointNumber?: number;
checkpointPath?: string;
compactionTokensUsed?: {

@@ -268,2 +305,5 @@ input: number;

}[];
reasoningOpaque?: string;
reasoningText?: string;
encryptedContent?: string;
parentToolCallId?: string;

@@ -299,3 +339,3 @@ };

data: {
model?: string;
model: string;
inputTokens?: number;

@@ -310,2 +350,3 @@ outputTokens?: number;

providerCallId?: string;
parentToolCallId?: string;
quotaSnapshots?: {

@@ -406,2 +447,14 @@ [k: string]: {

ephemeral?: boolean;
type: "skill.invoked";
data: {
name: string;
path: string;
content: string;
allowedTools?: string[];
};
} | {
id: string;
timestamp: string;
parentId: string | null;
ephemeral?: boolean;
type: "subagent.started";

@@ -408,0 +461,0 @@ data: {

+1
-1

@@ -9,2 +9,2 @@ /**

export { defineTool } from "./types.js";
export type { ConnectionState, CopilotClientOptions, CustomAgentConfig, GetAuthStatusResponse, GetStatusResponse, InfiniteSessionConfig, MCPLocalServerConfig, MCPRemoteServerConfig, MCPServerConfig, MessageOptions, ModelBilling, ModelCapabilities, ModelInfo, ModelPolicy, PermissionHandler, PermissionRequest, PermissionRequestResult, ResumeSessionConfig, SessionConfig, SessionEvent, SessionEventHandler, SessionEventPayload, SessionEventType, SessionMetadata, SystemMessageAppendConfig, SystemMessageConfig, SystemMessageReplaceConfig, Tool, ToolHandler, ToolInvocation, ToolResultObject, TypedSessionEventHandler, ZodSchema, } from "./types.js";
export type { ConnectionState, CopilotClientOptions, CustomAgentConfig, ForegroundSessionInfo, GetAuthStatusResponse, GetStatusResponse, InfiniteSessionConfig, MCPLocalServerConfig, MCPRemoteServerConfig, MCPServerConfig, MessageOptions, ModelBilling, ModelCapabilities, ModelInfo, ModelPolicy, PermissionHandler, PermissionRequest, PermissionRequestResult, ResumeSessionConfig, SessionConfig, SessionEvent, SessionEventHandler, SessionEventPayload, SessionEventType, SessionLifecycleEvent, SessionLifecycleEventType, SessionLifecycleHandler, SessionMetadata, SystemMessageAppendConfig, SystemMessageConfig, SystemMessageReplaceConfig, Tool, ToolHandler, ToolInvocation, ToolResultObject, TypedSessionEventHandler, TypedSessionLifecycleHandler, ZodSchema, } from "./types.js";

@@ -493,2 +493,6 @@ /**

}
/**
* Valid reasoning effort levels for models that support it.
*/
export type ReasoningEffort = "low" | "medium" | "high" | "xhigh";
export interface SessionConfig {

@@ -505,2 +509,8 @@ /**

/**
* Reasoning effort level for models that support it.
* Only valid for models where capabilities.supports.reasoningEffort is true.
* Use client.listModels() to check supported values for each model.
*/
reasoningEffort?: ReasoningEffort;
/**
* Override the default configuration directory location.

@@ -582,3 +592,3 @@ * When specified, the session will use this directory for storing config and state.

*/
export type ResumeSessionConfig = Pick<SessionConfig, "tools" | "provider" | "streaming" | "onPermissionRequest" | "onUserInputRequest" | "hooks" | "workingDirectory" | "mcpServers" | "customAgents" | "skillDirectories" | "disabledSkills"> & {
export type ResumeSessionConfig = Pick<SessionConfig, "tools" | "provider" | "streaming" | "reasoningEffort" | "onPermissionRequest" | "onUserInputRequest" | "hooks" | "workingDirectory" | "mcpServers" | "customAgents" | "skillDirectories" | "disabledSkills"> & {
/**

@@ -712,2 +722,4 @@ * When true, skips emitting the session.resume event.

vision: boolean;
/** Whether this model supports reasoning effort configuration */
reasoningEffort: boolean;
};

@@ -751,3 +763,46 @@ limits: {

billing?: ModelBilling;
/** Supported reasoning effort levels (only present if model supports reasoning effort) */
supportedReasoningEfforts?: ReasoningEffort[];
/** Default reasoning effort level (only present if model supports reasoning effort) */
defaultReasoningEffort?: ReasoningEffort;
}
/**
* Types of session lifecycle events
*/
export type SessionLifecycleEventType = "session.created" | "session.deleted" | "session.updated" | "session.foreground" | "session.background";
/**
* Session lifecycle event notification
* Sent when sessions are created, deleted, updated, or change foreground/background state
*/
export interface SessionLifecycleEvent {
/** Type of lifecycle event */
type: SessionLifecycleEventType;
/** ID of the session this event relates to */
sessionId: string;
/** Session metadata (not included for deleted sessions) */
metadata?: {
startTime: string;
modifiedTime: string;
summary?: string;
};
}
/**
* Handler for session lifecycle events
*/
export type SessionLifecycleHandler = (event: SessionLifecycleEvent) => void;
/**
* Typed handler for specific session lifecycle event types
*/
export type TypedSessionLifecycleHandler<K extends SessionLifecycleEventType> = (event: SessionLifecycleEvent & {
type: K;
}) => void;
/**
* Information about the foreground session in TUI+server mode
*/
export interface ForegroundSessionInfo {
/** ID of the foreground session, or undefined if none */
sessionId?: string;
/** Workspace path of the foreground session */
workspacePath?: string;
}
export {};

@@ -7,3 +7,3 @@ {

},
"version": "0.1.20",
"version": "0.1.21",
"description": "TypeScript SDK for programmatic control of GitHub Copilot CLI via JSON-RPC",

@@ -44,3 +44,3 @@ "main": "./dist/index.js",

"dependencies": {
"@github/copilot": "^0.0.399",
"@github/copilot": "^0.0.402",
"vscode-jsonrpc": "^8.2.1",

@@ -50,6 +50,6 @@ "zod": "^4.3.5"

"devDependencies": {
"@types/node": "^22.19.6",
"@typescript-eslint/eslint-plugin": "^8.0.0",
"@typescript-eslint/parser": "^8.0.0",
"esbuild": "^0.27.0",
"@types/node": "^25.2.0",
"@typescript-eslint/eslint-plugin": "^8.54.0",
"@typescript-eslint/parser": "^8.54.0",
"esbuild": "^0.27.2",
"eslint": "^9.0.0",

@@ -65,3 +65,3 @@ "glob": "^11.0.0",

"typescript": "^5.0.0",
"vitest": "^4.0.16"
"vitest": "^4.0.18"
},

@@ -68,0 +68,0 @@ "engines": {

@@ -89,4 +89,5 @@ # Copilot SDK for Node.js/TypeScript

- `sessionId?: string` - Custom session ID
- `sessionId?: string` - Custom session ID.
- `model?: string` - Model to use ("gpt-5", "claude-sonnet-4.5", etc.). **Required when using custom provider.**
- `reasoningEffort?: "low" | "medium" | "high" | "xhigh"` - Reasoning effort level for models that support it. Use `listModels()` to check which models support this option.
- `tools?: Tool[]` - Custom tools exposed to the CLI

@@ -119,2 +120,37 @@ - `systemMessage?: SystemMessageConfig` - System message customization (see below)

##### `getForegroundSessionId(): Promise<string | undefined>`
Get the ID of the session currently displayed in the TUI. Only available when connecting to a server running in TUI+server mode (`--ui-server`).
##### `setForegroundSessionId(sessionId: string): Promise<void>`
Request the TUI to switch to displaying the specified session. Only available in TUI+server mode.
##### `on(eventType: SessionLifecycleEventType, handler): () => void`
Subscribe to a specific session lifecycle event type. Returns an unsubscribe function.
```typescript
const unsubscribe = client.on("session.foreground", (event) => {
console.log(`Session ${event.sessionId} is now in foreground`);
});
```
##### `on(handler: SessionLifecycleHandler): () => void`
Subscribe to all session lifecycle events. Returns an unsubscribe function.
```typescript
const unsubscribe = client.on((event) => {
console.log(`${event.type}: ${event.sessionId}`);
});
```
**Lifecycle Event Types:**
- `session.created` - A new session was created
- `session.deleted` - A session was deleted
- `session.updated` - A session was updated (e.g., new messages)
- `session.foreground` - A session became the foreground session in TUI
- `session.background` - A session is no longer the foreground session
---

@@ -516,3 +552,3 @@

// request.allowFreeform - Whether freeform input is allowed (default: true)
console.log(`Agent asks: ${request.question}`);

@@ -522,3 +558,3 @@ if (request.choices) {

}
// Return the user's response

@@ -551,3 +587,3 @@ return {

},
// Called after each tool execution

@@ -561,3 +597,3 @@ onPostToolUse: async (input, invocation) => {

},
// Called when user submits a prompt

@@ -570,3 +606,3 @@ onUserPromptSubmitted: async (input, invocation) => {

},
// Called when session starts

@@ -579,3 +615,3 @@ onSessionStart: async (input, invocation) => {

},
// Called when session ends

@@ -585,3 +621,3 @@ onSessionEnd: async (input, invocation) => {

},
// Called when an error occurs

@@ -588,0 +624,0 @@ onErrorOccurred: async (input, invocation) => {