diff --git a/.github/workflows/link-check-internal.yml b/.github/workflows/link-check-internal.yml index a6071cd20b64..baa966011acd 100644 --- a/.github/workflows/link-check-internal.yml +++ b/.github/workflows/link-check-internal.yml @@ -89,12 +89,13 @@ jobs: run: npm run check-links-internal - name: Upload report artifact - if: failure() + if: always() uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: link-report-${{ matrix.version }}-${{ matrix.language }} path: artifacts/link-report-*.md retention-days: 5 + if-no-files-found: ignore - uses: ./.github/actions/slack-alert if: ${{ failure() && github.event_name != 'workflow_dispatch' }} diff --git a/assets/images/help/copilot/coding-agent/open-agent-session-in-copilot-cli.png b/assets/images/help/copilot/coding-agent/open-agent-session-in-copilot-cli.png new file mode 100644 index 000000000000..4feaa802831e Binary files /dev/null and b/assets/images/help/copilot/coding-agent/open-agent-session-in-copilot-cli.png differ diff --git a/assets/images/site/apple-touch-icon-114x114.png b/assets/images/site/apple-touch-icon-114x114.png index 1792a4283129..0d03234b9fd4 100644 Binary files a/assets/images/site/apple-touch-icon-114x114.png and b/assets/images/site/apple-touch-icon-114x114.png differ diff --git a/assets/images/site/apple-touch-icon-120x120.png b/assets/images/site/apple-touch-icon-120x120.png index 95903a6f899a..5d2a2b929277 100644 Binary files a/assets/images/site/apple-touch-icon-120x120.png and b/assets/images/site/apple-touch-icon-120x120.png differ diff --git a/assets/images/site/apple-touch-icon-144x144.png b/assets/images/site/apple-touch-icon-144x144.png index a7df9a401a44..c4e3d39c4b90 100644 Binary files a/assets/images/site/apple-touch-icon-144x144.png and b/assets/images/site/apple-touch-icon-144x144.png differ diff --git a/assets/images/site/apple-touch-icon-152x152.png b/assets/images/site/apple-touch-icon-152x152.png index 191e190e7312..b793062aeb39 100644 Binary files a/assets/images/site/apple-touch-icon-152x152.png and b/assets/images/site/apple-touch-icon-152x152.png differ diff --git a/assets/images/site/apple-touch-icon-180x180.png b/assets/images/site/apple-touch-icon-180x180.png index 29ab743018bf..04ea5081c168 100644 Binary files a/assets/images/site/apple-touch-icon-180x180.png and b/assets/images/site/apple-touch-icon-180x180.png differ diff --git a/assets/images/site/apple-touch-icon-192x192.png b/assets/images/site/apple-touch-icon-192x192.png index e23ec12299c7..118a6ed982d6 100644 Binary files a/assets/images/site/apple-touch-icon-192x192.png and b/assets/images/site/apple-touch-icon-192x192.png differ diff --git a/assets/images/site/apple-touch-icon-512x512.png b/assets/images/site/apple-touch-icon-512x512.png index ecea91f1d9ce..4a1923fde68b 100644 Binary files a/assets/images/site/apple-touch-icon-512x512.png and b/assets/images/site/apple-touch-icon-512x512.png differ diff --git a/assets/images/site/apple-touch-icon-57x57.png b/assets/images/site/apple-touch-icon-57x57.png index 23f6fc2430b7..75f83baec901 100644 Binary files a/assets/images/site/apple-touch-icon-57x57.png and b/assets/images/site/apple-touch-icon-57x57.png differ diff --git a/assets/images/site/apple-touch-icon-60x60.png b/assets/images/site/apple-touch-icon-60x60.png index 81be8bc98206..bae50ad51ac1 100644 Binary files a/assets/images/site/apple-touch-icon-60x60.png and b/assets/images/site/apple-touch-icon-60x60.png differ diff --git a/assets/images/site/apple-touch-icon-72x72.png b/assets/images/site/apple-touch-icon-72x72.png index b69474e6a7ee..d7c6b5f0d4b7 100644 Binary files a/assets/images/site/apple-touch-icon-72x72.png and b/assets/images/site/apple-touch-icon-72x72.png differ diff --git a/assets/images/site/apple-touch-icon-76x76.png b/assets/images/site/apple-touch-icon-76x76.png index be3506dc410b..9276c93b6d5f 100644 Binary files a/assets/images/site/apple-touch-icon-76x76.png and b/assets/images/site/apple-touch-icon-76x76.png differ diff --git a/assets/images/site/apple-touch-icon.png b/assets/images/site/apple-touch-icon.png index cb10a2b7cba0..5d2a2b929277 100644 Binary files a/assets/images/site/apple-touch-icon.png and b/assets/images/site/apple-touch-icon.png differ diff --git a/assets/images/site/favicon.ico b/assets/images/site/favicon.ico index 40e25b4cdd28..b91c543b8614 100644 Binary files a/assets/images/site/favicon.ico and b/assets/images/site/favicon.ico differ diff --git a/assets/images/site/favicon.png b/assets/images/site/favicon.png index 5d74638170ed..040b47f5ea5c 100644 Binary files a/assets/images/site/favicon.png and b/assets/images/site/favicon.png differ diff --git a/assets/images/site/favicon.svg b/assets/images/site/favicon.svg index 5241f67f951e..5ac282559c44 100644 --- a/assets/images/site/favicon.svg +++ b/assets/images/site/favicon.svg @@ -1 +1,6 @@ - + + + + + + diff --git a/assets/images/social-cards/actions.png b/assets/images/social-cards/actions.png index 40647b6a4c22..0c992b7995cc 100644 Binary files a/assets/images/social-cards/actions.png and b/assets/images/social-cards/actions.png differ diff --git a/assets/images/social-cards/code-security.png b/assets/images/social-cards/code-security.png index 46cfccf5347c..eb9dce059364 100644 Binary files a/assets/images/social-cards/code-security.png and b/assets/images/social-cards/code-security.png differ diff --git a/assets/images/social-cards/copilot.png b/assets/images/social-cards/copilot.png index 2360a07d6d5e..4e44638c587e 100644 Binary files a/assets/images/social-cards/copilot.png and b/assets/images/social-cards/copilot.png differ diff --git a/assets/images/social-cards/default.png b/assets/images/social-cards/default.png index 7405f132c147..5afef85bd1a8 100644 Binary files a/assets/images/social-cards/default.png and b/assets/images/social-cards/default.png differ diff --git a/assets/images/social-cards/issues.png b/assets/images/social-cards/issues.png index 906047323ca3..112ae1485342 100644 Binary files a/assets/images/social-cards/issues.png and b/assets/images/social-cards/issues.png differ diff --git a/content/code-security/concepts/secret-security/about-bypass-requests-for-push-protection.md b/content/code-security/concepts/secret-security/about-bypass-requests-for-push-protection.md new file mode 100644 index 000000000000..02609d14e1e4 --- /dev/null +++ b/content/code-security/concepts/secret-security/about-bypass-requests-for-push-protection.md @@ -0,0 +1,68 @@ +--- +title: About bypass requests for push protection +intro: 'Learn how bypass requests work when push protection blocks commits containing secrets.' +permissions: '{% data reusables.permissions.delegated-bypass-list %}' +versions: + fpt: '*' + ghec: '*' + ghes: '*' +topics: + - Secret scanning + - Secret Protection + - Alerts + - Repositories +shortTitle: Bypass requests +contentType: concepts +--- + +## About bypass requests for push protection + +When push protection blocks a commit containing a secret, contributors may need to bypass the block to complete their push. If delegated bypass for push protection is enabled, contributors without bypass privileges must submit a bypass request and wait for approval from designated reviewers. This allows organizations to maintain security oversight while enabling legitimate exceptions when needed. For more information, see [AUTOTITLE](/code-security/concepts/secret-security/about-delegated-bypass-for-push-protection). + +If delegated bypass for push protection is not enabled, contributors can bypass push protection at their own discretion. + +When enabling delegated bypass for push protection, organization owners or repository administrators decide which {% ifversion push-protection-bypass-fine-grained-permissions %}individuals, {% endif %}roles or teams can review (approve or deny) requests to bypass push protection. + +If you are a designated reviewer, you must review bypass requests and either approve or deny them based on the request details and your organization's security policies. + +## How bypass requests work + +When a contributor without bypass privileges requests to push a commit containing a secret, a bypass requests is sent to the reviewers. The designated group of reviewers: + +* Receives an email notification containing a link to the request +* Reviews the request in the "Bypass requests" page of the repository{% ifversion security-overview-delegated-bypass-requests %}, or in the organization's security overview{% endif %}. +* Has **7 days** to either approve or deny the request before the request expires + +### Information available to reviewers + +{% data variables.product.github %} displays the following information for each request: + +* Name of the user who attempted the push +* Repository where the push was attempted +* Commit hash of the push +* Timestamp of the push{% ifversion push-protection-delegated-bypass-enhancements %} +* File path and branch information (branch information is only available for pushes to single branches){% endif %} + +### Outcomes + +The contributor is notified by email of the decision and must take the required action: + +* **If the request is approved**: The contributor can push the commit containing the secret to the repository. +* **If the request is denied**: The contributor must remove the secret from the commit before successfully pushing the commit to the repository. + +## Automatic bypass request reviews + +You can use {% data variables.product.prodname_github_apps %} with fine-grained permissions to programmatically review and approve push protection bypass requests. This enables you to enforce consistent security policies, integrate with external security tools, or reduce manual review burden. + +{% ifversion ghes %} + +>[!NOTE] +> For {% data variables.product.prodname_ghe_server %}, the use of {% data variables.product.prodname_github_apps %} to review bypass requests is available from version 3.19. + +{% endif %} + +> For more information about permissions, see [Organization permissions for "Organization bypass requests for secret scanning"](/enterprise-cloud@latest/rest/authentication/permissions-required-for-github-apps?apiVersion=2022-11-28#organization-permissions-for-organization-bypass-requests-for-secret-scanning). + +## Next steps + +* To learn how to manage bypass requests for push protection as a reviewer, see [AUTOTITLE](/code-security/how-tos/secure-your-secrets/manage-bypass-requests/managing-requests-to-bypass-push-protection). diff --git a/content/code-security/concepts/secret-security/index.md b/content/code-security/concepts/secret-security/index.md index b10b39ae64eb..c787ea7932b2 100644 --- a/content/code-security/concepts/secret-security/index.md +++ b/content/code-security/concepts/secret-security/index.md @@ -16,6 +16,7 @@ children: - /about-secret-security-with-github - /about-alerts - /about-delegated-bypass-for-push-protection + - /about-bypass-requests-for-push-protection - /about-secret-scanning-for-partners - /github-secret-types - /push-protection-from-the-command-line diff --git a/content/code-security/concepts/security-at-scale/about-security-campaigns.md b/content/code-security/concepts/security-at-scale/about-security-campaigns.md index 19e3654ff130..cbb16ab8d2e2 100644 --- a/content/code-security/concepts/security-at-scale/about-security-campaigns.md +++ b/content/code-security/concepts/security-at-scale/about-security-campaigns.md @@ -38,6 +38,9 @@ A security campaign has many benefits over other ways of encouraging developers * Developers can see the alerts you've highlighted for remediation without leaving their normal workflows. * Each campaign has a named point of contact for questions, reviews, and collaboration. {% ifversion security-campaigns-autofix %} * For {% data variables.product.prodname_code_scanning %} alerts, {% data variables.copilot.copilot_autofix %} is automatically triggered to suggest a resolution. {% endif %} +{%- ifversion code-secret-alert-assignees %} +* For both {% data variables.product.prodname_code_scanning %} and {% data variables.product.prodname_secret_scanning %}, you can assign alerts in a campaign to users with write access{% ifversion copilot %} or to {% data variables.copilot.copilot_coding_agent %} to automatically generate pull requests with fixes{% endif %}. +{%- endif %} You can use one of the templates to select a group of closely related alerts for a campaign. This allows developers to build on the knowledge gained by resolving one alert and use it to fix several more, providing them with an incentive to fix multiple alerts. @@ -69,7 +72,7 @@ The creation workflow is the same for all campaigns, but you will notice a few d {% ifversion code-secret-alert-assignees %} -## Assigning alerts{% ifversion security-campaigns-assign-to-cca %} to users and {% data variables.copilot.copilot_coding_agent %}{% endif %} +## About assigning alerts{% ifversion security-campaigns-assign-to-cca %} to users and {% data variables.copilot.copilot_coding_agent %}{% endif %} {% ifversion code-secret-alert-assignees-ga %}{% elsif ghes = 3.20 %} diff --git a/content/code-security/how-tos/secure-your-secrets/customize-leak-detection/generating-regular-expressions-for-custom-patterns-with-copilot-secret-scanning.md b/content/code-security/how-tos/secure-your-secrets/customize-leak-detection/generating-regular-expressions-for-custom-patterns-with-copilot-secret-scanning.md index da9eca753587..a7dc297af1a4 100644 --- a/content/code-security/how-tos/secure-your-secrets/customize-leak-detection/generating-regular-expressions-for-custom-patterns-with-copilot-secret-scanning.md +++ b/content/code-security/how-tos/secure-your-secrets/customize-leak-detection/generating-regular-expressions-for-custom-patterns-with-copilot-secret-scanning.md @@ -1,6 +1,6 @@ --- title: Generating regular expressions for custom patterns with Copilot secret scanning -shortTitle: Regular expression generator +shortTitle: Generate regular expressions intro: You can use {% data variables.secret-scanning.copilot-secret-scanning %}'s {% data variables.secret-scanning.custom-pattern-regular-expression-generator %} to write regular expressions for custom patterns. The generator uses an AI model to generate expressions that match your input, and optionally example strings. permissions: '{% data reusables.permissions.security-repo-enable %}' allowTitleToDifferFromFilename: true diff --git a/content/code-security/how-tos/secure-your-secrets/manage-bypass-requests/managing-requests-to-bypass-push-protection.md b/content/code-security/how-tos/secure-your-secrets/manage-bypass-requests/managing-requests-to-bypass-push-protection.md index 3b3cdb334df7..a57f9d9affad 100644 --- a/content/code-security/how-tos/secure-your-secrets/manage-bypass-requests/managing-requests-to-bypass-push-protection.md +++ b/content/code-security/how-tos/secure-your-secrets/manage-bypass-requests/managing-requests-to-bypass-push-protection.md @@ -17,36 +17,15 @@ redirect_from: - /code-security/secret-scanning/using-advanced-secret-scanning-and-push-protection-features/delegated-bypass-for-push-protection/managing-requests-to-bypass-push-protection --- -## Managing requests to bypass push protection - {% data reusables.secret-scanning.push-protection-delegate-bypass-beta-note %} -When enabling delegated bypass for push protection, organization owners or repository administrators decide which {% ifversion push-protection-bypass-fine-grained-permissions %}individuals, {% endif %}roles or teams can review (approve or deny) requests to bypass push protection. - ->[!NOTE] -> You can also use {% data variables.product.prodname_github_apps %} with fine-grained permissions to programmatically review and approve push protection bypass requests. This enables your organization to streamline security request reviews and enforce policies, or integrate with external security tools, ensuring that all reviews meet established standards. _For {% data variables.product.prodname_ghe_server %}, the use of {% data variables.product.prodname_github_apps %} to review bypass requests is available from version 3.19._ -> For more information about permissions, see [Organization permissions for "Organization bypass requests for secret scanning"](/enterprise-cloud@latest/rest/authentication/permissions-required-for-github-apps?apiVersion=2022-11-28#organization-permissions-for-organization-bypass-requests-for-secret-scanning). - -When a contributor requests bypass privileges to push a commit containing a secret, this designated group of reviewers: - -* Receives an email notification containing a link to the request. -* Reviews the request in the "Bypass requests" page of the repository{% ifversion security-overview-delegated-bypass-requests %}, or in the organization's security overview{% endif %}. -* Has 7 days to either approve or deny the request before the request expires. - -To help reviewers efficiently triage secrets for which there is a bypass request, {% data variables.product.prodname_dotcom %} displays the following information in the request: - -* Name of the user who attempted the push. -* Repository where the push was attempted. -* Commit hash of the push. -* Timestamp of the push.{% ifversion push-protection-delegated-bypass-enhancements %} -* File path and branch information. The branch information is only available for pushes to single branches.{% endif %} +When delegated bypass for push protection is enabled, designated reviewers can approve or deny requests from contributors who want to push commits containing secrets. -The contributor is notified of the decision by email and must take the required action: +This article explains how to review and manage bypass requests for repositories and organizations. -* If the request is approved, the contributor can push the commit containing the secret to the repository. -* If the request is denied, the contributor must remove the secret from the commit in order to successfully push the commit to the repository. +For more information about how bypass requests work, see [AUTOTITLE](/code-security/concepts/secret-security/about-bypass-requests-for-push-protection). -### Managing requests for a repository +## Managing requests for a repository {% data reusables.repositories.navigate-to-repo %} {% data reusables.repositories.sidebar-security %} @@ -61,13 +40,13 @@ The contributor is notified of the decision by email and must take the required {% ifversion security-overview-delegated-bypass-requests %} -### Managing requests for an organization +## Managing requests for an organization Organization owners, security managers and organization members with the relevant fine-grained permission (via a custom role) can review and manage bypass requests for all repositories in the organization using security overview. See [AUTOTITLE](/code-security/security-overview/reviewing-requests-to-bypass-push-protection). {% endif %} -### Filtering requests +## Filtering requests You can filter requests by: @@ -76,7 +55,7 @@ You can filter requests by: * Timeframe * Status -#### Filtering by status +### Filtering by status The following statuses are assigned to a request: diff --git a/content/copilot/concepts/agents/about-copilot-cli.md b/content/copilot/concepts/agents/about-copilot-cli.md index 70efc5cb7387..3908046d8c59 100644 --- a/content/copilot/concepts/agents/about-copilot-cli.md +++ b/content/copilot/concepts/agents/about-copilot-cli.md @@ -31,13 +31,15 @@ For installation instructions, see [AUTOTITLE](/copilot/how-tos/set-up/install-c ## Modes of use -{% data variables.copilot.copilot_cli %} can be used in two modes: +{% data variables.copilot.copilot_cli %} can be used in three modes: * **Interactive mode**: Start an interactive session by using the `copilot` command. This is the default mode for working with the CLI. In this mode, you can prompt {% data variables.product.prodname_copilot_short %} to answer a question, or perform a task. You can react to {% data variables.product.prodname_copilot_short %}'s responses in the same session. ![Screenshot of the Welcome message in the interactive mode of {% data variables.product.prodname_copilot_short %}.](/assets/images/help/copilot/copilot-cli-welcome.png) +* **Plan mode**: Press Shift+Tab to cycle in and out of plan mode. In plan mode, {% data variables.product.prodname_copilot_short %} analyzes your request, asks clarifying questions to understand scope and requirements, and builds a structured implementation plan before writing any code. This helps you catch misunderstandings before any code is written, and stay in control of complex, multi-step tasks. + * **Programmatic mode**: You can also pass the CLI a single prompt directly on the command line. You do this by using the `-p` or `--prompt` command-line option. To allow {% data variables.product.prodname_copilot_short %} to modify and execute files you should also use one of the approval options (see [Allowing tools to be used without manual approval](#allowing-tools-to-be-used-without-manual-approval) later in this article). For example: ```bash copy @@ -47,7 +49,7 @@ For installation instructions, see [AUTOTITLE](/copilot/how-tos/set-up/install-c Alternatively, you can use a script to output command-line options and pipe this to `copilot`. For example: ```bash copy - echo ./script-outputting-options.sh | copilot + ./script-outputting-options.sh | copilot ``` > [!CAUTION] @@ -142,16 +144,31 @@ The following sections provide examples of tasks you can complete with {% data v `Branch off from main and create a {% data variables.product.prodname_actions %} workflow that will run on pull requests, or can be run manually. The workflow should run eslint to check for problems in the changes made in the PR. If warnings or errors are found these should be shown as messages in the diff view of the PR. I want to prevent code with errors from being merged into main so, if any errors are found, the workflow should cause the PR check to fail. Push the new branch and create a pull request.` +## Steering the conversation + +You can interact with {% data variables.product.prodname_copilot_short %} while it's thinking to steer the conversation: + +* **Enqueue additional messages**: Send follow-up messages to steer the conversation in a different direction, or queue additional instructions for {% data variables.product.prodname_copilot_short %} to process after it finishes its current response. This makes conversations feel more natural and keeps you in control. +* **Inline feedback on rejection**: When you reject a tool permission request, you can give {% data variables.product.prodname_copilot_short %} inline feedback about the rejection so it can adapt its approach without stopping entirely. This makes the conversation flow more naturally when you want to guide {% data variables.product.prodname_copilot_short %} away from certain actions. + +## Automatic context management + +{% data variables.copilot.copilot_cli %} automatically manages your conversation context: + +* **Auto-compaction**: When your conversation approaches 95% of the token limit, {% data variables.product.prodname_copilot_short %} automatically compresses your history in the background without interrupting your workflow. This enables virtually infinite sessions. +* **Manual control**: Use `/compact` to manually compress context anytime. Press Escape to cancel if you change your mind. +* **Visualize usage**: The `/context` command shows a detailed token usage breakdown so you can understand how your context window is being used. + ## Customizing {% data variables.copilot.copilot_cli %} You can customize {% data variables.copilot.copilot_cli %} in a number of ways: -* **Custom instructions**: Custom instructions allow you to give {% data variables.product.prodname_copilot_short %} additional context on your project and how to build, test and validate its changes. For more information, see [AUTOTITLE](/copilot/how-tos/use-copilot-agents/use-copilot-cli#use-custom-instructions). +* **Custom instructions**: Custom instructions allow you to give {% data variables.product.prodname_copilot_short %} additional context on your project and how to build, test and validate its changes. All custom instruction files now combine instead of using priority-based fallbacks. For more information, see [AUTOTITLE](/copilot/how-tos/use-copilot-agents/use-copilot-cli#use-custom-instructions). * **Model Context Protocol (MCP) servers**: MCP servers allow you to give {% data variables.product.prodname_copilot_short %} access to different data sources and tools. For more information, see [AUTOTITLE](/copilot/how-tos/use-copilot-agents/use-copilot-cli#add-an-mcp-server). * **{% data variables.copilot.custom_agents_caps_short %}**: {% data variables.copilot.custom_agents_caps_short %} allow you to create different specialized versions of {% data variables.product.prodname_copilot_short %} for different tasks. For example, you could customize {% data variables.product.prodname_copilot_short %} to be an expert frontend engineer following your team's guidelines. {% data variables.copilot.copilot_cli %} includes specialized {% data variables.copilot.custom_agents_short %} that it automatically delegates common tasks to. For more information, see [AUTOTITLE](/copilot/how-tos/use-copilot-agents/use-copilot-cli#use-custom-agents). * **Hooks**: Hooks allow you to execute custom shell commands at key points during agent execution, enabling you to add validation, logging, security scanning, or workflow automation. See [AUTOTITLE](/copilot/concepts/agents/coding-agent/about-hooks). * **Skills**: Skills allow you to enhance the ability of {% data variables.product.prodname_copilot_short %} to perform specialized tasks with instructions, scripts, and resources. For more information, see [AUTOTITLE](/copilot/concepts/agents/about-agent-skills). - +* **{% data variables.copilot.copilot_memory %}**: {% data variables.copilot.copilot_memory %} allows {% data variables.product.prodname_copilot_short %} to build a persistent understanding of your repository by storing "memories", which are pieces of information about coding conventions, patterns, and preferences that {% data variables.product.prodname_copilot_short %} deduces as it works. This reduces the need to repeatedly explain context in your prompts and makes future sessions more productive. For more information, see [AUTOTITLE](/copilot/concepts/agents/copilot-memory). ## Security considerations @@ -276,9 +293,9 @@ You can mitigate the risks associated with using the automatic approval options The default model used by {% data variables.copilot.copilot_cli %} is {% data variables.copilot.copilot_claude_sonnet_45 %}. {% data variables.product.github %} reserves the right to change this model. -You can change the model used by {% data variables.copilot.copilot_cli %} by using the `/model` slash command. Enter this command, then select a model from the list. +You can change the model used by {% data variables.copilot.copilot_cli %} by using the `/model` slash command or the `--model` command-line option. Enter this command, then select a model from the list. -Each time you submit a prompt to {% data variables.product.prodname_copilot_short %} in {% data variables.copilot.copilot_cli_short %}'s interactive mode, and each time you use {% data variables.copilot.copilot_cli_short %} in programmatic mode, your monthly quota of {% data variables.product.prodname_copilot_short %} premium requests is reduced by one, multiplied by the multiplier shown in parentheses in the model list. For example, `Claude Sonnet 4.5 (1x)` indicates that with this model each time you submit a prompt your quota of premium requests is reduced by one. For information about premium requests, see [AUTOTITLE](/copilot/managing-copilot/monitoring-usage-and-entitlements/about-premium-requests). +Each time you submit a prompt to {% data variables.product.prodname_copilot_short %} in {% data variables.copilot.copilot_cli_short %}'s interactive mode, and each time you use {% data variables.copilot.copilot_cli_short %} in programmatic mode, your monthly quota of {% data variables.product.prodname_copilot_short %} premium requests is reduced by one, multiplied by the multiplier shown in parentheses in the model list. For example, `Claude Sonnet 4.5 (1x)` indicates that with this model each time you submit a prompt your quota of premium requests is reduced by one. For information about premium requests, see [AUTOTITLE](/copilot/concepts/billing/copilot-requests). {% data reusables.cli.feedback %} diff --git a/content/copilot/concepts/agents/coding-agent/agent-management.md b/content/copilot/concepts/agents/coding-agent/agent-management.md index acedeaa85039..fb7fe4f3c15a 100644 --- a/content/copilot/concepts/agents/coding-agent/agent-management.md +++ b/content/copilot/concepts/agents/coding-agent/agent-management.md @@ -16,7 +16,11 @@ contentType: concepts AI agents are autonomous systems that can evaluate their environment, make decisions, and take actions to complete tasks. Agents can break down complex tasks into steps, use various tools and resources, plan their approach, and adapt based on human feedback until they accomplish their assigned objective. -{% data variables.copilot.copilot_coding_agent %} brings automation and assistance to every stage of the software development process on {% data variables.product.github %}. You can run multiple sessions of {% data variables.copilot.copilot_coding_agent %} concurrently, allowing you to efficiently delegate work items. Utilizing {% data variables.copilot.custom_agents_short %} you can build out a team of task-specific agents with customized system prompts to handle simpler tasks like writing tests and refactoring, giving you bandwidth to prioritize problem-solving and collaboration. See [AUTOTITLE](/copilot/concepts/agents/coding-agent/about-custom-agents). +{% data variables.copilot.copilot_coding_agent %} brings automation and assistance to every stage of the software development process on {% data variables.product.github %}. You can run multiple sessions of {% data variables.copilot.copilot_coding_agent %} concurrently, allowing you to efficiently delegate work items. + +Utilizing {% data variables.copilot.custom_agents_short %} you can build out a team of task-specific agents with customized system prompts to handle simpler tasks like writing tests and refactoring, giving you bandwidth to prioritize problem-solving and collaboration. See [AUTOTITLE](/copilot/concepts/agents/coding-agent/about-custom-agents). + +Model choice allows you to choose from a selection of AI models to use with your agents, each with its own particular strengths. See [AUTOTITLE](/copilot/reference/ai-models/supported-models). To learn more about {% data variables.copilot.copilot_coding_agent %}, see [AUTOTITLE](/copilot/concepts/agents/coding-agent/about-coding-agent). @@ -26,12 +30,13 @@ To learn more about {% data variables.copilot.copilot_coding_agent %}, see [AUTO From the Agents tab, you can: -* **Kick off new agent tasks**: Select any repository you have write access to, and optionally choose from {% data variables.copilot.custom_agents_short %} best suited for the task. See [AUTOTITLE](/copilot/how-tos/use-copilot-agents/coding-agent/create-a-pr). -* **Review the live session log, diff, and overview of changes**: Once {% data variables.product.prodname_copilot_short %} starts working, you can open the agent session to monitor agent activity. +* **Kick off new agent tasks**: Select an AI model of your choice, and optionally choose from {% data variables.copilot.custom_agents_short %} best suited for the task. See [AUTOTITLE](/copilot/how-tos/use-copilot-agents/coding-agent/create-a-pr). +* **Monitor live session logs**: Once {% data variables.product.prodname_copilot_short %} starts working, you can click any agent session to open the session log and follow its progress and thought process in real time. +* **Track active sessions**: You can view all active agent sessions that have been started in the repository. * **Steer agents mid-session**: If you realize you didn't scope a request correctly, or want {% data variables.product.prodname_copilot_short %} to use a specific tool or service, you can step in and provide **steering input** without stopping the run. Steering uses **one premium request** per message. See [AUTOTITLE](/copilot/how-tos/use-copilot-agents/coding-agent/track-copilot-sessions#steering-a-copilot-session-from-the-agents-tab). -* **Open a session in {% data variables.product.prodname_vscode_shortname %}**: When you want to start working on changes to an agent session in your local development environment, click the "Open in {% data variables.product.prodname_vscode_shortname %} Insiders" button to open the session in {% data variables.product.prodname_vscode_shortname %}. +* **Open a session in {% data variables.product.prodname_vscode_shortname %} or {% data variables.copilot.copilot_cli %}**: When you want to start working on changes to an agent session in your local development environment, click **{% octicon "vscode" aria-label="VS Code" %} Open in {% data variables.product.prodname_vscode_shortname %}** or **{% octicon "agent" aria-label="Agent" %} Continue in {% data variables.copilot.copilot_cli %}** to bring the session to your local machine. {% data reusables.copilot.coding-agent.use-latest-vscode %} -* **Review and merge agent code**: Once {% data variables.product.prodname_copilot_short %} completes a session, you can read a summary of the changes it made and scan the diff of the pull request to see if you want to request further improvements. If the changes look ready for a final review, you can jump right into the pull request from the agent session view to approve and merge. See [AUTOTITLE](/copilot/how-tos/use-copilot-agents/coding-agent/review-copilot-prs). +* **Review and merge agent code**: Once {% data variables.product.prodname_copilot_short %} completes a session, you can jump to the pull request to review the changes, request further improvements, or approve and merge. See [AUTOTITLE](/copilot/how-tos/use-copilot-agents/coding-agent/review-copilot-prs). ## Next steps diff --git a/content/copilot/concepts/auto-model-selection.md b/content/copilot/concepts/auto-model-selection.md index c52602e610f2..b9fc161de7c2 100644 --- a/content/copilot/concepts/auto-model-selection.md +++ b/content/copilot/concepts/auto-model-selection.md @@ -44,7 +44,7 @@ With {% data variables.copilot.copilot_auto_model_selection %}, you benefit from When you select **Auto** in {% data variables.copilot.copilot_chat_short %}, {% data variables.copilot.copilot_auto_model_selection_short_cap_a %} may choose from the following list of models, subject to your policies and subscription type. Models may change over time. * {% data variables.copilot.copilot_gpt_41 %} * {% data variables.copilot.copilot_gpt_5_mini %} - * {% data variables.copilot.copilot_gpt_51_codex_max %} + * {% data variables.copilot.copilot_gpt_52_codex %} * {% data variables.copilot.copilot_claude_haiku_45 %} * {% data variables.copilot.copilot_claude_sonnet_45 %} diff --git a/content/copilot/how-tos/use-copilot-agents/manage-agents.md b/content/copilot/how-tos/use-copilot-agents/manage-agents.md index ded7da257818..bd1bacc61e3e 100644 --- a/content/copilot/how-tos/use-copilot-agents/manage-agents.md +++ b/content/copilot/how-tos/use-copilot-agents/manage-agents.md @@ -15,13 +15,15 @@ contentType: how-tos ## 1. Select a repository and choose your agent 1. Start a new agent task. - - * Open the [Agents tab](https://github.com/copilot/agents?ref_product=copilot&ref_type=engagement&ref_style=text). - * Use the **Task** button or `/task` command from [{% data variables.copilot.copilot_chat_short %}](https://github.com/copilot?ref_product=copilot&ref_type=engagement&ref_style=text). + + * Open the **{% octicon "agent" aria-label="The Agents icon" %} Agents** tab in a repository + * Open the [Agents page](https://github.com/copilot/agents?ref_product=copilot&ref_type=engagement&ref_style=text) + * Use the **Task** button or `/task` command from [{% data variables.copilot.copilot_chat_short %}](https://github.com/copilot?ref_product=copilot&ref_type=engagement&ref_style=text) * Open the Agents panel by clicking the {% octicon "agent" aria-label="The Agents icon" %} at the top of any page on {% data variables.product.github %} -1. Using the dropdown menu, select the repository you want {% data variables.product.prodname_copilot_short %} to work in. +1. Using the dropdown menu, select the repository you want {% data variables.product.prodname_copilot_short %} to work in if needed. 1. Optionally, select a base branch for {% data variables.product.prodname_copilot_short %}'s pull request. {% data reusables.copilot.optional-select-custom-agent %} +1. Optionally, select the **CURRENT-MODEL** {% octicon "chevron-down" aria-hidden="true" aria-label="chevron-down" %} dropdown menu, then click the AI model of your choice. 1. Type a prompt describing your request. For example: ```text @@ -36,11 +38,9 @@ For more information on ways to start new agent tasks, see [AUTOTITLE](/copilot/ ## 2. Monitor agent activity -Once {% data variables.product.prodname_copilot_short %} starts working, it will continue to update the session log and overview with its progress and thought process. - -Each session displays its status. Click on a session to open the session log, where you can monitor the agent's progress and the session length. You can view the overview, file diff, premium request usage, and session count by clicking the **Open workbench** button. +Once {% data variables.product.prodname_copilot_short %} starts working, it will continue to update the session log with its progress and thought process. -![Screenshot of the top-right corner of the agents tab on {% data variables.product.github %}. The "Open workbench button is highlighted in a dark orange outline.](/assets/images/help/copilot/coding-agent/open-workbench.png) +Each session displays its status. Click on a session to open the session log, where you can monitor the agent's progress, see the tools it's using, and track how long the session has been running. Agent sessions can also be tracked from the {% data variables.product.prodname_cli %}, {% data variables.product.prodname_mobile %}, {% data variables.product.prodname_vscode %}, Raycast, and JetBrains IDEs. For more information, see [AUTOTITLE](/copilot/how-tos/use-copilot-agents/coding-agent/track-copilot-sessions). @@ -65,10 +65,26 @@ In the prompt box under the agent session log, prompt {% data variables.product. You can guide {% data variables.product.prodname_copilot_short %} in your local development environment on further changes, or make any edits that require human expertise. -Click the **Code** button in the top-right of the agent session view and select "Open in {% data variables.product.prodname_vscode_shortname %} Insiders" to launch the session directly in {% data variables.product.prodname_vscode_shortname %}. +### {% data variables.product.prodname_vscode_shortname %} + +At the bottom of the agent session view, click the **{% octicon "vscode" aria-label="VS Code" %} Open in {% data variables.product.prodname_vscode_shortname %}** button to launch the session directly in {% data variables.product.prodname_vscode_shortname %}. {% data reusables.copilot.coding-agent.use-latest-vscode %} +### {% data variables.copilot.copilot_cli %} + 1. At the bottom of the agent session view, click the dropdown list next to **{% octicon "vscode" aria-label="VS Code" %} Open in {% data variables.product.prodname_vscode_shortname %}**. + 1. Click **{% octicon "agent" aria-label="Agent" %} Continue in {% data variables.copilot.copilot_cli %}** to copy the `copilot --resume=` command to your clipboard. + ![Screenshot of the session action dropdown list, "Continue in Copilot CLI" is highlighted with a dark orange outline.](/assets/images/help/copilot/coding-agent/open-agent-session-in-copilot-cli.png) + 1. In your terminal, paste and run the command to resume the agent session. + ## 5. Review and merge agent code -Once {% data variables.product.prodname_copilot_short %} completes a session, you can click **Open workbench** and click the **Overview** tab to read through the summary of changes {% data variables.product.prodname_copilot_short %} has made. Select the **Files changed** tab to scan the diff of the pull request. If the changes look ready for a final review, navigate to the pull request to approve and merge the changes. See [AUTOTITLE](/copilot/how-tos/use-copilot-agents/coding-agent/review-copilot-prs). +Once {% data variables.product.prodname_copilot_short %} completes a session, you can navigate to the pull request to review the changes. From the pull request, you can scan the diff, request further improvements from {% data variables.product.prodname_copilot_short %}, or approve and merge the changes. See [AUTOTITLE](/copilot/how-tos/use-copilot-agents/coding-agent/review-copilot-prs). + +## 6. Archive agent sessions + +Sessions that have been stopped can be archived to remove them from the sessions list. + +1. Open the agent session you want to archive. +1. In the top right corner, click **{% octicon "kebab-horizontal" aria-label="More actions" %}**, then click **{% octicon "inbox" aria-hidden="true" aria-label="inbox" %} Archive session**. +1. In the dialog box that opens, click **Yes, archive**. diff --git a/content/copilot/how-tos/use-copilot-agents/use-copilot-cli.md b/content/copilot/how-tos/use-copilot-agents/use-copilot-cli.md index 1aa714703860..5a81beb417f5 100644 --- a/content/copilot/how-tos/use-copilot-agents/use-copilot-cli.md +++ b/content/copilot/how-tos/use-copilot-agents/use-copilot-cli.md @@ -64,9 +64,9 @@ Install {% data variables.copilot.copilot_cli_short %}. See [AUTOTITLE](/copilot **2. Yes, and approve TOOL for the rest of the running session**: - Allow {% data variables.product.prodname_copilot_short %} to use this tool—with any options—without asking again, for the rest of the currently running session. You will have to approve the command again in future sessions. + Allow {% data variables.product.prodname_copilot_short %} to use this tool—with any options—without asking again, for the rest of the currently running session. Any pending parallel permission requests of the same type will be auto-approved. You will have to approve the command again in future sessions. - Choosing this option is useful for a many tools—such as `chmod`—as it avoids you having to approve similar commands repeatedly in the same session. However, you should be aware of the security implications of this option. Choosing this option for the command `rm`, for example, would allow {% data variables.product.prodname_copilot_short %} to delete any file in or below the current folder without asking for your approval. + Choosing this option is useful for many tools—such as `chmod`—as it avoids you having to approve similar commands repeatedly in the same session. However, be aware of the security implications of this option. For example, choosing this option for the command `rm` would allow {% data variables.product.prodname_copilot_short %} to delete any file in the current directory or its subdirectories without asking for your approval. **3. No, and tell Copilot what to do differently (Esc)**: @@ -74,6 +74,8 @@ Install {% data variables.copilot.copilot_cli_short %}. See [AUTOTITLE](/copilot For example, if you ask {% data variables.product.prodname_copilot_short %} to create a bash script but you do not want to use the script {% data variables.product.prodname_copilot_short %} suggests, you can stop the current operation and enter a new prompt, such as: `Continue the previous task but include usage instructions in the script`. + When you reject a tool permission request, you can also give {% data variables.product.prodname_copilot_short %} inline feedback about the rejection so it can adapt its approach without stopping entirely. + ## Permissions {% data variables.copilot.copilot_cli_short %} uses a permissions system to control access to paths and URLs. At times, path and URL permission checks utilize heuristic-based detection, which has limitations to be aware of. @@ -116,6 +118,14 @@ Optimize your experience with {% data variables.copilot.copilot_cli_short %} wit If you enter a prompt and then decide you want to stop {% data variables.product.prodname_copilot_short %} from completing the task while it is still "Thinking," press Esc. +### Use plan mode + +Plan mode lets you collaborate with {% data variables.product.prodname_copilot_short %} on an implementation plan before any code is written. Press Shift+Tab to cycle in and out of plan mode. + +### Steer the conversation while {% data variables.product.prodname_copilot_short %} is thinking + +You can interact with {% data variables.product.prodname_copilot_short %} while it's thinking. Send follow-up messages to steer the conversation in a different direction, or queue additional instructions for {% data variables.product.prodname_copilot_short %} to process after it finishes its current response. + ### Include a specific file in your prompt To add a specific file to your prompt, use `@` followed by the relative path to the file. For example: `Explain @config/ci/ci-required-checks.yml` or `Fix the bug in @src/app.js`. This adds the contents of the file to your prompt as context for {% data variables.product.prodname_copilot_short %}. @@ -132,7 +142,7 @@ You can also add a trusted directory manually at any time by using the slash com /add-dir /path/to/directory ``` -If all of the files you want to work with are in a different location, you can switch the current working directory without starting a new {% data variables.copilot.copilot_cli_short %} session by using the slash command: +If all of the files you want to work with are in a different location, you can switch the current working directory without starting a new {% data variables.copilot.copilot_cli_short %} session by using either the `/cwd` or `/cd` slash commands: ```shell /cwd /path/to/directory @@ -156,13 +166,19 @@ You can delegate a task using the slash command, followed by a prompt: /delegate complete the API integration tests and fix any failing edge cases ``` +Alternatively, prefix a prompt with `&` to delegate it: + +```shell +& complete the API integration tests and fix any failing edge cases +``` + {% data variables.product.prodname_copilot_short %} will ask to commit any of your unstaged changes as a checkpoint in a new branch it creates. {% data variables.copilot.copilot_coding_agent %} will open a draft pull request, make changes in the background, and request a review from you. {% data variables.product.prodname_copilot_short %} will provide a link to the pull request and agent session on {% data variables.product.github %} once the session begins. ### Resume an interactive session -You can use the `--resume` command line option to cycle through and resume local and remote interactive sessions, allowing you to pick up right where you left off with your existing context. You can kick off a {% data variables.copilot.copilot_coding_agent %} session on {% data variables.product.github %}, and then use {% data variables.copilot.copilot_cli %} to bring that session to your local environment. +You can use the `--resume` command line option or the `/resume` slash command to cycle through and resume local and remote interactive sessions, allowing you to pick up right where you left off with your existing context. You can kick off a {% data variables.copilot.copilot_coding_agent %} session on {% data variables.product.github %}, and then use {% data variables.copilot.copilot_cli %} to bring that session to your local environment. You can quickly resume the most recently closed local session by using the `--continue` command line option. @@ -261,7 +277,19 @@ Details of your configured MCP servers are stored in the `mcp-config.json` file, * `/context`: Provides a visual overview of your current token usage * `/compact`: Manually compresses your conversation history to free up context space -{% data variables.copilot.copilot_cli %} automatically compresses your history when approaching 95% of the token limit. When you have less than 20% of a model's token limit remaining, a warning will be displayed indicating the context will be truncated when the limit is reached. +{% data variables.copilot.copilot_cli %} automatically compresses your history in the background when your conversation approaches 95% of the token limit, without interrupting your workflow. + +### Review code changes + +You can use the `/review` slash command to have {% data variables.product.prodname_copilot_short %} analyze code changes without leaving the CLI. This lets you get quick feedback on your changes prior to committing. + +### Enable all permissions + +For situations where you trust {% data variables.product.prodname_copilot_short %} to run freely, you can use the `--allow-all` or `--yolo` flags to enable all permissions at once. + +### Toggle reasoning visibility + +Press Ctrl+T to show or hide the model's reasoning process while it generates a response. This setting persists across sessions, allowing you to observe how {% data variables.product.prodname_copilot_short %} works through complex problems. ## Find out more diff --git a/content/copilot/reference/copilot-usage-metrics/copilot-usage-metrics.md b/content/copilot/reference/copilot-usage-metrics/copilot-usage-metrics.md index dda5aa024e96..d9962ce915a8 100644 --- a/content/copilot/reference/copilot-usage-metrics/copilot-usage-metrics.md +++ b/content/copilot/reference/copilot-usage-metrics/copilot-usage-metrics.md @@ -41,7 +41,7 @@ These metrics appear directly in the {% data variables.product.prodname_copilot_ | Model usage per day | Daily breakdown of chat model usage. | | Model usage per chat mode | Model usage by {% data variables.product.prodname_copilot_short %} feature (Ask, Edit, Agent). | | Model usage per language | Distribution of languages broken down by model. | -| Most used chat model | The most frequently used chat model in the current calendar month. | +| Most used chat model | The most frequently used chat model in the last 28 days. | | Requests per chat mode | Number of chat requests by mode (Ask, Edit, Agent). | ## Code generation dashboard metrics @@ -50,8 +50,8 @@ These metrics appear in the code generation dashboard and provide a breakdown of | Metric | Description | |:--|:--| -| Lines of code changed with AI | Total lines of code added and deleted across all modes during the current calendar month. | -| Agent contribution | Percentage of lines of code added and deleted by agents (including Edit, Agent, and custom modes) during the current calendar month. | +| Lines of code changed with AI | Total lines of code added and deleted across all modes in the last 28 days. | +| Agent contribution | Percentage of lines of code added and deleted by agents (including Edit, Agent, and custom modes) in the last 28 days. | | Average lines deleted by agent | Average number of lines automatically deleted by agents on behalf of active users during the current calendar month. | | Daily total of lines added and deleted | Total number of lines added to and deleted from the codebase across all modes for each day. | | User-initiated code changes | Lines suggested or manually added by users through code completions and chat panel actions (insert, copy, or apply). | diff --git a/content/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax.md b/content/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax.md index f426e12ea8c7..910ddae27080 100644 --- a/content/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax.md +++ b/content/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax.md @@ -24,7 +24,7 @@ To create a heading, add one to six # symbols before your heading tex ![Screenshot of rendered GitHub Markdown showing sample h1, h2, and h3 headers, which descend in type size and visual weight to show hierarchy level.](/assets/images/help/writing/headings-rendered.png) -When you use two or more headings, GitHub automatically generates a table of contents that you can access by clicking {% octicon "list-unordered" aria-label="The unordered list icon" %} within the file header. Each heading title is listed in the table of contents and you can click a title to navigate to the selected section. +When you use two or more headings, GitHub automatically generates a table of contents that you can access by clicking the "Outline" menu icon {% octicon "list-unordered" aria-label="Table of Contents" %} within the file header. Each heading title is listed in the table of contents and you can click a title to navigate to the selected section. ![Screenshot of a README file with the drop-down menu for the table of contents exposed. The table of contents icon is outlined in dark orange.](/assets/images/help/repository/headings-toc.png) diff --git a/content/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-readmes.md b/content/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-readmes.md index cae4d6ac9f3f..e2466d4fe321 100644 --- a/content/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-readmes.md +++ b/content/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-readmes.md @@ -38,7 +38,7 @@ When your README is viewed on GitHub, any content beyond 500 KiB will be truncat ## Auto-generated table of contents for markdown files -For the rendered view of any Markdown file in a repository, including README files, {% data variables.product.github %} will automatically generate a table of contents based on section headings. You can view the table of contents for a README file by clicking the {% octicon "list-unordered" aria-label="Table of Contents" %} menu icon in the top corner of the rendered page. +For the rendered view of any Markdown file in a repository, including README files, {% data variables.product.github %} will automatically generate a table of contents based on section headings. You can view the table of contents for a README file by clicking the "Outline" menu icon {% octicon "list-unordered" aria-label="Table of Contents" %} in the top corner of the rendered page. ## Section links in markdown files and blob pages diff --git a/data/reusables/copilot/coding-agent/agent-management-intro.md b/data/reusables/copilot/coding-agent/agent-management-intro.md index d4731bb8b73e..6cdf8cd973ea 100644 --- a/data/reusables/copilot/coding-agent/agent-management-intro.md +++ b/data/reusables/copilot/coding-agent/agent-management-intro.md @@ -1,4 +1 @@ -When utilizing {% data variables.product.github %}'s agentic features, you can use the [Agents tab](https://github.com/copilot/agents?ref_product=copilot&ref_type=engagement&ref_style=text) as a centralized control page where you can initiate, monitor, and manage agent tasks across {% data variables.product.github %}. - ->[!NOTE] -> The Agents tab is in public preview and subject to change. +When utilizing {% data variables.product.github %}'s agentic features, you can use the **Agents** tab within a repository that has {% data variables.copilot.copilot_coding_agent %} enabled to initiate, monitor, and manage agent sessions without leaving your workflow. You can also use the [Agents page](https://github.com/copilot/agents?ref_product=copilot&ref_type=engagement&ref_style=text) to view and start agent sessions. To learn how to enable {% data variables.copilot.copilot_coding_agent %}, see [AUTOTITLE](/copilot/concepts/agents/coding-agent/access-management). diff --git a/data/reusables/copilot/open-agents-panel-or-page.md b/data/reusables/copilot/open-agents-panel-or-page.md index d38706d05205..e155f4fe6356 100644 --- a/data/reusables/copilot/open-agents-panel-or-page.md +++ b/data/reusables/copilot/open-agents-panel-or-page.md @@ -1,4 +1,5 @@ 1. Open the agents panel or tab: + * Open the **{% octicon "agent" aria-label="The Agents icon" %} Agents** tab in a repository. + * **Navigate to the agents page**: Go to [github.com/copilot/agents](https://github.com/copilot/agents?ref_product=copilot&ref_type=engagement&ref_style=text). You can also get here by opening the agents panel, then clicking **View all**. * **Open the agents panel**: Click {% octicon "agent" aria-label="The Agents icon" %} in the navigation bar at the top right of {% data variables.product.github %}. - * **Navigate to the agents tab**: Go to [github.com/copilot/agents](https://github.com/copilot/agents?ref_product=copilot&ref_type=engagement&ref_style=text). You can also get here by opening the agents panel, then clicking **View all**. diff --git a/src/links/lib/extract-links.ts b/src/links/lib/extract-links.ts index 86f70f5fb5d2..12e8eec84214 100644 --- a/src/links/lib/extract-links.ts +++ b/src/links/lib/extract-links.ts @@ -337,3 +337,21 @@ export function checkInternalLink( return { exists: false, isRedirect: false } } + +/** + * Check if an asset link points to an existing file on disk + */ +export function checkAssetLink(href: string): boolean { + if (!href.startsWith('/assets/')) { + return false // Not an asset link + } + const assetPath = path.resolve(href.slice(1)) // Remove leading / + return fs.existsSync(assetPath) +} + +/** + * Check if a link is an asset link (starts with /assets/) + */ +export function isAssetLink(href: string): boolean { + return href.startsWith('/assets/') +} diff --git a/src/links/lib/link-report.ts b/src/links/lib/link-report.ts index 79b98f4b3f2f..82c31efc81ad 100644 --- a/src/links/lib/link-report.ts +++ b/src/links/lib/link-report.ts @@ -122,9 +122,7 @@ ${errors const warningSection = warnings.length > 0 - ? `### ⚠️ ${warnings.length} Redirect${warnings.length === 1 ? '' : 's'} to Update - -${warnings.map((group) => `- \`${group.target}\` → \`${group.occurrences[0]?.redirectTarget || '?'}\``).join('\n')} + ? `### ℹ️ ${warnings.length} redirect${warnings.length === 1 ? '' : 's'} to update ` : '' diff --git a/src/links/scripts/check-links-internal.ts b/src/links/scripts/check-links-internal.ts index bd3c4cd7801f..a28ec16f339e 100644 --- a/src/links/scripts/check-links-internal.ts +++ b/src/links/scripts/check-links-internal.ts @@ -26,7 +26,12 @@ import warmServer from '@/frame/lib/warm-server' import { renderContent } from '@/content-render/index' import { allVersions, allVersionKeys } from '@/versions/lib/all-versions' import languages from '@/languages/lib/languages-server' -import { normalizeLinkPath, checkInternalLink } from '@/links/lib/extract-links' +import { + normalizeLinkPath, + checkInternalLink, + checkAssetLink, + isAssetLink, +} from '@/links/lib/extract-links' import { type BrokenLink, generateInternalLinkReport, @@ -183,6 +188,19 @@ async function checkVersion( for (const link of links) { if (isExcludedLink(link.href)) continue + // Check if this is an asset link (images, etc.) - verify file exists on disk + if (isAssetLink(link.href)) { + if (!checkAssetLink(link.href)) { + brokenLinks.push({ + href: link.href, + file: page.relativePath, + lines: [0], + text: link.text, + }) + } + continue + } + const normalized = normalizeLinkPath(link.href) const result = checkInternalLink(normalized, pageMap, redirects) @@ -346,10 +364,14 @@ async function main() { console.log(`Created report issue: ${newReport.html_url}`) } - // Exit with error if broken links found - if (result.brokenLinks.length > 0) { - process.exit(1) - } + // Don't exit with error - the issue report is the mechanism for docs-content to act on broken links + // Exiting with error would trigger docs-alerts which only engineering monitors + console.log('') + console.log( + chalk.yellow( + 'Note: Report generated. Broken links should be fixed via the issue created in docs-content.', + ), + ) } // Run if invoked directly diff --git a/src/links/scripts/check-links-pr.ts b/src/links/scripts/check-links-pr.ts index f4b8e24264dc..d6257457b10f 100644 --- a/src/links/scripts/check-links-pr.ts +++ b/src/links/scripts/check-links-pr.ts @@ -24,6 +24,8 @@ import { extractLinksWithLiquid, createLiquidContext, checkInternalLink, + checkAssetLink, + isAssetLink, getRelativePath, } from '@/links/lib/extract-links' import { type BrokenLink, generatePRComment, groupBrokenLinks } from '@/links/lib/link-report' @@ -74,6 +76,20 @@ async function checkFile( totalLinksChecked = internalLinks.length for (const link of internalLinks) { + // Check if this is an asset link (images, etc.) - verify file exists on disk + if (isAssetLink(link.href)) { + if (!checkAssetLink(link.href)) { + brokenLinks.push({ + href: link.href, + file: getRelativePath(filePath), + lines: [link.line], + text: link.text, + isAutotitle: link.isAutotitle, + }) + } + continue + } + const result = checkInternalLink(link.href, pageMap, redirects) if (!result.exists) { diff --git a/src/links/tests/extract-links.ts b/src/links/tests/extract-links.ts index 1f8edee288db..c70ace3326e7 100644 --- a/src/links/tests/extract-links.ts +++ b/src/links/tests/extract-links.ts @@ -3,6 +3,8 @@ import { extractLinksFromMarkdown, normalizeLinkPath, checkInternalLink, + checkAssetLink, + isAssetLink, } from '../lib/extract-links' describe('extractLinksFromMarkdown', () => { @@ -209,3 +211,31 @@ describe('checkInternalLink', () => { expect(result.isRedirect).toBe(false) }) }) + +describe('isAssetLink', () => { + test('returns true for asset paths', () => { + expect(isAssetLink('/assets/images/help/test.png')).toBe(true) + expect(isAssetLink('/assets/cb-12345/images/help/test.png')).toBe(true) + }) + + test('returns false for non-asset paths', () => { + expect(isAssetLink('/actions/getting-started')).toBe(false) + expect(isAssetLink('/repositories/overview')).toBe(false) + expect(isAssetLink('https://example.com/assets/image.png')).toBe(false) + }) +}) + +describe('checkAssetLink', () => { + test('returns true for existing asset files', () => { + // Use a known existing asset file + expect(checkAssetLink('/assets/images/help/writing/headings-rendered.png')).toBe(true) + }) + + test('returns false for non-existent asset files', () => { + expect(checkAssetLink('/assets/images/does-not-exist-12345.png')).toBe(false) + }) + + test('returns false for non-asset paths', () => { + expect(checkAssetLink('/actions/getting-started')).toBe(false) + }) +}) diff --git a/src/links/tests/link-report.ts b/src/links/tests/link-report.ts index 028894fdb6b8..8723a036998f 100644 --- a/src/links/tests/link-report.ts +++ b/src/links/tests/link-report.ts @@ -269,9 +269,9 @@ describe('generatePRComment', () => { const comment = generatePRComment(links) - expect(comment).toContain('Redirect') - expect(comment).toContain('`/old`') - expect(comment).toContain('`/new`') + // Redirects now show a compact summary with info icon + expect(comment).toContain('redirect') + expect(comment).toContain('ℹ️') }) test('limits occurrences to 3 per group', () => {