@github/copilot-sdk 1.0.29 → 1.0.30-preview.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/docs/examples.md CHANGED
@@ -25,7 +25,8 @@ const session = await joinSession({
25
25
  >
26
26
  > - Use `process.platform === "win32"` to detect Windows at runtime.
27
27
  > - Clipboard: `pbcopy` on macOS, `clip` on Windows.
28
- > - Use `exec()` instead of `execFile()` for `.cmd` scripts like `code`, `npx`, `npm` on Windows.
28
+ > - Never interpolate tool arguments into `exec()` or shell command strings. Use `execFile()` or `spawn()` with argument arrays.
29
+ > - On Windows, `.cmd` and `.bat` wrappers require a shell. Invoke the actual executable or use the library's Node.js API instead.
29
30
  > - PowerShell stderr redirection uses `*>&1` instead of `2>&1`.
30
31
 
31
32
  ---
@@ -257,16 +258,41 @@ hooks: {
257
258
 
258
259
  Use `onPostToolUse` to run side effects after a tool completes.
259
260
 
261
+ On macOS and Linux, install the `code` command in your `PATH`. On Windows,
262
+ set `VSCODE_EXECUTABLE` to the absolute path of your installed `Code.exe`
263
+ (for example, `C:\Users\you\AppData\Local\Programs\Microsoft VS Code\Code.exe`),
264
+ not the `code.cmd` wrapper. This is trusted extension configuration, not a
265
+ tool argument.
266
+
260
267
  ```js
261
- import { exec } from "node:child_process";
268
+ import { spawn } from "node:child_process";
269
+ import { isAbsolute, resolve } from "node:path";
270
+
271
+ const isWindows = process.platform === "win32";
272
+ const vscodeExecutable = isWindows ? process.env.VSCODE_EXECUTABLE : "code";
273
+ if (!vscodeExecutable || (isWindows && !isAbsolute(vscodeExecutable))) {
274
+ throw new Error("Set VSCODE_EXECUTABLE to the absolute path of Code.exe.");
275
+ }
276
+ const editorEnv = { ...process.env };
277
+ // The native editor must open the file, not run it as a Node.js script.
278
+ delete editorEnv.ELECTRON_RUN_AS_NODE;
262
279
 
263
280
  hooks: {
264
281
  onPostToolUse: async (input) => {
265
282
  if (input.toolName === "create" || input.toolName === "edit") {
266
283
  const filePath = input.toolArgs?.path;
267
- if (filePath) {
268
- // Open the file in VS Code
269
- exec(`code "${filePath}"`, () => {});
284
+ if (typeof filePath === "string" && filePath) {
285
+ try {
286
+ const child = spawn(vscodeExecutable, [resolve(filePath)], {
287
+ detached: true,
288
+ stdio: "ignore",
289
+ env: editorEnv,
290
+ });
291
+ child.on("error", (err) => console.error("Could not open file in VS Code:", err.message));
292
+ child.unref();
293
+ } catch (err) {
294
+ console.error("Could not open file in VS Code:", err.message);
295
+ }
270
296
  }
271
297
  }
272
298
  },
@@ -295,20 +321,34 @@ hooks: {
295
321
 
296
322
  ### Running a linter after every file edit
297
323
 
324
+ Install ESLint in the session's working directory (`npm install --save-dev eslint`)
325
+ and configure it for TypeScript. Only run this hook in workspaces whose ESLint
326
+ configuration and plugins you trust. Use its Node.js API rather than `npx`:
327
+ an extension's `process.execPath` can be the Copilot single-executable binary,
328
+ not a general-purpose Node.js interpreter.
329
+
298
330
  ```js
299
- import { exec } from "node:child_process";
331
+ import { createRequire } from "node:module";
332
+ import { resolve } from "node:path";
333
+ import { pathToFileURL } from "node:url";
334
+
335
+ const require = createRequire(import.meta.url);
300
336
 
301
337
  hooks: {
302
338
  onPostToolUse: async (input) => {
303
339
  if (input.toolName === "edit") {
304
340
  const filePath = input.toolArgs?.path;
305
- if (filePath?.endsWith(".ts")) {
306
- const result = await new Promise((resolve) => {
307
- exec(`npx eslint "${filePath}"`, (err, stdout) => {
308
- resolve(err ? stdout : "No lint errors.");
309
- });
310
- });
311
- return { additionalContext: `Lint result: ${result}` };
341
+ if (typeof filePath === "string" && filePath.endsWith(".ts")) {
342
+ try {
343
+ const eslintModule = require.resolve("eslint", { paths: [process.cwd()] });
344
+ const { ESLint } = await import(pathToFileURL(eslintModule).href);
345
+ const eslint = new ESLint({ cwd: process.cwd(), globInputPaths: false });
346
+ const results = await eslint.lintFiles([resolve(filePath)]);
347
+ const formatter = await eslint.loadFormatter("stylish");
348
+ return { additionalContext: `Lint result: ${formatter.format(results) || "No lint errors."}` };
349
+ } catch (err) {
350
+ return { additionalContext: `Lint failed: ${err.message}` };
351
+ }
312
352
  }
313
353
  }
314
354
  },
@@ -603,11 +643,22 @@ const session = await joinSession({
603
643
 
604
644
  An extension that combines tools, hooks, and events.
605
645
 
646
+ Use the same VS Code setup as in
647
+ [Reacting when the agent creates or edits a file](#reacting-when-the-agent-creates-or-edits-a-file).
648
+
606
649
  ```js
607
- import { execFile, exec } from "node:child_process";
650
+ import { execFile, spawn } from "node:child_process";
651
+ import { isAbsolute, resolve } from "node:path";
608
652
  import { joinSession } from "@github/copilot-sdk/extension";
609
653
 
610
654
  const isWindows = process.platform === "win32";
655
+ const vscodeExecutable = isWindows ? process.env.VSCODE_EXECUTABLE : "code";
656
+ if (!vscodeExecutable || (isWindows && !isAbsolute(vscodeExecutable))) {
657
+ throw new Error("Set VSCODE_EXECUTABLE to the absolute path of Code.exe.");
658
+ }
659
+ const editorEnv = { ...process.env };
660
+ // The native editor must open the file, not run it as a Node.js script.
661
+ delete editorEnv.ELECTRON_RUN_AS_NODE;
611
662
  let copyNextResponse = false;
612
663
 
613
664
  function copyToClipboard(text) {
@@ -617,8 +668,17 @@ function copyToClipboard(text) {
617
668
  }
618
669
 
619
670
  function openInEditor(filePath) {
620
- if (isWindows) exec(`code "${filePath}"`, () => {});
621
- else execFile("code", [filePath], () => {});
671
+ try {
672
+ const child = spawn(vscodeExecutable, [resolve(filePath)], {
673
+ detached: true,
674
+ stdio: "ignore",
675
+ env: editorEnv,
676
+ });
677
+ child.on("error", (err) => console.error("Could not open file in VS Code:", err.message));
678
+ child.unref();
679
+ } catch (err) {
680
+ console.error("Could not open file in VS Code:", err.message);
681
+ }
622
682
  }
623
683
 
624
684
  const session = await joinSession({
@@ -645,7 +705,7 @@ const session = await joinSession({
645
705
  onPostToolUse: async (input) => {
646
706
  if (input.toolName === "create" || input.toolName === "edit") {
647
707
  const filePath = input.toolArgs?.path;
648
- if (filePath) openInEditor(filePath);
708
+ if (typeof filePath === "string" && filePath) openInEditor(filePath);
649
709
  }
650
710
  },
651
711
  },
package/package.json CHANGED
@@ -5,8 +5,8 @@
5
5
  "url": "https://github.com/github/copilot-agent-runtime.git",
6
6
  "directory": "src/sdk/nodejs"
7
7
  },
8
- "version": "1.0.29",
9
- "copilotCliVersion": "1.0.107",
8
+ "version": "1.0.30-preview.1",
9
+ "copilotCliVersion": "1.0.108-1",
10
10
  "description": "TypeScript SDK for programmatic control of GitHub Copilot CLI via JSON-RPC",
11
11
  "main": "./dist/cjs/index.js",
12
12
  "types": "./dist/index.d.ts",
@@ -52,6 +52,7 @@
52
52
  "lint:fix": "eslint --fix \"src/**/*.ts\" \"test/**/*.ts\"",
53
53
  "typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
54
54
  "generate": "cd ../scripts/codegen && npm run generate",
55
+ "generate:java-compat-fixtures": "tsx test/generate-java-compat-fixtures.ts",
55
56
  "set:cli-version": "node scripts/set-cli-version.js",
56
57
  "update:protocol-version": "tsx scripts/update-protocol-version.ts",
57
58
  "vendor:tools": "tsx scripts/vendor-build-tools.ts",
@@ -103,7 +104,7 @@
103
104
  "overrides": {
104
105
  "file-entry-cache": "$file-entry-cache",
105
106
  "glob": "$glob",
106
- "minimatch": "^11.0.4",
107
+ "minimatch": "11.0.2",
107
108
  "prettier": "$prettier",
108
109
  "vite": "$vite"
109
110
  },
@@ -117,18 +118,18 @@
117
118
  "README.md"
118
119
  ],
119
120
  "copilotRuntime": {
120
- "sourceSha": "2bfb456b9e0878c4cb3dd05cb9877ac9c97cbd68",
121
- "version": "1.0.107",
121
+ "sourceSha": "b4db2d4d6e538963777bfe225a166511699de1e7",
122
+ "version": "1.0.108-1",
122
123
  "visibility": "public"
123
124
  },
124
125
  "optionalDependencies": {
125
- "@github/copilot-sdk-darwin-arm64": "1.0.29",
126
- "@github/copilot-sdk-darwin-x64": "1.0.29",
127
- "@github/copilot-sdk-linux-arm64": "1.0.29",
128
- "@github/copilot-sdk-linux-x64": "1.0.29",
129
- "@github/copilot-sdk-linuxmusl-arm64": "1.0.29",
130
- "@github/copilot-sdk-linuxmusl-x64": "1.0.29",
131
- "@github/copilot-sdk-win32-arm64": "1.0.29",
132
- "@github/copilot-sdk-win32-x64": "1.0.29"
126
+ "@github/copilot-sdk-darwin-arm64": "1.0.30-preview.1",
127
+ "@github/copilot-sdk-darwin-x64": "1.0.30-preview.1",
128
+ "@github/copilot-sdk-linux-arm64": "1.0.30-preview.1",
129
+ "@github/copilot-sdk-linux-x64": "1.0.30-preview.1",
130
+ "@github/copilot-sdk-linuxmusl-arm64": "1.0.30-preview.1",
131
+ "@github/copilot-sdk-linuxmusl-x64": "1.0.30-preview.1",
132
+ "@github/copilot-sdk-win32-arm64": "1.0.30-preview.1",
133
+ "@github/copilot-sdk-win32-x64": "1.0.30-preview.1"
133
134
  }
134
135
  }