diff --git a/README.md b/README.md index 644152040..838847820 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Quick steps: 1. **(Optional) Install the Copilot CLI** For Node.js, Python, and .NET SDKs, the Copilot CLI is bundled automatically and no separate installation is required. -For the Go SDK, install the CLI manually or ensure `copilot` is available in your PATH. +For the Go SDK, [install the CLI manually](https://github.com/features/copilot/cli) or ensure `copilot` is available in your PATH. 2. **Install your preferred SDK** using the commands above. diff --git a/docs/index.md b/docs/index.md index 04ef99bd8..1b89439ae 100644 --- a/docs/index.md +++ b/docs/index.md @@ -22,8 +22,8 @@ Step-by-step tutorial that takes you from zero to a working Copilot app with str How to configure and deploy the SDK for your use case. -- [Local CLI](./setup/local-cli.md) — simplest path, uses your signed-in CLI -- [Bundled CLI](./setup/bundled-cli.md) — ship the CLI with your app +- [Default Setup (Bundled CLI)](./setup/bundled-cli.md) — the SDK includes the CLI automatically +- [Local CLI](./setup/local-cli.md) — use your own CLI binary or running instance - [Backend Services](./setup/backend-services.md) — server-side with headless CLI over TCP - [GitHub OAuth](./setup/github-oauth.md) — implement the OAuth flow - [Azure Managed Identity](./setup/azure-managed-identity.md) — BYOK with Azure AI Foundry diff --git a/docs/setup/bundled-cli.md b/docs/setup/bundled-cli.md index 516b1fe21..7419d4c18 100644 --- a/docs/setup/bundled-cli.md +++ b/docs/setup/bundled-cli.md @@ -1,76 +1,43 @@ -# Bundled CLI Setup +# Default Setup (Bundled CLI) -Package the Copilot CLI alongside your application so users don't need to install or configure anything separately. Your app ships with everything it needs. +The Node.js, Python, and .NET SDKs include the Copilot CLI as a dependency — your app ships with everything it needs, with no extra installation or configuration required. -**Best for:** Desktop apps, standalone tools, Electron apps, distributable CLI utilities. +**Best for:** Most applications — desktop apps, standalone tools, CLI utilities, prototypes, and more. ## How It Works -Instead of relying on a globally installed CLI, you include the CLI binary in your application bundle. The SDK points to your bundled copy via the `cliPath` option. +When you install the SDK, the Copilot CLI binary is included automatically. The SDK starts it as a child process and communicates over stdio. There's nothing extra to configure. ```mermaid flowchart TB - subgraph Bundle["Your Distributed App"] + subgraph Bundle["Your Application"] App["Application Code"] SDK["SDK Client"] - CLIBin["Copilot CLI Binary
(bundled)"] + CLIBin["Copilot CLI Binary
(included with SDK)"] end App --> SDK - SDK -- "cliPath" --> CLIBin + SDK --> CLIBin CLIBin -- "API calls" --> Copilot["☁️ GitHub Copilot"] style Bundle fill:#0d1117,stroke:#58a6ff,color:#c9d1d9 ``` **Key characteristics:** -- CLI binary ships with your app — no separate install needed -- You control the exact CLI version your app uses +- CLI binary is included with the SDK — no separate install needed +- The SDK manages the CLI version to ensure compatibility - Users authenticate through your app (or use env vars / BYOK) - Sessions are managed per-user on their machine -## Architecture: Bundled vs. Installed - -```mermaid -flowchart LR - subgraph Installed["Standard Setup"] - A1["Your App"] --> SDK1["SDK"] - SDK1 --> CLI1["Global CLI
(/usr/local/bin/copilot)"] - end - - subgraph Bundled["Bundled Setup"] - A2["Your App"] --> SDK2["SDK"] - SDK2 --> CLI2["Bundled CLI
(./vendor/copilot)"] - end - - style Installed fill:#161b22,stroke:#8b949e,color:#c9d1d9 - style Bundled fill:#0d1117,stroke:#3fb950,color:#c9d1d9 -``` - -## Setup - -### 1. Include the CLI in Your Project - -The CLI is distributed as part of the `@github/copilot` npm package. You can also obtain platform-specific binaries for your distribution pipeline. - -```bash -# The CLI is available from the @github/copilot package -npm install @github/copilot -``` - -### 2. Point the SDK to Your Bundled CLI +## Quick Start
Node.js / TypeScript ```typescript import { CopilotClient } from "@github/copilot-sdk"; -import path from "path"; -const client = new CopilotClient({ - // Point to the CLI binary in your app bundle - cliPath: path.join(__dirname, "vendor", "copilot"), -}); +const client = new CopilotClient(); const session = await client.createSession({ model: "gpt-4.1" }); const response = await session.sendAndWait({ prompt: "Hello!" }); @@ -87,11 +54,8 @@ await client.stop(); ```python from copilot import CopilotClient from copilot.session import PermissionHandler -from pathlib import Path -client = CopilotClient({ - "cli_path": str(Path(__file__).parent / "vendor" / "copilot"), -}) +client = CopilotClient() await client.start() session = await client.create_session(on_permission_request=PermissionHandler.approve_all, model="gpt-4.1") @@ -106,6 +70,8 @@ await client.stop()
Go +> **Note:** The Go SDK does not bundle the CLI. You must install the CLI separately or set `CLIPath` to point to an existing binary. See [Local CLI Setup](./local-cli.md) for details. + ```go package main @@ -120,9 +86,7 @@ import ( func main() { ctx := context.Background() - client := copilot.NewClient(&copilot.ClientOptions{ - CLIPath: "./vendor/copilot", - }) + client := copilot.NewClient(nil) if err := client.Start(ctx); err != nil { log.Fatal(err) } @@ -138,9 +102,7 @@ func main() { ```go -client := copilot.NewClient(&copilot.ClientOptions{ - CLIPath:"./vendor/copilot", -}) +client := copilot.NewClient(nil) if err := client.Start(ctx); err != nil { log.Fatal(err) } @@ -159,11 +121,7 @@ if d, ok := response.Data.(*copilot.AssistantMessageData); ok { .NET ```csharp -var client = new CopilotClient(new CopilotClientOptions -{ - CliPath = Path.Combine(AppContext.BaseDirectory, "vendor", "copilot"), -}); - +await using var client = new CopilotClient(); await using var session = await client.CreateSessionAsync( new SessionConfig { Model = "gpt-4.1" }); @@ -206,7 +164,7 @@ client.stop().get(); ## Authentication Strategies -When bundling, you need to decide how your users will authenticate. Here are the common patterns: +You need to decide how your users will authenticate. Here are the common patterns: ```mermaid flowchart TB @@ -225,13 +183,11 @@ flowchart TB ### Option A: User's Signed-In Credentials (Simplest) -The user signs in to the CLI once, and your bundled app uses those credentials. No extra code needed — this is the default behavior. +The user signs in to the CLI once, and your app uses those credentials. No extra code needed — this is the default behavior. ```typescript -const client = new CopilotClient({ - cliPath: path.join(__dirname, "vendor", "copilot"), - // Default: uses signed-in user credentials -}); +const client = new CopilotClient(); +// Default: uses signed-in user credentials ``` ### Option B: Token via Environment Variable @@ -240,7 +196,6 @@ Ship your app with instructions to set a token, or set it programmatically: ```typescript const client = new CopilotClient({ - cliPath: path.join(__dirname, "vendor", "copilot"), env: { COPILOT_GITHUB_TOKEN: getUserToken(), // Your app provides the token }, @@ -252,9 +207,7 @@ const client = new CopilotClient({ If you manage your own model provider keys, users don't need GitHub accounts at all: ```typescript -const client = new CopilotClient({ - cliPath: path.join(__dirname, "vendor", "copilot"), -}); +const client = new CopilotClient(); const session = await client.createSession({ model: "gpt-4.1", @@ -270,12 +223,10 @@ See the **[BYOK guide](../auth/byok.md)** for full details. ## Session Management -Bundled apps typically want named sessions so users can resume conversations: +Apps typically want named sessions so users can resume conversations: ```typescript -const client = new CopilotClient({ - cliPath: path.join(__dirname, "vendor", "copilot"), -}); +const client = new CopilotClient(); // Create a session tied to the user's project const sessionId = `project-${projectName}`; @@ -291,90 +242,6 @@ const resumed = await client.resumeSession(sessionId); Session state persists at `~/.copilot/session-state/{sessionId}/`. -## Distribution Patterns - -### Desktop App (Electron, Tauri) - -```mermaid -flowchart TB - subgraph Electron["Desktop App Package"] - UI["App UI"] --> Main["Main Process"] - Main --> SDK["SDK Client"] - SDK --> CLI["Copilot CLI
(in app resources)"] - end - CLI --> Cloud["☁️ GitHub Copilot"] - - style Electron fill:#0d1117,stroke:#58a6ff,color:#c9d1d9 -``` - -Include the CLI binary in your app's resources directory: - -```typescript -import { app } from "electron"; -import path from "path"; - -const cliPath = path.join( - app.isPackaged ? process.resourcesPath : __dirname, - "copilot" -); - -const client = new CopilotClient({ cliPath }); -``` - -### CLI Tool - -For distributable CLI tools, resolve the path relative to your binary: - -```typescript -import { fileURLToPath } from "url"; -import path from "path"; - -const __dirname = path.dirname(fileURLToPath(import.meta.url)); -const cliPath = path.join(__dirname, "..", "vendor", "copilot"); - -const client = new CopilotClient({ cliPath }); -``` - -## Platform-Specific Binaries - -When distributing for multiple platforms, include the correct binary for each: - -``` -my-app/ -├── vendor/ -│ ├── copilot-darwin-arm64 # macOS Apple Silicon -│ ├── copilot-darwin-x64 # macOS Intel -│ ├── copilot-linux-x64 # Linux x64 -│ └── copilot-win-x64.exe # Windows x64 -└── src/ - └── index.ts -``` - -```typescript -import os from "os"; - -function getCLIPath(): string { - const platform = process.platform; // "darwin", "linux", "win32" - const arch = os.arch(); // "arm64", "x64" - const ext = platform === "win32" ? ".exe" : ""; - const name = `copilot-${platform}-${arch}${ext}`; - return path.join(__dirname, "vendor", name); -} - -const client = new CopilotClient({ - cliPath: getCLIPath(), -}); -``` - -## Limitations - -| Limitation | Details | -|------------|---------| -| **Bundle size** | CLI binary adds to your app's distribution size | -| **Updates** | You manage CLI version updates in your release cycle | -| **Platform builds** | Need separate binaries for each OS/architecture | -| **Single user** | Each bundled CLI instance serves one user | - ## When to Move On | Need | Next Guide | diff --git a/docs/setup/index.md b/docs/setup/index.md index 268e26688..68daaa008 100644 --- a/docs/setup/index.md +++ b/docs/setup/index.md @@ -38,8 +38,8 @@ The setup guides below help you configure each layer for your scenario. You're building a personal assistant, side project, or experimental app. You want the simplest path to getting Copilot in your code. **Start with:** -1. **[Local CLI](./local-cli.md)** — Use the CLI already signed in on your machine -2. **[Bundled CLI](./bundled-cli.md)** — Package everything into a standalone app +1. **[Default Setup](./bundled-cli.md)** — The SDK includes the CLI automatically — just install and go +2. **[Local CLI](./local-cli.md)** — Use your own CLI binary or running instance (advanced) ### 🏢 Internal App Developer @@ -82,8 +82,8 @@ Use this table to find the right guides based on what you need to do: | What you need | Guide | |---------------|-------| -| Simplest possible setup | [Local CLI](./local-cli.md) | -| Ship a standalone app with Copilot | [Bundled CLI](./bundled-cli.md) | +| Getting started quickly | [Default Setup (Bundled CLI)](./bundled-cli.md) | +| Use your own CLI binary or server | [Local CLI](./local-cli.md) | | Users sign in with GitHub | [GitHub OAuth](./github-oauth.md) | | Use your own model keys (OpenAI, Azure, etc.) | [BYOK](../auth/byok.md) | | Azure BYOK with Managed Identity (no API keys) | [Azure Managed Identity](./azure-managed-identity.md) | @@ -129,11 +129,10 @@ flowchart LR All guides assume you have: -- **Copilot CLI** installed ([Installation guide](https://docs.github.com/en/copilot/how-tos/set-up/install-copilot-cli)) -- **One of the SDKs** installed: +- **One of the SDKs** installed (Node.js, Python, and .NET SDKs include the CLI automatically): - Node.js: `npm install @github/copilot-sdk` - Python: `pip install github-copilot-sdk` - - Go: `go get github.com/github/copilot-sdk/go` + - Go: `go get github.com/github/copilot-sdk/go` (requires separate CLI installation) - .NET: `dotnet add package GitHub.Copilot.SDK` If you're brand new, start with the **[Getting Started tutorial](../getting-started.md)** first, then come back here for production configuration. diff --git a/docs/setup/local-cli.md b/docs/setup/local-cli.md index 77d7a5e66..48092b735 100644 --- a/docs/setup/local-cli.md +++ b/docs/setup/local-cli.md @@ -1,18 +1,18 @@ # Local CLI Setup -Use the Copilot SDK with a Copilot CLI instance signed in on your machine. Depending on the SDK, this may be a bundled CLI (included automatically) or a system-installed CLI available in your PATH. This is the simplest configuration — zero auth code, zero infrastructure. +Use a specific CLI binary instead of the SDK's bundled CLI. This is an advanced option — you supply the CLI path explicitly, and you are responsible for ensuring version compatibility with the SDK. -**Best for:** Personal projects, prototyping, local development, learning the SDK. +**Use when:** You need to pin a specific CLI version, or work with the Go SDK (which does not bundle a CLI). ## How It Works -When a Copilot CLI instance is available (either bundled with the SDK or installed on your system) and signed in, credentials are stored in the system keychain. The SDK automatically starts the CLI as a child process and uses those stored credentials. +By default, the Node.js, Python, and .NET SDKs include their own CLI dependency (see [Default Setup](./bundled-cli.md)). If you need to override this — for example, to use a system-installed CLI — you can use the `cliPath` option. ```mermaid flowchart LR subgraph YourMachine["Your Machine"] App["Your App"] --> SDK["SDK Client"] - SDK -- "stdio" --> CLI["Copilot CLI
(auto-started)"] + SDK -- "cliPath" --> CLI["Copilot CLI
(your own binary)"] CLI --> Keychain["🔐 System Keychain
(stored credentials)"] end CLI -- "API calls" --> Copilot["☁️ GitHub Copilot"] @@ -21,14 +21,14 @@ flowchart LR ``` **Key characteristics:** -- CLI is spawned automatically by the SDK (using a bundled CLI or a system-installed CLI if available) -- Authentication uses the signed-in user's credentials from the system keychain -- Communication happens over stdio (stdin/stdout) — no network ports -- Sessions are local to your machine +- You explicitly provide the CLI binary path +- You are responsible for CLI version compatibility with the SDK +- Authentication uses the signed-in user's credentials from the system keychain (or env vars) +- Communication happens over stdio -## Quick Start +## Configuration -The default configuration requires no options at all: +### Using a local CLI binary
Node.js / TypeScript @@ -36,9 +36,11 @@ The default configuration requires no options at all: ```typescript import { CopilotClient } from "@github/copilot-sdk"; -const client = new CopilotClient(); -const session = await client.createSession({ model: "gpt-4.1" }); +const client = new CopilotClient({ + cliPath: "/usr/local/bin/copilot", +}); +const session = await client.createSession({ model: "gpt-4.1" }); const response = await session.sendAndWait({ prompt: "Hello!" }); console.log(response?.data.content); @@ -54,7 +56,9 @@ await client.stop(); from copilot import CopilotClient from copilot.session import PermissionHandler -client = CopilotClient() +client = CopilotClient({ + "cli_path": "/usr/local/bin/copilot", +}) await client.start() session = await client.create_session(on_permission_request=PermissionHandler.approve_all, model="gpt-4.1") @@ -69,6 +73,8 @@ await client.stop()
Go +> **Note:** The Go SDK does not bundle a CLI, so you must always provide `CLIPath`. + ```go package main @@ -83,7 +89,9 @@ import ( func main() { ctx := context.Background() - client := copilot.NewClient(nil) + client := copilot.NewClient(&copilot.ClientOptions{ + CLIPath: "/usr/local/bin/copilot", + }) if err := client.Start(ctx); err != nil { log.Fatal(err) } @@ -91,15 +99,15 @@ func main() { session, _ := client.CreateSession(ctx, &copilot.SessionConfig{Model: "gpt-4.1"}) response, _ := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "Hello!"}) - if d, ok := response.Data.(*copilot.AssistantMessageData); ok { - fmt.Println(d.Content) - } + fmt.Println(*response.Data.Content) } ``` ```go -client := copilot.NewClient(nil) +client := copilot.NewClient(&copilot.ClientOptions{ + CLIPath: "/usr/local/bin/copilot", +}) if err := client.Start(ctx); err != nil { log.Fatal(err) } @@ -107,9 +115,7 @@ defer client.Stop() session, _ := client.CreateSession(ctx, &copilot.SessionConfig{Model: "gpt-4.1"}) response, _ := session.SendAndWait(ctx, copilot.MessageOptions{Prompt: "Hello!"}) -if d, ok := response.Data.(*copilot.AssistantMessageData); ok { - fmt.Println(d.Content) -} +fmt.Println(*response.Data.Content) ```
@@ -118,7 +124,11 @@ if d, ok := response.Data.(*copilot.AssistantMessageData); ok { .NET ```csharp -await using var client = new CopilotClient(); +var client = new CopilotClient(new CopilotClientOptions +{ + CliPath = "/usr/local/bin/copilot", +}); + await using var session = await client.CreateSessionAsync( new SessionConfig { Model = "gpt-4.1" }); @@ -129,73 +139,16 @@ Console.WriteLine(response?.Data.Content);
-
-Java - -```java -import com.github.copilot.sdk.CopilotClient; -import com.github.copilot.sdk.events.*; -import com.github.copilot.sdk.json.*; - -var client = new CopilotClient(); -client.start().get(); - -var session = client.createSession(new SessionConfig() - .setModel("gpt-4.1") - .setOnPermissionRequest(request -> PermissionDecision.allow())).get(); - -var response = session.sendAndWait(new MessageOptions() - .setPrompt("Hello!")).get(); -System.out.println(response.getData().content()); - -client.stop().get(); -``` - -
- -That's it. The SDK handles everything: starting the CLI, authenticating, and managing the session. - -## What's Happening Under the Hood - -```mermaid -sequenceDiagram - participant App as Your App - participant SDK as SDK Client - participant CLI as Copilot CLI - participant GH as GitHub API - - App->>SDK: new CopilotClient() - Note over SDK: Locates CLI binary - - App->>SDK: createSession() - SDK->>CLI: Spawn process (stdio) - CLI->>CLI: Load credentials from keychain - CLI->>GH: Authenticate - GH-->>CLI: ✅ Valid session - CLI-->>SDK: Session created - SDK-->>App: Session ready - - App->>SDK: sendAndWait("Hello!") - SDK->>CLI: JSON-RPC request - CLI->>GH: Model API call - GH-->>CLI: Response - CLI-->>SDK: JSON-RPC response - SDK-->>App: Response data -``` - -## Configuration Options - -While defaults work great, you can customize the local setup: +## Additional Options ```typescript const client = new CopilotClient({ - // Override CLI location (by default, the SDK uses a bundled CLI or resolves one from your system) cliPath: "/usr/local/bin/copilot", // Set log level for debugging logLevel: "debug", - // Pass extra CLI arguments (example: set a custom log directory) + // Pass extra CLI arguments cliArgs: ["--log-dir=/tmp/copilot-logs"], // Set working directory @@ -218,7 +171,7 @@ The SDK picks these up automatically — no code changes needed. ## Managing Sessions -With the local CLI, sessions default to ephemeral. To create resumable sessions, provide your own session ID: +Sessions default to ephemeral. To create resumable sessions, provide your own session ID: ```typescript // Create a named session @@ -237,24 +190,13 @@ Session state is stored locally at `~/.copilot/session-state/{sessionId}/`. | Limitation | Details | |------------|---------| +| **Version compatibility** | You must ensure your CLI version is compatible with the SDK | | **Single user** | Credentials are tied to whoever signed in to the CLI | | **Local only** | The CLI runs on the same machine as your app | | **No multi-tenant** | Can't serve multiple users from one CLI instance | -| **Requires CLI login** | User must run `copilot` and authenticate first | - -## When to Move On - -If you need any of these, it's time to pick a more advanced setup: - -| Need | Next Guide | -|------|-----------| -| Ship your app to others | [Bundled CLI](./bundled-cli.md) | -| Multiple users signing in | [GitHub OAuth](./github-oauth.md) | -| Run on a server | [Backend Services](./backend-services.md) | -| Use your own model keys | [BYOK](../auth/byok.md) | ## Next Steps +- **[Default Setup](./bundled-cli.md)** — Use the SDK's built-in CLI (recommended for most use cases) - **[Getting Started tutorial](../getting-started.md)** — Build a complete interactive app - **[Authentication docs](../auth/index.md)** — All auth methods in detail -- **[Session Persistence](../features/session-persistence.md)** — Advanced session management