@github/copilot-sdk 1.0.13-preview.4 → 1.0.13-preview.6

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
@@ -8,6 +8,20 @@ To use the SDK, you'll need:
8
8
 
9
9
  - Node.js ^20.19.0 or >=22.12.0
10
10
 
11
+ The SDK uses an optional `@github/copilot-sdk-<platform>` package containing the
12
+ Copilot CLI runtime for the host platform. These packages are built from
13
+ verified `github/copilot-cli` release assets when the SDK is published, so
14
+ starting the SDK performs no runtime download. Set `COPILOT_CLI_PATH` to use an
15
+ existing installation instead.
16
+
17
+ The checked-in release pin is `copilotCliVersion` in `package.json`. Run
18
+ `npm run set:cli-version -- <version>` to update it and regenerate the compiled
19
+ metadata in `src/cliVersion.ts`. Packaging verifies release assets against the
20
+ release's `SHA256SUMS.txt`.
21
+
22
+ `npm run pack:release` builds the main package and all platform packages. Set
23
+ `COPILOT_CLI_DOWNLOAD_BASE_URL` to use a release mirror while packaging.
24
+
11
25
  ## Installation
12
26
 
13
27
  ```bash
@@ -22,6 +36,7 @@ Try the interactive chat sample (from the repo root):
22
36
  cd nodejs
23
37
  npm ci
24
38
  npm run build
39
+ export COPILOT_CLI_PATH="$(npm run --silent prepare:runtime -- --print-path)"
25
40
  cd samples
26
41
  npm install
27
42
  npm start
@@ -132,6 +147,7 @@ Create a new conversation session.
132
147
 
133
148
  - `sessionId?: string` - Custom session ID.
134
149
  - `model?: string` - Model to use ("gpt-5", "claude-sonnet-4.5", etc.). **Required when using custom provider.**
150
+ - `capi?: CapiSessionOptions` - Copilot API options. With `model: "auto"`, set `autoTier` to `"efficiency"`, `"balance"`, or `"intelligence"` to choose a routing preference. Requires a runtime with Auto tier support and V2 Auto routing. Omission preserves default behavior. See [Auto tier persistence](../docs/features/session-persistence.md#auto-tier-persistence) for resume semantics.
135
151
  - `reasoningEffort?: "low" | "medium" | "high" | "xhigh" | "max"` - Reasoning effort level for models that support it. Use `listModels()` to check which models support this option.
136
152
  - `tools?: Tool[]` - Custom tools exposed to the CLI. Tools without `handler` are declaration-only and must be resolved via pending tool-call RPCs.
137
153
  - `systemMessage?: SystemMessageConfig` - System message customization (see below)
@@ -935,15 +951,15 @@ const session = await client.createSession({
935
951
 
936
952
  The handler must return one of the `PermissionDecision` shapes (or `{ kind: "no-result" }`). Approval scopes are present-tense — they describe the decision to apply, not the outcome reported back on session events:
937
953
 
938
- | Kind | Meaning | Extra fields |
939
- | ------------------------ | -------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
940
- | `"approve-once"` | Allow this single request | — |
941
- | `"approve-for-session"` | Allow this request and remember the approval for the rest of the session | `approval?` (rule to remember), `domain?` (for URL approvals) |
942
- | `"approve-for-location"` | Allow this request and persist the approval for this project location (git root or cwd) | `approval` (rule to persist), `locationKey` (location to persist under) |
943
- | `"approve-permanently"` | Allow this request and persist the approval across sessions (currently used for URL domains) | `domain` (URL domain to approve) |
944
- | `"reject"` | Deny the request | `feedback?` (optional string surfaced to the agent) |
945
- | `"user-not-available"` | Deny the request because no user is available to confirm it | — |
946
- | `"no-result"` | Suppress this SDK client's response so another connected client can answer the pending request | — |
954
+ | Kind | Meaning | Extra fields |
955
+ | ------------------------ | ---------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
956
+ | `"approve-once"` | Allow this single request | — |
957
+ | `"approve-for-session"` | Allow this request and remember the approval for the rest of the session | `approval?` (rule to remember), `domain?` (for URL approvals) |
958
+ | `"approve-for-location"` | Allow this request and persist the approval for this project location (git root or cwd) | `approval` (rule to persist), `locationKey` (location to persist under) |
959
+ | `"approve-permanently"` | Allow this request and persist the approval across sessions (currently used for URL domains) | `domain` (URL domain to approve) |
960
+ | `"reject"` | Deny the request | `feedback?` (optional string surfaced to the agent) |
961
+ | `"user-not-available"` | Deny the request because no user is available to confirm it | — |
962
+ | `"no-result"` | Suppress this SDK client's response so another connected client can answer the pending request | — |
947
963
 
948
964
  ### Resuming Sessions
949
965
 
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var cliVersion_exports = {};
20
+ __export(cliVersion_exports, {
21
+ COPILOT_CLI_USE_NPM_PACKAGE: () => COPILOT_CLI_USE_NPM_PACKAGE,
22
+ COPILOT_CLI_VERSION: () => COPILOT_CLI_VERSION
23
+ });
24
+ module.exports = __toCommonJS(cliVersion_exports);
25
+ const COPILOT_CLI_VERSION = "1.0.83-3";
26
+ const COPILOT_CLI_USE_NPM_PACKAGE = false;
27
+ // Annotate the CommonJS export names for ESM import in node:
28
+ 0 && (module.exports = {
29
+ COPILOT_CLI_USE_NPM_PACKAGE,
30
+ COPILOT_CLI_VERSION
31
+ });
@@ -34,21 +34,19 @@ module.exports = __toCommonJS(client_exports);
34
34
  var import_node_child_process = require("node:child_process");
35
35
  var import_node_crypto = require("node:crypto");
36
36
  var import_node_fs = require("node:fs");
37
- var import_node_module = require("node:module");
38
37
  var import_node_net = require("node:net");
39
38
  var import_node_path = require("node:path");
40
- var import_node_url = require("node:url");
41
39
  var import_node = require("vscode-jsonrpc/node.js");
42
40
  var import_rpc = require("./generated/rpc.js");
43
41
  var import_sdkProtocolVersion = require("./sdkProtocolVersion.js");
44
42
  var import_session = require("./session.js");
45
43
  var import_runtimeArtifacts = require("./runtimeArtifacts.js");
44
+ var import_cliVersion = require("./cliVersion.js");
46
45
  var import_sessionFsProvider = require("./sessionFsProvider.js");
47
46
  var import_copilotRequestHandler = require("./copilotRequestHandler.js");
48
47
  var import_telemetry = require("./telemetry.js");
49
48
  var import_toolSet = require("./toolSet.js");
50
49
  var import_types = require("./types.js");
51
- const import_meta = {};
52
50
  const MIN_PROTOCOL_VERSION = 3;
53
51
  const RUNTIME_SHUTDOWN_TIMEOUT_MS = 1e4;
54
52
  function isZodSchema(value) {
@@ -151,6 +149,15 @@ function toWireCustomAgents(agents) {
151
149
  return { ...rest, mcpServers: toWireMcpServers(mcpServers) };
152
150
  });
153
151
  }
152
+ function clientInfoToWire(info) {
153
+ if (info == null) return void 0;
154
+ const wire = {};
155
+ if (info.applicationName) wire.editorName = info.applicationName;
156
+ if (info.applicationVersion) wire.editorVersion = info.applicationVersion;
157
+ if (info.integrationName) wire.extensionName = info.integrationName;
158
+ if (info.integrationVersion) wire.extensionVersion = info.integrationVersion;
159
+ return Object.keys(wire).length > 0 ? wire : void 0;
160
+ }
154
161
  function toWireLargeOutput(config) {
155
162
  if (!config) return void 0;
156
163
  const { outputDirectory, ...rest } = config;
@@ -208,53 +215,8 @@ function getNodeExecPath() {
208
215
  }
209
216
  return process.execPath;
210
217
  }
211
- function getCliPlatformPackageNames() {
212
- const arch = process.arch;
213
- const variants = process.platform === "linux" ? ["linux", "linuxmusl"] : [process.platform];
214
- return variants.map((variant) => `@github/copilot-${variant}-${arch}`);
215
- }
216
- function getBundledCliPackage() {
217
- const packageNames = getCliPlatformPackageNames();
218
- if (typeof import_meta.resolve === "function") {
219
- for (const packageName of packageNames) {
220
- try {
221
- const packageEntryUrl = import_meta.resolve(packageName);
222
- const packageEntryPath = (0, import_node_url.fileURLToPath)(packageEntryUrl);
223
- return {
224
- root: (0, import_node_path.dirname)(packageEntryPath),
225
- platform: packageName.slice("@github/copilot-".length)
226
- };
227
- } catch {
228
- }
229
- }
230
- throw new Error(
231
- `Could not resolve a @github/copilot platform package (tried ${packageNames.join(", ")}). Ensure @github/copilot is installed, or pass cliPath/cliUrl to CopilotClient.`
232
- );
233
- }
234
- const req = (0, import_node_module.createRequire)(__filename);
235
- const searchPaths = req.resolve.paths("@github/copilot") ?? [];
236
- for (const base of searchPaths) {
237
- for (const packageName of packageNames) {
238
- const root = (0, import_node_path.join)(base, ...packageName.split("/"));
239
- const candidate = (0, import_node_path.join)(root, "index.js");
240
- if ((0, import_node_fs.existsSync)(candidate)) {
241
- return {
242
- root,
243
- platform: packageName.slice("@github/copilot-".length)
244
- };
245
- }
246
- }
247
- }
248
- throw new Error(
249
- `Could not find a @github/copilot platform package (tried ${packageNames.join(", ")}). Searched ${searchPaths.length} paths. Ensure @github/copilot is installed, or pass cliPath/cliUrl to CopilotClient.`
250
- );
251
- }
252
218
  function getBundledRuntimePath() {
253
- const bundled = getBundledCliPackage();
254
- return (0, import_runtimeArtifacts.materializeRuntimeBundle)({
255
- packageRoot: bundled.root,
256
- platform: bundled.platform
257
- });
219
+ return (0, import_runtimeArtifacts.ensureRuntimeBundle)(import_cliVersion.COPILOT_CLI_VERSION);
258
220
  }
259
221
  class TeardownResilientStreamMessageWriter extends import_node.StreamMessageWriter {
260
222
  suppressWriteErrors = false;
@@ -473,8 +435,6 @@ class CopilotClient {
473
435
  const explicitCliPath = conn.path ?? effectiveEnv.COPILOT_CLI_PATH;
474
436
  if (explicitCliPath) {
475
437
  this.resolvedCliPath = explicitCliPath;
476
- } else {
477
- this.resolvedCliPath = getBundledRuntimePath();
478
438
  }
479
439
  }
480
440
  const connArgs = conn.kind === "stdio" || conn.kind === "tcp" ? conn.args ?? [] : [];
@@ -489,7 +449,8 @@ class CopilotClient {
489
449
  baseDirectory: options.baseDirectory,
490
450
  sessionIdleTimeoutSeconds: options.sessionIdleTimeoutSeconds ?? 0,
491
451
  enableRemoteSessions: options.enableRemoteSessions ?? false,
492
- mode: options.mode ?? "copilot-cli"
452
+ mode: options.mode ?? "copilot-cli",
453
+ clientInfo: options.clientInfo
493
454
  };
494
455
  if (this.options.mode === "empty") {
495
456
  const hasPersistence = this.options.baseDirectory !== void 0 || this.sessionFsConfig !== null || // External runtimes manage their own persistence layer; the SDK
@@ -505,17 +466,29 @@ class CopilotClient {
505
466
  connectionExtraArgs = [];
506
467
  /**
507
468
  * Parse CLI URL into host and port
508
- * Supports formats: "host:port", "http://host:port", "https://host:port", or just "port"
469
+ * Supports formats: "host:port", "[ipv6]:port", "http://host:port", "https://host:port", or just "port"
509
470
  */
510
471
  parseCliUrl(url) {
511
- let cleanUrl = url.replace(/^https?:\/\//, "");
472
+ const cleanUrl = url.replace(/^https?:\/\//, "");
512
473
  if (/^\d+$/.test(cleanUrl)) {
513
474
  return { host: "localhost", port: parseInt(cleanUrl, 10) };
514
475
  }
476
+ const ipv6Match = cleanUrl.match(/^\[([^\]]+)\]:(\d+)$/);
477
+ if (ipv6Match) {
478
+ const host2 = ipv6Match[1];
479
+ if (!(0, import_node_net.isIPv6)(host2)) {
480
+ throw new Error(`Invalid cliUrl format: ${url}`);
481
+ }
482
+ const port2 = parseInt(ipv6Match[2], 10);
483
+ if (isNaN(port2) || port2 <= 0 || port2 > 65535) {
484
+ throw new Error(`Invalid port in cliUrl: ${url}`);
485
+ }
486
+ return { host: host2, port: port2 };
487
+ }
515
488
  const parts = cleanUrl.split(":");
516
489
  if (parts.length !== 2) {
517
490
  throw new Error(
518
- `Invalid cliUrl format: ${url}. Expected "host:port", "http://host:port", or "port"`
491
+ `Invalid cliUrl format: ${url}. Expected "host:port", "[ipv6]:port", "http://host:port", or "port"`
519
492
  );
520
493
  }
521
494
  const host = parts[0] || "localhost";
@@ -1274,6 +1247,7 @@ class CopilotClient {
1274
1247
  gitHubTokenProviderRegistrationId,
1275
1248
  remoteSession: config.remoteSession,
1276
1249
  cloud: config.cloud,
1250
+ featureFlags: config.featureFlags,
1277
1251
  expAssignments: config.expAssignments,
1278
1252
  enableManagedSettings: config.enableManagedSettings,
1279
1253
  managedSettings: config.managedSettings
@@ -1509,6 +1483,7 @@ class CopilotClient {
1509
1483
  gitHubTokenProviderRegistrationId,
1510
1484
  remoteSession: config.remoteSession,
1511
1485
  openCanvases: config.openCanvases,
1486
+ featureFlags: config.featureFlags,
1512
1487
  expAssignments: config.expAssignments,
1513
1488
  enableManagedSettings: config.enableManagedSettings,
1514
1489
  managedSettings: config.managedSettings,
@@ -1657,6 +1632,10 @@ class CopilotClient {
1657
1632
  if (this.onGitHubTelemetry != null) {
1658
1633
  connectParams.enableGitHubTelemetryForwarding = true;
1659
1634
  }
1635
+ const clientInfo = clientInfoToWire(this.options.clientInfo);
1636
+ if (clientInfo != null) {
1637
+ connectParams.clientInfo = clientInfo;
1638
+ }
1660
1639
  const result = await raceAgainstExit(this.internalRpc.connect(connectParams));
1661
1640
  serverVersion = result.protocolVersion;
1662
1641
  } catch (err) {
@@ -1917,6 +1896,7 @@ class CopilotClient {
1917
1896
  * Start the CLI server process
1918
1897
  */
1919
1898
  async startCLIServer() {
1899
+ this.resolvedCliPath ??= await getBundledRuntimePath();
1920
1900
  return new Promise((resolve2, reject) => {
1921
1901
  this.stderrBuffer = "";
1922
1902
  const args = [...this.connectionExtraArgs, "--headless", "--no-auto-update"];
@@ -1954,7 +1934,7 @@ class CopilotClient {
1954
1934
  }
1955
1935
  if (!(0, import_node_fs.existsSync)(this.resolvedCliPath)) {
1956
1936
  throw new Error(
1957
- `Copilot CLI not found at ${this.resolvedCliPath}. Ensure @github/copilot is installed.`
1937
+ `Copilot CLI not found at ${this.resolvedCliPath}. Set COPILOT_CLI_PATH to use a custom installation.`
1958
1938
  );
1959
1939
  }
1960
1940
  const stdioConfig = this.connectionConfig.kind === "stdio" ? ["pipe", "pipe", "pipe"] : ["ignore", "pipe", "pipe"];
@@ -2081,12 +2061,19 @@ stderr: ${stderrOutput}`
2081
2061
  /** Starts the in-process FFI runtime with SDK-managed typed options. */
2082
2062
  async startInProcessFfi() {
2083
2063
  const explicitEntrypoint = this.resolvedEnv.COPILOT_CLI_PATH;
2084
- const runtimeLibrary = explicitEntrypoint ? (0, import_node_path.join)(
2085
- (0, import_node_path.dirname)((0, import_node_path.resolve)(explicitEntrypoint)),
2086
- "prebuilds",
2087
- CopilotClient.getNapiPrebuildsFolder(explicitEntrypoint),
2088
- "runtime.node"
2089
- ) : (0, import_node_path.join)((0, import_node_path.dirname)(getBundledRuntimePath()), "runtime.node");
2064
+ let runtimeLibrary;
2065
+ if (explicitEntrypoint) {
2066
+ const entrypointDirectory = (0, import_node_path.dirname)((0, import_node_path.resolve)(explicitEntrypoint));
2067
+ const adjacentRuntime = (0, import_node_path.join)(entrypointDirectory, "runtime.node");
2068
+ runtimeLibrary = (0, import_node_fs.existsSync)(adjacentRuntime) ? adjacentRuntime : (0, import_node_path.join)(
2069
+ entrypointDirectory,
2070
+ "prebuilds",
2071
+ CopilotClient.getNapiPrebuildsFolder(explicitEntrypoint),
2072
+ "runtime.node"
2073
+ );
2074
+ } else {
2075
+ runtimeLibrary = (0, import_node_path.join)((0, import_node_path.dirname)(await getBundledRuntimePath()), "runtime.node");
2076
+ }
2090
2077
  const { FfiRuntimeHost } = await import("./ffiRuntimeHost.js");
2091
2078
  const environment = {};
2092
2079
  if (this.options.gitHubToken) {
@@ -39,6 +39,17 @@ function createServerRpc(connection) {
39
39
  */
40
40
  ping: async (params) => connection.sendRequest("ping", params),
41
41
  /** @experimental */
42
+ hooks: {
43
+ /**
44
+ * Discovers hook actions enabled under server-side discovery settings from user, repository, plugin, and managed-policy sources.
45
+ *
46
+ * @param params Optional project paths and host-exclusion behavior for server-scoped hook discovery.
47
+ *
48
+ * @returns Server-discovered hook actions and partial-load diagnostics from user, repository, plugin, and managed-policy sources. Concrete sessions may include additional session-specific hook sources.
49
+ */
50
+ discover: async (params) => connection.sendRequest("hooks.discover", params)
51
+ },
52
+ /** @experimental */
42
53
  models: {
43
54
  /**
44
55
  * Lists Copilot models available to the authenticated user.
@@ -506,6 +517,14 @@ function createServerRpc(connection) {
506
517
  * @returns Sessions matching the filter, ordered most-recently-modified first.
507
518
  */
508
519
  list: async (params) => connection.sendRequest("sessions.list", params),
520
+ /**
521
+ * Reads a page of durable events directly from a local session's persisted journal without creating, resuming, or activating the session. The initial backward read uses a bounded tail scan for fast first paint; cursor continuations preserve the session event-log paging semantics. Persisted events may omit payloads that are reconstructed only for an active session.
522
+ *
523
+ * @param params Pagination options for reading an inactive or active local session's persisted event journal.
524
+ *
525
+ * @returns Batch of session events returned by a read, with cursor and continuation metadata.
526
+ */
527
+ readPersistedEvents: async (params) => connection.sendRequest("sessions.readPersistedEvents", params),
509
528
  /**
510
529
  * Finds the local session bound to a GitHub task ID, if any.
511
530
  *
@@ -18,32 +18,50 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var runtimeArtifacts_exports = {};
20
20
  __export(runtimeArtifacts_exports, {
21
+ RUNTIME_PLATFORMS: () => RUNTIME_PLATFORMS,
21
22
  defaultRuntimeCacheRoot: () => defaultRuntimeCacheRoot,
22
- materializeRuntimeBundle: () => materializeRuntimeBundle
23
+ ensureRuntimeBundle: () => ensureRuntimeBundle,
24
+ getRuntimePackageName: () => getRuntimePackageName,
25
+ getRuntimePlatform: () => getRuntimePlatform,
26
+ getRuntimeReleaseAssetName: () => getRuntimeReleaseAssetName,
27
+ materializeRuntimeBundle: () => materializeRuntimeBundle,
28
+ resolvePackageRoot: () => resolvePackageRoot,
29
+ validateFile: () => validateFile
23
30
  });
24
31
  module.exports = __toCommonJS(runtimeArtifacts_exports);
25
- var import_node_crypto = require("node:crypto");
26
32
  var import_node_fs = require("node:fs");
33
+ var import_node_crypto = require("node:crypto");
34
+ var import_node_module = require("node:module");
27
35
  var import_node_os = require("node:os");
28
36
  var import_node_path = require("node:path");
37
+ var import_cliVersion = require("./cliVersion.js");
38
+ const import_meta = {};
39
+ const require2 = (0, import_node_module.createRequire)(typeof __filename === "string" ? __filename : import_meta.url);
40
+ const RUNTIME_PLATFORMS = [
41
+ "darwin-arm64",
42
+ "darwin-x64",
43
+ "linux-arm64",
44
+ "linux-x64",
45
+ "linuxmusl-arm64",
46
+ "linuxmusl-x64",
47
+ "win32-arm64",
48
+ "win32-x64"
49
+ ];
29
50
  const EXCLUDED_TOP_LEVEL = /* @__PURE__ */ new Set([
30
51
  "app.js",
31
52
  "assets",
32
53
  "changelog.json",
33
54
  "copilot",
34
55
  "copilot.exe",
35
- "copilot-sdk",
36
56
  "foundry-local-sdk",
37
57
  "index.js",
38
58
  "LICENSE.md",
39
59
  "napi-oop-runtime",
40
60
  "npm-loader.js",
41
61
  "package.json",
42
- "preloads",
43
62
  "pvrecorder",
44
63
  "queries",
45
64
  "README.md",
46
- "sdk",
47
65
  "sea-loader.js",
48
66
  "webview"
49
67
  ]);
@@ -82,14 +100,12 @@ function collectRuntimeAssets(sources) {
82
100
  continue;
83
101
  }
84
102
  const parts = sourceRelative.split(import_node_path.sep);
85
- let relativePath = sourceRelative;
86
103
  if (parts[0] === "prebuilds") {
87
104
  if (parts[1] !== sources.platform || parts.length < 3) {
88
105
  continue;
89
106
  }
90
- relativePath = parts.slice(2).join(import_node_path.sep);
91
107
  }
92
- assets.push({ source, relativePath });
108
+ assets.push({ source, relativePath: sourceRelative });
93
109
  }
94
110
  };
95
111
  visit(sources.packageRoot);
@@ -117,15 +133,20 @@ function defaultRuntimeCacheRoot(platform = process.platform, home = (0, import_
117
133
  const cacheDirectory = platform === "win32" ? environment.LOCALAPPDATA ?? (0, import_node_path.join)(home, "AppData", "Local") : platform === "darwin" ? (0, import_node_path.join)(home, "Library", "Caches") : environment.XDG_CACHE_HOME ?? (0, import_node_path.join)(home, ".cache");
118
134
  return (0, import_node_path.join)(cacheDirectory, "github-copilot-sdk", "runtime");
119
135
  }
120
- function materializeRuntimeBundle(sources, cacheRoot = defaultRuntimeCacheRoot()) {
136
+ function materializeRuntimeBundle(sources, cacheRoot = defaultRuntimeCacheRoot(), cacheKey = `${sources.platform}-${sourceFingerprint(collectRuntimeAssets(sources))}`) {
121
137
  const assets = collectRuntimeAssets(sources);
122
- const wrapperName = process.platform === "win32" ? "copilot-runtime.exe" : "copilot-runtime";
123
- const sourceWrapper = assets.find((asset) => asset.relativePath === wrapperName)?.source;
124
- const sourceRuntimeNode = assets.find((asset) => asset.relativePath === "runtime.node")?.source;
138
+ const wrapperName = sources.platform.startsWith("win32") ? "copilot-runtime.exe" : "copilot-runtime";
139
+ const prebuildDir = (0, import_node_path.join)("prebuilds", sources.platform);
140
+ const wrapperRelative = (0, import_node_path.join)(prebuildDir, wrapperName);
141
+ const runtimeNodeRelative = (0, import_node_path.join)(prebuildDir, "runtime.node");
142
+ const sourceWrapper = assets.find((asset) => asset.relativePath === wrapperRelative)?.source;
143
+ const sourceRuntimeNode = assets.find(
144
+ (asset) => asset.relativePath === runtimeNodeRelative
145
+ )?.source;
125
146
  validateRuntimeBundle(sourceWrapper ?? "", sourceRuntimeNode ?? "");
126
- const installDir = (0, import_node_path.join)(cacheRoot, `${sources.platform}-${sourceFingerprint(assets)}`);
127
- const installedWrapper = (0, import_node_path.join)(installDir, wrapperName);
128
- const installedRuntimeNode = (0, import_node_path.join)(installDir, "runtime.node");
147
+ const installDir = (0, import_node_path.join)(cacheRoot, cacheKey);
148
+ const installedWrapper = (0, import_node_path.join)(installDir, wrapperRelative);
149
+ const installedRuntimeNode = (0, import_node_path.join)(installDir, runtimeNodeRelative);
129
150
  if ((0, import_node_fs.existsSync)(installDir)) {
130
151
  validateRuntimeBundle(installedWrapper, installedRuntimeNode);
131
152
  makeExecutable(installedWrapper);
@@ -139,7 +160,7 @@ function materializeRuntimeBundle(sources, cacheRoot = defaultRuntimeCacheRoot()
139
160
  (0, import_node_fs.mkdirSync)((0, import_node_path.dirname)(destination), { recursive: true });
140
161
  (0, import_node_fs.copyFileSync)(asset.source, destination);
141
162
  }
142
- const stagedWrapper = (0, import_node_path.join)(stagingDir, wrapperName);
163
+ const stagedWrapper = (0, import_node_path.join)(stagingDir, wrapperRelative);
143
164
  makeExecutable(stagedWrapper);
144
165
  (0, import_node_fs.renameSync)(stagingDir, installDir);
145
166
  } catch (error) {
@@ -152,8 +173,82 @@ function materializeRuntimeBundle(sources, cacheRoot = defaultRuntimeCacheRoot()
152
173
  }
153
174
  return installedWrapper;
154
175
  }
176
+ function isMusl() {
177
+ if (process.platform !== "linux") {
178
+ return false;
179
+ }
180
+ const report = process.report?.getReport();
181
+ return report?.header?.glibcVersionRuntime === void 0;
182
+ }
183
+ function getRuntimePlatform(platform = process.platform, arch = process.arch, musl = isMusl()) {
184
+ if (arch !== "x64" && arch !== "arm64") {
185
+ throw new Error(`Unsupported Copilot CLI architecture: ${arch}.`);
186
+ }
187
+ if (platform === "linux") {
188
+ return `${musl ? "linuxmusl" : "linux"}-${arch}`;
189
+ }
190
+ if (platform === "darwin" || platform === "win32") {
191
+ return `${platform}-${arch}`;
192
+ }
193
+ throw new Error(`Unsupported Copilot CLI platform: ${platform}-${arch}.`);
194
+ }
195
+ function getRuntimeReleaseAssetName(version, platform) {
196
+ return `github-copilot-${version}-${platform}.tgz`;
197
+ }
198
+ function getRuntimePackageName(platform) {
199
+ return `@github/copilot-sdk-${platform}`;
200
+ }
201
+ function resolvePackageRoot(packageName, searchPaths = require2.resolve.paths(packageName) ?? []) {
202
+ return searchPaths.map((base) => (0, import_node_path.join)(base, ...packageName.split("/"))).find((candidate) => (0, import_node_fs.existsSync)((0, import_node_path.join)(candidate, "package.json")));
203
+ }
204
+ async function ensureRuntimeBundle(version, options = {}) {
205
+ const platform = options.platform ?? getRuntimePlatform();
206
+ if (import_cliVersion.COPILOT_CLI_USE_NPM_PACKAGE) {
207
+ const packageName2 = `@github/copilot-${platform}`;
208
+ const packageRoot2 = resolvePackageRoot(packageName2, options.packageSearchPaths);
209
+ if (!packageRoot2) {
210
+ throw new Error(`Could not resolve ${packageName2} for Copilot CLI ${version}.`);
211
+ }
212
+ validateFile(
213
+ (0, import_node_path.join)(packageRoot2, "prebuilds", platform, "runtime.node"),
214
+ "Copilot runtime.node"
215
+ );
216
+ return materializeRuntimeBundle(
217
+ { packageRoot: packageRoot2, platform },
218
+ options.cacheRoot,
219
+ `${version}-${platform}`
220
+ );
221
+ }
222
+ const packageName = getRuntimePackageName(platform);
223
+ const packageRoot = resolvePackageRoot(packageName, options.packageSearchPaths);
224
+ if (!packageRoot) {
225
+ throw new Error(
226
+ `Could not resolve ${packageName}. Reinstall @github/copilot-sdk so its platform package is installed.`
227
+ );
228
+ }
229
+ const wrapperName = platform.startsWith("win32") ? "copilot-runtime.exe" : "copilot-runtime";
230
+ const prebuildDir = (0, import_node_path.join)(packageRoot, "prebuilds", platform);
231
+ const wrapper = (0, import_node_path.join)(prebuildDir, wrapperName);
232
+ try {
233
+ validateRuntimeBundle(wrapper, (0, import_node_path.join)(prebuildDir, "runtime.node"));
234
+ } catch (error) {
235
+ throw new Error(
236
+ `${packageName} is missing required Copilot CLI runtime files. Reinstall @github/copilot-sdk.`,
237
+ { cause: error }
238
+ );
239
+ }
240
+ makeExecutable(wrapper);
241
+ return wrapper;
242
+ }
155
243
  // Annotate the CommonJS export names for ESM import in node:
156
244
  0 && (module.exports = {
245
+ RUNTIME_PLATFORMS,
157
246
  defaultRuntimeCacheRoot,
158
- materializeRuntimeBundle
247
+ ensureRuntimeBundle,
248
+ getRuntimePackageName,
249
+ getRuntimePlatform,
250
+ getRuntimeReleaseAssetName,
251
+ materializeRuntimeBundle,
252
+ resolvePackageRoot,
253
+ validateFile
159
254
  });
@@ -0,0 +1,2 @@
1
+ export declare const COPILOT_CLI_VERSION = "1.0.83-3";
2
+ export declare const COPILOT_CLI_USE_NPM_PACKAGE = false;
@@ -0,0 +1,6 @@
1
+ const COPILOT_CLI_VERSION = "1.0.83-3";
2
+ const COPILOT_CLI_USE_NPM_PACKAGE = false;
3
+ export {
4
+ COPILOT_CLI_USE_NPM_PACKAGE,
5
+ COPILOT_CLI_VERSION
6
+ };
package/dist/client.d.ts CHANGED
@@ -92,7 +92,7 @@ export declare class CopilotClient {
92
92
  private connectionExtraArgs;
93
93
  /**
94
94
  * Parse CLI URL into host and port
95
- * Supports formats: "host:port", "http://host:port", "https://host:port", or just "port"
95
+ * Supports formats: "host:port", "[ipv6]:port", "http://host:port", "https://host:port", or just "port"
96
96
  */
97
97
  private parseCliUrl;
98
98
  private validateSessionFsConfig;