diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a42d77f0ea6..8faa174523df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Docs changelog +**21 April 2026** + +We recently published two new guides for organizations adopting Copilot cloud agent. + +* Pre-enablement: [Building guardrails for GitHub Copilot cloud agent](https://docs.github.com/en/enterprise-cloud@latest/copilot/tutorials/cloud-agent/build-guardrails) helps you expand built-in protections to create a secure environment for agents to operate in. +* Post-enablement: [Giving GitHub Copilot cloud agent access to resources in your organization](https://docs.github.com/en/enterprise-cloud@latest/copilot/tutorials/cloud-agent/give-access-to-resources) helps you get more out of Copilot by giving it access to MCP servers and internal packages, while promoting secure, consistent practices. + +
+ **15 April 2026** LSP servers greatly improve Copilot CLI's ability to work with your code. For example, when Copilot renames a symbol throughout a project it can do this more quickly and reliably if it has access to an LSP server for the language the code is written in. diff --git a/assets/images/help/copilot/cloud-agent/open-agent-session-in-copilot-cli.png b/assets/images/help/copilot/cloud-agent/open-agent-session-in-copilot-cli.png deleted file mode 100644 index 4feaa802831e..000000000000 Binary files a/assets/images/help/copilot/cloud-agent/open-agent-session-in-copilot-cli.png and /dev/null differ diff --git a/content/copilot/concepts/agents/copilot-cli/cancel-and-roll-back.md b/content/copilot/concepts/agents/copilot-cli/cancel-and-roll-back.md new file mode 100644 index 000000000000..e25d30058598 --- /dev/null +++ b/content/copilot/concepts/agents/copilot-cli/cancel-and-roll-back.md @@ -0,0 +1,75 @@ +--- +title: Canceling a {% data variables.copilot.copilot_cli %} operation and rolling back changes +shortTitle: Cancel and roll back +intro: 'Find out about the different ways to cancel an active {% data variables.product.prodname_copilot_short %} operation, and how to roll back changes made during a session if the result isn''t what you expected.' +versions: + feature: copilot +contentType: concepts +docsTeamMetrics: + - copilot-cli +category: + - Learn about Copilot # Copilot discovery page + - Learn about Copilot CLI # Copilot CLI bespoke page +--- + +## Introduction + +When you work in an interactive {% data variables.copilot.copilot_cli_short %} session, you can press Esc or Ctrl+C to control what {% data variables.product.prodname_copilot_short %} is doing. Both keypresses can cancel operations, but they work slightly differently: + +* Ctrl+C immediately stops the current operation. +* A single Esc keypress gives you more gradual control—letting you dismiss dialogs, clear queued prompts, or cancel an operation in stages. + +If {% data variables.product.prodname_copilot_short %} has already made changes and you want to undo them, you can roll back your workspace to a previous point in the session. {% data variables.copilot.copilot_cli_short %} takes a snapshot of your workspace state each time you enter a prompt, and this allows you to rewind to an earlier state by pressing Esc twice when {% data variables.product.prodname_copilot_short %} is idle and the input area is empty. + +## What pressing Esc does in different situations + +Pressing Esc once performs different actions depending on the current state of the session: + +| Current state | What pressing Esc does | +| ------------- | ------------------------ | +| {% data variables.product.prodname_copilot_short %} is active with no queued prompts. | Cancels the running operation. | +| {% data variables.product.prodname_copilot_short %} is active and there are queued prompts. | Clears the queued prompts without stopping the current operation. | +| A dialog, overlay, or picker is open. | Closes the dialog, overlay, or picker. | +| {% data variables.product.prodname_copilot_short %} is idle. | Shows a brief reminder that pressing Esc again quickly will open the rewind picker. See [Rolling back changes](#rolling-back-changes). | + +## When to use Esc instead of Ctrl+C + +The main difference between these two ways of canceling an operation is that Esc is designed for gradual, targeted intervention, while Ctrl+C is a hard stop. + +Use Esc when you want to interact with {% data variables.product.prodname_copilot_short %} without necessarily ending the current operation. For example, if a permission dialog appears and you want to deny that specific request, pressing Esc dismisses the dialog and {% data variables.product.prodname_copilot_short %} continues working—it just won't use the tool you denied. Similarly, if you've queued follow-up prompts and want to cancel them without interrupting the work already in progress, Esc clears the queue while the current operation keeps running. Pressing Esc only cancels the operation outright if there are no dialogs open and no queued prompts to clear first. + +Use Ctrl+C when you want to stop everything at once. It immediately cancels the active operation and clears any queued prompts in a single keypress. Any file write that is already in progress will complete—files are not left corrupted mid-write—but any remaining planned changes are abandoned. Pressing Ctrl+C a second time within two seconds, when the input area is empty, exits the session entirely. + +As a rule of thumb, use Esc when you want to intervene selectively, and Ctrl+C when you want to stop and start over. + +## Rolling back changes + +While {% data variables.product.prodname_copilot_short %} is inactive and there is no text in the input area, you can press Esc twice to display a list of points in your current session that you can roll back to. Each point corresponds to a snapshot of your workspace that was taken immediately before {% data variables.product.prodname_copilot_short %} started working on the prompt shown in the list. + +For full details of how to use the double Esc keypress to roll back changes made during a session, see [AUTOTITLE](/copilot/how-tos/copilot-cli/roll-back-changes). + +> [!WARNING] +> {% data reusables.copilot.copilot-cli.cli-rewind-warning %} + +### What happens when you roll back + +When you select a snapshot from the rewind picker, the following actions occur: + +1. **Git state is restored.** The repository is checked out to the Git commit and branch recorded in the snapshot. +1. **Untracked files are cleaned.** Files that did not exist at the time of the snapshot are removed. +1. **Modified files are restored.** Files that were changed after the snapshot are reverted to their backed-up state, including permissions and staging state. +1. **Session history is truncated.** The conversation is rewound to the point where the selected snapshot was taken. All messages and tool calls that occurred after that point are removed from the session. +1. **Snapshots are removed.** The selected snapshot and all snapshots after it are permanently deleted. Only snapshots from earlier conversation steps remain available for future rewinds. +1. **Rollback confirmed.** After the rollback, {% data variables.product.prodname_copilot_short %} displays a message indicating how many files were restored. +1. **Your prompt is restored.** The prompt associated with the selected snapshot is placed in the input area. + +### Changes that can't be rolled back + +Rewind is unavailable in the following situations: + +* **Files over 10 MB.** Individual files larger than 10 MB are skipped during snapshot creation. Changes to these files are not restored during a rollback. +* **More than 500 changed files.** If more than 500 files were changed during a single step of a CLI conversation, a snapshot is not created for that step. You will not be able to roll back changes made in that step. Earlier snapshots are unaffected. + +## Further reading + +* [AUTOTITLE](/copilot/reference/copilot-cli-reference/cli-command-reference) diff --git a/content/copilot/concepts/agents/copilot-cli/index.md b/content/copilot/concepts/agents/copilot-cli/index.md index a78a8fa3a4be..4fb6f7c59556 100644 --- a/content/copilot/concepts/agents/copilot-cli/index.md +++ b/content/copilot/concepts/agents/copilot-cli/index.md @@ -8,6 +8,7 @@ versions: children: - /about-copilot-cli - /comparing-cli-features + - /cancel-and-roll-back - /about-remote-access - /about-custom-agents - /about-cli-plugins diff --git a/content/copilot/how-tos/copilot-cli/index.md b/content/copilot/how-tos/copilot-cli/index.md index 101102e16629..bb40b56de0c1 100644 --- a/content/copilot/how-tos/copilot-cli/index.md +++ b/content/copilot/how-tos/copilot-cli/index.md @@ -25,9 +25,11 @@ children: - /use-copilot-cli-agents - /administer-copilot-cli-for-your-enterprise - /speed-up-task-completion + - /roll-back-changes - /chronicle - /content/copilot/concepts/agents/copilot-cli/about-copilot-cli - /content/copilot/concepts/agents/copilot-cli/comparing-cli-features + - /content/copilot/concepts/agents/copilot-cli/cancel-and-roll-back - /content/copilot/concepts/agents/about-agent-skills - /content/copilot/concepts/agents/copilot-cli/about-cli-plugins - /content/copilot/concepts/agents/copilot-cli/autopilot diff --git a/content/copilot/how-tos/copilot-cli/roll-back-changes.md b/content/copilot/how-tos/copilot-cli/roll-back-changes.md new file mode 100644 index 000000000000..a7c47cfd1920 --- /dev/null +++ b/content/copilot/how-tos/copilot-cli/roll-back-changes.md @@ -0,0 +1,70 @@ +--- +title: Rolling back changes made during a {% data variables.copilot.copilot_cli %} session +shortTitle: Roll back changes +intro: 'Rewind your {% data variables.copilot.copilot_cli_short %} session to a previous prompt to undo changes and restore your repository to a previous state.' +versions: + feature: copilot +contentType: how-tos +category: + - Author and optimize with Copilot # Copilot discovery page + - Build with Copilot CLI # Copilot CLI bespoke page +docsTeamMetrics: + - copilot-cli +--- + +## Introduction + +When you work in an interactive {% data variables.copilot.copilot_cli_short %} session, {% data variables.product.prodname_copilot_short %} can make changes to files, run shell commands, and modify your repository. If the result isn't what you expected, you can rewind to a previous point in the session to undo those changes. + +When you enter a prompt, the first thing {% data variables.copilot.copilot_cli_short %} does is take a snapshot of your workspace state. This snapshot allows you to roll back to that point in the session if you need to. You can trigger a rewind by pressing Esc twice, or by using the `/undo` slash command. + +This article explains how to roll back changes. For more conceptual information about rewinding to an earlier point in a session, see [AUTOTITLE](/copilot/concepts/agents/copilot-cli/cancel-and-roll-back). + +## Prerequisites + +* **You must be working in a Git repository with at least one commit.** {% data variables.copilot.copilot_cli_short %} uses Git operations to track and restore workspace state. +* **A snapshot must exist.** Snapshots are created automatically at the start of each of your interactions with {% data variables.product.prodname_copilot_short %} in a CLI session. You can't roll back changes made before your first prompt in a session, or to the repository state for a step where snapshot creation was skipped, see [Changes that can't be rolled back](/copilot/concepts/agents/copilot-cli/cancel-and-roll-back#changes-that-cant-be-rolled-back). + +## Rolling back with a double Esc keypress + +> [!WARNING] +> * {% data reusables.copilot.copilot-cli.cli-rewind-warning %} +> * Rewinding cannot be undone. Once you roll back to a snapshot, all snapshots and session history after that point are permanently removed. + +When {% data variables.product.prodname_copilot_short %} has finished responding to a prompt you've entered: + +1. Make sure the input area is empty. If there's text in the input area, pressing Esc twice in quick succession clears the text. +1. Press Esc twice in quick succession to open the rewind picker. + + The rewind picker lists the available snapshots for the current session, with the most recent first. The ten most recent snapshots are displayed. If there are more than ten snapshots available you can use the arrow key to scroll down through earlier snapshots. + + For each snapshot, the beginning of the prompt you entered is shown, with an indication of how long ago you submitted it. + +1. Choose a snapshot to roll back to. This will return you to the state of the repository when you entered the associated prompt. + + > [!NOTE] + > The repository is rolled back to its state immediately before {% data variables.product.prodname_copilot_short %} started working on the prompt, not immediately after it finished working on the prompt. + + The prompt you selected is shown in the input area, so you can edit and resubmit it, if required. + +## Rolling back with the `/undo` slash command + +The `/undo` slash command, and its alias `/rewind`, provide an alternative way of opening the rewind picker. + +Both commands produce the same result that you get by pressing Esc twice when {% data variables.product.prodname_copilot_short %} is idle and there is no text in the input area. + +## Verifying the rollback + +After rolling back, you can use Git commands to verify the state of your repository and confirm that it matches your expectations. + +Typing `!` allows you to run shell commands directly from the {% data variables.copilot.copilot_cli_short %} input prompt, so you don't need to exit the CLI to check the repository state. + +| To do this | Enter this command | +| ---------- | ------------------------ | +| Check which files show as modified, staged, or untracked. | `! git status` | +| Show the SHA and commit message of the current commit. | `! git log --oneline -1` | +| Review the unstaged changes. | `! git diff` | + +## Further reading + +* [AUTOTITLE](/copilot/reference/copilot-cli-reference/cli-command-reference) diff --git a/content/copilot/how-tos/copilot-sdk/troubleshooting/sdk-and-cli-compatibility.md b/content/copilot/how-tos/copilot-sdk/troubleshooting/sdk-and-cli-compatibility.md index 5f10da7276ea..c83b556c9cbc 100644 --- a/content/copilot/how-tos/copilot-sdk/troubleshooting/sdk-and-cli-compatibility.md +++ b/content/copilot/how-tos/copilot-sdk/troubleshooting/sdk-and-cli-compatibility.md @@ -118,7 +118,6 @@ contentType: how-tos | Screen reader mode | `--screen-reader` | Accessibility | | Rich diff rendering | `--plain-diff` | Terminal rendering | | Startup banner | `--banner` | Visual element | -| Streamer mode | `/streamer-mode` | TUI display mode | | Alternate screen buffer | `--alt-screen`, `--no-alt-screen` | Terminal rendering | | Mouse support | `--mouse`, `--no-mouse` | Terminal input | | **Path/Permission Shortcuts** | | | diff --git a/content/copilot/how-tos/use-copilot-agents/cloud-agent/customize-the-agent-environment.md b/content/copilot/how-tos/use-copilot-agents/cloud-agent/customize-the-agent-environment.md index 32516b39d1ef..345cfa573aa7 100644 --- a/content/copilot/how-tos/use-copilot-agents/cloud-agent/customize-the-agent-environment.md +++ b/content/copilot/how-tos/use-copilot-agents/cloud-agent/customize-the-agent-environment.md @@ -13,7 +13,7 @@ redirect_from: - /copilot/how-tos/agents/copilot-coding-agent/customize-the-agent-environment - /copilot/how-tos/agents/coding-agent/customize-the-agent-environment contentType: how-tos -category: +category: - Configure Copilot --- @@ -110,28 +110,7 @@ In its ephemeral development environment, {% data variables.product.prodname_cop You can use a Copilot setup steps file to deterministically install tools or dependencies before {% data variables.product.prodname_copilot_short %} starts work. To do this, add `steps` to the `copilot-setup-steps` job: -```yaml -# ... - -jobs: - copilot-setup-steps: - # ... - - # You can define any steps you want, and they will run before the agent starts. - # If you do not check out your code, Copilot will do this for you. - steps: - - name: Checkout code - uses: {% data reusables.actions.action-checkout %} - - - name: Set up Node.js - uses: {% data reusables.actions.action-setup-node %} - with: - node-version: "20" - cache: "npm" - - - name: Install JavaScript dependencies - run: npm ci -``` +{% data reusables.copilot.cloud-agent.install-dependencies %} ## Upgrading to larger {% data variables.product.prodname_dotcom %}-hosted {% data variables.product.prodname_actions %} runners @@ -158,14 +137,14 @@ By default, {% data variables.product.prodname_copilot_short %} works in a stand ## Using self-hosted {% data variables.product.prodname_actions %} runners -You can run {% data variables.copilot.copilot_cloud_agent %} on self-hosted runners. You may want to do this to match how you run CI/CD workflows on {% data variables.product.prodname_actions %}, or to give {% data variables.product.prodname_copilot_short %} access to internal resources on your network. +You can run {% data variables.copilot.copilot_cloud_agent %} on self-hosted runners. You may want to do this to match how you run CI/CD workflows on {% data variables.product.prodname_actions %}, or to give {% data variables.product.prodname_copilot_short %} access to internal resources on your network. We recommend that you only use {% data variables.copilot.copilot_cloud_agent %} with ephemeral, single-use runners that are not reused for multiple jobs. Most customers set this up using ARC (Actions Runner Controller) or the {% data variables.product.prodname_actions %} Runner Scale Set Client. For more information, see [AUTOTITLE](/actions/reference/runners/self-hosted-runners#supported-autoscaling-solutions). > [!NOTE] > {% data variables.copilot.copilot_cloud_agent %} is only compatible with Ubuntu x64 and Windows 64-bit runners. Runners with macOS or other operating systems are not supported. -1. Configure network security controls for your {% data variables.product.prodname_actions %} runners to ensure that {% data variables.copilot.copilot_cloud_agent %} does not have open access to your network or the public internet. +1. Configure network security controls for your {% data variables.product.prodname_actions %} runners to ensure that {% data variables.copilot.copilot_cloud_agent %} does not have open access to your network or the public internet. You must configure your firewall to allow connections to the [standard hosts required for {% data variables.product.prodname_actions %} self-hosted runners](/actions/reference/runners/self-hosted-runners#accessible-domains-by-function), plus the following hosts: @@ -193,7 +172,7 @@ We recommend that you only use {% data variables.copilot.copilot_cloud_agent %} ## Switching {% data variables.product.prodname_copilot_short %} to a Windows development environment -By default, {% data variables.product.prodname_copilot_short %} uses an Ubuntu Linux-based development environment. +By default, {% data variables.product.prodname_copilot_short %} uses an Ubuntu Linux-based development environment. You may want to use a Windows development environment if you're building software for Windows or your repository uses a Windows-based toolchain so {% data variables.product.prodname_copilot_short %} can build your project, run tests and validate its work. diff --git a/content/copilot/how-tos/use-copilot-agents/cloud-agent/extend-cloud-agent-with-mcp.md b/content/copilot/how-tos/use-copilot-agents/cloud-agent/extend-cloud-agent-with-mcp.md index 2266a05e7389..74dd25e29fca 100644 --- a/content/copilot/how-tos/use-copilot-agents/cloud-agent/extend-cloud-agent-with-mcp.md +++ b/content/copilot/how-tos/use-copilot-agents/cloud-agent/extend-cloud-agent-with-mcp.md @@ -129,7 +129,6 @@ The [Sentry MCP server](https://github.com/getsentry/sentry-mcp) gives {% data v // We can use the $SENTRY_HOST environment variable which is passed to // the server because of the `env` value below. "args": ["@sentry/mcp-server@latest", "--host=$SENTRY_HOST"], - "tools": ["get_issue_details", "get_issue_summary"], "env": { // We can specify an environment variable value as a string... "SENTRY_HOST": "https://contoso.sentry.io", 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 b5cf739dba0b..e5d7181108e3 100644 --- a/content/copilot/reference/copilot-cli-reference/cli-command-reference.md +++ b/content/copilot/reference/copilot-cli-reference/cli-command-reference.md @@ -18,27 +18,63 @@ docsTeamMetrics: | Command | Purpose | |------------------------|----------------------------------------------------| -| `copilot` | Launch the interactive user interface. | -| `copilot help [topic]` | Display help information. Help topics include: `config`, `commands`, `environment`, `logging`, `permissions`, and `providers`. | +| `copilot` | Launch the interactive user interface. | +| `copilot help [TOPIC]` | Display help information. Help topics include: `config`, `commands`, `environment`, `logging`, `monitoring`, `permissions`, and `providers`. | | `copilot init` | Initialize {% data variables.product.prodname_copilot_short %} custom instructions for this repository. | -| `copilot update` | Download and install the latest version. | -| `copilot version` | Display version information and check for updates. | | `copilot login` | Authenticate with {% data variables.product.prodname_copilot_short %} via the OAuth device flow. Accepts `--host HOST` to specify the {% data variables.product.github %} host URL (default: `https://github.com`). | -| `copilot logout` | Sign out of {% data variables.product.github %} and remove stored credentials. | -| `copilot plugin` | Manage plugins and plugin marketplaces. | +| `copilot login` [OPTION] | Authenticate with {% data variables.product.prodname_copilot_short %} via the OAuth device flow. See [`copilot login` options](#copilot-login-options). | | `copilot mcp` | Manage MCP server configurations from the command line. | +| `copilot plugin` | Manage plugins and plugin marketplaces. | +| `copilot update` | Download and install the latest version. | +| `copilot version` | Display version information and check for updates. | + +### `copilot login` options + +| Option | Purpose | +|-------------------------|-----------------------------------------------------------------------------------------------| +| `--host HOST` | {% data variables.product.github %} host URL (default: `https://github.com`). Use this to authenticate with a {% data variables.product.prodname_ghe_cloud %} instance that uses data residency (for example, `https://example.ghe.com`). | +| `--config-dir PATH` | Set the configuration directory (default: `~/.copilot`). | + +The default authentication mode is a web-based browser flow. After completion, an authentication token is stored securely in the system credential store. If a credential store is not found, the token is stored in a plain text config file under `~/.copilot/`. + +Alternatively, {% data variables.copilot.copilot_cli_short %} will use an authentication token found in environment variables. The following are checked in order of precedence: `COPILOT_GITHUB_TOKEN`, `GH_TOKEN`, `GITHUB_TOKEN`. This method is most suitable for headless use such as automation. + +Supported token types include {% data variables.product.pat_v2_plural %} (v2 PATs) with the "Copilot Requests" permission, OAuth tokens from the {% data variables.product.prodname_copilot_short %} CLI app, and OAuth tokens from the {% data variables.product.prodname_cli %} (`gh`) app. Classic {% data variables.product.pat_generic_plural %} (`ghp_`) are not supported. + +**Examples:** + +```shell +# Authenticate with github.com +copilot login + +# Authenticate with GitHub Enterprise Cloud (data residency) +copilot login --host https://example.ghe.com + +# Use a fine-grained PAT via environment variable +COPILOT_GITHUB_TOKEN=github_pat_... copilot +``` ## Global shortcuts in the interactive interface | Shortcut | Purpose | |-------------------------------------|---------------------------------------| | `@ FILENAME` | Include file contents in the context. | -| Ctrl+X then `/` | After you have started typing a prompt, this allows you to run a slash command—for example, if you want to change the model without having to retype your prompt. | -| Esc | Cancel the current operation. | +| `# NUMBER` | Include a {% data variables.product.github %} issue or pull request in the context. | | `! COMMAND` | Execute a command in your local shell, bypassing {% data variables.product.prodname_copilot_short %}. | +| `?` | Open quick help (on an empty prompt). | +| Esc | Cancel the current operation. | | Ctrl+C | Cancel operation / clear input. Press twice to exit. | | Ctrl+D | Shutdown. | +| Ctrl+G | Edit the prompt in an external editor (`$EDITOR`). | | Ctrl+L | Clear the screen. | +| Ctrl+Enter or Ctrl+Q | Queue a message to send while the agent is busy. | +| Ctrl+R | Reverse search through command history. | +| Ctrl+V | Paste from clipboard as an attachment. | +| Ctrl+X then `/` | After you have started typing a prompt, this allows you to run a slash command—for example, if you want to change the model without having to retype your prompt. | +| Ctrl+X then `e` | Edit the prompt in an external editor (`$EDITOR`). | +| Ctrl+X then `o` | Open the most recent link from the timeline. | +| Ctrl+Z | Suspend the process to the background (Unix). | +| Shift+Enter or Option+Enter (Mac) / Alt+Enter (Windows/Linux) | Insert a newline in the input. | | Shift+Tab | Cycle between standard, plan, and autopilot mode. | ## Timeline shortcuts in the interactive interface @@ -48,6 +84,7 @@ docsTeamMetrics: | Ctrl+O | While there is nothing in the prompt input, this expands recent items in {% data variables.product.prodname_copilot_short %}'s response timeline to show more details. | | Ctrl+E | While there is nothing in the prompt input, this expands all items in {% data variables.product.prodname_copilot_short %}'s response timeline. | | Ctrl+T | Expand/collapse display of reasoning in responses. | +| Page Up/Page Down | Scroll the timeline up or down by one page. | ## Navigation shortcuts in the interactive interface @@ -57,50 +94,48 @@ docsTeamMetrics: | Ctrl+B | Move to the previous character. | | Ctrl+E | Move to end of the line (when typing). | | Ctrl+F | Move to the next character. | -| Ctrl+G | Edit the prompt in an external editor. | | Ctrl+H | Delete the previous character. | | Ctrl+K | Delete from cursor to end of the line. If the cursor is at the end of the line, delete the line break. | | Ctrl+U | Delete from cursor to beginning of the line. | | Ctrl+W | Delete the previous word. | -| Home | Move to the start of the current line. | -| End | Move to the end of the current line. | -| Ctrl+Home | Move to the start of the text. | -| Ctrl+End | Move to the end of the text. | -| Meta+/ | Move the cursor by a word. | +| Home | Move to the start of the text. | +| End | Move to the end of the text. | +| Alt+/ (Windows/Linux)
Option+/ (Mac) | Move the cursor by a word. | | / | Navigate the command history. | - ## Slash commands in the interactive interface | Command | Purpose | |-----------------------------------------------------|---------| | `/add-dir PATH` | Add a directory to the allowed list for file access. | | `/agent` | Browse and select from available agents (if any). See [AUTOTITLE](/copilot/concepts/agents/copilot-cli/about-custom-agents). | -| `/allow-all`, `/yolo` | Enable all permissions (tools, paths, and URLs). | -| `/changelog [SUMMARIZE] [VERSION]` | Display the CLI changelog with an optional AI-generated summary. | -| `/clear [PROMPT]`, `/new [PROMPT]` | Start a new conversation. | +| `/ask QUESTION` | Ask a quick side question without adding to the conversation history. {% data reusables.copilot.experimental %} | +| `/allow-all [on\|off\|show]`, `/yolo [on\|off\|show]` | Enable all permissions (tools, paths, and URLs). | +| `/changelog [summarize] [VERSION\|last N\|since VERSION]`, `/release-notes [summarize] [VERSION\|last N\|since VERSION]` | Display the CLI changelog. Optionally specify a version, a count of recent releases, or a starting version. Add the keyword `summarize` for an AI-generated summary. | +| `/chronicle ` | Session history tools and insights. {% data reusables.copilot.experimental %} | +| `/clear [PROMPT]`, `/new [PROMPT]`, `/reset [PROMPT]` | Start a new conversation. | | `/compact` | Summarize the conversation history to reduce context window usage. See [AUTOTITLE](/copilot/concepts/agents/copilot-cli/context-management#compaction). | | `/context` | Show the context window token usage and visualization. See [AUTOTITLE](/copilot/concepts/agents/copilot-cli/context-management#checking-your-context-usage). | | `/copy` | Copy the last response to the clipboard. | | `/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. | +| `/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. | -| `/feedback` | Provide feedback about the CLI. | +| `/feedback`, `/bug` | Provide feedback about the CLI. | | `/fleet [PROMPT]` | Enable parallel subagent execution of parts of a task. See [AUTOTITLE](/copilot/concepts/agents/copilot-cli/fleet). | | `/help` | Show the help for interactive commands. | | `/ide` | Connect to an IDE workspace. See [AUTOTITLE](/copilot/how-tos/copilot-cli/connecting-vs-code#managing-the-connection-with-the-ide-slash-command). | | `/init` | Initialize {% data variables.product.prodname_copilot_short %} custom instructions and agentic features for this repository. See [Project initialization for {% data variables.product.prodname_copilot_short %}](#project-initialization-for-copilot). | | `/instructions` | View and toggle custom instruction files. | -| `/keep-alive [on\|busy\|NUMBERm\|NUMBERh]` | Prevent the machine from going to sleep: while a CLI session is active, while the agent is busy, or for a defined length of time. | +| `/keep-alive [on\|busy\|NUMBERm\|NUMBERh]` | Prevent the machine from going to sleep: while a CLI session is active, while the agent is busy, or for a defined length of time. {% data reusables.copilot.experimental %} | | `/list-dirs` | Display all of the directories for which file access has been allowed. | | `/login` | Log in to {% data variables.product.prodname_copilot_short %}. | | `/logout` | Log out of {% data variables.product.prodname_copilot_short %}. | | `/lsp [show\|test\|reload\|help] [SERVER-NAME]` | Manage the language server configuration. | | `/mcp [show\|add\|edit\|delete\|disable\|enable\|auth\|reload] [SERVER-NAME]` | Manage the MCP server configuration. See [AUTOTITLE](/copilot/how-tos/copilot-cli/customize-copilot/add-mcp-servers#managing-mcp-servers). | | `/model`, `/models [MODEL]` | Select the AI model you want to use. | -| `/on-air`, `/streamer-mode` | Toggle streamer mode (hides preview model names). | | `/plan [PROMPT]` | Create an implementation plan before coding. | | `/plugin [marketplace\|install\|uninstall\|update\|list] [ARGS...]` | Manage plugins and plugin marketplaces. See [AUTOTITLE](/copilot/concepts/agents/copilot-cli/about-cli-plugins). | | `/pr [view\|create\|fix\|auto]` | Operate on pull requests for the current branch. | @@ -109,16 +144,17 @@ docsTeamMetrics: | `/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]` | Switch to a different session by choosing from a list (optionally specify a session ID). | +| `/resume [SESSION-ID]`, `/continue [SESSION-ID]` | Switch to a different session by choosing from a list (optionally specify a session ID). | | `/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]` | Show session information and a workspace summary. Use the subcommands for details. | -| `/share [file\|gist] [session\|research] [PATH]` | Share the session to a Markdown file or {% data variables.product.github %} gist. | +| `/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. | +| `/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. | | `/tasks` | View and manage background tasks (subagents and shell sessions). | | `/terminal-setup` | Configure the terminal for multiline input support (Shift+Enter and Ctrl+Enter). | -| `/theme [show\|set\|list] [auto\|THEME-ID]` | View or configure the terminal theme. | +| `/theme [default\|dim\|high-contrast\|colorblind]` | View or set the color mode. | | `/undo`, `/rewind` | Rewind the last turn and revert file changes. | -| `/update` | Update the CLI to the latest version. | +| `/update`, `/upgrade` | Update the CLI to the latest version. | | `/usage` | Display session usage metrics and statistics. | | `/user [show\|list\|switch]` | Manage the current {% data variables.product.github %} user. | | `/version` | Display version information and check for updates. | @@ -129,7 +165,6 @@ For a complete list of available slash commands enter `/help` in the CLI's inter | Option | Purpose | |------------------------------------|------------------------------------------| -| `--acp` | Start the Agent Client Protocol server. | | `--add-dir=PATH` | Add a directory to the allowed list for file access (can be used multiple times). | | `--add-github-mcp-tool=TOOL` | Add a tool to enable for the {% data variables.product.github %} MCP server, instead of the default CLI subset (can be used multiple times). Use `*` for all tools. | | `--add-github-mcp-toolset=TOOLSET` | Add a toolset to enable for the {% data variables.product.github %} MCP server, instead of the default CLI subset (can be used multiple times). Use `all` for all toolsets. | @@ -143,15 +178,15 @@ For a complete list of available slash commands enter `/help` in the CLI's inter | `--allow-url=URL ...` | Allow access to specific URLs or domains. For multiple URLs, use a quoted, comma-separated list. | | `--autopilot` | Enable autopilot continuation in prompt mode. See [AUTOTITLE](/copilot/concepts/agents/copilot-cli/autopilot). | | `--available-tools=TOOL ...` | Only these tools will be available to the model. For multiple tools, use a quoted, comma-separated list. See [AUTOTITLE](/copilot/how-tos/copilot-cli/allowing-tools). | -| `--banner` | Show the startup banner. | +| `--banner`, `--no-banner` | Show or hide the startup banner. | | `--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. | | `--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`). | | `--disable-mcp-server=SERVER-NAME` | Disable a specific MCP server (can be used multiple times). | -| `--disable-parallel-tools-execution` | Disable parallel execution of tools (LLM can still make parallel tool calls, but they will be executed sequentially). | | `--disallow-temp-dir` | Prevent automatic access to the system temporary directory. | | `--effort=LEVEL`, `--reasoning-effort=LEVEL` | Set the reasoning effort level (`low`, `medium`, `high`). | | `--enable-all-github-mcp-tools` | Enable all {% data variables.product.github %} MCP server tools, instead of the default CLI subset. Overrides the `--add-github-mcp-toolset` and `--add-github-mcp-tool` options. | @@ -164,7 +199,7 @@ For a complete list of available slash commands enter `/help` in the CLI's inter | `--log-level=LEVEL` | Set the log level (choices: `none`, `error`, `warning`, `info`, `debug`, `all`, `default`). | | `--max-autopilot-continues=COUNT` | Maximum number of continuation messages in autopilot mode (default: unlimited). See [AUTOTITLE](/copilot/concepts/agents/copilot-cli/autopilot). | | `--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. | +| `--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.| | `--no-ask-user` | Disable the `ask_user` tool (the agent works autonomously without asking questions). | | `--no-auto-update` | Disable downloading CLI updates automatically. | @@ -180,7 +215,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). | +| `--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). | | `-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. | @@ -193,11 +228,11 @@ For a complete list of available slash commands enter `/help` in the CLI's inter For a complete list of commands and options, run `copilot help`. > [!NOTE] -> The `--remote` and `--no-remote` options require the remote sessions feature to be available on your account. +> The `--remote`, `--no-remote`, and `--connect` options require the remote sessions feature to be available on your account. ## Tool availability values -The `--available-tools` and `--excluded-tools` options support the following values for specifying tools: +The `--available-tools` and `--excluded-tools` options support these values: ### Shell tools @@ -222,7 +257,7 @@ The `--available-tools` and `--excluded-tools` options support the following val | Tool name | Description | |---|---| -| `task` | Run sub-agents | +| `task` | Run subagents | | `read_agent` | Check background agent status | | `list_agents` | List available agents | @@ -235,15 +270,6 @@ The `--available-tools` and `--excluded-tools` options support the following val | `web_fetch` | Fetch and parse web content | | `skill` | Invoke custom skills | | `ask_user` | Ask the user a question | -| `report_intent` | Report what the agent plans to do | -| `show_file` | Display a file prominently | -| `fetch_copilot_cli_documentation` | Look up CLI documentation | -| `update_todo` | Update task checklist | -| `store_memory` | Persist facts across sessions | -| `task_complete` | Signal task is done (autopilot only) | -| `exit_plan_mode` | Exit plan mode | -| `sql` | Query session data (experimental) | -| `lsp` | Language server refactoring (experimental) | ## Tool permission patterns @@ -293,7 +319,6 @@ copilot --allow-tool='MyMCP' | `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. | -| `COPILOT_CLI_ENABLED_FEATURE_FLAGS` | Comma-separated list of feature flags to enable (for example, `"SOME_FEATURE,SOME_OTHER_FEATURE"`). | ## Configuration file settings @@ -309,7 +334,7 @@ Settings cascade from user to repository to local, with more specific scopes ove | Key | Type | Default | Description | |-----|------|---------|-------------| -| `allowed_urls` | `string[]` | `[]` | URLs or domains allowed without prompting. | +| `allowedUrls` | `string[]` | `[]` | URLs or domains allowed without prompting. | | `autoUpdate` | `boolean` | `true` | Automatically download CLI updates. | | `banner` | `"always"` \| `"once"` \| `"never"` | `"once"` | Animated banner display frequency. | | `bashEnv` | `boolean` | `false` | Enable `BASH_ENV` support for bash shells. | @@ -317,36 +342,41 @@ Settings cascade from user to repository to local, with more specific scopes ove | `compactPaste` | `boolean` | `true` | Collapse large pastes into compact tokens. | | `custom_agents.default_local_only` | `boolean` | `false` | Only use local custom agents. | | `denied_urls` | `string[]` | `[]` | URLs or domains blocked (takes precedence over `allowed_urls`). | -| `enabledFeatureFlags` | `object` | — | Enable or disable individual feature flags. Keys are flag names; values are `true` (enable) or `false` (explicitly disable). Takes precedence over the legacy `feature_flags.enabled` array format. See [Feature flag reference](#feature-flag-reference). | | `experimental` | `boolean` | `false` | Enable experimental features. | | `includeCoAuthoredBy` | `boolean` | `true` | Add a `Co-authored-by` trailer to git commits made by the agent. | | `companyAnnouncements` | `string[]` | `[]` | Custom messages shown randomly on startup. | | `logLevel` | `"none"` \| `"error"` \| `"warning"` \| `"info"` \| `"debug"` \| `"all"` \| `"default"` | `"default"` | Logging verbosity. | -| `model` | `string` | varies | AI model to use (see the `/model` command). | +| `model` | `string` | varies | AI model to use (see the `/model` command). Set to `"auto"` to let {% data variables.product.prodname_copilot_short %} pick the best available model automatically. | | `powershellFlags` | `string[]` | `["-NoProfile", "-NoLogo"]` | Flags passed to PowerShell (`pwsh`) on startup. Windows only. | | `effortLevel` | `string` | `"medium"` | Reasoning effort level for extended thinking (e.g., `"low"`, `"medium"`, `"high"`, `"xhigh"`). Higher levels use more compute. | +| `mergeStrategy` | `"rebase"` \| `"merge"` | — | Conflict resolution strategy for `/pr fix conflicts`. When set to `"rebase"`, conflicts are resolved by rebasing onto the base branch. When set to `"merge"`, the base branch is merged into the feature branch. If not configured, a picker dialog is shown. | | `renderMarkdown` | `boolean` | `true` | Render Markdown in terminal output. | | `screenReader` | `boolean` | `false` | Enable screen reader optimizations. | | `stream` | `boolean` | `true` | Enable streaming responses. | | `storeTokenPlaintext` | `boolean` | `false` | Store authentication tokens in plain text in the configuration file when no system keychain is available. | | `streamerMode` | `boolean` | `false` | Hide preview model names and quota details (useful when demonstrating {% data variables.copilot.copilot_cli_short %}). | | `theme` | `"auto"` \| `"dark"` \| `"light"` | `"auto"` | Terminal color theme. | -| `trusted_folders` | `string[]` | `[]` | Folders with pre-granted file access. | | `mouse` | `boolean` | `true` | Enable mouse support in alt screen mode. | | `respectGitignore` | `boolean` | `true` | Exclude gitignored files from the `@` file picker. | | `disableAllHooks` | `boolean` | `false` | Disable all hooks. | | `hooks` | `object` | — | Inline user-level hook definitions. | +| `copyOnSelect` | `boolean` | `true` (macOS), `false` (other) | Automatically copy mouse-selected text to the system clipboard in alt screen mode. | +| `statusLine` | `object` | — | Custom status line display. `type`: must be `"command"`. `command`: path to a script that receives session JSON on stdin and prints status content to stdout. `padding`: optional left-padding spaces. | +| `suppress_init_folders` | `string[]` | `[]` | Folders where the `/init` suggestion has been dismissed. Managed automatically by `/init suppress`. | | `updateTerminalTitle` | `boolean` | `true` | Show the current intent in the terminal title. | ### Repository settings (`.github/copilot/settings.json`) -Repository settings apply to everyone who works in the repository. Only a subset of settings is supported at the repository level. Unsupported keys are ignored. +Repository settings apply to everyone who works in the repository. Only the keys listed in the following table are supported at the repository level. Any other keys—including keys that are valid in the user configuration file—are silently ignored. | Key | Type | Merge behavior | Description | |-----|------|---------------|-------------| | `companyAnnouncements` | `string[]` | Replaced—repository takes precedence | Messages shown randomly on startup. | +| `disableAllHooks` | `boolean` | Repository takes precedence | Disable all hooks. | | `enabledPlugins` | `Record` | Merged—repository overrides user for same key | Declarative plugin auto-install. | | `extraKnownMarketplaces` | `Record` | Merged—repository overrides user for same key | Plugin marketplaces available in this repository. | +| `hooks` | `object` | Concatenated—repository hooks run after user hooks | Hook definitions scoped to this repository. See [Hooks reference](#hooks-reference). | +| `mergeStrategy` | `"rebase"` \| `"merge"` | Repository takes precedence | Conflict resolution strategy for `/pr fix conflicts`. | ### Local settings (`.github/copilot/settings.local.json`) @@ -830,7 +860,7 @@ The `notification` hook fires asynchronously when the CLI emits a system notific |------|---------------| | `shell_completed` | A background (async) shell command finishes | | `shell_detached_completed` | A detached shell session completes | -| `agent_completed` | A background sub-agent finishes (completed or failed) | +| `agent_completed` | A background subagent finishes (completed or failed) | | `agent_idle` | A background agent finishes a turn and enters idle state (waiting for `write_agent`) | | `permission_prompt` | The agent requests permission to execute a tool | | `elicitation_dialog` | The agent requests additional information from the user | @@ -970,6 +1000,27 @@ MCP servers are loaded from multiple sources, each with a different trust level. All MCP tool invocations require explicit permission. This applies even to read-only operations on external services. +### Enterprise MCP allowlist + +{% data variables.product.prodname_enterprise %} organizations can enforce an allowlist of permitted MCP servers. When active, the CLI evaluates each non-default server against the enterprise policy before connecting. + +When a {% data variables.product.prodname_enterprise %} registry policy is detected (or the `MCP_ENTERPRISE_ALLOWLIST` experimental feature flag is enabled), the CLI: + +1. Computes a fingerprint for each configured non-default server based on its command, arguments, and remote URL. +1. Sends the fingerprints to the enterprise allowlist evaluate endpoint. +1. Allows only servers whose fingerprints are approved; all others are blocked with a message naming the enterprise. + +This check is fail-closed: if the evaluate endpoint is unreachable or returns an error, non-default servers are blocked until the policy can be verified. + +When a server is blocked by an enterprise allowlist, the CLI displays: + +```text +MCP server "SERVER-NAME" was blocked by your enterprise "ENTERPRISE-NAME". +Contact your enterprise administrator to add this server to the allowlist. +``` + +Built-in default servers are always exempt from allowlist enforcement. + ### Migrating from `.vscode/mcp.json` If your project uses `.vscode/mcp.json` (VS Code's MCP configuration format), migrate to `.mcp.json` for {% data variables.copilot.copilot_cli %}. The migration remaps the `servers` key to `mcpServers`. @@ -1034,7 +1085,7 @@ 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. Only available in experimental mode. | +| `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 %} | | `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. | @@ -1047,7 +1098,7 @@ Custom agents are specialized AI agents defined in Markdown files. The filename | `description` | string | Yes | Description shown in the agent list and `task` tool. | | `infer` | boolean | No | Allow auto-delegation by the main agent. Default: `true`. | | `mcp-servers` | object | No | MCP servers to connect. Uses the same schema as `~/.copilot/mcp-config.json`. | -| `model` | string | No | AI model for this agent. When unset, inherits the outer agent's model. | +| `model` | string | No | AI model for this agent. When unset, inherits the outer agent's model. When the session model is set to `Auto` (server-selected), subagents always inherit the resolved session model regardless of this field. | | `name` | string | No | Display name. Defaults to the filename. | | `tools` | string[] | No | Tools available to the agent. Default: `["*"]` (all tools). | @@ -1258,39 +1309,6 @@ When content capture is enabled, the following attributes are populated. | `gen_ai.tool.call.arguments` | Tool input arguments | | `gen_ai.tool.call.result` | Tool output | -## Feature flag reference - -Feature flags enable functionality that is not yet generally available. You can enable or disable individual flags in three ways: - -* **Environment variable**: Set `COPILOT_CLI_ENABLED_FEATURE_FLAGS` to a comma-separated list of flag names (for example, `"SOME_FEATURE,SOME_OTHER_FEATURE"`). -* **Slash command**: Use `/experimental on` in an interactive session to enable all experimental-tier flags. -* **Configuration file**: Add an `enabledFeatureFlags` object to `~/.copilot/config.json`. Set a flag to `true` to enable it or `false` to explicitly disable a flag that would otherwise be enabled by your tier. - -```json -{ - "enabledFeatureFlags": { - "SOME_FEATURE": true, - "SOME_OTHER_FEATURE": false - } -} -``` - -> [!NOTE] -> The legacy `feature_flags.enabled` array format is still supported as a fallback, but `enabledFeatureFlags` takes precedence when both are present. - -| Flag | Tier | Description | -|------|------|-------------| -| `RUBBER_DUCK_AGENT` | experimental | Rubber-duck subagent for adversarial feedback on code and designs | -| `BACKGROUND_SESSIONS` | experimental | Multiple concurrent sessions with background management | -| `MULTI_TURN_AGENTS` | experimental | Multi-turn subagent message passing via `write_agent` | -| `EXTENSIONS` | experimental | Programmatic extensions with custom tools and hooks | -| `QUEUED_COMMANDS` | staff-or-experimental | Queue commands with Ctrl+Enter while the agent runs | -| `PERSISTED_PERMISSIONS` | staff-or-experimental | Persist tool permissions across sessions per location | -| `SESSION_STORE` | staff-or-experimental | SQLite-based session store for cross-session history | -| `COMPUTER_USE` | staff | Built-in computer use MCP server (screen capture and mouse/keyboard control) | -| `copilot-feature-agentic-memory` | on | Persistent memory tools across sessions | -| `COPILOT_SWE_AGENT_BACKGROUND_AGENTS` | on | Background agent task execution | - ## Further reading * [AUTOTITLE](/copilot/how-tos/copilot-cli) 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 ca501b9c5a83..eb1e976572ab 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 @@ -50,7 +50,7 @@ Common settings include: | Key | Type | Description | |-----|------|-------------| -| `model` | string | AI model to use (e.g., `"gpt-5.2"`, `"claude-sonnet-4.6"`) | +| `model` | string | AI model to use (for example, `"gpt-5.2"`, `"claude-sonnet-4.6"`). Set to `Auto` to let {% data variables.product.prodname_copilot_short %} pick the best available model automatically. | | `effortLevel` | string | Reasoning effort level for models that support it | | `theme` | string | Color theme: `"auto"`, `"dark"`, or `"light"` | | `mouse` | boolean | Enable mouse support in alt screen mode (default: `true`) | @@ -61,9 +61,8 @@ Common settings include: | `stream` | boolean | Stream responses token by token (default: `true`) | | `includeCoAuthoredBy` | boolean | Add Co-authored-by to agent-created commits (default: `true`) | | `respectGitignore` | boolean | Exclude gitignored files from the `@` file picker (default: `true`) | -| `trusted_folders` | string[] | Folders where read/execute permission has been granted | -| `allowed_urls` | string[] | URLs or domains allowed without prompting | -| `denied_urls` | string[] | URLs or domains that are always denied | +| `allowedUrls` | string[] | URLs or domains allowed without prompting | +| `deniedUrls` | string[] | URLs or domains that are always denied | | `logLevel` | string | Log verbosity: `"none"`, `"error"`, `"warning"`, `"info"`, `"debug"`, `"all"`, or `"default"` (default: `"default"`) | | `disableAllHooks` | boolean | Disable all hooks (default: `false`) | | `hooks` | object | Inline user-level hook definitions | diff --git a/content/copilot/reference/review-excluded-files.md b/content/copilot/reference/review-excluded-files.md index 854f260d1b23..be94825f4416 100644 --- a/content/copilot/reference/review-excluded-files.md +++ b/content/copilot/reference/review-excluded-files.md @@ -79,6 +79,9 @@ Files matching these patterns are also excluded: * `**/*.map` * `**/out/**/*` * `**/vendor/**/*` -* `**/bin/**/*` * `**/generated/**/*` * `**/generated-sources/**/*` +* `**/bin/**/*` + + > [!NOTE] + > Rust files matching `**/bin/**/*.rs` _are_ included for review. diff --git a/content/copilot/tutorials/cloud-agent/give-access-to-resources.md b/content/copilot/tutorials/cloud-agent/give-access-to-resources.md new file mode 100644 index 000000000000..a5ecda353f19 --- /dev/null +++ b/content/copilot/tutorials/cloud-agent/give-access-to-resources.md @@ -0,0 +1,104 @@ +--- +title: 'Giving GitHub Copilot cloud agent access to resources in your organization' +shortTitle: 'Give access to resources' +intro: 'Get more out of {% data variables.product.prodname_copilot_short %} by giving it access to approved MCP servers and internal packages.' +versions: + feature: copilot +contentType: tutorials +category: + - Manage Copilot for a team + - Roll Copilot out at scale +--- + +{% data variables.copilot.copilot_cloud_agent %} can connect to MCP servers, use private packages, and access external services, but only if your organization's repositories are configured to allow it. + +Although much of the configuration below is done at the repository level, organization owners have control over which resources are in scope and who can configure access to them. + +## Example scenario + +Your organization uses Sentry to track bugs in your Node app. New exceptions are raised as issues on {% data variables.product.github %}, and your developers want to assign these issues to {% data variables.product.prodname_copilot_short %}. + +You want {% data variables.product.prodname_copilot_short %} to: + +* Connect to the Sentry MCP server so it can access details on your Sentry instance +* Install dependencies, including private packages hosted on {% data variables.product.github %}, to build your app and run tests +* Follow your organization's conventions for error-handling + +## Storing secrets securely + +By default, the scope of {% data variables.product.prodname_copilot_short %}'s authentication token is limited to the repository where it's running. This means that {% data variables.product.prodname_copilot_short %} won't be able to authenticate to external systems or access private, organization-scoped packages. + +Repository administrators should add variables and secrets that {% data variables.product.prodname_copilot_short %} requires to a dedicated `copilot` {% data variables.product.prodname_actions %} environment. {% data variables.product.prodname_copilot_short %} can access this data in its setup and task execution. It won't be able to access variables or secrets outside this environment, such as organization-wide {% data variables.product.prodname_actions %} secrets. + +### Example: Save a secret + +A repository administrator saves an authentication token for the organization's Sentry instance. + +1. Go to the **Environments** section of the repository settings. +1. Create a new environment called `copilot`. +1. Save an access token for your Sentry instance in an environment secret called `COPILOT_MCP_SENTRY_ACCESS_TOKEN`. + +> [!TIP] We don't need to save a token for our private {% data variables.product.prodname_registry %} registry, which we'll access using the standard {% data variables.product.prodname_actions %} `GITHUB_TOKEN`. However, you would want to save an authentication token if you were using an external package registry. + +## Configuring access to MCP servers + +Organization and enterprise owners can set a policy to allow users to configure access to MCP servers. If this policy is enabled, users can configure MCP servers for {% data variables.copilot.copilot_cloud_agent %} in repository settings or in custom agent profiles. For organization-wide consistency, we recommend creating **custom agent profiles** at the organization or enterprise level. + +A session using a custom agent has access to MCP servers configured in **both** the repository settings and the agent profile. However, the more use cases you cover with organization-wide custom agents, the less users will need to configure ad hoc access to MCP servers in repository settings. + +We recommend browsing the [{% data variables.product.github %} MCP Registry](https://github.com/mcp) to find trusted, highly rated options. + +### Example: Create a custom agent + +An organization owner creates a custom agent profile for the Sentry agent. It has access to the Sentry MCP server and custom instructions for the organization's error-handling conventions. + +1. Create a repository called `.github-private` in your organization. Optionally, an enterprise owner can set this repository as the source for all custom agents in the enterprise. +1. In the repository, add an `agent.md` file with a profile like the following. This includes configuration for the MCP server, which references the secret we saved. + + ``` text + --- + name: sentry-error-fixer + description: Proposed fixes for exception issues raised from Sentry + mcp-servers: + sentry: + type: 'local' + command: 'npx' + args: ['@sentry/mcp-server@latest'] + env: + SENTRY_ACCESS_TOKEN: {% raw %}${{ secrets.COPILOT_MCP_SENTRY_ACCESS_TOKEN }}{% endraw %} + --- + + You are an error resolution specialist. When you're assigned an issue created by our Sentry integration, check for error details and stack traces using the MCP server, then propose a fix. + + Make sure you check that your proposed fix works by building the site with `npm run build` and running the test suite in `npm test`. + ``` + +1. When developers assign an issue to {% data variables.product.prodname_copilot_short %}, they can select the custom agent from a dropdown. + +## Installing private packages + +The best way to give {% data variables.product.prodname_copilot_short %} access to a project's dependencies is to install them in a `copilot-setup-steps.yml` workflow file. This file defines how the environment is set up before {% data variables.product.prodname_copilot_short %} starts working. + +To allow the workflow to pull your private, organization-scoped packages, you will update the package settings to make sure that the repository's `GITHUB_TOKEN` has access to the package. This is more secure than using a long-lived {% data variables.product.pat_generic %} with organization permissions. + +### Example: Install Node dependencies + +A developer creates a workflow to install the Node dependencies defined in a repository's `package-lock.json` file. This includes private, organization-scoped packages hosted on {% data variables.product.github %}. + +1. The developer creates a `copilot-setup-steps.yml` file in the repository. +1. They add steps for installing the project's dependencies. For example: + + {% data reusables.copilot.cloud-agent.install-dependencies %} + +1. An organization administrator ensures that the repository has access to the organization's private packages by granting access to the repository in each package's settings. See [AUTOTITLE](/packages/learn-github-packages/configuring-a-packages-access-control-and-visibility#github-actions-access-for-packages-scoped-to-organizations). + +>[!TIP] If you need to access packages that are hosted internally within your corporate network, you may need to run {% data variables.copilot.copilot_cloud_agent %} on self-hosted {% data variables.product.prodname_actions %} runners. + +## Controlling who can configure these settings + +Now you have seen how access to resources is controlled at the repository and organization levels, consider how much scope you want to give users to manage these settings. + +1. **Choose which repositories have access** to {% data variables.copilot.copilot_cloud_agent %}. If you're concerned about a specific repository, you can block it for all users. +1. **Consider who gets admin access** to these repositories. You can control this at the organization level by creating a team with the **All-repository admin** custom role. These users will be able to manage configuration _settings_, such as MCP configuration and `copilot` environments, in every repository. +1. **Use rulesets and CODEOWNERS files** to control edits of configuration _files_, such as `copilot-setup-steps.yml`, which anyone with write access can edit by default. +1. **Review the default firewall**. The firewall doesn't affect connections to MCP servers or setup steps in `copilot-setup-steps.yml`, but it does limit {% data variables.product.prodname_copilot_short %}'s access to the Internet during task execution. See [AUTOTITLE](/copilot/how-tos/use-copilot-agents/cloud-agent/customize-the-agent-firewall). diff --git a/content/copilot/tutorials/cloud-agent/index.md b/content/copilot/tutorials/cloud-agent/index.md index 7b2be160db42..1a564b7b0ba7 100644 --- a/content/copilot/tutorials/cloud-agent/index.md +++ b/content/copilot/tutorials/cloud-agent/index.md @@ -10,6 +10,7 @@ children: - /pilot-cloud-agent - /improve-a-project - /build-guardrails + - /give-access-to-resources contentType: tutorials redirect_from: - /copilot/tutorials/coding-agent diff --git a/content/support/contacting-github-support/creating-a-support-ticket.md b/content/support/contacting-github-support/creating-a-support-ticket.md index ff0a6b40bbf7..16d2c70bf5e9 100644 --- a/content/support/contacting-github-support/creating-a-support-ticket.md +++ b/content/support/contacting-github-support/creating-a-support-ticket.md @@ -78,13 +78,15 @@ Especially for tickets with {% data variables.product.support_ticket_priority_ur ## Creating a support ticket{% ifversion ghes %} using the {% data variables.contact.enterprise_portal %}{% endif %} -> [!NOTE] -> Before you submit a ticket, you have the option of using {% data variables.copilot.copilot_in_support %} to receive an immediate response to your question. If {% data variables.copilot.copilot_in_support %} is unable to resolve your issue, you can continue submitting your ticket. For more information, see [AUTOTITLE](/support/learning-about-github-support/about-copilot-in-github-support). +Before you submit a ticket, you have the option of using {% data variables.copilot.copilot_in_support %} to receive an immediate response to your question. If {% data variables.copilot.copilot_in_support %} is unable to resolve your issue, you can continue submitting your ticket. For more information, see [AUTOTITLE](/support/learning-about-github-support/about-copilot-in-github-support). + +> [!IMPORTANT] +> If your enterprise uses {% data variables.enterprise.data_residency_short %}, you must sign in with your {% data variables.enterprise.data_residency_site %} account when creating a support ticket about your data-resident enterprise. Otherwise, you will be asked to open a new ticket using your {% data variables.enterprise.data_residency_site %} account. 1. Navigate to the {% data variables.contact.contact_landing_page_portal %} and choose one of the following options: * To sign in with your {% data variables.product.github %} account, click **Sign in with {% data variables.product.github %}**. - * If your organization uses {% data variables.enterprise.data_residency_short %} or {% data variables.enterprise.prodname_managed_users %} (accounts ending in `.ghe`): + * If your enterprise uses {% data variables.enterprise.data_residency_short %} (you will use a domain like `{% data variables.enterprise.data_residency_example_domain %}`): 1. In the sign-in dialog, click **Sign in to your .ghe account**. 1. Enter your enterprise or tenant name (provided by your administrator) and continue. 1. Complete the SAML authentication process as prompted. This will sign you in to your .ghe enterprise-managed account. diff --git a/data/reusables/copilot/cloud-agent/install-dependencies.md b/data/reusables/copilot/cloud-agent/install-dependencies.md new file mode 100644 index 000000000000..d2e4545621b3 --- /dev/null +++ b/data/reusables/copilot/cloud-agent/install-dependencies.md @@ -0,0 +1,22 @@ +```yaml +# ... + +jobs: + copilot-setup-steps: + # ... + + # You can define any steps you want, and they will run before the agent starts. + # If you do not check out your code, Copilot will do this for you. + steps: + - name: Checkout code + uses: {% data reusables.actions.action-checkout %} + + - name: Set up Node.js + uses: {% data reusables.actions.action-setup-node %} + with: + node-version: "20" + cache: "npm" + + - name: Install JavaScript dependencies + run: npm ci +``` diff --git a/data/reusables/copilot/copilot-cli/cli-rewind-warning.md b/data/reusables/copilot/copilot-cli/cli-rewind-warning.md new file mode 100644 index 000000000000..0218b807e97d --- /dev/null +++ b/data/reusables/copilot/copilot-cli/cli-rewind-warning.md @@ -0,0 +1 @@ +Rewinding restores your entire workspace to the state it was in at the selected snapshot. This reverts all changes made after that point—not only changes made by {% data variables.product.prodname_copilot_short %}, but also any manual edits, and changes resulting from shell commands. Any new files created in the workspace after the snapshot was taken are deleted, irrespective of their Git status. diff --git a/data/reusables/copilot/experimental.md b/data/reusables/copilot/experimental.md new file mode 100644 index 000000000000..817b67d556ec --- /dev/null +++ b/data/reusables/copilot/experimental.md @@ -0,0 +1 @@ +Only available in experimental mode. diff --git a/data/reusables/copilot/trial-period.md b/data/reusables/copilot/trial-period.md deleted file mode 100644 index 64bb6b746dce..000000000000 --- a/data/reusables/copilot/trial-period.md +++ /dev/null @@ -1 +0,0 @@ -30 diff --git a/src/content-pipelines/config.yml b/src/content-pipelines/config.yml index 2ba9ae316698..01d357911c3c 100644 --- a/src/content-pipelines/config.yml +++ b/src/content-pipelines/config.yml @@ -24,7 +24,10 @@ copilot-cli: - content/copilot/reference/copilot-cli-reference/cli-plugin-reference.md - content/copilot/reference/copilot-cli-reference/acp-server.md - content/copilot/reference/copilot-cli-reference/cli-config-dir-reference.md - exclusions: [] + exclusions: + - All mentions of, or information directly relating to, feature flags + - enabledFeatureFlags configuration setting + - COPILOT_CLI_ENABLED_FEATURE_FLAGS environment variable content-mapping: | cli-plugin-reference.md covers only plugin-specific content. All other CLI topics (hooks, MCP, skills, agents, permissions, etc.) belong in cli-command-reference.md even when they mention plugins. diff --git a/src/content-pipelines/state/copilot-cli.sha b/src/content-pipelines/state/copilot-cli.sha index 3813f23c6c28..960e9f298976 100644 --- a/src/content-pipelines/state/copilot-cli.sha +++ b/src/content-pipelines/state/copilot-cli.sha @@ -1 +1 @@ -584832db507d47454ed410791e2d0c53468bea20 +aaf6f363050eb7ad4b98542f7389b76f4e29f5b8 diff --git a/src/languages/lib/correct-translation-content.ts b/src/languages/lib/correct-translation-content.ts index fca1adefd0f9..2e1eb3fed434 100644 --- a/src/languages/lib/correct-translation-content.ts +++ b/src/languages/lib/correct-translation-content.ts @@ -26,6 +26,10 @@ export function correctTranslatedContentStrings( // Remove colon prefix on Liquid tags: `{%:` → `{%` content = content.replace(/\{%:/g, '{%') + // `{% siVersion X %}` — Spanish "si" (if) fused with "Version" = ifversion + content = content.replaceAll('{% siVersion ', '{% ifversion ') + content = content.replaceAll('{%- siVersion ', '{%- ifversion ') + content = content.replaceAll('{% vulnerables variables.', '{% data variables.') content = content.replaceAll('{% datos variables', '{% data variables') content = content.replaceAll('{% de datos variables', '{% data variables') @@ -235,9 +239,17 @@ export function correctTranslatedContentStrings( } if (context.code === 'pt') { + // `{%–` — en-dash (U+2013) used instead of hyphen in `{%-` trim modifier + content = content.replaceAll('{%–', '{%-') + content = content.replaceAll('{% dados variables', '{% data variables') content = content.replaceAll('{% de dados variables', '{% data variables') content = content.replaceAll('{% dados reusables', '{% data reusables') + // `{% dadosvariables` / `{% datavariables` — no space between "dados"/"data" and "variables" + content = content.replaceAll('{% dadosvariables', '{% data variables') + content = content.replaceAll('{%- dadosvariables', '{%- data variables') + content = content.replaceAll('{% datavariables', '{% data variables') + content = content.replaceAll('{%- datavariables', '{%- data variables') // Fully translated reusables path: `{% dados reutilizáveis.X.Y %}` → `{% data reusables.X.Y %}` content = content.replaceAll('{% dados reutilizáveis.', '{% data reusables.') // Translated path segment inside reusables path: `repositórios` → `repositories` @@ -292,6 +304,9 @@ export function correctTranslatedContentStrings( if (context.code === 'zh') { content = content.replaceAll('{% 数据variables', '{% data variables') content = content.replaceAll('{% 数据 variables', '{% data variables') + // `{%数据variables` — no space between `{%` and 数据 (data) + content = content.replaceAll('{%数据variables', '{% data variables') + content = content.replaceAll('{%数据 variables', '{% data variables') // Order matters: the more specific `s.` variant must run first to // avoid the broader rule producing a double-s (`reusabless`). content = content.replaceAll('{% 数据可重用s.', '{% data reusables.') @@ -467,6 +482,12 @@ export function correctTranslatedContentStrings( content = content.replaceAll('{% données variables', '{% data variables') content = content.replaceAll('{% données réutilisables.', '{% data reusables.') content = content.replaceAll('{% variables de données.', '{% data variables.') + // `{% de données variables.` — preposition "de" prepended to "données variables" + content = content.replaceAll('{% de données variables.', '{% data variables.') + content = content.replaceAll('{%- de données variables.', '{%- data variables.') + // `{% de data variables.` — partially-corrected form (données already fixed to data) + content = content.replaceAll('{% de data variables.', '{% data variables.') + content = content.replaceAll('{%- de data variables.', '{%- data variables.') content = content.replaceAll('{% autre %}', '{% else %}') content = content.replaceAll('{%- autre %}', '{%- else %}') content = content.replaceAll('{% brut %}', '{% raw %}') @@ -571,6 +592,10 @@ export function correctTranslatedContentStrings( content = content.replaceAll('{% 옥티콘 ', '{% octicon ') content = content.replaceAll('{%- 옥티콘 ', '{%- octicon ') + // `{% data Variables.` — capital V in "Variables" (Korean translator capitalised the word) + content = content.replaceAll('{% data Variables.', '{% data variables.') + content = content.replaceAll('{%- data Variables.', '{%- data variables.') + // Korean translation of github-glossary.md content = content.replaceAll('{{ 용어집.term }}', '{{ glossary.term }}') // `{% 데이터 재사용.` — Korean translation of "data reusables" path @@ -662,8 +687,23 @@ export function correctTranslatedContentStrings( // `{% Endnotiz %}` — "end note" = endnote content = content.replaceAll('{% Endnotiz %}', '{% endnote %}') content = content.replaceAll('{%- Endnotiz %}', '{%- endnote %}') + // `{% data-variables.` — hyphen used instead of space between "data" and "variables" + content = content.replaceAll('{% data-variables.', '{% data variables.') + content = content.replaceAll('{%- data-variables.', '{%- data variables.') + // `{%- Datenworkflow variables.` — compound "Datenworkflow" (data workflow) = data + content = content.replaceAll('{%- Datenworkflow variables.', '{%- data variables.') + content = content.replaceAll('{% Datenworkflow variables.', '{% data variables.') + // `{% ifec ` — truncated/corrupted form of "ifversion" + content = content.replaceAll('{% ifec ', '{% ifversion ') + content = content.replaceAll('{%- ifec ', '{%- ifversion ') + // `{% andere %}` / `{%- andere %}` — German "andere" (other) = else + content = content.replaceAll('{% andere %}', '{% else %}') + content = content.replaceAll('{%- andere %}', '{%- else %}') // `{% Dateninstanz` — "data instance" = data content = content.replaceAll('{% Dateninstanz ', '{% data ') + // `{% Datenauflistung ` — "data listing" (compound) = data + content = content.replaceAll('{% Datenauflistung ', '{% data ') + content = content.replaceAll('{%- Datenauflistung ', '{%- data ') // `{% ifversion-Sicherheitskonfigurationen %}` — hyphenated compound content = content.replaceAll( '{% ifversion-Sicherheitskonfigurationen %}', @@ -731,6 +771,20 @@ export function correctTranslatedContentStrings( content = content.replaceAll('{% dada variables', '{% data variables') content = content.replaceAll('{% % data', '{% data') + // Leading dot in `{% data` paths: `{% data .variables.X %}` / `{% data .reusables.X %}` + // — translator inserted a stray dot. Affects ja, pt, zh. + content = content.replaceAll('{% data .variables.', '{% data variables.') + content = content.replaceAll('{%- data .variables.', '{%- data variables.') + content = content.replaceAll('{% data .reusables.', '{% data reusables.') + content = content.replaceAll('{%- data .reusables.', '{%- data reusables.') + + // Singular "variable" / "reusable" in `{% data` paths: + // `{% data variable.product.X %}` → `{% data variables.product.X %}` (es, zh) + content = content.replaceAll('{% data variable.', '{% data variables.') + content = content.replaceAll('{%- data variable.', '{%- data variables.') + content = content.replaceAll('{% data reusable.', '{% data reusables.') + content = content.replaceAll('{%- data reusable.', '{%- data reusables.') + // Double-quote corruption in href attributes content = content.replace(/href=""https:\/\//g, 'href="https://') diff --git a/src/languages/tests/correct-translation-content.ts b/src/languages/tests/correct-translation-content.ts index 308391c5bb5b..26f5382ff528 100644 --- a/src/languages/tests/correct-translation-content.ts +++ b/src/languages/tests/correct-translation-content.ts @@ -131,6 +131,11 @@ describe('correctTranslatedContentStrings', () => { '{% data reusables.profile.access_org %}', ) }) + + test('fixes siVersion → ifversion', () => { + expect(fix('{% siVersion productos-ghas %}', 'es')).toBe('{% ifversion productos-ghas %}') + expect(fix('{%- siVersion productos-ghas %}', 'es')).toBe('{%- ifversion productos-ghas %}') + }) }) // ─── JAPANESE (ja) ────────────────────────────────────────────────── @@ -318,6 +323,26 @@ describe('correctTranslatedContentStrings', () => { ) }) + test('fixes en-dash in trim modifier', () => { + // `{%–` — en-dash (U+2013) used instead of hyphen in `{%-` trim modifier + expect(fix('{%– ifversion projects-v1 %}', 'pt')).toBe('{%- ifversion projects-v1 %}') + expect(fix('{%– endif %}', 'pt')).toBe('{%- endif %}') + }) + + test('fixes datavariables / dadosvariables (no space)', () => { + // `{% datavariables` — no space between "data" and "variables" (post-translation) + expect(fix('{% datavariables.product.github %}', 'pt')).toBe( + '{% data variables.product.github %}', + ) + expect(fix('{%- datavariables.product.github %}', 'pt')).toBe( + '{%- data variables.product.github %}', + ) + // `{% dadosvariables` — Portuguese "dados" fused with "variables" + expect(fix('{% dadosvariables.product.github %}', 'pt')).toBe( + '{% data variables.product.github %}', + ) + }) + test('fixes translated else variants', () => { expect(fix('{% senão %}', 'pt')).toBe('{% else %}') expect(fix('{%- senão %}', 'pt')).toBe('{%- else %}') @@ -434,6 +459,13 @@ describe('correctTranslatedContentStrings', () => { '{% data variables.product.github %}', ) expect(fix('{% 数据可重用s.foo %}', 'zh')).toBe('{% data reusables.foo %}') + // No space between `{%` and 数据 + expect(fix('{%数据variables.product.github%}', 'zh')).toBe( + '{% data variables.product.github%}', + ) + expect(fix('{%数据 variables.product.github%}', 'zh')).toBe( + '{% data variables.product.github%}', + ) }) test('fixes translated else and raw', () => { @@ -687,6 +719,14 @@ describe('correctTranslatedContentStrings', () => { '{% data variables.product.github %}', ) expect(fix('{% données reusables.foo %}', 'fr')).toBe('{% data reusables.foo %}') + // `{% de données variables.` — preposition "de" prepended + expect(fix('{% de données variables.product.github %}', 'fr')).toBe( + '{% data variables.product.github %}', + ) + // `{% de data variables.` — partially-corrected form + expect(fix('{% de data variables.product.github %}', 'fr')).toBe( + '{% data variables.product.github %}', + ) }) test('fixes translated else', () => { @@ -889,6 +929,15 @@ describe('correctTranslatedContentStrings', () => { expect(fix('{% 주석 끝 %}', 'ko')).toBe('{% endnote %}') expect(fix('{%- 주석 끝 %}', 'ko')).toBe('{%- endnote %}') }) + + test('fixes capitalized Variables → data variables', () => { + expect(fix('{% data Variables.product.github %}', 'ko')).toBe( + '{% data variables.product.github %}', + ) + expect(fix('{%- data Variables.product.github %}', 'ko')).toBe( + '{%- data variables.product.github %}', + ) + }) }) // ─── GERMAN (de) ────────────────────────────────────────────────── @@ -1088,6 +1137,44 @@ describe('correctTranslatedContentStrings', () => { '{% ifversion enterprise-installed-apps %}', ) }) + + test('fixes data-variables (hyphen instead of space)', () => { + expect(fix('{% data-variables.product.github %}', 'de')).toBe( + '{% data variables.product.github %}', + ) + expect(fix('{%- data-variables.product.github %}', 'de')).toBe( + '{%- data variables.product.github %}', + ) + }) + + test('fixes Datenworkflow variables → data variables', () => { + expect(fix('{%- Datenworkflow variables.product.prodname_actions %}', 'de')).toBe( + '{%- data variables.product.prodname_actions %}', + ) + expect(fix('{% Datenworkflow variables.product.prodname_actions %}', 'de')).toBe( + '{% data variables.product.prodname_actions %}', + ) + }) + + test('fixes ifec → ifversion', () => { + expect(fix('{% ifec ghec %}', 'de')).toBe('{% ifversion ghec %}') + expect(fix('{%- ifec ghec %}', 'de')).toBe('{%- ifversion ghec %}') + }) + + test('fixes andere → else', () => { + expect(fix('{% andere %}', 'de')).toBe('{% else %}') + expect(fix('{%- andere %}', 'de')).toBe('{%- else %}') + }) + + test('fixes Datenauflistung → data', () => { + // `{% Datenauflistung variables.X %}` — "data listing" compound = data + expect(fix('{% Datenauflistung variables.product.github %}', 'de')).toBe( + '{% data variables.product.github %}', + ) + expect(fix('{%- Datenauflistung variables.product.github %}', 'de')).toBe( + '{%- data variables.product.github %}', + ) + }) }) describe('Generic fixes (all languages)', () => { @@ -1108,6 +1195,28 @@ describe('correctTranslatedContentStrings', () => { ) }) + test('fixes leading dot in {% data paths', () => { + // `{% data .variables.X %}` — translator inserted a stray dot + expect(fix('{% data .variables.product.prodname_ghe_server %}', 'ja')).toBe( + '{% data variables.product.prodname_ghe_server %}', + ) + expect(fix('{%- data .variables.product.github %}', 'pt')).toBe( + '{%- data variables.product.github %}', + ) + expect(fix('{% data .reusables.foo.bar %}', 'zh')).toBe('{% data reusables.foo.bar %}') + }) + + test('fixes singular variable / reusable in {% data paths', () => { + // `{% data variable.product.X %}` (singular) → `{% data variables.product.X %}` + expect(fix('{% data variable.product.prodname_container_registry %}', 'zh')).toBe( + '{% data variables.product.prodname_container_registry %}', + ) + expect(fix('{%- data variable.product.github %}', 'es')).toBe( + '{%- data variables.product.github %}', + ) + expect(fix('{% data reusable.foo.bar %}', 'fr')).toBe('{% data reusables.foo.bar %}') + }) + test('fixes capitalized platform tags across all languages', () => { expect(fix('{% Windows %}', 'zh')).toBe('{% windows %}') expect(fix('{% Eclipse %}', 'zh')).toBe('{% eclipse %}')