From ffb509cfc48025bcc1a15ee65ecdb93a78c6599f Mon Sep 17 00:00:00 2001 From: Tim Pope Date: Fri, 24 Apr 2026 11:10:26 -0400 Subject: [PATCH 1/3] Replace .copilot/config.json references with .copilot/settings.json (#60921) Co-authored-by: hubwriter --- .../copilot-cli/manage-pull-requests.md | 2 +- .../authenticate-copilot-cli.md | 2 +- .../configure-copilot-cli.md | 6 +- .../how-tos/copilot-cli/steer-remotely.md | 2 +- .../use-copilot-cli-agents/overview.md | 2 +- .../cli-command-reference.md | 155 ++++++++++++++---- .../cli-config-dir-reference.md | 27 +-- .../cli-programmatic-reference.md | 6 +- 8 files changed, 145 insertions(+), 57 deletions(-) diff --git a/content/copilot/how-tos/copilot-cli/manage-pull-requests.md b/content/copilot/how-tos/copilot-cli/manage-pull-requests.md index 224d98b09525..c099bcda46fe 100644 --- a/content/copilot/how-tos/copilot-cli/manage-pull-requests.md +++ b/content/copilot/how-tos/copilot-cli/manage-pull-requests.md @@ -156,7 +156,7 @@ When resolving conflicts, {% data variables.copilot.copilot_cli_short %} needs t To set a default merge strategy so that you are not prompted each time, add the `mergeStrategy` setting to your configuration file. You can set this in your personal user settings for {% data variables.product.prodname_copilot_short %}, or in the repository settings. -* **User settings**: Add `"mergeStrategy": "rebase"` or `"mergeStrategy": "merge"` to your user-level configuration file (typically `~/.copilot/config.json`). +* **User settings**: Add `"mergeStrategy": "rebase"` or `"mergeStrategy": "merge"` to your user-level configuration file (typically `~/.copilot/settings.json`). * **Repository settings**: Add the same setting to `.github/copilot/settings.json` in your repository root. ## Fixing CI failures diff --git a/content/copilot/how-tos/copilot-cli/set-up-copilot-cli/authenticate-copilot-cli.md b/content/copilot/how-tos/copilot-cli/set-up-copilot-cli/authenticate-copilot-cli.md index f75cfaea969b..c290e49374ed 100644 --- a/content/copilot/how-tos/copilot-cli/set-up-copilot-cli/authenticate-copilot-cli.md +++ b/content/copilot/how-tos/copilot-cli/set-up-copilot-cli/authenticate-copilot-cli.md @@ -67,7 +67,7 @@ By default, the CLI stores your OAuth token in your operating system's keychain | Windows | Credential Manager | | Linux | libsecret (GNOME Keyring, KWallet) | -If the system keychain is unavailable—for example, on a headless Linux server without `libsecret` installed—the CLI prompts you to store the token in a plaintext configuration file at `~/.copilot/config.json`. +If the system keychain is unavailable—for example, on a headless Linux server without `libsecret` installed—the CLI prompts you to store the token in a plaintext configuration file at `~/.copilot/settings.json`. When you run a command, {% data variables.copilot.copilot_cli_short %} checks for credentials in the following order: diff --git a/content/copilot/how-tos/copilot-cli/set-up-copilot-cli/configure-copilot-cli.md b/content/copilot/how-tos/copilot-cli/set-up-copilot-cli/configure-copilot-cli.md index 2b9a305721b7..8157aced9470 100644 --- a/content/copilot/how-tos/copilot-cli/set-up-copilot-cli/configure-copilot-cli.md +++ b/content/copilot/how-tos/copilot-cli/set-up-copilot-cli/configure-copilot-cli.md @@ -41,10 +41,10 @@ If you choose to trust the directory for future sessions, the trusted directory You can edit the list of permanently trusted directories. -1. Open the CLI’s `config.json` file. By default, it’s stored in a `.copilot` folder under your home directory: +1. Open the CLI’s `settings.json` file. By default, it’s stored in a `.copilot` folder under your home directory: - * **macOS/Linux**: `~/.copilot/config.json` - * **Windows**: `$HOME\.copilot\config.json` + * **macOS/Linux**: `~/.copilot/settings.json` + * **Windows**: `$HOME\.copilot\settings.json` You can change the config location by setting the `COPILOT_HOME` environment variable. diff --git a/content/copilot/how-tos/copilot-cli/steer-remotely.md b/content/copilot/how-tos/copilot-cli/steer-remotely.md index ced6f695a5da..41a6261c5979 100644 --- a/content/copilot/how-tos/copilot-cli/steer-remotely.md +++ b/content/copilot/how-tos/copilot-cli/steer-remotely.md @@ -58,7 +58,7 @@ Details for accessing the session remotely are displayed when the interactive se ### Configuring remote access to always be enabled -If you always want your interactive CLI sessions to be remotely accessible, add the following to your {% data variables.product.prodname_copilot_short %} configuration file (typically located at `~/.copilot/config.json`): +If you always want your interactive CLI sessions to be remotely accessible, add the following to your {% data variables.product.prodname_copilot_short %} configuration file (typically located at `~/.copilot/settings.json`): ```json copy { diff --git a/content/copilot/how-tos/copilot-cli/use-copilot-cli-agents/overview.md b/content/copilot/how-tos/copilot-cli/use-copilot-cli-agents/overview.md index 1b5fe2634093..ed6fff88ecb1 100644 --- a/content/copilot/how-tos/copilot-cli/use-copilot-cli-agents/overview.md +++ b/content/copilot/how-tos/copilot-cli/use-copilot-cli-agents/overview.md @@ -271,7 +271,7 @@ For additional information use one of the following commands in your terminal: `copilot help config` - You can adjust the configuration settings by editing the `config.json` file, which is located, by default, in the `~/.copilot` directory. This location can be changed by setting the `COPILOT_HOME` environment variable. + You can adjust the configuration settings by editing the `settings.json` file, which is located, by default, in the `~/.copilot` directory. This location can be changed by setting the `COPILOT_HOME` environment variable. * **Environment variables** that affect {% data variables.copilot.copilot_cli_short %}: diff --git a/content/copilot/reference/copilot-cli-reference/cli-command-reference.md b/content/copilot/reference/copilot-cli-reference/cli-command-reference.md index 66aae9a15272..2c4a14f85231 100644 --- a/content/copilot/reference/copilot-cli-reference/cli-command-reference.md +++ b/content/copilot/reference/copilot-cli-reference/cli-command-reference.md @@ -102,6 +102,7 @@ COPILOT_GITHUB_TOKEN=github_pat_... copilot | End | Move to the end of the text. | | Alt+/ (Windows/Linux)
Option+/ (Mac) | Move the cursor by a word. | | / | Navigate the command history. | +| Tab / Ctrl+Y | Accept the current inline completion suggestion. | ## Slash commands in the interactive interface @@ -120,6 +121,7 @@ COPILOT_GITHUB_TOKEN=github_pat_... copilot | `/cwd`, `/cd [PATH]` | Change the working directory or display the current directory. | | `/delegate [PROMPT]` | Delegate changes to a remote repository with an AI-generated pull request. See [AUTOTITLE](/copilot/how-tos/copilot-cli/use-copilot-cli-agents/delegate-tasks-to-cca). | | `/diff` | Review the changes made in the current directory. | +| `/downgrade ` | Download and restart into a specific CLI version. Available for team accounts. | | `/env` | Show loaded environment details (instructions, MCP servers, skills, agents, plugins, LSPs, extensions). | | `/exit`, `/quit` | Exit the CLI. | | `/experimental [on\|off\|show]` | Toggle, set, or show experimental features. | @@ -144,9 +146,9 @@ COPILOT_GITHUB_TOKEN=github_pat_... copilot | `/research TOPIC` | Run a deep research investigation using {% data variables.product.github %} search and web sources. See [AUTOTITLE](/copilot/concepts/agents/copilot-cli/research). | | `/reset-allowed-tools` | Reset the list of allowed tools. | | `/restart` | Restart the CLI, preserving the current session. | -| `/resume [SESSION-ID]`, `/continue [SESSION-ID]` | Switch to a different session by choosing from a list (optionally specify a session ID). | +| `/resume [VALUE]`, `/continue` | Switch to a different session by choosing from a list. Optionally specify a session ID, ID prefix, or session name to resume a specific session. | | `/review [PROMPT]` | Run the code review agent to analyze changes. See [AUTOTITLE](/copilot/how-tos/copilot-cli/use-copilot-cli-agents/agentic-code-review). | -| `/session [checkpoints [n]\|files\|plan\|rename NAME]`, `/sessions [checkpoints [n]\|files\|plan\|rename NAME]` | Show session information and a workspace summary. Use the subcommands for details. | +| `/session [info\|checkpoints [n]\|files\|plan\|rename [NAME]\|cleanup\|prune\|delete [ID]\|delete-all]`, `/sessions [info\|checkpoints [n]\|files\|plan\|rename [NAME]\|cleanup\|prune\|delete [ID]\|delete-all]` | Show session information and manage sessions. Subcommands: `info`, `checkpoints`, `files`, `plan`, `rename`, `cleanup`, `prune`, `delete`, `delete-all`. | | `/share [file\|html\|gist] [session\|research] [PATH]`, `/export [file\|html\|gist] [session\|research] [PATH]` | Share the session to a Markdown file, interactive HTML file, or {% data variables.product.github %} gist. | | `/skills [list\|info\|add\|remove\|reload] [ARGS...]` | Manage skills for enhanced capabilities. See [AUTOTITLE](/copilot/how-tos/copilot-cli/customize-copilot/create-skills). | | `/statusline`, `/footer` | Configure which items appear in the status line. | @@ -182,7 +184,7 @@ For a complete list of available slash commands enter `/help` in the CLI's inter | `--bash-env` | Enable `BASH_ENV` support for bash shells. | | `--config-dir=PATH` | Set the configuration directory (default: `~/.copilot`). | | `--connect[=SESSION-ID]` | Connect directly to a remote session (optionally specify a session ID or task ID). Conflicts with `--resume` and `--continue`. | -| `--continue` | Resume the most recent session. | +| `--continue` | Resume the most recent session in the current working directory, falling back to the globally most recent session. | | `--deny-tool=TOOL ...` | Tools the CLI does not have permission to use. Will not prompt for permission. For multiple tools, use a quoted, comma-separated list. | | `--deny-url=URL ...` | Deny access to specific URLs or domains, takes precedence over `--allow-url`. For multiple URLs, use a quoted, comma-separated list. | | `--disable-builtin-mcps` | Disable all built-in MCP servers (currently: `github-mcp-server`). | @@ -201,6 +203,7 @@ For a complete list of available slash commands enter `/help` in the CLI's inter | `--mode=MODE` | Set the initial agent mode (choices: `interactive`, `plan`, `autopilot`). Cannot be combined with `--autopilot` or `--plan`. | | `--model=MODEL` | Set the AI model you want to use. Pass `auto` to let {% data variables.product.prodname_copilot_short %} pick the best available model automatically. | | `--mouse[=VALUE]` | Enable mouse support in alt screen mode. VALUE can be `on` (default) or `off`. When enabled, the CLI captures mouse events in alt screen mode—scroll wheel, clicks, etc. When disabled, the terminal's native mouse behavior is preserved. Once set the setting is persisted by being written to your configuration file.| +| `-n NAME`, `--name=NAME` | Set a name for the new session. Used by `--resume` and `/resume` to find sessions by name. | | `--no-ask-user` | Disable the `ask_user` tool (the agent works autonomously without asking questions). | | `--no-auto-update` | Disable downloading CLI updates automatically. | | `--no-bash-env` | Disable `BASH_ENV` support for bash shells. | @@ -215,7 +218,7 @@ For a complete list of available slash commands enter `/help` in the CLI's inter | `--plain-diff` | Disable rich diff rendering (syntax highlighting via the diff tool specified by your git config). | | `--plugin-dir=DIRECTORY` | Load a plugin from a local directory (can be used multiple times). | | `--remote` | Enable remote access to this session from {% data variables.product.prodname_dotcom_the_website %} and {% data variables.product.prodname_mobile %}. See [AUTOTITLE](/copilot/how-tos/copilot-cli/steer-remotely). | -| `--resume=SESSION-ID` | Resume a previous interactive session by choosing from a list (optionally specify a session ID or unique prefix of 7+ hex characters). | +| `--resume[=VALUE]` | Resume a previous interactive session by choosing from a list. Optionally specify a session ID, ID prefix, or session name. Name matching is exact and case-insensitive; falls back to the auto-generated summary when no explicit name matches. | | `-s`, `--silent` | Output only the agent response (without usage statistics), useful for scripting with `-p`. | | `--screen-reader` | Enable screen reader optimizations. | | `--secret-env-vars=VAR ...` | Redact an environment variable from shell and MCP server environments (can be used multiple times). For multiple variables, use a quoted, comma-separated list. The values in the `GITHUB_TOKEN` and `COPILOT_GITHUB_TOKEN` environment variables are redacted from output by default. | @@ -239,37 +242,38 @@ The `--available-tools` and `--excluded-tools` options support these values: | Tool name | Description | |---|---| | `bash` / `powershell` | Execute commands | +| `list_bash` / `list_powershell` | List active shell sessions | | `read_bash` / `read_powershell` | Read output from a shell session | -| `write_bash` / `write_powershell` | Send input to a shell session | | `stop_bash` / `stop_powershell` | Terminate a shell session | -| `list_bash` / `list_powershell` | List active shell sessions | +| `write_bash` / `write_powershell` | Send input to a shell session | ### File operation tools | Tool name | Description | |---|---| -| `view` | Read files or directories | +| `apply_patch` | Apply patches (used by some models instead of `edit`/`create`) | | `create` | Create new files | | `edit` | Edit files via string replacement | -| `apply_patch` | Apply patches (used by some models instead of `edit`/`create`) | +| `view` | Read files or directories | ### Agent and task delegation tools | Tool name | Description | |---|---| -| `task` | Run subagents | -| `read_agent` | Check background agent status | | `list_agents` | List available agents | +| `read_agent` | Check background agent status | +| `task` | Run subagents | ### Other tools | Tool name | Description | |---|---| -| `grep` (or `rg`) | Search for text in files | +| `ask_user` | Ask the user a question | | `glob` | Find files matching patterns | -| `web_fetch` | Fetch and parse web content | +| `grep` (or `rg`) | Search for text in files | +| `show_file` | Present code snippets inline in the timeline. {% data reusables.copilot.experimental %} | | `skill` | Invoke custom skills | -| `ask_user` | Ask the user a question | +| `web_fetch` | Fetch and parse web content | ## Tool permission patterns @@ -277,12 +281,12 @@ The `--allow-tool` and `--deny-tool` options accept permission patterns in the f | Kind | Description | Example patterns | |------|-------------|-----------------| +| `memory` | Storing facts to agent memory | `memory` | +| `read` | File or directory reads | `read`, `read(.env)` | | `shell` | Shell command execution | `shell(git push)`, `shell(git:*)`, `shell` | +| `url` | URL access via web-fetch or shell | `url(github.com)`, `url(https://*.api.com)` | | `write` | File creation or modification | `write`, `write(src/*.ts)` | -| `read` | File or directory reads | `read`, `read(.env)` | | SERVER-NAME | MCP server tool invocation | `MyMCP(create_issue)`, `MyMCP` | -| `url` | URL access via web-fetch or shell | `url(github.com)`, `url(https://*.api.com)` | -| `memory` | Storing facts to agent memory | `memory` | For `shell` rules, the `:*` suffix matches the command stem followed by a space, preventing partial matches. For example, `shell(git:*)` matches `git push` and `git pull` but does not match `gitea`. @@ -303,27 +307,33 @@ copilot --allow-tool='MyMCP' | Variable | Description | |----------|-------------| -| `COPILOT_MODEL` | Set the AI model. | +| `COLORFGBG` | Fallback for dark/light terminal background detection. | | `COPILOT_ALLOW_ALL` | Set to `true` to allow all permissions automatically (equivalent to `--allow-all`). | | `COPILOT_AUTO_UPDATE` | Set to `false` to disable automatic updates. | +| `COPILOT_CACHE_HOME` | Override the cache directory (used for marketplace caches, auto-update packages, and other ephemeral data). See [AUTOTITLE](/copilot/reference/copilot-cli-reference/cli-config-dir-reference#changing-the-location-of-the-configuration-directory) for platform defaults. | | `COPILOT_CUSTOM_INSTRUCTIONS_DIRS` | Comma-separated list of additional directories for custom instructions. | -| `COPILOT_SKILLS_DIRS` | Comma-separated list of additional directories for skills. | | `COPILOT_EDITOR` | Editor command for interactive editing (checked after `$VISUAL` and `$EDITOR`). Defaults to `vi` if none are set. | +| `COPILOT_GH_HOST` |{% data variables.product.github %} hostname for {% data variables.copilot.copilot_cli_short %} only, overriding `GH_HOST`. Use when `GH_HOST` targets {% data variables.product.prodname_ghe_server %} but {% data variables.product.prodname_copilot_short %} needs to authenticate against {% data variables.product.prodname_dotcom_the_website %} or a {% data variables.product.prodname_ghe_cloud %} hostname. | | `COPILOT_GITHUB_TOKEN` | Authentication token. Takes precedence over `GH_TOKEN` and `GITHUB_TOKEN`. | | `COPILOT_HOME` | Override the configuration and state directory. Default: `$HOME/.copilot`. | -| `COPILOT_CACHE_HOME` | Override the cache directory (used for marketplace caches, auto-update packages, and other ephemeral data). See [AUTOTITLE](/copilot/reference/copilot-cli-reference/cli-config-dir-reference#changing-the-location-of-the-configuration-directory) for platform defaults. | -| `COPILOT_SUBAGENT_MAX_DEPTH` | Maximum subagent nesting depth. Default: `6`. Range: `1`–`256`. | +| `COPILOT_MODEL` | Set the AI model. | +| `COPILOT_PROMPT_FRAME` | Set to `1` to enable the decorative UI frame around the input prompt, or `0` to disable it. Overrides the `PROMPT_FRAME` experimental feature flag for the current session. | +| `COPILOT_SKILLS_DIRS` | Comma-separated list of additional directories for skills. | | `COPILOT_SUBAGENT_MAX_CONCURRENT` | Maximum concurrent subagents across the entire session tree. Default: `32`. Range: `1`–`256`. | +| `COPILOT_SUBAGENT_MAX_DEPTH` | Maximum subagent nesting depth. Default: `6`. Range: `1`–`256`. | +| `GH_HOST` | {% data variables.product.github %} hostname for both {% data variables.product.prodname_cli %} and {% data variables.copilot.copilot_cli_short %} (default: `github.com`). Set to your {% data variables.product.prodname_ghe_cloud %} with data residency hostname. Override with `COPILOT_GH_HOST` for {% data variables.copilot.copilot_cli_short %} only. | | `GH_TOKEN` | Authentication token. Takes precedence over `GITHUB_TOKEN`. | | `GITHUB_TOKEN` | Authentication token. | -| `USE_BUILTIN_RIPGREP` | Set to `false` to use the system ripgrep instead of the bundled version. | | `PLAIN_DIFF` | Set to `true` to disable rich diff rendering. | -| `COLORFGBG` | Fallback for dark/light terminal background detection. | +| `USE_BUILTIN_RIPGREP` | Set to `false` to use the system ripgrep instead of the bundled version. | ## Configuration file settings For detailed information about configuration file settings—including the full list of user settings, repository settings, local settings, and how they cascade—see [AUTOTITLE](/copilot/reference/copilot-cli-reference/cli-config-dir-reference#configuration-file-settings). +> [!NOTE] +> User settings were previously stored in `~/.copilot/config.json`. Existing settings in that location are automatically migrated to `~/.copilot/settings.json` on startup. + ## Project initialization for {% data variables.product.prodname_copilot_short %} When you use the command `copilot init`, or the slash command `/init` within an interactive session, {% data variables.product.prodname_copilot_short %} analyzes your codebase and writes or updates a `.github/copilot-instructions.md` file in the repository. This custom instructions file contains project-specific guidance that will improve future CLI sessions. @@ -348,11 +358,11 @@ For more information, see [AUTOTITLE](/copilot/how-tos/configure-custom-instruct ## Hooks reference -Hooks are external commands that execute at specific lifecycle points during a session, enabling custom automation, security controls, and integrations. Hook configuration files are loaded automatically from `.github/hooks/*.json` in your repository. +Hooks are external commands, HTTP webhooks, or (on `sessionStart` only) prompt strings that execute at specific lifecycle points during a session, enabling custom automation, security controls, and integrations. Hook configuration files are loaded automatically from `.github/hooks/*.json` in your repository. ### Hook configuration format -Hook configuration files use JSON format with version `1`. +Hook configuration files use JSON format with version `1`. Each hook entry is a command hook, an HTTP hook, or (on `sessionStart` only) a prompt hook. #### Command hooks @@ -378,12 +388,12 @@ Command hooks run shell scripts and are supported on all hook types. | Field | Type | Required | Description | |-------|------|----------|-------------| -| `type` | `"command"` | Yes | Must be `"command"`. | | `bash` | string | One of `bash`/`powershell` | Shell command for Unix. | -| `powershell` | string | One of `bash`/`powershell` | Shell command for Windows. | | `cwd` | string | No | Working directory for the command (relative to repository root or absolute). | | `env` | object | No | Environment variables to set (supports variable expansion). | +| `powershell` | string | One of `bash`/`powershell` | Shell command for Windows. | | `timeoutSec` | number | No | Timeout in seconds. Default: `30`. | +| `type` | `"command"` | Yes | Must be `"command"`. | #### Prompt hooks @@ -405,14 +415,80 @@ Prompt hooks auto-submit text as if the user typed it. They are only supported o | Field | Type | Required | Description | |-------|------|----------|-------------| -| `type` | `"prompt"` | Yes | Must be `"prompt"`. | | `prompt` | string | Yes | Text to submit—can be a natural language message or a slash command. | +| `type` | `"prompt"` | Yes | Must be `"prompt"`. | + +#### HTTP hooks + +HTTP hooks POST the event payload as JSON to a configured URL and parse the JSON response body. They are supported on all hook event types and are useful for webhook-style integrations—remote policy services, audit endpoints, and approval workflows—without requiring a local executable. + +```json +{ + "version": 1, + "hooks": { + "preToolUse": [ + { + "type": "http", + "url": "https://policy.example.com/preToolUse" + } + ] + } +} +``` + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `type` | `"http"` | Yes | Must be `"http"`. | +| `url` | string | Yes | Endpoint URL. Must use `http:` or `https:`. No env var substitution in the URL itself. | +| `headers` | object | No | Request headers. Values support `$VAR` / `${VAR}` substitution restricted to names listed in `allowedEnvVars`. | +| `allowedEnvVars` | string[] | No | Allowlist for header value templating. Setting to a non-empty array requires HTTPS. | +| `timeoutSec` | number | No | Per-request timeout in seconds. Default: `30`. `timeout` is accepted as an alias; `timeoutSec` takes precedence. | +| `matcher` | string | No | Regex filter. Supported only on `preCompact`, `subagentStart`, `permissionRequest`, and `notification`. Anchored as `^(?:pattern)$`. | + +The response body uses the same JSON schema as command hook stdout for each event. Respond `204 No Content` or any 2xx with empty body when no action is needed. + +> [!WARNING] +> HTTP hooks have no exit-code semantics. A non-2xx response is a hook failure, not a deny decision. To deny a tool call from an HTTP `preToolUse` hook, return `200 OK` with `{"permissionDecision":"deny","permissionDecisionReason":"..."}`. To deny from an HTTP `permissionRequest` hook, return `200 OK` with `{"behavior":"deny","message":"..."}`. + +A hook entry with both `bash` and `url` fields parses as whichever variant matches first; the unused field is silently dropped. Always set `type` explicitly and remove command-hook fields when using HTTP hooks. + +##### HTTP hook security + +HTTPS is required in the following cases: + +* When `allowedEnvVars` is a non-empty array, to prevent credentials from being sent over plaintext. +* By default for `preToolUse` and `permissionRequest` hooks, to protect the permission decision channel. + +The CLI enforces a default-deny SSRF policy: any URL whose hostname resolves to a loopback, private, link-local, or cloud metadata address is rejected before connection. DNS is resolved up front and all returned addresses are validated (DNS rebinding defense). + +The following environment variables relax these defaults for development and testing only. + +| Variable | Effect | Intended use | +|----------|--------|--------------| +| `COPILOT_HOOK_ALLOW_LOCALHOST=1` | Permits `http://` to literal `localhost`, `127.*`, or `[::1]` (HTTPS rules), and any hostname resolving entirely to loopback (SSRF rule). | Local development only | +| `COPILOT_HOOK_ALLOW_HTTP_AUTH_HOOKS=1` | Permits `http://` for `preToolUse` and `permissionRequest` hooks anywhere. | Testing only | + +Both variables must be set before launching `copilot`. Do not set them globally, in CI, or in shared environments. + +##### HTTP hook failure semantics + +| Condition | Behavior | +|-----------|----------| +| 2xx + valid JSON body | Body parsed per event output schema. | +| 2xx + empty or non-JSON body | No action. | +| Non-2xx response | Hook fails. Error logged. Agent continues. | +| 3xx redirect | Hook fails ("returned redirect"). Agent continues. | +| Timeout | Hook fails. Error logged. Agent continues. | +| Network, DNS, or TLS error | Hook fails. Error logged. Agent continues. | +| Configuration validation error at load | Entire configuration file rejected; no hooks from that file register. | + +For `preToolUse` and `permissionRequest`, an HTTP hook failure is fail-open: the agent falls through to the default permission flow. ### Hook events | Event | Fires when | Output processed | -|-------|-----------|-----------------| -| `sessionStart` | A new or resumed session begins. | No | +|-------|------------|------------------| +| `sessionStart` | A new or resumed session begins. | Optional — can return `additionalContext` to inject session-wide context prepended to every turn. | | `sessionEnd` | The session terminates. | No | | `userPromptSubmitted` | The user submits a prompt. | No | | `preToolUse` | Before each tool executes. | Yes — can allow, deny, or modify. | @@ -745,13 +821,17 @@ When configured with the PascalCase event name `PreToolUse`, the payload uses sn ### `preToolUse` decision control -The `preToolUse` hook can control tool execution by writing a JSON object to stdout. +The `preToolUse` hook can control tool execution by writing a JSON object to stdout (command hooks) or returning it in the response body (HTTP hooks). | Field | Values | Description | |-------|--------|-------------| | `permissionDecision` | `"allow"`, `"deny"`, `"ask"` | Whether the tool executes. Empty output uses default behavior. | -| `permissionDecisionReason` | string | Reason shown to the agent. Required when decision is `"deny"`. | -| `modifiedArgs` | object | Substitute tool arguments to use instead of the originals. | +| `permissionDecisionReason` | string | Reason shown to the agent. Recommended when decision is `"deny"` or `"ask"`. | +| `modifiedArgs` | unknown | Replaces the entire tool input before execution. Only valid when `permissionDecision` is not `"deny"` or `"ask"`. | +| `additionalContext` | string | Queued as context for the next model turn. Only valid when `permissionDecision` is not `"deny"` or `"ask"`. | + +> [!NOTE] +> The {% data variables.product.prodname_vscode_shortname %} alias (`PreToolUse`) also accepts nested `hookSpecificOutput.{permissionDecision, permissionDecisionReason, updatedInput, additionalContext}`. `updatedInput` is normalized to `modifiedArgs`. Top-level fields are accepted as a fallback. ### `agentStop` / `subagentStop` decision control @@ -774,7 +854,7 @@ Output JSON to stdout to control the permission decision: | `message` | string | Reason fed back to the LLM when denying. | | `interrupt` | boolean | When `true` combined with `"deny"`, stops the agent entirely. | -Return empty output or `{}` to fall through to the default behavior (show the user dialog, or deny in pipe mode). Exit code `2` is treated as a deny; if the hook also outputs JSON on stdout, those fields are merged with the deny decision. +Return empty output or `{}` to fall through to the default behavior (show the user dialog, or deny in pipe mode). For command hooks, exit code `2` is treated as a deny; stdout JSON (if any) is merged with `{"behavior":"deny"}`, and stderr is ignored. ### `notification` hook @@ -831,7 +911,7 @@ If `additionalContext` is returned, the text is injected into the session as a p | `web_fetch` | Fetch web pages. | | `task` | Run subagent tasks. | -If multiple hooks of the same type are configured, they execute in order. For `preToolUse`, if any hook returns `"deny"`, the tool is blocked. For `postToolUseFailure` command hooks, exiting with code `2` causes stderr to be returned as recovery guidance for the assistant. Hook failures (non-zero exit codes or timeouts) are logged and skipped—they never block agent execution. +If multiple hooks of the same type are configured, they execute in order. For `preToolUse`, if any hook returns `"deny"`, the tool is blocked. Exit codes apply to command hooks only—for HTTP hooks, see the [HTTP hook failure semantics](#http-hook-failure-semantics). For `postToolUseFailure` command hooks, exiting with code `2` causes stderr to be returned as recovery guidance for the assistant. For `permissionRequest` command hooks, exit code `2` is treated as a deny; stdout JSON (if any) is merged with `{"behavior":"deny"}`, and stderr is ignored. Hook failures (non-zero exit codes or timeouts) are logged and skipped—they never block agent execution. ## MCP server configuration @@ -926,6 +1006,10 @@ The CLI includes built-in MCP servers that are available without additional setu Use `--disable-builtin-mcps` to disable all built-in servers, or `--disable-mcp-server SERVER-NAME` to disable a specific one. +### MCP server naming + +Server names can contain any printable characters, including spaces, Unicode characters, and punctuation. Control characters (U+0000–U+001F, U+007F) and the closing brace (`}`) are not allowed. Server names are used as prefixes for tool names—for example, a server named `my-server` produces tool names like `my-server-fetch`, and a server named `My Server` produces `My Server-fetch`. + ### MCP server trust levels MCP servers are loaded from multiple sources, each with a different trust level. @@ -1025,10 +1109,11 @@ Custom agents are specialized AI agents defined in Markdown files. The filename | Agent | Default model | Description | |-------|--------------|-------------| | `code-review` | claude-sonnet-4.5 | High signal-to-noise code review. Analyzes diffs for bugs, security issues, and logic errors. | -| `rubber-duck` | complementary model | Use a complementary model to provide a constructive critique of proposals, designs, implementations, or tests. Identifies weak points and suggests improvements. {% data reusables.copilot.experimental %} | +| `configure-copilot` | varies | Built-in sub-agent for managing {% data variables.copilot.copilot_cli_short %} configuration through natural language—adding MCP servers, installing agents, and managing skills. {% data reusables.copilot.experimental %} | | `explore` | claude-haiku-4.5 | Fast codebase exploration. Searches files, reads code, and answers questions. Returns focused answers under 300 words. Safe to run in parallel. | | `general-purpose` | claude-sonnet-4.5 | Full-capability agent for complex multi-step tasks. Runs in a separate context window. | | `research` | claude-sonnet-4.6 | Deep research agent. Generates a report based on information in your codebase, in relevant repositories, and on the web. | +| `rubber-duck` | complementary model | Use a complementary model to provide a constructive critique of proposals, designs, implementations, or tests. Identifies weak points and suggests improvements. When using Claude, it uses a GPT model; when using GPT, it uses Claude Opus 4.7. Never makes direct code changes. {% data reusables.copilot.experimental %} | | `task` | claude-haiku-4.5 | Command execution (tests, builds, lints). Returns brief summary on success, full output on failure. | ### Custom agent frontmatter fields diff --git a/content/copilot/reference/copilot-cli-reference/cli-config-dir-reference.md b/content/copilot/reference/copilot-cli-reference/cli-config-dir-reference.md index f38583eb411a..86cac1f7af4e 100644 --- a/content/copilot/reference/copilot-cli-reference/cli-config-dir-reference.md +++ b/content/copilot/reference/copilot-cli-reference/cli-config-dir-reference.md @@ -23,7 +23,7 @@ The `~/.copilot` directory contains the following top-level items. | Path | Type | Description | |------|------|-------------| -| `config.json` | File | Your personal configuration settings | +| `settings.json` | File | Your personal configuration settings | | `copilot-instructions.md` | File | Personal custom instructions (applied to all sessions) | | `instructions/` | Directory | Additional personal `*.instructions.md` files | | `mcp-config.json` | File | User-level MCP server definitions | @@ -46,10 +46,13 @@ The `~/.copilot` directory contains the following top-level items. The following files are designed to be edited by you directly, or managed through CLI commands. -### `config.json` +### `settings.json` This is the primary configuration file for {% data variables.copilot.copilot_cli_short %}. You can edit it directly in a text editor, or use interactive commands like `/model` and `/theme` to change specific values from within a session. The file supports JSON with comments (JSONC). +> [!NOTE] +> The configuration file was renamed from `config.json` to `settings.json`. Existing settings are automatically migrated from `~/.copilot/config.json` on startup. + For the full list of settings and how they interact with repository-level configuration, see [Configuration file settings](#configuration-file-settings) later in this article. > [!TIP] @@ -91,7 +94,7 @@ For more information, see [AUTOTITLE](/copilot/how-tos/copilot-cli/customize-cop ### `hooks/` -Store user-level hook scripts here. These hooks apply to all your sessions. You can also define hooks inline in `config.json` using the `hooks` key. Repository-level hooks (in `.github/hooks/`) are loaded alongside user-level hooks. +Store user-level hook scripts here. These hooks apply to all your sessions. You can also define hooks inline in your user configuration file (`~/.copilot/config.json`) using the `hooks` key. Repository-level hooks (in `.github/hooks/`) are loaded alongside user-level hooks. For more information, see [AUTOTITLE](/copilot/how-tos/copilot-cli/customize-copilot/use-hooks). @@ -168,17 +171,17 @@ The `--config-dir` option takes precedence over `COPILOT_HOME`, which in turn ta | Item | Safe to delete? | Effect | |------|-----------------|--------| +| `agents/`, `skills/`, `hooks/` | Not recommended | You will lose your personal customizations. Back up first. | +| `copilot-instructions.md`, `instructions/` | Not recommended | You will lose your personal custom instructions. Back up first. | +| `installed-plugins/` | Not recommended | Use `copilot plugin uninstall` instead, to ensure plugin metadata in `settings.json` stays consistent. | | `logs/` | Yes | Log files are re-created each session. Deleting them has no functional impact. | +| `lsp-config.json` | Not recommended | You will lose your user-level LSP server definitions. Back up first. | +| `mcp-config.json` | Not recommended | You will lose your user-level MCP server definitions. Back up first. | +| `permissions-config.json` | With caution | Resets all saved permissions. The CLI will prompt you again for tool and directory approvals. | | `plugin-data/` | Yes | Plugin persistent data is re-created as needed. | | `session-state/` | With caution | Deleting removes session history. You will no longer be able to resume past sessions. | | `session-store.db` | With caution | Deleting removes cross-session data. The file is re-created automatically. | -| `config.json` | With caution | Resets all configuration to defaults. You will need to reconfigure your preferences and re-authenticate. | -| `permissions-config.json` | With caution | Resets all saved permissions. The CLI will prompt you again for tool and directory approvals. | -| `installed-plugins/` | Not recommended | Use `copilot plugin uninstall` instead, to ensure plugin metadata in `config.json` stays consistent. | -| `mcp-config.json` | Not recommended | You will lose your user-level MCP server definitions. Back up first. | -| `lsp-config.json` | Not recommended | You will lose your user-level LSP server definitions. Back up first. | -| `copilot-instructions.md`, `instructions/` | Not recommended | You will lose your personal custom instructions. Back up first. | -| `agents/`, `skills/`, `hooks/` | Not recommended | You will lose your personal customizations. Back up first. | +| `settings.json` | With caution | Resets all configuration to defaults. You will need to reconfigure your preferences and re-authenticate. | ## Configuration file settings @@ -186,11 +189,11 @@ Settings cascade from user to repository to local, with more specific scopes ove | Scope | Location | Purpose | |-------|----------|---------| -| User | `~/.copilot/config.json` | Global defaults for all repositories. Use the `COPILOT_HOME` environment variable to specify an alternative path. | +| User | `~/.copilot/settings.json` | Global defaults for all repositories. Use the `COPILOT_HOME` environment variable to specify an alternative path. | | Repository | `.github/copilot/settings.json` | Shared repository configuration (committed to the repository). | | Local | `.github/copilot/settings.local.json` | Personal overrides (add this to `.gitignore`). | -### User settings (`~/.copilot/config.json`) +### User settings (`~/.copilot/settings.json`) These settings apply across all your sessions and repositories. You can edit this file directly, or use slash commands to update individual values. diff --git a/content/copilot/reference/copilot-cli-reference/cli-programmatic-reference.md b/content/copilot/reference/copilot-cli-reference/cli-programmatic-reference.md index 90d2f5b6b8c1..2a1fa0ce2b46 100644 --- a/content/copilot/reference/copilot-cli-reference/cli-programmatic-reference.md +++ b/content/copilot/reference/copilot-cli-reference/cli-programmatic-reference.md @@ -119,12 +119,12 @@ copilot -p "Fix the race condition in the worker pool" \ Alternatively, you can set the `COPILOT_MODEL` environment variable to specify a model for the duration of the shell session. -To persist a model selection across shell sessions, you can set the `model` key in the CLI configuration file. This file is located at `~/.copilot/config.json` (or `$COPILOT_HOME/.copilot/config.json` if you have set the `COPILOT_HOME` environment variable). Some models also allow you to set a reasoning effort level, which controls how much time the model spends thinking before responding. +To persist a model selection across shell sessions, you can set the `model` key in the CLI configuration file. This file is located at `~/.copilot/settings.json` (or `$COPILOT_HOME/settings.json` if you have set the `COPILOT_HOME` environment variable). Some models also allow you to set a reasoning effort level, which controls how much time the model spends thinking before responding. ```json copy { "model": "gpt-5.3-codex", - "reasoning_effort": "low" + "effortLevel": "low" } ``` @@ -138,7 +138,7 @@ When determining which model to use for a given prompt, the CLI checks for model * Where a custom agent is used: the model specified in the custom agent definition (if any). * The `--model` command line option. * The `COPILOT_MODEL` environment variable. -* The `model` key in the configuration file (`~/.copilot/config.json` or `$COPILOT_HOME/.copilot/config.json`). +* The `model` key in the configuration file (`~/.copilot/settings.json` or `$COPILOT_HOME/settings.json`). * The CLI's default model. ## Using custom agents From edd75bacdeade46feb8224b02fa0d8dd4a822c8b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 Apr 2026 09:06:23 -0700 Subject: [PATCH 2/3] Bump liquidjs from 10.25.5 to 10.25.7 in the npm_and_yarn group across 1 directory (#60945) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index fc0dc0c3b7f9..c98c68f86116 100644 --- a/package-lock.json +++ b/package-lock.json @@ -67,7 +67,7 @@ "javascript-stringify": "^2.1.0", "js-cookie": "^3.0.5", "js-yaml": "^4.1.1", - "liquidjs": "^10.25.5", + "liquidjs": "^10.25.7", "lodash": "^4.18.0", "lodash-es": "^4.18.0", "lowdb": "7.0.1", @@ -11047,9 +11047,9 @@ } }, "node_modules/liquidjs": { - "version": "10.25.5", - "resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-10.25.5.tgz", - "integrity": "sha512-GKiKeZjJDdVoQAu+S9rzkYsYnYhcep5W3WwZXgb5f+yq484P/k9JqamBbGYu+LBEixcUAXZr2jogdAIjB3ki1w==", + "version": "10.25.7", + "resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-10.25.7.tgz", + "integrity": "sha512-rPCjJLiD4eDhQjvv964AeXFC+HbeYBbZrd7Z82Q6hqv1lX7G+5w4SJcKLn9CAAAwHI4aS3dTdo083UB79K3pDA==", "license": "MIT", "dependencies": { "commander": "^10.0.0" diff --git a/package.json b/package.json index c428df1c2ec0..d783b2822961 100644 --- a/package.json +++ b/package.json @@ -227,7 +227,7 @@ "javascript-stringify": "^2.1.0", "js-cookie": "^3.0.5", "js-yaml": "^4.1.1", - "liquidjs": "^10.25.5", + "liquidjs": "^10.25.7", "lodash": "^4.18.0", "lodash-es": "^4.18.0", "lowdb": "7.0.1", From f9a695878128ac2c7bad4efb7456b29200fe366b Mon Sep 17 00:00:00 2001 From: docs-bot <77750099+docs-bot@users.noreply.github.com> Date: Fri, 24 Apr 2026 09:51:34 -0700 Subject: [PATCH 3/3] GraphQL schema update (#60948) Co-authored-by: github-merge-queue <118344674+github-merge-queue@users.noreply.github.com> --- src/graphql/data/fpt/changelog.json | 17 ++++++++++++ src/graphql/data/fpt/schema.docs.graphql | 24 ++++++++++++++-- src/graphql/data/fpt/schema.json | 34 +++++++++++++++++++++++ src/graphql/data/ghec/schema.docs.graphql | 24 ++++++++++++++-- src/graphql/data/ghec/schema.json | 34 +++++++++++++++++++++++ 5 files changed, 129 insertions(+), 4 deletions(-) diff --git a/src/graphql/data/fpt/changelog.json b/src/graphql/data/fpt/changelog.json index b13623c09d0c..b7f137b2afcd 100644 --- a/src/graphql/data/fpt/changelog.json +++ b/src/graphql/data/fpt/changelog.json @@ -1,4 +1,21 @@ [ + { + "schemaChanges": [ + { + "title": "The GraphQL schema includes these changes:", + "changes": [ + "

Type TeamReviewRequestable was added

", + "

Field id was added to interface TeamReviewRequestable

", + "

Field name was added to interface TeamReviewRequestable

", + "

Field slug was added to interface TeamReviewRequestable

", + "

Team object implements TeamReviewRequestable interface

" + ] + } + ], + "previewChanges": [], + "upcomingChanges": [], + "date": "2026-04-24" + }, { "schemaChanges": [ { diff --git a/src/graphql/data/fpt/schema.docs.graphql b/src/graphql/data/fpt/schema.docs.graphql index 5e2e270c40dd..01dad0baa560 100644 --- a/src/graphql/data/fpt/schema.docs.graphql +++ b/src/graphql/data/fpt/schema.docs.graphql @@ -56319,7 +56319,7 @@ input RequestReviewsInput { """ The Node IDs of the team to request. """ - teamIds: [ID!] @possibleTypes(concreteTypes: ["Team"]) + teamIds: [ID!] @possibleTypes(concreteTypes: ["Team"], abstractType: "TeamReviewRequestable") """ Add users to the set rather than replace. @@ -62571,7 +62571,7 @@ input TagNamePatternParametersInput { """ A team of users in an organization. """ -type Team implements MemberStatusable & Node & Subscribable { +type Team implements MemberStatusable & Node & Subscribable & TeamReviewRequestable { """ A list of teams that are ancestors of this team. """ @@ -64315,6 +64315,26 @@ enum TeamReviewAssignmentAlgorithm { ROUND_ROBIN } +""" +Represents a team that can be requested to review a pull request. +""" +interface TeamReviewRequestable { + """ + The Node ID of the TeamReviewRequestable object + """ + id: ID! + + """ + The name of the team. + """ + name: String! + + """ + A unique, human-readable identifier for the team. + """ + slug: String! +} + """ The role of a user on a team. """ diff --git a/src/graphql/data/fpt/schema.json b/src/graphql/data/fpt/schema.json index 57ef4167297f..2553bb569c8d 100644 --- a/src/graphql/data/fpt/schema.json +++ b/src/graphql/data/fpt/schema.json @@ -69169,6 +69169,11 @@ "name": "Subscribable", "id": "subscribable", "href": "/graphql/reference/interfaces#subscribable" + }, + { + "name": "TeamReviewRequestable", + "id": "teamreviewrequestable", + "href": "/graphql/reference/interfaces#teamreviewrequestable" } ], "fields": [ @@ -80335,6 +80340,35 @@ } ] }, + { + "name": "TeamReviewRequestable", + "id": "teamreviewrequestable", + "href": "/graphql/reference/interfaces#teamreviewrequestable", + "description": "

Represents a team that can be requested to review a pull request.

", + "fields": [ + { + "name": "id", + "description": "

The Node ID of the TeamReviewRequestable object.

", + "type": "ID!", + "id": "id", + "href": "/graphql/reference/scalars#id" + }, + { + "name": "name", + "description": "

The name of the team.

", + "type": "String!", + "id": "string", + "href": "/graphql/reference/scalars#string" + }, + { + "name": "slug", + "description": "

A unique, human-readable identifier for the team.

", + "type": "String!", + "id": "string", + "href": "/graphql/reference/scalars#string" + } + ] + }, { "name": "TopicAuditEntryData", "id": "topicauditentrydata", diff --git a/src/graphql/data/ghec/schema.docs.graphql b/src/graphql/data/ghec/schema.docs.graphql index 5e2e270c40dd..01dad0baa560 100644 --- a/src/graphql/data/ghec/schema.docs.graphql +++ b/src/graphql/data/ghec/schema.docs.graphql @@ -56319,7 +56319,7 @@ input RequestReviewsInput { """ The Node IDs of the team to request. """ - teamIds: [ID!] @possibleTypes(concreteTypes: ["Team"]) + teamIds: [ID!] @possibleTypes(concreteTypes: ["Team"], abstractType: "TeamReviewRequestable") """ Add users to the set rather than replace. @@ -62571,7 +62571,7 @@ input TagNamePatternParametersInput { """ A team of users in an organization. """ -type Team implements MemberStatusable & Node & Subscribable { +type Team implements MemberStatusable & Node & Subscribable & TeamReviewRequestable { """ A list of teams that are ancestors of this team. """ @@ -64315,6 +64315,26 @@ enum TeamReviewAssignmentAlgorithm { ROUND_ROBIN } +""" +Represents a team that can be requested to review a pull request. +""" +interface TeamReviewRequestable { + """ + The Node ID of the TeamReviewRequestable object + """ + id: ID! + + """ + The name of the team. + """ + name: String! + + """ + A unique, human-readable identifier for the team. + """ + slug: String! +} + """ The role of a user on a team. """ diff --git a/src/graphql/data/ghec/schema.json b/src/graphql/data/ghec/schema.json index 57ef4167297f..2553bb569c8d 100644 --- a/src/graphql/data/ghec/schema.json +++ b/src/graphql/data/ghec/schema.json @@ -69169,6 +69169,11 @@ "name": "Subscribable", "id": "subscribable", "href": "/graphql/reference/interfaces#subscribable" + }, + { + "name": "TeamReviewRequestable", + "id": "teamreviewrequestable", + "href": "/graphql/reference/interfaces#teamreviewrequestable" } ], "fields": [ @@ -80335,6 +80340,35 @@ } ] }, + { + "name": "TeamReviewRequestable", + "id": "teamreviewrequestable", + "href": "/graphql/reference/interfaces#teamreviewrequestable", + "description": "

Represents a team that can be requested to review a pull request.

", + "fields": [ + { + "name": "id", + "description": "

The Node ID of the TeamReviewRequestable object.

", + "type": "ID!", + "id": "id", + "href": "/graphql/reference/scalars#id" + }, + { + "name": "name", + "description": "

The name of the team.

", + "type": "String!", + "id": "string", + "href": "/graphql/reference/scalars#string" + }, + { + "name": "slug", + "description": "

A unique, human-readable identifier for the team.

", + "type": "String!", + "id": "string", + "href": "/graphql/reference/scalars#string" + } + ] + }, { "name": "TopicAuditEntryData", "id": "topicauditentrydata",