@github/copilot-sdk 1.0.0-beta.9 → 1.0.1

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/README.md CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  TypeScript SDK for programmatic control of GitHub Copilot CLI via JSON-RPC.
4
4
 
5
- > **Note:** This SDK is in public preview and may change in breaking ways.
6
-
7
5
  ## Installation
8
6
 
9
7
  ```bash
@@ -57,7 +55,7 @@ await session.disconnect();
57
55
  await client.stop();
58
56
  ```
59
57
 
60
- Sessions also support `Symbol.asyncDispose` for use with [`await using`](https://github.com/tc39/proposal-explicit-resource-management) (TypeScript 5.2+/Node.js 18.0+):
58
+ Sessions also support `Symbol.asyncDispose` for use with [`await using`](https://github.com/tc39/proposal-explicit-resource-management) (TypeScript 5.2+ / Node.js 20+):
61
59
 
62
60
  ```typescript
63
61
  await using session = await client.createSession({
@@ -82,14 +80,20 @@ new CopilotClient(options?: CopilotClientOptions)
82
80
  - `connection?: RuntimeConnection` - How to connect to the Copilot runtime. Construct via the factory functions on `RuntimeConnection`:
83
81
  - `RuntimeConnection.forStdio({ path?, args? })` (default) — spawn the runtime and communicate over its stdin/stdout.
84
82
  - `RuntimeConnection.forTcp({ port?, connectionToken?, path?, args? })` — spawn the runtime as a TCP server.
85
- - `RuntimeConnection.forUri(url, { connectionToken? })` — connect to an already-running runtime (mutually exclusive with `gitHubToken`/`useLoggedInUser`).
86
- - `cwd?: string` - Working directory for the runtime process (default: current process cwd).
83
+ - `RuntimeConnection.forUri(url, { connectionToken? })` — connect to an already-running runtime (mutually exclusive with `gitHubToken`/`useLoggedInUser`). There is no top-level `cliUrl` shortcut; use this factory for URL-based connections.
84
+ - `mode?: "empty" | "copilot-cli"` - Defaulting strategy. Use `"empty"` for multi-user server mode; defaults to `"copilot-cli"`.
85
+ - `workingDirectory?: string` - Working directory for the runtime process (default: current process cwd).
87
86
  - `baseDirectory?: string` - Base directory for Copilot data (session state, config, etc.). Sets `COPILOT_HOME` on the spawned runtime. When not set, the runtime defaults to `~/.copilot`. Ignored when connecting via `RuntimeConnection.forUri`.
88
- - `logLevel?: string` - Log level. When omitted, the runtime uses its own default (currently `"info"`).
87
+ - `logLevel?: "none" | "error" | "warning" | "info" | "debug" | "all"` - Log level. When omitted, the runtime uses its own default (currently `"info"`).
88
+ - `env?: Record<string, string | undefined>` - Environment variables for the runtime process. When omitted, inherits `process.env`.
89
89
  - `gitHubToken?: string` - GitHub token for authentication. When provided, takes priority over other auth methods.
90
90
  - `useLoggedInUser?: boolean` - Whether to use logged-in user for authentication (default: true, but false when `gitHubToken` is provided). Cannot be used with `RuntimeConnection.forUri`.
91
+ - `onListModels?: () => Promise<ModelInfo[]> | ModelInfo[]` - Optional model-list provider, useful when using a custom provider.
91
92
  - `telemetry?: TelemetryConfig` - OpenTelemetry configuration for the runtime process. Providing this object enables telemetry — no separate flag needed. See [Telemetry](#telemetry) below.
92
93
  - `onGetTraceContext?: TraceContextProvider` - Advanced: callback for linking your application's own OpenTelemetry spans into the same distributed trace as the runtime's spans. Not needed for normal telemetry collection. See [Telemetry](#telemetry) below.
94
+ - `sessionFs?: SessionFsConfig` - Custom session filesystem provider.
95
+ - `sessionIdleTimeoutSeconds?: number` - Server-wide idle timeout for sessions in seconds. Ignored when connecting via `RuntimeConnection.forUri`.
96
+ - `enableRemoteSessions?: boolean` - Enable Mission Control remote session support. Ignored when connecting via `RuntimeConnection.forUri`.
93
97
 
94
98
  #### Methods
95
99
 
@@ -163,7 +167,7 @@ Get the ID of the session currently displayed in the TUI. Only available when co
163
167
 
164
168
  Request the TUI to switch to displaying the specified session. Only available in TUI+server mode.
165
169
 
166
- ##### `on(eventType: SessionLifecycleEventType, handler): () => void`
170
+ ##### `onLifecycle(eventType: SessionLifecycleEventType, handler): () => void`
167
171
 
168
172
  Subscribe to a specific session lifecycle event type. Returns an unsubscribe function.
169
173
 
@@ -173,7 +177,7 @@ const unsubscribe = client.onLifecycle("session.foreground", (event) => {
173
177
  });
174
178
  ```
175
179
 
176
- ##### `on(handler: SessionLifecycleHandler): () => void`
180
+ ##### `onLifecycle(handler: SessionLifecycleHandler): () => void`
177
181
 
178
182
  Subscribe to all session lifecycle events. Returns an unsubscribe function.
179
183
 
@@ -1031,7 +1035,7 @@ try {
1031
1035
 
1032
1036
  ## Requirements
1033
1037
 
1034
- - Node.js >= 18.0.0
1038
+ - Node.js ^20.19.0 or >=22.12.0
1035
1039
  - GitHub Copilot CLI installed and in PATH (or provide a custom `connection`)
1036
1040
 
1037
1041
  ## License
package/dist/canvas.d.ts CHANGED
@@ -1,14 +1,17 @@
1
1
  import type { CanvasJsonSchema, CanvasProviderCloseRequest, CanvasProviderInvokeActionRequest, CanvasProviderOpenRequest, CanvasProviderOpenResult } from "./generated/rpc.js";
2
- export type { CanvasJsonSchema, CanvasHostContext } from "./generated/rpc.js";
2
+ export type { CanvasJsonSchema, CanvasHostContext, CanvasHostContextCapabilities, } from "./generated/rpc.js";
3
3
  /**
4
4
  * Extension-owned canvases declared via
5
5
  * `joinSession({ canvases: [createCanvas({...})] })`.
6
6
  *
7
7
  * The runtime sends provider callbacks as `canvas.open`, `canvas.close`, and
8
- * `canvas.invokeAction` JSON-RPC requests via the codegen client session API
8
+ * `canvas.action.invoke` JSON-RPC requests via the codegen client session API
9
9
  * pipeline. The SDK routes those requests by `canvasId` to the in-process
10
10
  * handlers bound by `createCanvas`. Re-opening with an existing `instanceId`
11
11
  * is how the host focuses an existing panel; reload is a renderer-only concern.
12
+ *
13
+ * @experimental Canvas types are part of an experimental wire-protocol surface
14
+ * and may change or be removed in future SDK or CLI releases.
12
15
  */
13
16
  /**
14
17
  * A single agent-callable action contributed by a canvas. The metadata
@@ -18,6 +21,9 @@ export type { CanvasJsonSchema, CanvasHostContext } from "./generated/rpc.js";
18
21
  *
19
22
  * Names MUST NOT start with `canvas.` — that prefix is reserved for
20
23
  * lifecycle verbs.
24
+ *
25
+ * @experimental This type is part of an experimental wire-protocol surface
26
+ * and may change or be removed in future SDK or CLI releases.
21
27
  */
22
28
  export interface CanvasAction {
23
29
  /** Action identifier, unique within the canvas. */
@@ -32,6 +38,9 @@ export interface CanvasAction {
32
38
  /**
33
39
  * Declarative metadata for a single canvas, serialized over the wire on
34
40
  * `session.create` / `session.resume`.
41
+ *
42
+ * @experimental This type is part of an experimental wire-protocol surface
43
+ * and may change or be removed in future SDK or CLI releases.
35
44
  */
36
45
  export interface CanvasDeclaration {
37
46
  /** Canvas id, unique within the declaring connection. */
@@ -45,7 +54,12 @@ export interface CanvasDeclaration {
45
54
  /** Agent-invocable actions exposed via `invoke_canvas_action`. */
46
55
  actions?: Omit<CanvasAction, "handler">[];
47
56
  }
48
- /** Structured error returned from canvas handlers. */
57
+ /**
58
+ * Structured error returned from canvas handlers.
59
+ *
60
+ * @experimental This class is part of an experimental wire-protocol surface
61
+ * and may change or be removed in future SDK or CLI releases.
62
+ */
49
63
  export declare class CanvasError extends Error {
50
64
  readonly code: string;
51
65
  constructor(code: string, message: string);
@@ -55,6 +69,9 @@ export declare class CanvasError extends Error {
55
69
  /**
56
70
  * Options accepted by {@link createCanvas}. Combines the declarative
57
71
  * {@link CanvasDeclaration} fields with the in-process handler closures.
72
+ *
73
+ * @experimental This interface is part of an experimental wire-protocol surface
74
+ * and may change or be removed in future SDK or CLI releases.
58
75
  */
59
76
  export interface CanvasOptions {
60
77
  /** @see CanvasDeclaration.id */
@@ -87,6 +104,9 @@ export interface CanvasOptions {
87
104
  * ergonomics) where other SDKs (Rust, Python, Go, .NET) expose a single
88
105
  * `CanvasHandler` per session that switches on `canvasId`. Both shapes target
89
106
  * the same JSON-RPC wire protocol; the divergence is API ergonomics only.
107
+ *
108
+ * @experimental This class is part of an experimental wire-protocol surface
109
+ * and may change or be removed in future SDK or CLI releases.
90
110
  */
91
111
  export declare class Canvas {
92
112
  readonly declaration: CanvasDeclaration;
@@ -99,5 +119,8 @@ export declare class Canvas {
99
119
  * `DefineTool`'s co-location ergonomics) where other SDKs (Rust, Python, Go,
100
120
  * .NET) expose a single `CanvasHandler` per session that switches on
101
121
  * `canvasId`. Both shapes target the same JSON-RPC wire protocol.
122
+ *
123
+ * @experimental This function is part of an experimental wire-protocol surface
124
+ * and may change or be removed in future SDK or CLI releases.
102
125
  */
103
126
  export declare function createCanvas(options: CanvasOptions): Canvas;
@@ -68,6 +68,15 @@ function toWireCustomAgents(agents) {
68
68
  return { ...rest, mcpServers: toWireMcpServers(mcpServers) };
69
69
  });
70
70
  }
71
+ function toWireLargeOutput(config) {
72
+ if (!config) return void 0;
73
+ const { outputDirectory, ...rest } = config;
74
+ const wire = { ...rest };
75
+ if (outputDirectory !== void 0) {
76
+ wire.outputDir = outputDirectory;
77
+ }
78
+ return wire;
79
+ }
71
80
  function toolFilterListToArray(value) {
72
81
  if (value === void 0) {
73
82
  return void 0;
@@ -620,7 +629,17 @@ class CopilotClient {
620
629
  /** Mode-specific defaults spread under the caller's config (app values win). */
621
630
  configDefaultsForMode() {
622
631
  if (this.options.mode === "empty") {
623
- return { enableSessionTelemetry: false };
632
+ return {
633
+ enableSessionTelemetry: false,
634
+ mcpOAuthTokenStorage: "in-memory",
635
+ skipEmbeddingRetrieval: true,
636
+ embeddingCacheStorage: "in-memory",
637
+ enableOnDemandInstructionDiscovery: false,
638
+ enableFileHooks: false,
639
+ enableHostGitOperations: false,
640
+ enableSessionStore: false,
641
+ enableSkills: false
642
+ };
624
643
  }
625
644
  return {};
626
645
  }
@@ -706,51 +725,64 @@ class CopilotClient {
706
725
  }
707
726
  config = { ...this.configDefaultsForMode(), ...config };
708
727
  config.systemMessage = this.getSystemMessageConfigForMode(config.systemMessage);
709
- const sessionId = config.sessionId ?? (0, import_node_crypto.randomUUID)();
710
- const session = new import_session.CopilotSession(
711
- sessionId,
712
- this.connection,
713
- void 0,
714
- this.onGetTraceContext
715
- );
716
- session.registerTools(config.tools);
717
- session.registerCanvases(config.canvases);
718
- session.registerCommands(config.commands);
719
- session.registerPermissionHandler(config.onPermissionRequest);
720
- if (config.onUserInputRequest) {
721
- session.registerUserInputHandler(config.onUserInputRequest);
722
- }
723
- if (config.onElicitationRequest) {
724
- session.registerElicitationHandler(config.onElicitationRequest);
725
- }
726
- if (config.onExitPlanModeRequest) {
727
- session.registerExitPlanModeHandler(config.onExitPlanModeRequest);
728
- }
729
- if (config.onAutoModeSwitchRequest) {
730
- session.registerAutoModeSwitchHandler(config.onAutoModeSwitchRequest);
731
- }
732
- if (config.hooks) {
733
- session.registerHooks(config.hooks);
734
- }
728
+ const callerSessionId = config.sessionId;
729
+ const useServerGeneratedId = config.cloud != null && callerSessionId == null;
730
+ const localSessionId = useServerGeneratedId ? void 0 : callerSessionId ?? (0, import_node_crypto.randomUUID)();
735
731
  const { wirePayload: wireSystemMessage, transformCallbacks } = extractTransformCallbacks(
736
732
  config.systemMessage
737
733
  );
738
- if (transformCallbacks) {
739
- session.registerTransformCallbacks(transformCallbacks);
740
- }
741
- if (config.onEvent) {
742
- session.on(config.onEvent);
734
+ const initializeSession = (sessionId) => {
735
+ const s = new import_session.CopilotSession(
736
+ sessionId,
737
+ this.connection,
738
+ void 0,
739
+ this.onGetTraceContext
740
+ );
741
+ s.registerTools(config.tools);
742
+ s.registerCanvases(config.canvases);
743
+ s.registerCommands(config.commands);
744
+ s.registerPermissionHandler(config.onPermissionRequest);
745
+ if (config.onUserInputRequest) {
746
+ s.registerUserInputHandler(config.onUserInputRequest);
747
+ }
748
+ if (config.onElicitationRequest) {
749
+ s.registerElicitationHandler(config.onElicitationRequest);
750
+ }
751
+ if (config.onExitPlanModeRequest) {
752
+ s.registerExitPlanModeHandler(config.onExitPlanModeRequest);
753
+ }
754
+ if (config.onAutoModeSwitchRequest) {
755
+ s.registerAutoModeSwitchHandler(config.onAutoModeSwitchRequest);
756
+ }
757
+ if (config.hooks) {
758
+ s.registerHooks(config.hooks);
759
+ }
760
+ if (transformCallbacks) {
761
+ s.registerTransformCallbacks(transformCallbacks);
762
+ }
763
+ if (config.onEvent) {
764
+ s.on(config.onEvent);
765
+ }
766
+ this.sessions.set(sessionId, s);
767
+ this.setupSessionFs(s, config);
768
+ return s;
769
+ };
770
+ let session;
771
+ let registeredId;
772
+ if (localSessionId !== void 0) {
773
+ session = initializeSession(localSessionId);
774
+ registeredId = localSessionId;
743
775
  }
744
- this.sessions.set(sessionId, session);
745
- this.setupSessionFs(session, config);
746
776
  const toolFilterOptions = this.resolveToolFilterOptions(config);
747
777
  try {
748
778
  const response = await this.connection.sendRequest("session.create", {
749
779
  ...await (0, import_telemetry.getTraceContext)(this.onGetTraceContext),
750
780
  model: config.model,
751
- sessionId,
781
+ sessionId: localSessionId,
752
782
  clientName: config.clientName,
753
783
  reasoningEffort: config.reasoningEffort,
784
+ reasoningSummary: config.reasoningSummary,
785
+ contextTier: config.contextTier,
754
786
  tools: config.tools?.map((tool) => ({
755
787
  name: tool.name,
756
788
  description: tool.description,
@@ -761,6 +793,7 @@ class CopilotClient {
761
793
  canvases: config.canvases?.map((canvas) => canvas.declaration),
762
794
  requestCanvasRenderer: config.requestCanvasRenderer,
763
795
  requestExtensions: config.requestExtensions,
796
+ extensionSdkPath: config.extensionSdkPath,
764
797
  extensionInfo: config.extensionInfo,
765
798
  commands: config.commands?.map((cmd) => ({
766
799
  name: cmd.name,
@@ -773,9 +806,11 @@ class CopilotClient {
773
806
  provider: config.provider,
774
807
  enableSessionTelemetry: config.enableSessionTelemetry,
775
808
  modelCapabilities: config.modelCapabilities,
809
+ largeOutput: toWireLargeOutput(config.largeOutput),
776
810
  requestPermission: !!config.onPermissionRequest,
777
811
  requestUserInput: !!config.onUserInputRequest,
778
812
  requestElicitation: !!config.onElicitationRequest,
813
+ ...config.enableMcpApps ? { requestMcpApps: true } : {},
779
814
  requestExitPlanMode: !!config.onExitPlanModeRequest,
780
815
  requestAutoModeSwitch: !!config.onAutoModeSwitchRequest,
781
816
  hooks: !!(config.hooks && Object.values(config.hooks).some(Boolean)),
@@ -783,13 +818,23 @@ class CopilotClient {
783
818
  streaming: config.streaming,
784
819
  includeSubAgentStreamingEvents: config.includeSubAgentStreamingEvents ?? true,
785
820
  mcpServers: toWireMcpServers(config.mcpServers),
821
+ mcpOAuthTokenStorage: config.mcpOAuthTokenStorage,
786
822
  envValueMode: "direct",
787
823
  customAgents: toWireCustomAgents(config.customAgents),
788
824
  defaultAgent: config.defaultAgent,
789
825
  agent: config.agent,
790
- configDir: config.configDir,
826
+ configDir: config.configDirectory,
791
827
  enableConfigDiscovery: config.enableConfigDiscovery,
828
+ skipEmbeddingRetrieval: config.skipEmbeddingRetrieval,
829
+ embeddingCacheStorage: config.embeddingCacheStorage,
830
+ organizationCustomInstructions: config.organizationCustomInstructions,
831
+ enableOnDemandInstructionDiscovery: config.enableOnDemandInstructionDiscovery,
832
+ enableFileHooks: config.enableFileHooks,
833
+ enableHostGitOperations: config.enableHostGitOperations,
834
+ enableSessionStore: config.enableSessionStore,
835
+ enableSkills: config.enableSkills,
792
836
  skillDirectories: config.skillDirectories,
837
+ pluginDirectories: config.pluginDirectories,
793
838
  instructionDirectories: config.instructionDirectories,
794
839
  disabledSkills: config.disabledSkills,
795
840
  infiniteSessions: config.infiniteSessions,
@@ -797,12 +842,30 @@ class CopilotClient {
797
842
  remoteSession: config.remoteSession,
798
843
  cloud: config.cloud
799
844
  });
800
- const { workspacePath, capabilities } = response;
845
+ const {
846
+ sessionId: returnedSessionId,
847
+ workspacePath,
848
+ capabilities
849
+ } = response;
850
+ if (!returnedSessionId) {
851
+ throw new Error("session.create response did not include a sessionId");
852
+ }
853
+ if (localSessionId !== void 0 && localSessionId !== returnedSessionId) {
854
+ throw new Error(
855
+ `session.create returned sessionId ${returnedSessionId} but the caller requested ${localSessionId}`
856
+ );
857
+ }
858
+ if (session === void 0) {
859
+ session = initializeSession(returnedSessionId);
860
+ registeredId = returnedSessionId;
861
+ }
801
862
  session["_workspacePath"] = workspacePath;
802
863
  session.setCapabilities(capabilities);
803
864
  await this.updateSessionOptionsForMode(session, config);
804
865
  } catch (e) {
805
- this.sessions.delete(sessionId);
866
+ if (registeredId !== void 0) {
867
+ this.sessions.delete(registeredId);
868
+ }
806
869
  throw e;
807
870
  }
808
871
  return session;
@@ -881,6 +944,8 @@ class CopilotClient {
881
944
  clientName: config.clientName,
882
945
  model: config.model,
883
946
  reasoningEffort: config.reasoningEffort,
947
+ reasoningSummary: config.reasoningSummary,
948
+ contextTier: config.contextTier,
884
949
  systemMessage: wireSystemMessage,
885
950
  availableTools: toolFilterOptions.availableTools,
886
951
  excludedTools: toolFilterOptions.excludedTools,
@@ -896,6 +961,7 @@ class CopilotClient {
896
961
  canvases: config.canvases?.map((canvas) => canvas.declaration),
897
962
  requestCanvasRenderer: config.requestCanvasRenderer,
898
963
  requestExtensions: config.requestExtensions,
964
+ extensionSdkPath: config.extensionSdkPath,
899
965
  extensionInfo: config.extensionInfo,
900
966
  commands: config.commands?.map((cmd) => ({
901
967
  name: cmd.name,
@@ -903,27 +969,39 @@ class CopilotClient {
903
969
  })),
904
970
  provider: config.provider,
905
971
  modelCapabilities: config.modelCapabilities,
972
+ largeOutput: toWireLargeOutput(config.largeOutput),
906
973
  requestPermission: config.onPermissionRequest !== import_types.defaultJoinSessionPermissionHandler,
907
974
  requestUserInput: !!config.onUserInputRequest,
908
975
  requestElicitation: !!config.onElicitationRequest,
976
+ ...config.enableMcpApps ? { requestMcpApps: true } : {},
909
977
  requestExitPlanMode: !!config.onExitPlanModeRequest,
910
978
  requestAutoModeSwitch: !!config.onAutoModeSwitchRequest,
911
979
  hooks: !!(config.hooks && Object.values(config.hooks).some(Boolean)),
912
980
  workingDirectory: config.workingDirectory,
913
- configDir: config.configDir,
981
+ configDir: config.configDirectory,
914
982
  enableConfigDiscovery: config.enableConfigDiscovery,
983
+ skipEmbeddingRetrieval: config.skipEmbeddingRetrieval,
984
+ embeddingCacheStorage: config.embeddingCacheStorage,
985
+ organizationCustomInstructions: config.organizationCustomInstructions,
986
+ enableOnDemandInstructionDiscovery: config.enableOnDemandInstructionDiscovery,
987
+ enableFileHooks: config.enableFileHooks,
988
+ enableHostGitOperations: config.enableHostGitOperations,
989
+ enableSessionStore: config.enableSessionStore,
990
+ enableSkills: config.enableSkills,
915
991
  streaming: config.streaming,
916
992
  includeSubAgentStreamingEvents: config.includeSubAgentStreamingEvents ?? true,
917
993
  mcpServers: toWireMcpServers(config.mcpServers),
994
+ mcpOAuthTokenStorage: config.mcpOAuthTokenStorage,
918
995
  envValueMode: "direct",
919
996
  customAgents: toWireCustomAgents(config.customAgents),
920
997
  defaultAgent: config.defaultAgent,
921
998
  agent: config.agent,
922
999
  skillDirectories: config.skillDirectories,
1000
+ pluginDirectories: config.pluginDirectories,
923
1001
  instructionDirectories: config.instructionDirectories,
924
1002
  disabledSkills: config.disabledSkills,
925
1003
  infiniteSessions: config.infiniteSessions,
926
- suppressResumeEvent: config.suppressResumeEvent,
1004
+ disableResume: config.suppressResumeEvent,
927
1005
  continuePendingWork: config.continuePendingWork,
928
1006
  gitHubToken: config.gitHubToken,
929
1007
  remoteSession: config.remoteSession,
@@ -35,8 +35,10 @@ async function joinSession(config = {}) {
35
35
  );
36
36
  }
37
37
  const client = new import_client.CopilotClient({ _internalConnection: { kind: "parent-process" } });
38
+ const { extensionSdkPath: _stripped, ...rest } = config;
39
+ void _stripped;
38
40
  return client.resumeSession(sessionId, {
39
- ...config,
41
+ ...rest,
40
42
  onPermissionRequest: config.onPermissionRequest ?? import_types.defaultJoinSessionPermissionHandler,
41
43
  suppressResumeEvent: config.suppressResumeEvent ?? true
42
44
  });